1 // Copyright (c) 2006-2009 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 #include "net/http/http_stream_parser.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/trace_event.h"
9 #include "net/base/io_buffer.h"
10 #include "net/http/http_request_info.h"
11 #include "net/http/http_response_headers.h"
12 #include "net/http/http_util.h"
13
14 namespace net {
15
HttpStreamParser(ClientSocketHandle * connection,GrowableIOBuffer * read_buffer,LoadLog * load_log)16 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
17 GrowableIOBuffer* read_buffer,
18 LoadLog* load_log)
19 : io_state_(STATE_NONE),
20 request_(NULL),
21 request_headers_(NULL),
22 request_body_(NULL),
23 read_buf_(read_buffer),
24 read_buf_unused_offset_(0),
25 response_header_start_offset_(-1),
26 response_body_length_(-1),
27 response_body_read_(0),
28 chunked_decoder_(NULL),
29 user_read_buf_(NULL),
30 user_read_buf_len_(0),
31 user_callback_(NULL),
32 connection_(connection),
33 load_log_(load_log),
34 ALLOW_THIS_IN_INITIALIZER_LIST(
35 io_callback_(this, &HttpStreamParser::OnIOComplete)) {
36 DCHECK_EQ(0, read_buffer->offset());
37 }
38
SendRequest(const HttpRequestInfo * request,const std::string & headers,UploadDataStream * request_body,HttpResponseInfo * response,CompletionCallback * callback)39 int HttpStreamParser::SendRequest(const HttpRequestInfo* request,
40 const std::string& headers,
41 UploadDataStream* request_body,
42 HttpResponseInfo* response,
43 CompletionCallback* callback) {
44 DCHECK_EQ(STATE_NONE, io_state_);
45 DCHECK(!user_callback_);
46 DCHECK(callback);
47 DCHECK(response);
48
49 request_ = request;
50 response_ = response;
51 scoped_refptr<StringIOBuffer> headers_io_buf = new StringIOBuffer(headers);
52 request_headers_ = new DrainableIOBuffer(headers_io_buf,
53 headers_io_buf->size());
54 request_body_.reset(request_body);
55
56 io_state_ = STATE_SENDING_HEADERS;
57 int result = DoLoop(OK);
58 if (result == ERR_IO_PENDING)
59 user_callback_ = callback;
60
61 return result > 0 ? OK : result;
62 }
63
ReadResponseHeaders(CompletionCallback * callback)64 int HttpStreamParser::ReadResponseHeaders(CompletionCallback* callback) {
65 DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE);
66 DCHECK(!user_callback_);
67 DCHECK(callback);
68
69 // This function can be called with io_state_ == STATE_DONE if the
70 // connection is closed after seeing just a 1xx response code.
71 if (io_state_ == STATE_DONE)
72 return ERR_CONNECTION_CLOSED;
73
74 int result = OK;
75 io_state_ = STATE_READ_HEADERS;
76
77 if (read_buf_->offset() > 0) {
78 // Simulate the state where the data was just read from the socket.
79 result = read_buf_->offset() - read_buf_unused_offset_;
80 read_buf_->set_offset(read_buf_unused_offset_);
81 }
82 if (result > 0)
83 io_state_ = STATE_READ_HEADERS_COMPLETE;
84
85 result = DoLoop(result);
86 if (result == ERR_IO_PENDING)
87 user_callback_ = callback;
88
89 return result > 0 ? OK : result;
90 }
91
ReadResponseBody(IOBuffer * buf,int buf_len,CompletionCallback * callback)92 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len,
93 CompletionCallback* callback) {
94 DCHECK(io_state_ == STATE_BODY_PENDING || io_state_ == STATE_DONE);
95 DCHECK(!user_callback_);
96 DCHECK(callback);
97 DCHECK_LE(buf_len, kMaxBufSize);
98
99 if (io_state_ == STATE_DONE)
100 return OK;
101
102 user_read_buf_ = buf;
103 user_read_buf_len_ = buf_len;
104 io_state_ = STATE_READ_BODY;
105
106 int result = DoLoop(OK);
107 if (result == ERR_IO_PENDING)
108 user_callback_ = callback;
109
110 return result;
111 }
112
OnIOComplete(int result)113 void HttpStreamParser::OnIOComplete(int result) {
114 result = DoLoop(result);
115
116 // The client callback can do anything, including destroying this class,
117 // so any pending callback must be issued after everything else is done.
118 if (result != ERR_IO_PENDING && user_callback_) {
119 CompletionCallback* c = user_callback_;
120 user_callback_ = NULL;
121 c->Run(result);
122 }
123 }
124
DoLoop(int result)125 int HttpStreamParser::DoLoop(int result) {
126 bool can_do_more = true;
127 do {
128 switch (io_state_) {
129 case STATE_SENDING_HEADERS:
130 TRACE_EVENT_BEGIN("http.write_headers", request_, request_->url.spec());
131 if (result < 0)
132 can_do_more = false;
133 else
134 result = DoSendHeaders(result);
135 TRACE_EVENT_END("http.write_headers", request_, request_->url.spec());
136 break;
137 case STATE_SENDING_BODY:
138 TRACE_EVENT_BEGIN("http.write_body", request_, request_->url.spec());
139 if (result < 0)
140 can_do_more = false;
141 else
142 result = DoSendBody(result);
143 TRACE_EVENT_END("http.write_body", request_, request_->url.spec());
144 break;
145 case STATE_REQUEST_SENT:
146 DCHECK(result != ERR_IO_PENDING);
147 can_do_more = false;
148 break;
149 case STATE_READ_HEADERS:
150 TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec());
151 LoadLog::BeginEvent(load_log_,
152 LoadLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS);
153 result = DoReadHeaders();
154 break;
155 case STATE_READ_HEADERS_COMPLETE:
156 result = DoReadHeadersComplete(result);
157 LoadLog::EndEvent(load_log_,
158 LoadLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS);
159 TRACE_EVENT_END("http.read_headers", request_, request_->url.spec());
160 break;
161 case STATE_BODY_PENDING:
162 DCHECK(result != ERR_IO_PENDING);
163 can_do_more = false;
164 break;
165 case STATE_READ_BODY:
166 TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec());
167 result = DoReadBody();
168 // DoReadBodyComplete handles error conditions.
169 break;
170 case STATE_READ_BODY_COMPLETE:
171 result = DoReadBodyComplete(result);
172 TRACE_EVENT_END("http.read_body", request_, request_->url.spec());
173 break;
174 case STATE_DONE:
175 DCHECK(result != ERR_IO_PENDING);
176 can_do_more = false;
177 break;
178 default:
179 NOTREACHED();
180 can_do_more = false;
181 break;
182 }
183 } while (result != ERR_IO_PENDING && can_do_more);
184
185 return result;
186 }
187
DoSendHeaders(int result)188 int HttpStreamParser::DoSendHeaders(int result) {
189 request_headers_->DidConsume(result);
190
191 if (request_headers_->BytesRemaining() > 0) {
192 // Record our best estimate of the 'request time' as the time when we send
193 // out the first bytes of the request headers.
194 if (request_headers_->BytesRemaining() == request_headers_->size()) {
195 response_->request_time = base::Time::Now();
196 }
197 result = connection_->socket()->Write(request_headers_,
198 request_headers_->BytesRemaining(),
199 &io_callback_);
200 } else if (request_body_ != NULL && request_body_->size()) {
201 io_state_ = STATE_SENDING_BODY;
202 result = OK;
203 } else {
204 io_state_ = STATE_REQUEST_SENT;
205 }
206 return result;
207 }
208
DoSendBody(int result)209 int HttpStreamParser::DoSendBody(int result) {
210 if (result > 0)
211 request_body_->DidConsume(result);
212
213 if (request_body_->position() < request_body_->size()) {
214 int buf_len = static_cast<int>(request_body_->buf_len());
215 result = connection_->socket()->Write(request_body_->buf(), buf_len,
216 &io_callback_);
217 } else {
218 io_state_ = STATE_REQUEST_SENT;
219 }
220 return result;
221 }
222
DoReadHeaders()223 int HttpStreamParser::DoReadHeaders() {
224 io_state_ = STATE_READ_HEADERS_COMPLETE;
225
226 // Grow the read buffer if necessary.
227 if (read_buf_->RemainingCapacity() == 0)
228 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
229
230 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
231 // See if the user is passing in an IOBuffer with a NULL |data_|.
232 CHECK(read_buf_->data());
233
234 return connection_->socket()->Read(read_buf_,
235 read_buf_->RemainingCapacity(),
236 &io_callback_);
237 }
238
DoReadHeadersComplete(int result)239 int HttpStreamParser::DoReadHeadersComplete(int result) {
240 if (result == 0)
241 result = ERR_CONNECTION_CLOSED;
242
243 if (result < 0 && result != ERR_CONNECTION_CLOSED) {
244 io_state_ = STATE_DONE;
245 return result;
246 }
247 if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 &&
248 connection_->ShouldResendFailedRequest(result)) {
249 io_state_ = STATE_DONE;
250 return result;
251 }
252
253 // Record our best estimate of the 'response time' as the time when we read
254 // the first bytes of the response headers.
255 if (read_buf_->offset() == 0 && result != ERR_CONNECTION_CLOSED)
256 response_->response_time = base::Time::Now();
257
258 if (result == ERR_CONNECTION_CLOSED) {
259 // The connection closed before we detected the end of the headers.
260 // parse things as well as we can and let the caller decide what to do.
261 if (read_buf_->offset() == 0) {
262 // The connection was closed before any data was sent. Likely an error
263 // rather than empty HTTP/0.9 response.
264 io_state_ = STATE_DONE;
265 return ERR_EMPTY_RESPONSE;
266 } else {
267 int end_offset;
268 if (response_header_start_offset_ >= 0) {
269 io_state_ = STATE_READ_BODY_COMPLETE;
270 end_offset = read_buf_->offset();
271 } else {
272 io_state_ = STATE_BODY_PENDING;
273 end_offset = 0;
274 }
275 DoParseResponseHeaders(end_offset);
276 return result;
277 }
278 }
279
280 read_buf_->set_offset(read_buf_->offset() + result);
281 DCHECK_LE(read_buf_->offset(), read_buf_->capacity());
282 DCHECK(result >= 0);
283
284 int end_of_header_offset = ParseResponseHeaders();
285 if (end_of_header_offset == -1) {
286 io_state_ = STATE_READ_HEADERS;
287 // Prevent growing the headers buffer indefinitely.
288 if (read_buf_->offset() - read_buf_unused_offset_ >= kMaxHeaderBufSize) {
289 io_state_ = STATE_DONE;
290 return ERR_RESPONSE_HEADERS_TOO_BIG;
291 }
292 } else {
293 // Note where the headers stop.
294 read_buf_unused_offset_ = end_of_header_offset;
295
296 if (response_->headers->response_code() / 100 == 1) {
297 // After processing a 1xx response, the caller will ask for the next
298 // header, so reset state to support that. We don't just skip these
299 // completely because 1xx codes aren't acceptable when establishing a
300 // tunnel.
301 io_state_ = STATE_REQUEST_SENT;
302 response_header_start_offset_ = -1;
303 } else {
304 io_state_ = STATE_BODY_PENDING;
305 CalculateResponseBodySize();
306 // If the body is 0, the caller may not call ReadResponseBody, which
307 // is where any extra data is copied to read_buf_, so we move the
308 // data here and transition to DONE.
309 if (response_body_length_ == 0) {
310 io_state_ = STATE_DONE;
311 int extra_bytes = read_buf_->offset() - read_buf_unused_offset_;
312 if (extra_bytes) {
313 CHECK(extra_bytes > 0);
314 memmove(read_buf_->StartOfBuffer(),
315 read_buf_->StartOfBuffer() + read_buf_unused_offset_,
316 extra_bytes);
317 }
318 read_buf_->SetCapacity(extra_bytes);
319 read_buf_unused_offset_ = 0;
320 return OK;
321 }
322 }
323 }
324 return result;
325 }
326
DoReadBody()327 int HttpStreamParser::DoReadBody() {
328 io_state_ = STATE_READ_BODY_COMPLETE;
329
330 // There may be some data left over from reading the response headers.
331 if (read_buf_->offset()) {
332 int available = read_buf_->offset() - read_buf_unused_offset_;
333 if (available) {
334 CHECK(available > 0);
335 int bytes_from_buffer = std::min(available, user_read_buf_len_);
336 memcpy(user_read_buf_->data(),
337 read_buf_->StartOfBuffer() + read_buf_unused_offset_,
338 bytes_from_buffer);
339 read_buf_unused_offset_ += bytes_from_buffer;
340 if (bytes_from_buffer == available) {
341 read_buf_->SetCapacity(0);
342 read_buf_unused_offset_ = 0;
343 }
344 return bytes_from_buffer;
345 } else {
346 read_buf_->SetCapacity(0);
347 read_buf_unused_offset_ = 0;
348 }
349 }
350
351 // Check to see if we're done reading.
352 if (IsResponseBodyComplete())
353 return 0;
354
355 DCHECK_EQ(0, read_buf_->offset());
356 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_,
357 &io_callback_);
358 }
359
DoReadBodyComplete(int result)360 int HttpStreamParser::DoReadBodyComplete(int result) {
361 if (result == 0)
362 result = ERR_CONNECTION_CLOSED;
363
364 // Filter incoming data if appropriate. FilterBuf may return an error.
365 if (result > 0 && chunked_decoder_.get()) {
366 result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result);
367 if (result == 0 && !chunked_decoder_->reached_eof()) {
368 // Don't signal completion of the Read call yet or else it'll look like
369 // we received end-of-file. Wait for more data.
370 io_state_ = STATE_READ_BODY;
371 return OK;
372 }
373 }
374
375 if (result > 0)
376 response_body_read_ += result;
377
378 if (result < 0 || IsResponseBodyComplete()) {
379 io_state_ = STATE_DONE;
380
381 // Save the overflow data, which can be in two places. There may be
382 // some left over in |user_read_buf_|, plus there may be more
383 // in |read_buf_|. But the part left over in |user_read_buf_| must have
384 // come from the |read_buf_|, so there's room to put it back at the
385 // start first.
386 int additional_save_amount = read_buf_->offset() - read_buf_unused_offset_;
387 int save_amount = 0;
388 if (chunked_decoder_.get()) {
389 save_amount = chunked_decoder_->bytes_after_eof();
390 } else if (response_body_length_ >= 0) {
391 int64 extra_data_read = response_body_read_ - response_body_length_;
392 if (extra_data_read > 0) {
393 save_amount = static_cast<int>(extra_data_read);
394 if (result > 0)
395 result -= save_amount;
396 }
397 }
398
399 CHECK(save_amount + additional_save_amount <= kMaxBufSize);
400 if (read_buf_->capacity() < save_amount + additional_save_amount) {
401 read_buf_->SetCapacity(save_amount + additional_save_amount);
402 }
403
404 if (save_amount) {
405 memcpy(read_buf_->StartOfBuffer(), user_read_buf_->data() + result,
406 save_amount);
407 }
408 read_buf_->set_offset(save_amount);
409 if (additional_save_amount) {
410 memmove(read_buf_->data(),
411 read_buf_->StartOfBuffer() + read_buf_unused_offset_,
412 additional_save_amount);
413 read_buf_->set_offset(save_amount + additional_save_amount);
414 }
415 read_buf_unused_offset_ = 0;
416 } else {
417 io_state_ = STATE_BODY_PENDING;
418 user_read_buf_ = NULL;
419 user_read_buf_len_ = 0;
420 }
421
422 return result;
423 }
424
ParseResponseHeaders()425 int HttpStreamParser::ParseResponseHeaders() {
426 int end_offset = -1;
427
428 // Look for the start of the status line, if it hasn't been found yet.
429 if (response_header_start_offset_ < 0) {
430 response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine(
431 read_buf_->StartOfBuffer() + read_buf_unused_offset_,
432 read_buf_->offset() - read_buf_unused_offset_);
433 }
434
435 if (response_header_start_offset_ >= 0) {
436 end_offset = HttpUtil::LocateEndOfHeaders(
437 read_buf_->StartOfBuffer() + read_buf_unused_offset_,
438 read_buf_->offset() - read_buf_unused_offset_,
439 response_header_start_offset_);
440 } else if (read_buf_->offset() - read_buf_unused_offset_ >= 8) {
441 // Enough data to decide that this is an HTTP/0.9 response.
442 // 8 bytes = (4 bytes of junk) + "http".length()
443 end_offset = 0;
444 }
445
446 if (end_offset == -1)
447 return -1;
448
449 DoParseResponseHeaders(end_offset);
450 return end_offset + read_buf_unused_offset_;
451 }
452
DoParseResponseHeaders(int end_offset)453 void HttpStreamParser::DoParseResponseHeaders(int end_offset) {
454 scoped_refptr<HttpResponseHeaders> headers;
455 if (response_header_start_offset_ >= 0) {
456 headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
457 read_buf_->StartOfBuffer() + read_buf_unused_offset_, end_offset));
458 } else {
459 // Enough data was read -- there is no status line.
460 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
461 }
462
463 response_->headers = headers;
464 response_->vary_data.Init(*request_, *response_->headers);
465 }
466
CalculateResponseBodySize()467 void HttpStreamParser::CalculateResponseBodySize() {
468 // Figure how to determine EOF:
469
470 // For certain responses, we know the content length is always 0. From
471 // RFC 2616 Section 4.3 Message Body:
472 //
473 // For response messages, whether or not a message-body is included with
474 // a message is dependent on both the request method and the response
475 // status code (section 6.1.1). All responses to the HEAD request method
476 // MUST NOT include a message-body, even though the presence of entity-
477 // header fields might lead one to believe they do. All 1xx
478 // (informational), 204 (no content), and 304 (not modified) responses
479 // MUST NOT include a message-body. All other responses do include a
480 // message-body, although it MAY be of zero length.
481 switch (response_->headers->response_code()) {
482 // Note that 1xx was already handled earlier.
483 case 204: // No Content
484 case 205: // Reset Content
485 case 304: // Not Modified
486 response_body_length_ = 0;
487 break;
488 }
489 if (request_->method == "HEAD")
490 response_body_length_ = 0;
491
492 if (response_body_length_ == -1) {
493 // Ignore spurious chunked responses from HTTP/1.0 servers and
494 // proxies. Otherwise "Transfer-Encoding: chunked" trumps
495 // "Content-Length: N"
496 if (response_->headers->GetHttpVersion() >= HttpVersion(1, 1) &&
497 response_->headers->HasHeaderValue("Transfer-Encoding", "chunked")) {
498 chunked_decoder_.reset(new HttpChunkedDecoder());
499 } else {
500 response_body_length_ = response_->headers->GetContentLength();
501 // If response_body_length_ is still -1, then we have to wait
502 // for the server to close the connection.
503 }
504 }
505 }
506
GetUploadProgress() const507 uint64 HttpStreamParser::GetUploadProgress() const {
508 if (!request_body_.get())
509 return 0;
510
511 return request_body_->position();
512 }
513
GetResponseInfo()514 HttpResponseInfo* HttpStreamParser::GetResponseInfo() {
515 return response_;
516 }
517
IsResponseBodyComplete() const518 bool HttpStreamParser::IsResponseBodyComplete() const {
519 if (chunked_decoder_.get())
520 return chunked_decoder_->reached_eof();
521 if (response_body_length_ != -1)
522 return response_body_read_ >= response_body_length_;
523
524 return false; // Must read to EOF.
525 }
526
CanFindEndOfResponse() const527 bool HttpStreamParser::CanFindEndOfResponse() const {
528 return chunked_decoder_.get() || response_body_length_ >= 0;
529 }
530
IsMoreDataBuffered() const531 bool HttpStreamParser::IsMoreDataBuffered() const {
532 return read_buf_->offset() > read_buf_unused_offset_;
533 }
534
535 } // namespace net
536