15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_parser.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/logging.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_data_stream.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_chunked_decoder.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_info.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace net {
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxMergedHeaderAndBodySize = 1400;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kRequestBodyBufferSize = 1 << 14;  // 16KB
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstd::string GetResponseHeaderLines(const HttpResponseHeaders& headers) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string raw_headers = headers.raw_headers();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* null_separated_headers = raw_headers.c_str();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* header_line = null_separated_headers;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cr_separated_headers;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (header_line[0] != 0) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cr_separated_headers += header_line;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cr_separated_headers += "\n";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_line += strlen(header_line) + 1;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cr_separated_headers;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return true if |headers| contain multiple |field_name| fields with different
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values.
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool HeadersContainMultipleCopiesOfField(const HttpResponseHeaders& headers,
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                         const std::string& field_name) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* it = NULL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string field_value;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!headers.EnumerateHeader(&it, field_name, &field_value))
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There's at least one |field_name| header.  Check if there are any more
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such headers, and if so, return true if they have different values.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string field_value2;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (headers.EnumerateHeader(&it, field_name, &field_value2)) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (field_value != field_value2)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::Value* NetLogSendRequestBodyCallback(int length,
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           bool is_chunked,
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           bool did_merge,
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           NetLog::LogLevel /* log_level */) {
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetInteger("length", length);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetBoolean("is_chunked", is_chunked);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetBoolean("did_merge", did_merge);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dict;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Returns true if |error_code| is an error for which we give the server a
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// chance to send a body containing error information, if the error was received
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// while trying to upload a request body.
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ShouldTryReadingOnUploadError(int error_code) {
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return (error_code == ERR_CONNECTION_RESET);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to DrainableIOBuffer(), but this version comes with its own
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// storage. The motivation is to avoid repeated allocations of
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DrainableIOBuffer.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<SeekableIOBuffer> buf = new SeekableIOBuffer(1024);
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// // capacity() == 1024. size() == BytesRemaining() == BytesConsumed() == 0.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // data() points to the beginning of the buffer.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // Read() takes an IOBuffer.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int bytes_read = some_reader->Read(buf, buf->capacity());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// buf->DidAppend(bytes_read);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // size() == BytesRemaining() == bytes_read. data() is unaffected.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while (buf->BytesRemaining() > 0) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // Write() takes an IOBuffer. If it takes const char*, we could
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///  // simply use the regular IOBuffer like buf->data() + offset.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int bytes_written = Write(buf, buf->BytesRemaining());
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   buf->DidConsume(bytes_written);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // BytesRemaining() == 0. BytesConsumed() == size().
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// // data() points to the end of the consumed bytes (exclusive).
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // If you want to reuse the buffer, be sure to clear the buffer.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// buf->Clear();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // size() == BytesRemaining() == BytesConsumed() == 0.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // data() points to the beginning of the buffer.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass HttpStreamParser::SeekableIOBuffer : public IOBuffer {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SeekableIOBuffer(int capacity)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : IOBuffer(capacity),
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      real_data_(data_),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      capacity_(capacity),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_(0),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      used_(0) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DidConsume() changes the |data_| pointer so that |data_| always points
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the first unconsumed byte.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidConsume(int bytes) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetOffset(used_ + bytes);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of unconsumed bytes.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int BytesRemaining() const {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size_ - used_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seeks to an arbitrary point in the buffer. The notion of bytes consumed
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and remaining are updated appropriately.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOffset(int bytes) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GE(bytes, 0);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_LE(bytes, size_);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    used_ = bytes;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_ = real_data_ + used_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called after data is added to the buffer. Adds |bytes| added to
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |size_|. data() is unaffected.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidAppend(int bytes) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GE(bytes, 0);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GE(size_ + bytes, 0);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_LE(size_ + bytes, capacity_);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ += bytes;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes the logical size to 0, and the offset to 0.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Clear() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ = 0;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetOffset(0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the logical size of the buffer (i.e the number of bytes of data
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the buffer).
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size() const { return size_; }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the capacity of the buffer. The capacity is the size used when
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the object is created.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int capacity() const { return capacity_; };
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SeekableIOBuffer() {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // data_ will be deleted in IOBuffer::~IOBuffer().
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_ = real_data_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* real_data_;
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const int capacity_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size_;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int used_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2 CRLFs + max of 8 hex chars.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t HttpStreamParser::kChunkHeaderFooterSize = 12;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const HttpRequestInfo* request,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GrowableIOBuffer* read_buffer,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const BoundNetLog& net_log)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : io_state_(STATE_NONE),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_(request),
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_headers_(NULL),
1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      request_headers_length_(0),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_(read_buffer),
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_unused_offset_(0),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_header_start_offset_(-1),
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      received_bytes_(0),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_body_length_(-1),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_body_read_(0),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_read_buf_(NULL),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_read_buf_len_(0),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connection_(connection),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log_(net_log),
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sent_last_chunk_(false),
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      upload_error_(OK),
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_callback_ = base::Bind(&HttpStreamParser::OnIOComplete,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            weak_ptr_factory_.GetWeakPtr());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpStreamParser::~HttpStreamParser() {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::SendRequest(const std::string& request_line,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const HttpRequestHeaders& headers,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  HttpResponseInfo* response,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const CompletionCallback& callback) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(STATE_NONE, io_state_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(response);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net_log_.AddEvent(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HttpRequestHeaders::NetLogCallback,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&headers),
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &request_line));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "()"
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " request_line = \"" << request_line << "\""
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " headers = \"" << headers.ToString() << "\"";
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_ = response;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put the peer's IP address and port into the response.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint ip_endpoint;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = connection_->socket()->GetPeerAddress(&ip_endpoint);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != OK)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_->socket_address = HostPortPair::FromIPEndPoint(ip_endpoint);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string request = request_line + headers.ToString();
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request_headers_length_ = request.size();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request_->upload_data_stream != NULL) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_body_send_buf_ = new SeekableIOBuffer(kRequestBodyBufferSize);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (request_->upload_data_stream->is_chunked()) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Read buffer is adjusted to guarantee that |request_body_send_buf_| is
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // large enough to hold the encoded chunk.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_body_read_buf_ =
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new SeekableIOBuffer(kRequestBodyBufferSize - kChunkHeaderFooterSize);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // No need to encode request body, just send the raw data.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_body_read_buf_ = request_body_send_buf_;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  io_state_ = STATE_SEND_HEADERS;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we have a small request body, then we'll merge with the headers into a
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // single write.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_merge = false;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldMergeRequestHeadersAndBody(request, request_->upload_data_stream)) {
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    size_t merged_size =
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        request_headers_length_ + request_->upload_data_stream->size();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<IOBuffer> merged_request_headers_and_body(
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new IOBuffer(merged_size));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We'll repurpose |request_headers_| to store the merged headers and
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // body.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_headers_ = new DrainableIOBuffer(
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        merged_request_headers_and_body.get(), merged_size);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    memcpy(request_headers_->data(), request.data(), request_headers_length_);
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    request_headers_->DidConsume(request_headers_length_);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t todo = request_->upload_data_stream->size();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (todo) {
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int consumed = request_->upload_data_stream
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          ->Read(request_headers_.get(), todo, CompletionCallback());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_GT(consumed, 0);  // Read() won't fail if not chunked.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_headers_->DidConsume(consumed);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      todo -= consumed;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(request_->upload_data_stream->IsEOF());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reset the offset, so the buffer can be read from the beginning.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_headers_->SetOffset(0);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_merge = true;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_log_.AddEvent(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&NetLogSendRequestBodyCallback,
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   request_->upload_data_stream->size(),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   false, /* not chunked */
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   true /* merged */));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!did_merge) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we didn't merge the body with the headers, then |request_headers_|
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // contains just the HTTP headers.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    request_headers_ =
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new DrainableIOBuffer(headers_io_buf.get(), headers_io_buf->size());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = DoLoop(OK);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_IO_PENDING)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result > 0 ? OK : result;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) {
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(0, read_buf_unused_offset_);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function can be called with io_state_ == STATE_DONE if the
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection is closed after seeing just a 1xx response code.
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (io_state_ == STATE_DONE)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_CONNECTION_CLOSED;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = OK;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_state_ = STATE_READ_HEADERS;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_buf_->offset() > 0) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate the state where the data was just read from the socket.
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    result = read_buf_->offset();
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    read_buf_->set_offset(0);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result > 0)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_state_ = STATE_READ_HEADERS_COMPLETE;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = DoLoop(result);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_IO_PENDING)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result > 0 ? OK : result;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::Close(bool not_reusable) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (not_reusable && connection_->socket())
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    connection_->socket()->Disconnect();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connection_->Reset();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const CompletionCallback& callback) {
3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(buf_len, kMaxBufSize);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (io_state_ == STATE_DONE)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_read_buf_ = buf;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_read_buf_len_ = buf_len;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_state_ = STATE_READ_BODY;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = DoLoop(OK);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_IO_PENDING)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_ = callback;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::OnIOComplete(int result) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = DoLoop(result);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The client callback can do anything, including destroying this class,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so any pending callback must be issued after everything else is done.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != ERR_IO_PENDING && !callback_.is_null()) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompletionCallback c = callback_;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_.Reset();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c.Run(result);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoLoop(int result) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
3730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_NE(ERR_IO_PENDING, result);
3740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_NE(STATE_DONE, io_state_);
3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_NE(STATE_NONE, io_state_);
3760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    State state = io_state_;
3770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_NONE;
3780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    switch (state) {
3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      case STATE_SEND_HEADERS:
3800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        DCHECK_EQ(OK, result);
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        result = DoSendHeaders();
3820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        break;
3830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      case STATE_SEND_HEADERS_COMPLETE:
3840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        result = DoSendHeadersComplete(result);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      case STATE_SEND_BODY:
3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        DCHECK_EQ(OK, result);
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        result = DoSendBody();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      case STATE_SEND_BODY_COMPLETE:
3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        result = DoSendBodyComplete(result);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      case STATE_SEND_REQUEST_READ_BODY_COMPLETE:
3940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        result = DoSendRequestReadBodyComplete(result);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_HEADERS:
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS);
3980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        DCHECK_GE(result, 0);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result = DoReadHeaders();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_HEADERS_COMPLETE:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result = DoReadHeadersComplete(result);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net_log_.EndEventWithNetErrorCode(
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_BODY:
4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        DCHECK_GE(result, 0);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result = DoReadBody();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_READ_BODY_COMPLETE:
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result = DoReadBodyComplete(result);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } while (result != ERR_IO_PENDING &&
4180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           (io_state_ != STATE_DONE && io_state_ != STATE_NONE));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::DoSendHeaders() {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_remaining = request_headers_->BytesRemaining();
4250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_GT(bytes_remaining, 0);
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Record our best estimate of the 'request time' as the time when we send
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // out the first bytes of the request headers.
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (bytes_remaining == request_headers_->size())
4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    response_->request_time = base::Time::Now();
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  io_state_ = STATE_SEND_HEADERS_COMPLETE;
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return connection_->socket()
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ->Write(request_headers_.get(), bytes_remaining, io_callback_);
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::DoSendHeadersComplete(int result) {
4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result < 0) {
4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // In the unlikely case that the headers and body were merged, all the
4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // the headers were sent, but not all of the body way, and |result| is
4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // an error that this should try reading after, stash the error for now and
4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // act like the request was successfully sent.
4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (request_headers_->BytesConsumed() >= request_headers_length_ &&
4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ShouldTryReadingOnUploadError(result)) {
4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      upload_error_ = result;
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return OK;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return result;
4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request_headers_->DidConsume(result);
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (request_headers_->BytesRemaining() > 0) {
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_SEND_HEADERS;
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return OK;
4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (request_->upload_data_stream != NULL &&
4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      (request_->upload_data_stream->is_chunked() ||
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // !IsEOF() indicates that the body wasn't merged.
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      (request_->upload_data_stream->size() > 0 &&
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        !request_->upload_data_stream->IsEOF()))) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net_log_.AddEvent(
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&NetLogSendRequestBodyCallback,
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   request_->upload_data_stream->size(),
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   request_->upload_data_stream->is_chunked(),
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   false /* not merged */));
4680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_SEND_BODY;
4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return OK;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Finished sending the request.
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return OK;
4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::DoSendBody() {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_body_send_buf_->BytesRemaining() > 0) {
4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_SEND_BODY_COMPLETE;
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return connection_->socket()
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ->Write(request_body_send_buf_.get(),
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                request_body_send_buf_->BytesRemaining(),
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                io_callback_);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) {
4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Finished sending the request.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_body_read_buf_->Clear();
4910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  io_state_ = STATE_SEND_REQUEST_READ_BODY_COMPLETE;
492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return request_->upload_data_stream->Read(request_body_read_buf_.get(),
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            request_body_read_buf_->capacity(),
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            io_callback_);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::DoSendBodyComplete(int result) {
4980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result < 0) {
4990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // If |result| is an error that this should try reading after, stash the
5000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // error for now and act like the request was successfully sent.
5010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (ShouldTryReadingOnUploadError(result)) {
5020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      upload_error_ = result;
5030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return OK;
5040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
5050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return result;
5060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request_body_send_buf_->DidConsume(result);
5090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  io_state_ = STATE_SEND_BODY;
5110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return OK;
5120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |result| is the result of read from the request body from the last call to
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DoSendBody().
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(result, 0);  // There won't be errors.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chunked data needs to be encoded.
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request_->upload_data_stream->is_chunked()) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result == 0) {  // Reached the end.
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(request_->upload_data_stream->IsEOF());
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sent_last_chunk_ = true;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Encode the buffer as 1 chunk.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece payload(request_body_read_buf_->data(), result);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_body_send_buf_->Clear();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = EncodeChunk(payload,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         request_body_send_buf_->data(),
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         request_body_send_buf_->capacity());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == 0) {  // Reached the end.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reaching EOF means we can finish sending request body unless the data is
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // chunked. (i.e. No need to send the terminal chunk.)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(request_->upload_data_stream->IsEOF());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!request_->upload_data_stream->is_chunked());
5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Finished sending the request.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result > 0) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_body_send_buf_->DidAppend(result);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = 0;
5420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_SEND_BODY;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoReadHeaders() {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_state_ = STATE_READ_HEADERS_COMPLETE;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Grow the read buffer if necessary.
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_buf_->RemainingCapacity() == 0)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See if the user is passing in an IOBuffer with a NULL |data_|.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(read_buf_->data());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return connection_->socket()
559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoReadHeadersComplete(int result) {
5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  result = HandleReadHeaderResult(result);
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(mmenke):  The code below is ugly and hacky.  A much better and more
5660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // flexible long term solution would be to separate out the read and write
5670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // loops, though this would involve significant changes, both here and
5680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // elsewhere (WebSockets, for instance).
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If still reading the headers, or there was no error uploading the request
5710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // body, just return the result.
5720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (io_state_ == STATE_READ_HEADERS || upload_error_ == OK)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If the result is ERR_IO_PENDING, |io_state_| should be STATE_READ_HEADERS.
5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_NE(ERR_IO_PENDING, result);
5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // On errors, use the original error received when sending the request.
5790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The main cases where these are different is when there's a header-related
5800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // error code, or when there's an ERR_CONNECTION_CLOSED, which can result in
5810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // special handling of partial responses and HTTP/0.9 responses.
5820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result < 0) {
5830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Nothing else to do.  In the HTTP/0.9 or only partial headers received
5840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // cases, can normally go to other states after an error reading headers.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_state_ = STATE_DONE;
5860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Don't let caller see the headers.
5870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    response_->headers = NULL;
5880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return upload_error_;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Skip over 1xx responses as usual, and allow 4xx/5xx error responses to
5920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // override the error received while uploading the body.
5930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int response_code_class = response_->headers->response_code() / 100;
5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (response_code_class == 1 || response_code_class == 4 ||
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      response_code_class == 5) {
596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return result;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // All other status codes are not allowed after an error during upload, to
6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // make sure the consumer has some indication there was an error.
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Nothing else to do.
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  io_state_ = STATE_DONE;
6040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Don't let caller see the headers.
6050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  response_->headers = NULL;
6060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return upload_error_;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoReadBody() {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_state_ = STATE_READ_BODY_COMPLETE;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There may be some data left over from reading the response headers.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_buf_->offset()) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int available = read_buf_->offset() - read_buf_unused_offset_;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (available) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_GT(available, 0);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int bytes_from_buffer = std::min(available, user_read_buf_len_);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(user_read_buf_->data(),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             read_buf_->StartOfBuffer() + read_buf_unused_offset_,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             bytes_from_buffer);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_unused_offset_ += bytes_from_buffer;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bytes_from_buffer == available) {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        read_buf_->SetCapacity(0);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        read_buf_unused_offset_ = 0;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return bytes_from_buffer;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_->SetCapacity(0);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_unused_offset_ = 0;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if we're done reading.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsResponseBodyComplete())
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0, read_buf_->offset());
638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return connection_->socket()
639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ->Read(user_read_buf_.get(), user_read_buf_len_, io_callback_);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoReadBodyComplete(int result) {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the connection is closed, there are numerous ways to interpret it.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - If a Content-Length header is present and the body contains exactly that
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    number of bytes at connection close, the response is successful.
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - If a Content-Length header is present and the body contains fewer bytes
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    than promised by the header at connection close, it may indicate that
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    the connection was closed prematurely, or it may indicate that the
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    server sent an invalid Content-Length header. Unfortunately, the invalid
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    Content-Length header case does occur in practice and other browsers are
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    tolerant of it. We choose to treat it as an error for now, but the
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    download system treats it as a non-error, and URLRequestHttpJob also
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    treats it as OK if the Content-Length is the post-decoded body content
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    length.
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - If chunked encoding is used and the terminating chunk has been processed
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    when the connection is closed, the response is successful.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - If chunked encoding is used and the terminating chunk has not been
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    processed when the connection is closed, it may indicate that the
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    connection was closed prematurely or it may indicate that the server
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    sent an invalid chunked encoding. We choose to treat it as
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    an invalid chunked encoding.
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - If a Content-Length is not present and chunked encoding is not used,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    connection close is the only way to signal that the response is
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    complete. Unfortunately, this also means that there is no way to detect
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    early close of a connection. No error is returned.
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (chunked_decoder_.get())
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result = ERR_INCOMPLETE_CHUNKED_ENCODING;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result = ERR_CONTENT_LENGTH_MISMATCH;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (result > 0)
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    received_bytes_ += result;
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter incoming data if appropriate.  FilterBuf may return an error.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result > 0 && chunked_decoder_.get()) {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result == 0 && !chunked_decoder_->reached_eof()) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't signal completion of the Read call yet or else it'll look like
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // we received end-of-file.  Wait for more data.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_state_ = STATE_READ_BODY;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return OK;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result > 0)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_body_read_ += result;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result <= 0 || IsResponseBodyComplete()) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_state_ = STATE_DONE;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save the overflow data, which can be in two places.  There may be
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // some left over in |user_read_buf_|, plus there may be more
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in |read_buf_|.  But the part left over in |user_read_buf_| must have
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // come from the |read_buf_|, so there's room to put it back at the
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // start first.
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int additional_save_amount = read_buf_->offset() - read_buf_unused_offset_;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int save_amount = 0;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (chunked_decoder_.get()) {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      save_amount = chunked_decoder_->bytes_after_eof();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (response_body_length_ >= 0) {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int64 extra_data_read = response_body_read_ - response_body_length_;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (extra_data_read > 0) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        save_amount = static_cast<int>(extra_data_read);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (result > 0)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          result -= save_amount;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_LE(save_amount + additional_save_amount, kMaxBufSize);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (read_buf_->capacity() < save_amount + additional_save_amount) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_->SetCapacity(save_amount + additional_save_amount);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (save_amount) {
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      received_bytes_ -= save_amount;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(read_buf_->StartOfBuffer(), user_read_buf_->data() + result,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             save_amount);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_buf_->set_offset(save_amount);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (additional_save_amount) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memmove(read_buf_->data(),
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              read_buf_->StartOfBuffer() + read_buf_unused_offset_,
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              additional_save_amount);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_buf_->set_offset(save_amount + additional_save_amount);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_buf_unused_offset_ = 0;
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Now waiting for more of the body to be read.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    user_read_buf_ = NULL;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    user_read_buf_len_ = 0;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint HttpStreamParser::HandleReadHeaderResult(int result) {
7440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_EQ(0, read_buf_unused_offset_);
7450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result == 0)
7470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    result = ERR_CONNECTION_CLOSED;
7480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result < 0 && result != ERR_CONNECTION_CLOSED) {
7500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_DONE;
7510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return result;
7520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
7530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If we've used the connection before, then we know it is not a HTTP/0.9
7540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // response and return ERR_CONNECTION_CLOSED.
7550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 &&
7560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      connection_->is_reused()) {
7570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_DONE;
7580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return result;
7590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
7600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Record our best estimate of the 'response time' as the time when we read
7620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the first bytes of the response headers.
7630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (read_buf_->offset() == 0 && result != ERR_CONNECTION_CLOSED)
7640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    response_->response_time = base::Time::Now();
7650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result == ERR_CONNECTION_CLOSED) {
7670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // The connection closed before we detected the end of the headers.
7680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (read_buf_->offset() == 0) {
7690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // The connection was closed before any data was sent. Likely an error
7700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // rather than empty HTTP/0.9 response.
7710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      io_state_ = STATE_DONE;
7720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return ERR_EMPTY_RESPONSE;
7730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    } else if (request_->url.SchemeIsSecure()) {
7740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // The connection was closed in the middle of the headers. For HTTPS we
7750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // don't parse partial headers. Return a different error code so that we
7760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // know that we shouldn't attempt to retry the request.
7770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      io_state_ = STATE_DONE;
7780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return ERR_RESPONSE_HEADERS_TRUNCATED;
7790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
7800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Parse things as well as we can and let the caller decide what to do.
7810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int end_offset;
7820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (response_header_start_offset_ >= 0) {
7830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      io_state_ = STATE_READ_BODY_COMPLETE;
7840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      end_offset = read_buf_->offset();
7850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    } else {
7860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // Now waiting for the body to be read.
7870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      end_offset = 0;
7880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
7890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int rv = DoParseResponseHeaders(end_offset);
7900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (rv < 0)
7910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return rv;
7920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return result;
7930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
7940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  read_buf_->set_offset(read_buf_->offset() + result);
7960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_LE(read_buf_->offset(), read_buf_->capacity());
7970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_GE(result,  0);
7980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int end_of_header_offset = ParseResponseHeaders();
8000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Note: -1 is special, it indicates we haven't found the end of headers.
8020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Anything less than -1 is a net::Error, so we bail out.
8030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (end_of_header_offset < -1)
8040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return end_of_header_offset;
8050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (end_of_header_offset == -1) {
8070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_state_ = STATE_READ_HEADERS;
8080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Prevent growing the headers buffer indefinitely.
8090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (read_buf_->offset() >= kMaxHeaderBufSize) {
8100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      io_state_ = STATE_DONE;
8110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return ERR_RESPONSE_HEADERS_TOO_BIG;
8120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
8130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
8140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CalculateResponseBodySize();
8150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // If the body is zero length, the caller may not call ReadResponseBody,
8160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // which is where any extra data is copied to read_buf_, so we move the
8170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // data here.
8180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (response_body_length_ == 0) {
8190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      int extra_bytes = read_buf_->offset() - end_of_header_offset;
8200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (extra_bytes) {
8210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        CHECK_GT(extra_bytes, 0);
8220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        memmove(read_buf_->StartOfBuffer(),
8230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                read_buf_->StartOfBuffer() + end_of_header_offset,
8240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                extra_bytes);
8250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
8260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      read_buf_->SetCapacity(extra_bytes);
8270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (response_->headers->response_code() / 100 == 1) {
8280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // After processing a 1xx response, the caller will ask for the next
8290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // header, so reset state to support that. We don't completely ignore a
8300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // 1xx response because it cannot be returned in reply to a CONNECT
8310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // request so we return OK here, which lets the caller inspect the
8320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // response and reject it in the event that we're setting up a CONNECT
8330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // tunnel.
8340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        response_header_start_offset_ = -1;
8350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        response_body_length_ = -1;
8360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // Now waiting for the second set of headers to be read.
8370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      } else {
8380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        io_state_ = STATE_DONE;
8390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
8400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return OK;
8410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
8420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Note where the headers stop.
8440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    read_buf_unused_offset_ = end_of_header_offset;
8450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Now waiting for the body to be read.
8460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
8470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return result;
8480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::ParseResponseHeaders() {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int end_offset = -1;
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(0, read_buf_unused_offset_);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look for the start of the status line, if it hasn't been found yet.
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_header_start_offset_ < 0) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine(
8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        read_buf_->StartOfBuffer(), read_buf_->offset());
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_header_start_offset_ >= 0) {
8614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    end_offset = HttpUtil::LocateEndOfHeaders(read_buf_->StartOfBuffer(),
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              read_buf_->offset(),
8634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              response_header_start_offset_);
8644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else if (read_buf_->offset() >= 8) {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enough data to decide that this is an HTTP/0.9 response.
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 8 bytes = (4 bytes of junk) + "http".length()
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end_offset = 0;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (end_offset == -1)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = DoParseResponseHeaders(end_offset);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv < 0)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return end_offset;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::DoParseResponseHeaders(int end_offset) {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpResponseHeaders> headers;
8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(0, read_buf_unused_offset_);
8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_header_start_offset_ >= 0) {
884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    received_bytes_ += end_offset;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        read_buf_->StartOfBuffer(), end_offset));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enough data was read -- there is no status line.
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for multiple Content-Length headers with no Transfer-Encoding header.
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If they exist, and have distinct values, it's a potential response
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // smuggling attack.
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!headers->HasHeader("Transfer-Encoding")) {
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (HeadersContainMultipleCopiesOfField(*headers.get(), "Content-Length"))
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for multiple Content-Disposition or Location headers.  If they exist,
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it's also a potential response smuggling attack.
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (HeadersContainMultipleCopiesOfField(*headers.get(),
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          "Content-Disposition"))
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION;
905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (HeadersContainMultipleCopiesOfField(*headers.get(), "Location"))
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_->headers = headers;
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1;
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  response_->vary_data.Init(*request_, *response_->headers.get());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "()"
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           << " content_length = \"" << response_->headers->GetContentLength()
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           << "\n\""
914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           << " headers = \""
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           << GetResponseHeaderLines(*response_->headers.get()) << "\"";
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::CalculateResponseBodySize() {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Figure how to determine EOF:
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For certain responses, we know the content length is always 0. From
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RFC 2616 Section 4.3 Message Body:
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For response messages, whether or not a message-body is included with
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a message is dependent on both the request method and the response
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // status code (section 6.1.1). All responses to the HEAD request method
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MUST NOT include a message-body, even though the presence of entity-
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // header fields might lead one to believe they do. All 1xx
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (informational), 204 (no content), and 304 (not modified) responses
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MUST NOT include a message-body. All other responses do include a
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message-body, although it MAY be of zero length.
9334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (response_->headers->response_code() / 100 == 1) {
9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    response_body_length_ = 0;
9354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    switch (response_->headers->response_code()) {
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 204:  // No Content
9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 205:  // Reset Content
9394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 304:  // Not Modified
9404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        response_body_length_ = 0;
9414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
9424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_->method == "HEAD")
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_body_length_ = 0;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_body_length_ == -1) {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "Transfer-Encoding: chunked" trumps "Content-Length: N"
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response_->headers->IsChunkEncoded()) {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chunked_decoder_.reset(new HttpChunkedDecoder());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_body_length_ = response_->headers->GetContentLength();
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If response_body_length_ is still -1, then we have to wait
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // for the server to close the connection.
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress HttpStreamParser::GetUploadProgress() const {
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!request_->upload_data_stream)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UploadProgress();
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return UploadProgress(request_->upload_data_stream->position(),
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        request_->upload_data_stream->size());
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::IsResponseBodyComplete() const {
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chunked_decoder_.get())
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return chunked_decoder_->reached_eof();
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_body_length_ != -1)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_body_read_ >= response_body_length_;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;  // Must read to EOF.
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::CanFindEndOfResponse() const {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chunked_decoder_.get() || response_body_length_ >= 0;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::IsMoreDataBuffered() const {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return read_buf_->offset() > read_buf_unused_offset_;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::IsConnectionReused() const {
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle::SocketReuseType reuse_type = connection_->reuse_type();
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return connection_->is_reused() ||
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         reuse_type == ClientSocketHandle::UNUSED_IDLE;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::SetConnectionReused() {
99123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::IsConnectionReusable() const {
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return connection_->socket() && connection_->socket()->IsConnectedAndIdle();
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) {
9997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (request_->url.SchemeIsSecure() && connection_->socket()) {
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLClientSocket* ssl_socket =
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<SSLClientSocket*>(connection_->socket());
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket->GetSSLInfo(ssl_info);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpStreamParser::GetSSLCertRequestInfo(
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLCertRequestInfo* cert_request_info) {
10087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (request_->url.SchemeIsSecure() && connection_->socket()) {
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLClientSocket* ssl_socket =
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<SSLClientSocket*>(connection_->socket());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket->GetSSLCertRequestInfo(cert_request_info);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpStreamParser::EncodeChunk(const base::StringPiece& payload,
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  char* output,
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  size_t output_size) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (output_size < payload.size() + kChunkHeaderFooterSize)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_INVALID_ARGUMENT;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* cursor = output;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the header.
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int num_chars = base::snprintf(output, output_size,
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "%X\r\n",
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       static_cast<int>(payload.size()));
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cursor += num_chars;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the payload if any.
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (payload.size() > 0) {
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(cursor, payload.data(), payload.size());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cursor += payload.size();
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the trailing CRLF.
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(cursor, "\r\n", 2);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cursor += 2;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cursor - output;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpStreamParser::ShouldMergeRequestHeadersAndBody(
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& request_headers,
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UploadDataStream* request_body) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_body != NULL &&
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // IsInMemory() ensures that the request body is not chunked.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_body->IsInMemory() &&
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_body->size() > 0) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t merged_size = request_headers.size() + request_body->size();
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (merged_size <= kMaxMergedHeaderAndBodySize)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1055