Web Inspector: Do not try to parse incomplete HTTP requests
[WebKit-https.git] / Source / WebKit2 / UIProcess / InspectorServer / HTTPRequest.cpp
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
31 using namespace WebCore;
32
33 namespace WebKit {
34
35 PassRefPtr<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
73 size_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 = KURL(KURL(), url);
78     return result;
79 }
80
81 size_t HTTPRequest::parseHeaders(const char* data, size_t length, String& failureReason)
82 {
83     const char* p = data;
84     const char* end = data + length;
85     AtomicString 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
106 size_t HTTPRequest::parseRequestBody(const char* data, size_t length)
107 {
108     return parseHTTPRequestBody(data, length, m_body);
109 }
110
111 HTTPRequest::HTTPRequest()
112     : m_httpVersion(WebCore::Unknown)
113 {
114 }
115
116 HTTPRequest::HTTPRequest(const String& requestMethod, const KURL& url, HTTPVersion version)
117     : m_url(url)
118     , m_httpVersion(version)
119     , m_requestMethod(requestMethod)
120 {
121 }
122
123 HTTPRequest::~HTTPRequest()
124 {
125 }
126
127 } // namespace WebCore