Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(470)

Side by Side Diff: net/tools/flip_server/balsa_frame.h

Issue 25085002: Break out balsa and epoll_server from net/tools/flip_server. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/tools/flip_server/balsa_enums.h ('k') | net/tools/flip_server/balsa_frame.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 NET_TOOLS_FLIP_SERVER_BALSA_FRAME_H_
6 #define NET_TOOLS_FLIP_SERVER_BALSA_FRAME_H_
7
8 #include <strings.h>
9
10 #include <utility>
11 #include <vector>
12
13 #include "base/compiler_specific.h"
14 #include "base/port.h"
15 #include "net/tools/flip_server/balsa_enums.h"
16 #include "net/tools/flip_server/balsa_headers.h"
17 #include "net/tools/flip_server/balsa_visitor_interface.h"
18 #include "net/tools/flip_server/buffer_interface.h"
19 #include "net/tools/flip_server/http_message_constants.h"
20 #include "net/tools/flip_server/simple_buffer.h"
21
22 // For additional debug output, uncomment the following:
23 // #define DEBUGFRAMER 1
24
25 namespace net {
26
27 // BalsaFrame is a 'Model' of a framer (haha).
28 // It exists as a proof of concept headers framer.
29 class BalsaFrame {
30 public:
31 typedef std::vector<std::pair<size_t, size_t> > Lines;
32
33 typedef BalsaHeaders::HeaderLineDescription HeaderLineDescription;
34 typedef BalsaHeaders::HeaderLines HeaderLines;
35 typedef BalsaHeaders::HeaderTokenList HeaderTokenList;
36
37 // TODO(fenix): get rid of the 'kValidTerm*' stuff by using the 'since last
38 // index' strategy. Note that this implies getting rid of the HeaderFramed()
39
40 static const uint32 kValidTerm1 = '\n' << 16 |
41 '\r' << 8 |
42 '\n';
43 static const uint32 kValidTerm1Mask = 0xFF << 16 |
44 0xFF << 8 |
45 0xFF;
46 static const uint32 kValidTerm2 = '\n' << 8 |
47 '\n';
48 static const uint32 kValidTerm2Mask = 0xFF << 8 |
49 0xFF;
50 BalsaFrame();
51 ~BalsaFrame();
52
53 // Reset reinitializes all the member variables of the framer and clears the
54 // attached header object (but doesn't change the pointer value headers_).
55 void Reset();
56
57 const BalsaHeaders* const_balsa_headers() const { return headers_; }
58 BalsaHeaders* balsa_headers() { return headers_; }
59 // The method set_balsa_headers clears the headers provided and attaches them
60 // to the framer. This is a required step before the framer will process any
61 // input message data.
62 // To detach the header object from the framer, use set_balsa_headers(NULL).
63 void set_balsa_headers(BalsaHeaders* headers) {
64 if (headers_ != headers) {
65 headers_ = headers;
66 }
67 if (headers_) {
68 // Clear the headers if they are non-null, even if the new headers are
69 // the same as the old.
70 headers_->Clear();
71 }
72 }
73
74 void set_balsa_visitor(BalsaVisitorInterface* visitor) {
75 visitor_ = visitor;
76 if (visitor_ == NULL) {
77 visitor_ = &do_nothing_visitor_;
78 }
79 }
80
81 void set_is_request(bool is_request) { is_request_ = is_request; }
82
83 bool is_request() const {
84 return is_request_;
85 }
86
87 void set_request_was_head(bool request_was_head) {
88 request_was_head_ = request_was_head;
89 }
90
91 bool request_was_head() const {
92 return request_was_head_;
93 }
94
95 void set_max_header_length(size_t max_header_length) {
96 max_header_length_ = max_header_length;
97 }
98
99 size_t max_header_length() const {
100 return max_header_length_;
101 }
102
103 void set_max_request_uri_length(size_t max_request_uri_length) {
104 max_request_uri_length_ = max_request_uri_length;
105 }
106
107 size_t max_request_uri_length() const {
108 return max_request_uri_length_;
109 }
110
111
112 bool MessageFullyRead() {
113 return parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ;
114 }
115
116 BalsaFrameEnums::ParseState ParseState() const { return parse_state_; }
117
118
119 bool Error() {
120 return parse_state_ == BalsaFrameEnums::PARSE_ERROR;
121 }
122
123 BalsaFrameEnums::ErrorCode ErrorCode() const { return last_error_; }
124
125 const BalsaHeaders* headers() const { return headers_; }
126 BalsaHeaders* mutable_headers() { return headers_; }
127
128 size_t BytesSafeToSplice() const;
129 void BytesSpliced(size_t bytes_spliced);
130
131 size_t ProcessInput(const char* input, size_t size);
132
133 // Parses input and puts the key, value chunk extensions into extensions.
134 // TODO(phython): Find a better data structure to put the extensions into.
135 static void ProcessChunkExtensions(const char* input, size_t size,
136 BalsaHeaders* extensions);
137
138 protected:
139 // The utils object needs access to the ParseTokenList in order to do its
140 // job.
141 friend class BalsaHeadersTokenUtils;
142
143 inline void ProcessContentLengthLine(
144 size_t line_idx,
145 BalsaHeadersEnums::ContentLengthStatus* status,
146 size_t* length);
147
148 inline void ProcessTransferEncodingLine(size_t line_idx);
149
150 void ProcessFirstLine(const char* begin,
151 const char* end);
152
153 void CleanUpKeyValueWhitespace(
154 const char* stream_begin,
155 const char* line_begin,
156 const char* current,
157 const char* line_end,
158 HeaderLineDescription* current_header_line);
159
160 void FindColonsAndParseIntoKeyValue();
161
162 void ProcessHeaderLines();
163
164 inline size_t ProcessHeaders(const char* message_start,
165 size_t message_length);
166
167 void AssignParseStateAfterHeadersHaveBeenParsed();
168
169 inline bool LineFramingFound(char current_char) {
170 return current_char == '\n';
171 }
172
173 // TODO(fenix): get rid of the following function and its uses (and
174 // replace with something more efficient)
175 inline bool HeaderFramingFound(char current_char) {
176 // Note that the 'if (current_char == '\n' ...)' test exists to ensure that
177 // the HeaderFramingMayBeFound test works properly. In benchmarking done on
178 // 2/13/2008, the 'if' actually speeds up performance of the function
179 // anyway..
180 if (current_char == '\n' || current_char == '\r') {
181 term_chars_ <<= 8;
182 // This is necessary IFF architecture has > 8 bit char. Alas, I'm
183 // paranoid.
184 term_chars_ |= current_char & 0xFF;
185
186 if ((term_chars_ & kValidTerm1Mask) == kValidTerm1) {
187 term_chars_ = 0;
188 return true;
189 }
190 if ((term_chars_ & kValidTerm2Mask) == kValidTerm2) {
191 term_chars_ = 0;
192 return true;
193 }
194 } else {
195 term_chars_ = 0;
196 }
197 return false;
198 }
199
200 inline bool HeaderFramingMayBeFound() const {
201 return term_chars_ != 0;
202 }
203
204 private:
205 class DoNothingBalsaVisitor : public BalsaVisitorInterface {
206 virtual void ProcessBodyInput(const char *input, size_t size) OVERRIDE {}
207 virtual void ProcessBodyData(const char *input, size_t size) OVERRIDE {}
208 virtual void ProcessHeaderInput(const char *input, size_t size) OVERRIDE {}
209 virtual void ProcessTrailerInput(const char *input, size_t size) OVERRIDE {}
210 virtual void ProcessHeaders(const BalsaHeaders& headers) OVERRIDE {}
211 virtual void ProcessRequestFirstLine(const char* line_input,
212 size_t line_length,
213 const char* method_input,
214 size_t method_length,
215 const char* request_uri_input,
216 size_t request_uri_length,
217 const char* version_input,
218 size_t version_length) OVERRIDE {}
219 virtual void ProcessResponseFirstLine(const char *line_input,
220 size_t line_length,
221 const char *version_input,
222 size_t version_length,
223 const char *status_input,
224 size_t status_length,
225 const char *reason_input,
226 size_t reason_length) OVERRIDE {}
227 virtual void ProcessChunkLength(size_t chunk_length) OVERRIDE {}
228 virtual void ProcessChunkExtensions(const char *input,
229 size_t size) OVERRIDE {}
230 virtual void HeaderDone() OVERRIDE {}
231 virtual void MessageDone() OVERRIDE {}
232 virtual void HandleHeaderError(BalsaFrame* framer) OVERRIDE {}
233 virtual void HandleHeaderWarning(BalsaFrame* framer) OVERRIDE {}
234 virtual void HandleChunkingError(BalsaFrame* framer) OVERRIDE {}
235 virtual void HandleBodyError(BalsaFrame* framer) OVERRIDE {}
236 };
237
238 bool last_char_was_slash_r_;
239 bool saw_non_newline_char_;
240 bool start_was_space_;
241 bool chunk_length_character_extracted_;
242 bool is_request_; // This is not reset in Reset()
243 bool request_was_head_; // This is not reset in Reset()
244 size_t max_header_length_; // This is not reset in Reset()
245 size_t max_request_uri_length_; // This is not reset in Reset()
246 BalsaVisitorInterface* visitor_;
247 size_t chunk_length_remaining_;
248 size_t content_length_remaining_;
249 const char* last_slash_n_loc_;
250 const char* last_recorded_slash_n_loc_;
251 size_t last_slash_n_idx_;
252 uint32 term_chars_;
253 BalsaFrameEnums::ParseState parse_state_;
254 BalsaFrameEnums::ErrorCode last_error_;
255
256 Lines lines_;
257
258 BalsaHeaders* headers_; // This is not reset to NULL in Reset().
259 DoNothingBalsaVisitor do_nothing_visitor_;
260 };
261
262 } // namespace net
263
264 #endif // NET_TOOLS_FLIP_SERVER_BALSA_FRAME_H_
265
OLDNEW
« no previous file with comments | « net/tools/flip_server/balsa_enums.h ('k') | net/tools/flip_server/balsa_frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698