Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_BROWSER_CHROMEOS_GDATA_TEST_SERVERS_HTTP_REQUEST_H_ | |
| 6 #define CHROME_BROWSER_CHROMEOS_GDATA_TEST_SERVERS_HTTP_REQUEST_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <string> | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "googleurl/src/gurl.h" | |
| 13 | |
| 14 namespace gdata { | |
| 15 namespace test_servers { | |
| 16 | |
| 17 enum HTTP_METHOD { | |
|
satorux1
2012/10/12 08:29:18
HttpMethod
mtomasz
2012/10/12 11:09:46
Here I am confused. On chromium website they sugge
satorux1
2012/10/16 03:12:18
MACRO_STYLE is for members. The enum types should
| |
| 18 UNKNOWN = 0, | |
| 19 OPTIONS = 1, | |
| 20 GET = 2, | |
| 21 HEAD = 4, | |
|
satorux1
2012/10/12 08:29:18
The following would be better:
OPTIONS = 1 << 0,
mtomasz
2012/10/12 11:09:46
I wanted to use it in the future for bit sets, lik
| |
| 22 POST = 8, | |
| 23 PUT = 16, | |
| 24 DELETE = 32, | |
| 25 TRACE = 64, | |
| 26 CONNECT = 128, | |
| 27 CUSTOM = 256 | |
|
satorux1
2012/10/12 08:29:18
Do we need all the method types? I'd suggest to re
mtomasz
2012/10/12 11:09:46
Done.
| |
| 28 }; | |
| 29 | |
| 30 // Wraps the HTTP request. Since it can be big, use scoped_ptr to pass it | |
| 31 // instead of copying. | |
| 32 class HttpRequest { | |
| 33 public: | |
| 34 HttpRequest() : method(UNKNOWN) {} | |
| 35 virtual ~HttpRequest() {} | |
| 36 | |
| 37 GURL url; | |
| 38 HTTP_METHOD method; | |
| 39 std::string raw_url; | |
| 40 std::string protocol; | |
| 41 std::map<std::string, std::string> headers; | |
| 42 std::string content; | |
| 43 | |
| 44 private: | |
| 45 DISALLOW_COPY_AND_ASSIGN(HttpRequest); | |
| 46 }; | |
| 47 | |
| 48 // Parses the input data and produces valid HttpRequest objects. The common | |
| 49 // use is as below: | |
| 50 // HttpRequestParser parser; | |
| 51 // (...) | |
| 52 // void OnDataChunkReceived(Socket* socket, const char* data, int size) { | |
| 53 // parser.ProcessChunk(data, size); | |
| 54 // STATE parser_state; | |
| 55 // while ((parser_state = ParseRequest()) == HttpRequestParser::READY) { | |
| 56 // scoped_ptr<HttpRequest> request = parser.GetRequest(); | |
| 57 // (... process the request ...) | |
| 58 // } | |
| 59 // if (parser_state == HttpRequestParser::SYNTAX_ERROR) | |
| 60 // socket.Close(); | |
| 61 class HttpRequestParser { | |
| 62 public: | |
| 63 // State of the parser. | |
| 64 enum STATE { | |
|
satorux1
2012/10/12 08:29:18
Enum names should look like State
| |
| 65 REQUEST_LINE, | |
| 66 HEADER_LINE, | |
| 67 DATA, | |
| 68 READY, | |
| 69 SYNTAX_ERROR | |
|
satorux1
2012/10/12 08:29:18
Please add , at the end. it makes slightly easier
mtomasz
2012/10/12 11:09:46
Done.
| |
| 70 }; | |
|
satorux1
2012/10/12 08:29:18
Please add comments for each state.
mtomasz
2012/10/12 11:09:46
Done.
| |
| 71 | |
| 72 HttpRequestParser(); | |
| 73 virtual ~HttpRequestParser(); | |
| 74 | |
| 75 // Adds chunk of data into the internal buffer. | |
| 76 virtual void ProcessChunk(const char *data, int length); | |
| 77 | |
| 78 // Parses the http request (including data - if provided) according to: | |
| 79 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html. | |
| 80 // If returns READY, then it means that the whole request has been found | |
| 81 // in the internal buffer (and parsed). After calling GetRequest(), it will be | |
| 82 // ready to parse another request. If the parser enters the SYNTAX_ERROR | |
| 83 // state, then no further parsing will possible. | |
| 84 STATE ParseRequest(); | |
| 85 | |
| 86 // Retrieves parsed request. Can be only called, when the parser is in READY | |
| 87 // state. You can call it once, since it clears the internal request builder | |
| 88 // after a call. | |
| 89 scoped_ptr<HttpRequest> GetRequest(); | |
| 90 | |
| 91 private: | |
| 92 // This is a type of token for ShiftToken() method. IDENTIFIER is a token | |
| 93 // ended with a space, HEADER_KEY is ended with colon, LINE is a token | |
| 94 // including anything until the first \r\n occurence. | |
| 95 enum SHIFT_TOKEN_TYPE { | |
| 96 IDENTIFIER, | |
| 97 HEADER_KEY, | |
| 98 LINE, | |
| 99 }; | |
| 100 | |
| 101 std::string buffer_; | |
| 102 scoped_ptr<HttpRequest> request_builder_; | |
| 103 STATE state_; | |
| 104 | |
| 105 int buffer_position_; | |
| 106 int crlf_position_; | |
| 107 int crlf_checked_position_; | |
| 108 int current_content_length_; | |
| 109 | |
| 110 // Received a token from the internal buffer and shifts the buffer's pointer. | |
| 111 virtual std::string ShiftToken(SHIFT_TOKEN_TYPE token_type); | |
| 112 | |
| 113 // Shifts \r\n from the current position in the internal buffer. If not found, | |
| 114 // then returns false. | |
| 115 virtual bool ShiftCrLf(); | |
| 116 | |
| 117 // Shifts |length| number of bytes from the current position in the buffer. | |
| 118 // Passed argument's value must be less or equal to available bytes in the | |
| 119 // internal buffer (from the current position). Returned pointer is not a | |
| 120 // string, but a pointer to the requested data. Especially, it is not null- | |
| 121 // terminated. | |
| 122 virtual const char* ShiftData(int length); | |
|
satorux1
2012/10/12 08:29:18
You might want to use StringPiece instead of char*
mtomasz
2012/10/12 11:09:46
Done.
| |
| 123 | |
| 124 // Skips all the spaces in the beginning of the current position of the | |
| 125 // internal buffer. | |
| 126 virtual void SkipSpaces(); | |
| 127 | |
| 128 // This helper function tells if there is a reason to process new data in | |
| 129 // the internal buffer. Parsing the request is performed line by line for | |
| 130 // headers, however for content it is parsed as soon as new chunk arrives. | |
| 131 virtual bool ShouldParseBuffer(); | |
| 132 | |
| 133 // Helper function, updates the |crlf_position_| member with a valid value. | |
| 134 // The member stores position of the first \r\n occurence in the internal | |
| 135 // buffer after the previous one. Returns true if the CrLF sequence was | |
| 136 // found. | |
| 137 virtual bool FindNextCrLf(); | |
| 138 }; | |
| 139 | |
| 140 } // namespace test_servers | |
| 141 } // namespace gdata | |
| 142 | |
| 143 #endif // CHROME_BROWSER_CHROMEOS_GDATA_TEST_SERVERS_HTTP_REQUEST_H_ | |
| OLD | NEW |