Home | History | Annotate | Download | only in http
      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    507 uint64 HttpStreamParser::GetUploadProgress() const {
    508   if (!request_body_.get())
    509     return 0;
    510 
    511   return request_body_->position();
    512 }
    513 
    514 HttpResponseInfo* HttpStreamParser::GetResponseInfo() {
    515   return response_;
    516 }
    517 
    518 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 
    527 bool HttpStreamParser::CanFindEndOfResponse() const {
    528   return chunked_decoder_.get() || response_body_length_ >= 0;
    529 }
    530 
    531 bool HttpStreamParser::IsMoreDataBuffered() const {
    532   return read_buf_->offset() > read_buf_unused_offset_;
    533 }
    534 
    535 }  // namespace net
    536