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