1/* 2 * Copyright (C) 2011 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "HTTPRequest.h" 28 29#include <wtf/text/CString.h> 30 31using namespace WebCore; 32 33namespace WebKit { 34 35PassRefPtr<HTTPRequest> HTTPRequest::parseHTTPRequestFromBuffer(const char* data, size_t length, String& failureReason) 36{ 37 if (!length) { 38 failureReason = "No data to parse."; 39 return 0; 40 } 41 42 // Request we will be building. 43 RefPtr<HTTPRequest> request = HTTPRequest::create(); 44 45 // Advance a pointer through the data as needed. 46 const char* pos = data; 47 size_t remainingLength = length; 48 49 // 1. Parse Method + URL. 50 size_t requestLineLength = request->parseRequestLine(pos, remainingLength, failureReason); 51 if (!requestLineLength) 52 return 0; 53 pos += requestLineLength; 54 remainingLength -= requestLineLength; 55 56 // 2. Parse HTTP Headers. 57 size_t headersLength = request->parseHeaders(pos, remainingLength, failureReason); 58 if (!headersLength) 59 return 0; 60 pos += headersLength; 61 remainingLength -= headersLength; 62 63 // 3. Parse HTTP Data. 64 size_t dataLength = request->parseRequestBody(pos, remainingLength); 65 pos += dataLength; 66 remainingLength -= dataLength; 67 68 // We should have processed the entire input. 69 ASSERT(!remainingLength); 70 return request.release(); 71} 72 73size_t HTTPRequest::parseRequestLine(const char* data, size_t length, String& failureReason) 74{ 75 String url; 76 size_t result = parseHTTPRequestLine(data, length, failureReason, m_requestMethod, url, m_httpVersion); 77 m_url = URL(URL(), url); 78 return result; 79} 80 81size_t HTTPRequest::parseHeaders(const char* data, size_t length, String& failureReason) 82{ 83 const char* p = data; 84 const char* end = data + length; 85 String name; 86 String value; 87 for (; p < data + length; p++) { 88 size_t consumedLength = parseHTTPHeader(p, end - p, failureReason, name, value); 89 if (!consumedLength) 90 return 0; 91 p += consumedLength; 92 if (name.isEmpty()) 93 break; 94 m_headerFields.add(name, value); 95 } 96 97 // If we got here and "name" is empty, it means the headers are valid and ended with a 98 // blank line (parseHTTPHeader returns "name" as empty if parsing a blank line), otherwise 99 // the headers didn't end with a blank line and we have an invalid request. 100 // See also http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html 101 if (!name.isEmpty()) 102 return 0; 103 return p - data; 104} 105 106size_t HTTPRequest::parseRequestBody(const char* data, size_t length) 107{ 108 return parseHTTPRequestBody(data, length, m_body); 109} 110 111HTTPRequest::HTTPRequest() 112 : m_httpVersion(WebCore::Unknown) 113{ 114} 115 116HTTPRequest::HTTPRequest(const String& requestMethod, const URL& url, HTTPVersion version) 117 : m_url(url) 118 , m_httpVersion(version) 119 , m_requestMethod(requestMethod) 120{ 121} 122 123HTTPRequest::~HTTPRequest() 124{ 125} 126 127} // namespace WebCore 128