• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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