• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_stream_parser.h"
6 
7 #include "base/compiler_specific.h"
8 #include "base/metrics/histogram.h"
9 #include "base/string_util.h"
10 #include "net/base/address_list.h"
11 #include "net/base/auth.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/ssl_cert_request_info.h"
14 #include "net/http/http_net_log_params.h"
15 #include "net/http/http_request_headers.h"
16 #include "net/http/http_request_info.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_util.h"
19 #include "net/socket/ssl_client_socket.h"
20 #include "net/socket/client_socket_handle.h"
21 
22 namespace net {
23 
HttpStreamParser(ClientSocketHandle * connection,const HttpRequestInfo * request,GrowableIOBuffer * read_buffer,const BoundNetLog & net_log)24 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
25                                    const HttpRequestInfo* request,
26                                    GrowableIOBuffer* read_buffer,
27                                    const BoundNetLog& net_log)
28     : io_state_(STATE_NONE),
29       request_(request),
30       request_headers_(NULL),
31       request_body_(NULL),
32       read_buf_(read_buffer),
33       read_buf_unused_offset_(0),
34       response_header_start_offset_(-1),
35       response_body_length_(-1),
36       response_body_read_(0),
37       chunked_decoder_(NULL),
38       user_read_buf_(NULL),
39       user_read_buf_len_(0),
40       user_callback_(NULL),
41       connection_(connection),
42       net_log_(net_log),
43       ALLOW_THIS_IN_INITIALIZER_LIST(
44           io_callback_(this, &HttpStreamParser::OnIOComplete)),
45       chunk_length_(0),
46       chunk_length_without_encoding_(0),
47       sent_last_chunk_(false) {
48   DCHECK_EQ(0, read_buffer->offset());
49 }
50 
~HttpStreamParser()51 HttpStreamParser::~HttpStreamParser() {
52   if (request_body_ != NULL && request_body_->is_chunked())
53     request_body_->set_chunk_callback(NULL);
54 }
55 
SendRequest(const std::string & request_line,const HttpRequestHeaders & headers,UploadDataStream * request_body,HttpResponseInfo * response,CompletionCallback * callback)56 int HttpStreamParser::SendRequest(const std::string& request_line,
57                                   const HttpRequestHeaders& headers,
58                                   UploadDataStream* request_body,
59                                   HttpResponseInfo* response,
60                                   CompletionCallback* callback) {
61   DCHECK_EQ(STATE_NONE, io_state_);
62   DCHECK(!user_callback_);
63   DCHECK(callback);
64   DCHECK(response);
65 
66   if (net_log_.IsLoggingAllEvents()) {
67     net_log_.AddEvent(
68         NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
69         make_scoped_refptr(new NetLogHttpRequestParameter(
70             request_line, headers)));
71   }
72   response_ = response;
73 
74   // Put the peer's IP address and port into the response.
75   AddressList address;
76   int result = connection_->socket()->GetPeerAddress(&address);
77   if (result != OK)
78     return result;
79   response_->socket_address = HostPortPair::FromAddrInfo(address.head());
80 
81   std::string request = request_line + headers.ToString();
82   scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
83   request_headers_ = new DrainableIOBuffer(headers_io_buf,
84                                            headers_io_buf->size());
85   request_body_.reset(request_body);
86   if (request_body_ != NULL && request_body_->is_chunked()) {
87     request_body_->set_chunk_callback(this);
88     const int kChunkHeaderFooterSize = 12;  // 2 CRLFs + max of 8 hex chars.
89     chunk_buf_ = new IOBuffer(request_body_->GetMaxBufferSize() +
90                               kChunkHeaderFooterSize);
91   }
92 
93   io_state_ = STATE_SENDING_HEADERS;
94   result = DoLoop(OK);
95   if (result == ERR_IO_PENDING)
96     user_callback_ = callback;
97 
98   return result > 0 ? OK : result;
99 }
100 
ReadResponseHeaders(CompletionCallback * callback)101 int HttpStreamParser::ReadResponseHeaders(CompletionCallback* callback) {
102   DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE);
103   DCHECK(!user_callback_);
104   DCHECK(callback);
105 
106   // This function can be called with io_state_ == STATE_DONE if the
107   // connection is closed after seeing just a 1xx response code.
108   if (io_state_ == STATE_DONE)
109     return ERR_CONNECTION_CLOSED;
110 
111   int result = OK;
112   io_state_ = STATE_READ_HEADERS;
113 
114   if (read_buf_->offset() > 0) {
115     // Simulate the state where the data was just read from the socket.
116     result = read_buf_->offset() - read_buf_unused_offset_;
117     read_buf_->set_offset(read_buf_unused_offset_);
118   }
119   if (result > 0)
120     io_state_ = STATE_READ_HEADERS_COMPLETE;
121 
122   result = DoLoop(result);
123   if (result == ERR_IO_PENDING)
124     user_callback_ = callback;
125 
126   return result > 0 ? OK : result;
127 }
128 
Close(bool not_reusable)129 void HttpStreamParser::Close(bool not_reusable) {
130   if (not_reusable && connection_->socket())
131     connection_->socket()->Disconnect();
132   connection_->Reset();
133 }
134 
ReadResponseBody(IOBuffer * buf,int buf_len,CompletionCallback * callback)135 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len,
136                                        CompletionCallback* callback) {
137   DCHECK(io_state_ == STATE_BODY_PENDING || io_state_ == STATE_DONE);
138   DCHECK(!user_callback_);
139   DCHECK(callback);
140   DCHECK_LE(buf_len, kMaxBufSize);
141 
142   if (io_state_ == STATE_DONE)
143     return OK;
144 
145   user_read_buf_ = buf;
146   user_read_buf_len_ = buf_len;
147   io_state_ = STATE_READ_BODY;
148 
149   int result = DoLoop(OK);
150   if (result == ERR_IO_PENDING)
151     user_callback_ = callback;
152 
153   return result;
154 }
155 
OnIOComplete(int result)156 void HttpStreamParser::OnIOComplete(int result) {
157   result = DoLoop(result);
158 
159   // The client callback can do anything, including destroying this class,
160   // so any pending callback must be issued after everything else is done.
161   if (result != ERR_IO_PENDING && user_callback_) {
162     CompletionCallback* c = user_callback_;
163     user_callback_ = NULL;
164     c->Run(result);
165   }
166 }
167 
OnChunkAvailable()168 void HttpStreamParser::OnChunkAvailable() {
169   // This method may get called while sending the headers or body, so check
170   // before processing the new data. If we were still initializing or sending
171   // headers, we will automatically start reading the chunks once we get into
172   // STATE_SENDING_BODY so nothing to do here.
173   DCHECK(io_state_ == STATE_SENDING_HEADERS || io_state_ == STATE_SENDING_BODY);
174   if (io_state_ == STATE_SENDING_BODY)
175     OnIOComplete(0);
176 }
177 
DoLoop(int result)178 int HttpStreamParser::DoLoop(int result) {
179   bool can_do_more = true;
180   do {
181     switch (io_state_) {
182       case STATE_SENDING_HEADERS:
183         if (result < 0)
184           can_do_more = false;
185         else
186           result = DoSendHeaders(result);
187         break;
188       case STATE_SENDING_BODY:
189         if (result < 0)
190           can_do_more = false;
191         else
192           result = DoSendBody(result);
193         break;
194       case STATE_REQUEST_SENT:
195         DCHECK(result != ERR_IO_PENDING);
196         can_do_more = false;
197         break;
198       case STATE_READ_HEADERS:
199         net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, NULL);
200         result = DoReadHeaders();
201         break;
202       case STATE_READ_HEADERS_COMPLETE:
203         result = DoReadHeadersComplete(result);
204         net_log_.EndEventWithNetErrorCode(
205             NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS, result);
206         break;
207       case STATE_BODY_PENDING:
208         DCHECK(result != ERR_IO_PENDING);
209         can_do_more = false;
210         break;
211       case STATE_READ_BODY:
212         result = DoReadBody();
213         // DoReadBodyComplete handles error conditions.
214         break;
215       case STATE_READ_BODY_COMPLETE:
216         result = DoReadBodyComplete(result);
217         break;
218       case STATE_DONE:
219         DCHECK(result != ERR_IO_PENDING);
220         can_do_more = false;
221         break;
222       default:
223         NOTREACHED();
224         can_do_more = false;
225         break;
226     }
227   } while (result != ERR_IO_PENDING && can_do_more);
228 
229   return result;
230 }
231 
DoSendHeaders(int result)232 int HttpStreamParser::DoSendHeaders(int result) {
233   request_headers_->DidConsume(result);
234   int bytes_remaining = request_headers_->BytesRemaining();
235   if (bytes_remaining > 0) {
236     // Record our best estimate of the 'request time' as the time when we send
237     // out the first bytes of the request headers.
238     if (bytes_remaining == request_headers_->size()) {
239       response_->request_time = base::Time::Now();
240 
241       // We'll record the count of uncoalesced packets IFF coalescing will help,
242       // and otherwise we'll use an enum to tell why it won't help.
243       enum COALESCE_POTENTIAL {
244         // Coalescing won't reduce packet count.
245         NO_ADVANTAGE = 0,
246         // There is only a header packet or we have a request body but the
247         // request body isn't available yet (can't coalesce).
248         HEADER_ONLY = 1,
249         // Various cases of coalasced savings.
250         COALESCE_POTENTIAL_MAX = 30
251       };
252       size_t coalesce = HEADER_ONLY;
253       if (request_body_ != NULL && !request_body_->is_chunked()) {
254         const size_t kBytesPerPacket = 1430;
255         uint64 body_packets = (request_body_->size() + kBytesPerPacket - 1) /
256                               kBytesPerPacket;
257         uint64 header_packets = (bytes_remaining + kBytesPerPacket - 1) /
258                                 kBytesPerPacket;
259         uint64 coalesced_packets = (request_body_->size() + bytes_remaining +
260                                     kBytesPerPacket - 1) / kBytesPerPacket;
261         if (coalesced_packets < header_packets + body_packets) {
262           if (coalesced_packets > COALESCE_POTENTIAL_MAX)
263             coalesce = COALESCE_POTENTIAL_MAX;
264           else
265             coalesce = static_cast<size_t>(header_packets + body_packets);
266         } else {
267           coalesce = NO_ADVANTAGE;
268         }
269       }
270       UMA_HISTOGRAM_ENUMERATION("Net.CoalescePotential", coalesce,
271                                 COALESCE_POTENTIAL_MAX);
272     }
273     result = connection_->socket()->Write(request_headers_,
274                                           bytes_remaining,
275                                           &io_callback_);
276   } else if (request_body_ != NULL &&
277              (request_body_->is_chunked() || request_body_->size())) {
278     io_state_ = STATE_SENDING_BODY;
279     result = OK;
280   } else {
281     io_state_ = STATE_REQUEST_SENT;
282   }
283   return result;
284 }
285 
DoSendBody(int result)286 int HttpStreamParser::DoSendBody(int result) {
287   if (request_body_->is_chunked()) {
288     chunk_length_ -= result;
289     if (chunk_length_) {
290       memmove(chunk_buf_->data(), chunk_buf_->data() + result, chunk_length_);
291       return connection_->socket()->Write(chunk_buf_, chunk_length_,
292                                           &io_callback_);
293     }
294 
295     if (sent_last_chunk_) {
296       io_state_ = STATE_REQUEST_SENT;
297       return OK;
298     }
299 
300     request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_);
301     chunk_length_without_encoding_ = 0;
302     chunk_length_ = 0;
303 
304     int buf_len = static_cast<int>(request_body_->buf_len());
305     if (request_body_->eof()) {
306       static const char kLastChunk[] = "0\r\n\r\n";
307       chunk_length_ = strlen(kLastChunk);
308       memcpy(chunk_buf_->data(), kLastChunk, chunk_length_);
309       sent_last_chunk_ = true;
310     } else if (buf_len) {
311       // Encode and send the buffer as 1 chunk.
312       std::string chunk_header = StringPrintf("%X\r\n", buf_len);
313       char* chunk_ptr = chunk_buf_->data();
314       memcpy(chunk_ptr, chunk_header.data(), chunk_header.length());
315       chunk_ptr += chunk_header.length();
316       memcpy(chunk_ptr, request_body_->buf()->data(), buf_len);
317       chunk_ptr += buf_len;
318       memcpy(chunk_ptr, "\r\n", 2);
319       chunk_length_without_encoding_ = buf_len;
320       chunk_length_ = chunk_header.length() + buf_len + 2;
321     }
322 
323     if (!chunk_length_)  // More POST data is yet to come?
324       return ERR_IO_PENDING;
325 
326     return connection_->socket()->Write(chunk_buf_, chunk_length_,
327                                         &io_callback_);
328   }
329 
330   // Non-chunked request body.
331   request_body_->MarkConsumedAndFillBuffer(result);
332 
333   if (!request_body_->eof()) {
334     int buf_len = static_cast<int>(request_body_->buf_len());
335     result = connection_->socket()->Write(request_body_->buf(), buf_len,
336                                           &io_callback_);
337   } else {
338     io_state_ = STATE_REQUEST_SENT;
339   }
340   return result;
341 }
342 
DoReadHeaders()343 int HttpStreamParser::DoReadHeaders() {
344   io_state_ = STATE_READ_HEADERS_COMPLETE;
345 
346   // Grow the read buffer if necessary.
347   if (read_buf_->RemainingCapacity() == 0)
348     read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
349 
350   // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
351   // See if the user is passing in an IOBuffer with a NULL |data_|.
352   CHECK(read_buf_->data());
353 
354   return connection_->socket()->Read(read_buf_,
355                                      read_buf_->RemainingCapacity(),
356                                      &io_callback_);
357 }
358 
DoReadHeadersComplete(int result)359 int HttpStreamParser::DoReadHeadersComplete(int result) {
360   if (result == 0)
361     result = ERR_CONNECTION_CLOSED;
362 
363   if (result < 0 && result != ERR_CONNECTION_CLOSED) {
364     io_state_ = STATE_DONE;
365     return result;
366   }
367   // If we've used the connection before, then we know it is not a HTTP/0.9
368   // response and return ERR_CONNECTION_CLOSED.
369   if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 &&
370       connection_->is_reused()) {
371     io_state_ = STATE_DONE;
372     return result;
373   }
374 
375   // Record our best estimate of the 'response time' as the time when we read
376   // the first bytes of the response headers.
377   if (read_buf_->offset() == 0 && result != ERR_CONNECTION_CLOSED)
378     response_->response_time = base::Time::Now();
379 
380   if (result == ERR_CONNECTION_CLOSED) {
381     // The connection closed before we detected the end of the headers.
382     // parse things as well as we can and let the caller decide what to do.
383     if (read_buf_->offset() == 0) {
384       // The connection was closed before any data was sent. Likely an error
385       // rather than empty HTTP/0.9 response.
386       io_state_ = STATE_DONE;
387       return ERR_EMPTY_RESPONSE;
388     } else {
389       int end_offset;
390       if (response_header_start_offset_ >= 0) {
391         io_state_ = STATE_READ_BODY_COMPLETE;
392         end_offset = read_buf_->offset();
393       } else {
394         io_state_ = STATE_BODY_PENDING;
395         end_offset = 0;
396       }
397       int rv = DoParseResponseHeaders(end_offset);
398       if (rv < 0)
399         return rv;
400       return result;
401     }
402   }
403 
404   read_buf_->set_offset(read_buf_->offset() + result);
405   DCHECK_LE(read_buf_->offset(), read_buf_->capacity());
406   DCHECK_GE(result,  0);
407 
408   int end_of_header_offset = ParseResponseHeaders();
409 
410   // Note: -1 is special, it indicates we haven't found the end of headers.
411   // Anything less than -1 is a net::Error, so we bail out.
412   if (end_of_header_offset < -1)
413     return end_of_header_offset;
414 
415   if (end_of_header_offset == -1) {
416     io_state_ = STATE_READ_HEADERS;
417     // Prevent growing the headers buffer indefinitely.
418     if (read_buf_->offset() - read_buf_unused_offset_ >= kMaxHeaderBufSize) {
419       io_state_ = STATE_DONE;
420       return ERR_RESPONSE_HEADERS_TOO_BIG;
421     }
422   } else {
423     // Note where the headers stop.
424     read_buf_unused_offset_ = end_of_header_offset;
425 
426     if (response_->headers->response_code() / 100 == 1) {
427       // After processing a 1xx response, the caller will ask for the next
428       // header, so reset state to support that.  We don't just skip these
429       // completely because 1xx codes aren't acceptable when establishing a
430       // tunnel.
431       io_state_ = STATE_REQUEST_SENT;
432       response_header_start_offset_ = -1;
433     } else {
434       io_state_ = STATE_BODY_PENDING;
435       CalculateResponseBodySize();
436       // If the body is 0, the caller may not call ReadResponseBody, which
437       // is where any extra data is copied to read_buf_, so we move the
438       // data here and transition to DONE.
439       if (response_body_length_ == 0) {
440         io_state_ = STATE_DONE;
441         int extra_bytes = read_buf_->offset() - read_buf_unused_offset_;
442         if (extra_bytes) {
443           CHECK_GT(extra_bytes, 0);
444           memmove(read_buf_->StartOfBuffer(),
445                   read_buf_->StartOfBuffer() + read_buf_unused_offset_,
446                   extra_bytes);
447         }
448         read_buf_->SetCapacity(extra_bytes);
449         read_buf_unused_offset_ = 0;
450         return OK;
451       }
452     }
453   }
454   return result;
455 }
456 
DoReadBody()457 int HttpStreamParser::DoReadBody() {
458   io_state_ = STATE_READ_BODY_COMPLETE;
459 
460   // There may be some data left over from reading the response headers.
461   if (read_buf_->offset()) {
462     int available = read_buf_->offset() - read_buf_unused_offset_;
463     if (available) {
464       CHECK_GT(available, 0);
465       int bytes_from_buffer = std::min(available, user_read_buf_len_);
466       memcpy(user_read_buf_->data(),
467              read_buf_->StartOfBuffer() + read_buf_unused_offset_,
468              bytes_from_buffer);
469       read_buf_unused_offset_ += bytes_from_buffer;
470       if (bytes_from_buffer == available) {
471         read_buf_->SetCapacity(0);
472         read_buf_unused_offset_ = 0;
473       }
474       return bytes_from_buffer;
475     } else {
476       read_buf_->SetCapacity(0);
477       read_buf_unused_offset_ = 0;
478     }
479   }
480 
481   // Check to see if we're done reading.
482   if (IsResponseBodyComplete())
483     return 0;
484 
485   DCHECK_EQ(0, read_buf_->offset());
486   return connection_->socket()->Read(user_read_buf_, user_read_buf_len_,
487                                      &io_callback_);
488 }
489 
DoReadBodyComplete(int result)490 int HttpStreamParser::DoReadBodyComplete(int result) {
491   // If we didn't get a content-length and aren't using a chunked encoding,
492   // the only way to signal the end of a stream is to close the connection,
493   // so we don't treat that as an error, though in some cases we may not
494   // have completely received the resource.
495   if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse())
496     result = ERR_CONNECTION_CLOSED;
497 
498   // Filter incoming data if appropriate.  FilterBuf may return an error.
499   if (result > 0 && chunked_decoder_.get()) {
500     result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result);
501     if (result == 0 && !chunked_decoder_->reached_eof()) {
502       // Don't signal completion of the Read call yet or else it'll look like
503       // we received end-of-file.  Wait for more data.
504       io_state_ = STATE_READ_BODY;
505       return OK;
506     }
507   }
508 
509   if (result > 0)
510     response_body_read_ += result;
511 
512   if (result <= 0 || IsResponseBodyComplete()) {
513     io_state_ = STATE_DONE;
514 
515     // Save the overflow data, which can be in two places.  There may be
516     // some left over in |user_read_buf_|, plus there may be more
517     // in |read_buf_|.  But the part left over in |user_read_buf_| must have
518     // come from the |read_buf_|, so there's room to put it back at the
519     // start first.
520     int additional_save_amount = read_buf_->offset() - read_buf_unused_offset_;
521     int save_amount = 0;
522     if (chunked_decoder_.get()) {
523       save_amount = chunked_decoder_->bytes_after_eof();
524     } else if (response_body_length_ >= 0) {
525       int64 extra_data_read = response_body_read_ - response_body_length_;
526       if (extra_data_read > 0) {
527         save_amount = static_cast<int>(extra_data_read);
528         if (result > 0)
529           result -= save_amount;
530       }
531     }
532 
533     CHECK_LE(save_amount + additional_save_amount, kMaxBufSize);
534     if (read_buf_->capacity() < save_amount + additional_save_amount) {
535       read_buf_->SetCapacity(save_amount + additional_save_amount);
536     }
537 
538     if (save_amount) {
539       memcpy(read_buf_->StartOfBuffer(), user_read_buf_->data() + result,
540              save_amount);
541     }
542     read_buf_->set_offset(save_amount);
543     if (additional_save_amount) {
544       memmove(read_buf_->data(),
545               read_buf_->StartOfBuffer() + read_buf_unused_offset_,
546               additional_save_amount);
547       read_buf_->set_offset(save_amount + additional_save_amount);
548     }
549     read_buf_unused_offset_ = 0;
550   } else {
551     io_state_ = STATE_BODY_PENDING;
552     user_read_buf_ = NULL;
553     user_read_buf_len_ = 0;
554   }
555 
556   return result;
557 }
558 
ParseResponseHeaders()559 int HttpStreamParser::ParseResponseHeaders() {
560   int end_offset = -1;
561 
562   // Look for the start of the status line, if it hasn't been found yet.
563   if (response_header_start_offset_ < 0) {
564     response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine(
565         read_buf_->StartOfBuffer() + read_buf_unused_offset_,
566         read_buf_->offset() - read_buf_unused_offset_);
567   }
568 
569   if (response_header_start_offset_ >= 0) {
570     end_offset = HttpUtil::LocateEndOfHeaders(
571         read_buf_->StartOfBuffer() + read_buf_unused_offset_,
572         read_buf_->offset() - read_buf_unused_offset_,
573         response_header_start_offset_);
574   } else if (read_buf_->offset() - read_buf_unused_offset_ >= 8) {
575     // Enough data to decide that this is an HTTP/0.9 response.
576     // 8 bytes = (4 bytes of junk) + "http".length()
577     end_offset = 0;
578   }
579 
580   if (end_offset == -1)
581     return -1;
582 
583   int rv = DoParseResponseHeaders(end_offset);
584   if (rv < 0)
585     return rv;
586   return end_offset + read_buf_unused_offset_;
587 }
588 
DoParseResponseHeaders(int end_offset)589 int HttpStreamParser::DoParseResponseHeaders(int end_offset) {
590   scoped_refptr<HttpResponseHeaders> headers;
591   if (response_header_start_offset_ >= 0) {
592     headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
593         read_buf_->StartOfBuffer() + read_buf_unused_offset_, end_offset));
594   } else {
595     // Enough data was read -- there is no status line.
596     headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
597   }
598 
599   // Check for multiple Content-Length headers with a Transfer-Encoding header.
600   // If they exist, it's a potential response smuggling attack.
601 
602   void* it = NULL;
603   const std::string content_length_header("Content-Length");
604   std::string content_length_value;
605   if (!headers->HasHeader("Transfer-Encoding") &&
606       headers->EnumerateHeader(
607           &it, content_length_header, &content_length_value)) {
608     // Ok, there's no Transfer-Encoding header and there's at least one
609     // Content-Length header.  Check if there are any more Content-Length
610     // headers, and if so, make sure they have the same value.  Otherwise, it's
611     // a possible response smuggling attack.
612     std::string content_length_value2;
613     while (headers->EnumerateHeader(
614         &it, content_length_header, &content_length_value2)) {
615       if (content_length_value != content_length_value2)
616         return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH;
617     }
618   }
619 
620   response_->headers = headers;
621   response_->vary_data.Init(*request_, *response_->headers);
622   return OK;
623 }
624 
CalculateResponseBodySize()625 void HttpStreamParser::CalculateResponseBodySize() {
626   // Figure how to determine EOF:
627 
628   // For certain responses, we know the content length is always 0. From
629   // RFC 2616 Section 4.3 Message Body:
630   //
631   // For response messages, whether or not a message-body is included with
632   // a message is dependent on both the request method and the response
633   // status code (section 6.1.1). All responses to the HEAD request method
634   // MUST NOT include a message-body, even though the presence of entity-
635   // header fields might lead one to believe they do. All 1xx
636   // (informational), 204 (no content), and 304 (not modified) responses
637   // MUST NOT include a message-body. All other responses do include a
638   // message-body, although it MAY be of zero length.
639   switch (response_->headers->response_code()) {
640     // Note that 1xx was already handled earlier.
641     case 204:  // No Content
642     case 205:  // Reset Content
643     case 304:  // Not Modified
644       response_body_length_ = 0;
645       break;
646   }
647   if (request_->method == "HEAD")
648     response_body_length_ = 0;
649 
650   if (response_body_length_ == -1) {
651     // Ignore spurious chunked responses from HTTP/1.0 servers and
652     // proxies. Otherwise "Transfer-Encoding: chunked" trumps
653     // "Content-Length: N"
654     if (response_->headers->GetHttpVersion() >= HttpVersion(1, 1) &&
655         response_->headers->HasHeaderValue("Transfer-Encoding", "chunked")) {
656       chunked_decoder_.reset(new HttpChunkedDecoder());
657     } else {
658       response_body_length_ = response_->headers->GetContentLength();
659       // If response_body_length_ is still -1, then we have to wait
660       // for the server to close the connection.
661     }
662   }
663 }
664 
GetUploadProgress() const665 uint64 HttpStreamParser::GetUploadProgress() const {
666   if (!request_body_.get())
667     return 0;
668 
669   return request_body_->position();
670 }
671 
GetResponseInfo()672 HttpResponseInfo* HttpStreamParser::GetResponseInfo() {
673   return response_;
674 }
675 
IsResponseBodyComplete() const676 bool HttpStreamParser::IsResponseBodyComplete() const {
677   if (chunked_decoder_.get())
678     return chunked_decoder_->reached_eof();
679   if (response_body_length_ != -1)
680     return response_body_read_ >= response_body_length_;
681 
682   return false;  // Must read to EOF.
683 }
684 
CanFindEndOfResponse() const685 bool HttpStreamParser::CanFindEndOfResponse() const {
686   return chunked_decoder_.get() || response_body_length_ >= 0;
687 }
688 
IsMoreDataBuffered() const689 bool HttpStreamParser::IsMoreDataBuffered() const {
690   return read_buf_->offset() > read_buf_unused_offset_;
691 }
692 
IsConnectionReused() const693 bool HttpStreamParser::IsConnectionReused() const {
694   ClientSocketHandle::SocketReuseType reuse_type = connection_->reuse_type();
695   return connection_->is_reused() ||
696          reuse_type == ClientSocketHandle::UNUSED_IDLE;
697 }
698 
SetConnectionReused()699 void HttpStreamParser::SetConnectionReused() {
700   connection_->set_is_reused(true);
701 }
702 
IsConnectionReusable() const703 bool HttpStreamParser::IsConnectionReusable() const {
704   return connection_->socket() && connection_->socket()->IsConnectedAndIdle();
705 }
706 
GetSSLInfo(SSLInfo * ssl_info)707 void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) {
708   if (request_->url.SchemeIs("https") && connection_->socket()) {
709     SSLClientSocket* ssl_socket =
710         static_cast<SSLClientSocket*>(connection_->socket());
711     ssl_socket->GetSSLInfo(ssl_info);
712   }
713 }
714 
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)715 void HttpStreamParser::GetSSLCertRequestInfo(
716     SSLCertRequestInfo* cert_request_info) {
717   if (request_->url.SchemeIs("https") && connection_->socket()) {
718     SSLClientSocket* ssl_socket =
719         static_cast<SSLClientSocket*>(connection_->socket());
720     ssl_socket->GetSSLCertRequestInfo(cert_request_info);
721   }
722 }
723 
724 }  // namespace net
725