1 // Copyright (c) 2012 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.
5 #include "net/http/http_stream_parser.h"
8 #include "base/compiler_specific.h"
9 #include "base/strings/string_util.h"
10 #include "base/values.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/upload_data_stream.h"
14 #include "net/http/http_chunked_decoder.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/client_socket_handle.h"
20 #include "net/socket/ssl_client_socket.h"
24 const size_t kMaxMergedHeaderAndBodySize
= 1400;
25 const size_t kRequestBodyBufferSize
= 1 << 14; // 16KB
27 std::string
GetResponseHeaderLines(const net::HttpResponseHeaders
& headers
) {
28 std::string raw_headers
= headers
.raw_headers();
29 const char* null_separated_headers
= raw_headers
.c_str();
30 const char* header_line
= null_separated_headers
;
31 std::string cr_separated_headers
;
32 while (header_line
[0] != 0) {
33 cr_separated_headers
+= header_line
;
34 cr_separated_headers
+= "\n";
35 header_line
+= strlen(header_line
) + 1;
37 return cr_separated_headers
;
40 // Return true if |headers| contain multiple |field_name| fields with different
42 bool HeadersContainMultipleCopiesOfField(
43 const net::HttpResponseHeaders
& headers
,
44 const std::string
& field_name
) {
46 std::string field_value
;
47 if (!headers
.EnumerateHeader(&it
, field_name
, &field_value
))
49 // There's at least one |field_name| header. Check if there are any more
50 // such headers, and if so, return true if they have different values.
51 std::string field_value2
;
52 while (headers
.EnumerateHeader(&it
, field_name
, &field_value2
)) {
53 if (field_value
!= field_value2
)
59 base::Value
* NetLogSendRequestBodyCallback(
63 net::NetLog::LogLevel
/* log_level */) {
64 base::DictionaryValue
* dict
= new base::DictionaryValue();
65 dict
->SetInteger("length", length
);
66 dict
->SetBoolean("is_chunked", is_chunked
);
67 dict
->SetBoolean("did_merge", did_merge
);
75 // Similar to DrainableIOBuffer(), but this version comes with its own
76 // storage. The motivation is to avoid repeated allocations of
81 // scoped_refptr<SeekableIOBuffer> buf = new SeekableIOBuffer(1024);
82 // // capacity() == 1024. size() == BytesRemaining() == BytesConsumed() == 0.
83 // // data() points to the beginning of the buffer.
85 // // Read() takes an IOBuffer.
86 // int bytes_read = some_reader->Read(buf, buf->capacity());
87 // buf->DidAppend(bytes_read);
88 // // size() == BytesRemaining() == bytes_read. data() is unaffected.
90 // while (buf->BytesRemaining() > 0) {
91 // // Write() takes an IOBuffer. If it takes const char*, we could
92 /// // simply use the regular IOBuffer like buf->data() + offset.
93 // int bytes_written = Write(buf, buf->BytesRemaining());
94 // buf->DidConsume(bytes_written);
96 // // BytesRemaining() == 0. BytesConsumed() == size().
97 // // data() points to the end of the consumed bytes (exclusive).
99 // // If you want to reuse the buffer, be sure to clear the buffer.
101 // // size() == BytesRemaining() == BytesConsumed() == 0.
102 // // data() points to the beginning of the buffer.
104 class HttpStreamParser::SeekableIOBuffer
: public net::IOBuffer
{
106 explicit SeekableIOBuffer(int capacity
)
107 : IOBuffer(capacity
),
114 // DidConsume() changes the |data_| pointer so that |data_| always points
115 // to the first unconsumed byte.
116 void DidConsume(int bytes
) {
117 SetOffset(used_
+ bytes
);
120 // Returns the number of unconsumed bytes.
121 int BytesRemaining() const {
122 return size_
- used_
;
125 // Seeks to an arbitrary point in the buffer. The notion of bytes consumed
126 // and remaining are updated appropriately.
127 void SetOffset(int bytes
) {
129 DCHECK_LE(bytes
, size_
);
131 data_
= real_data_
+ used_
;
134 // Called after data is added to the buffer. Adds |bytes| added to
135 // |size_|. data() is unaffected.
136 void DidAppend(int bytes
) {
138 DCHECK_GE(size_
+ bytes
, 0);
139 DCHECK_LE(size_
+ bytes
, capacity_
);
143 // Changes the logical size to 0, and the offset to 0.
149 // Returns the logical size of the buffer (i.e the number of bytes of data
151 int size() const { return size_
; }
153 // Returns the capacity of the buffer. The capacity is the size used when
154 // the object is created.
155 int capacity() const { return capacity_
; };
158 virtual ~SeekableIOBuffer() {
159 // data_ will be deleted in IOBuffer::~IOBuffer().
169 // 2 CRLFs + max of 8 hex chars.
170 const size_t HttpStreamParser::kChunkHeaderFooterSize
= 12;
172 HttpStreamParser::HttpStreamParser(ClientSocketHandle
* connection
,
173 const HttpRequestInfo
* request
,
174 GrowableIOBuffer
* read_buffer
,
175 const BoundNetLog
& net_log
)
176 : io_state_(STATE_NONE
),
178 request_headers_(NULL
),
179 read_buf_(read_buffer
),
180 read_buf_unused_offset_(0),
181 response_header_start_offset_(-1),
183 response_body_length_(-1),
184 response_body_read_(0),
185 user_read_buf_(NULL
),
186 user_read_buf_len_(0),
187 connection_(connection
),
189 sent_last_chunk_(false),
190 weak_ptr_factory_(this) {
191 io_callback_
= base::Bind(&HttpStreamParser::OnIOComplete
,
192 weak_ptr_factory_
.GetWeakPtr());
195 HttpStreamParser::~HttpStreamParser() {
198 int HttpStreamParser::SendRequest(const std::string
& request_line
,
199 const HttpRequestHeaders
& headers
,
200 HttpResponseInfo
* response
,
201 const CompletionCallback
& callback
) {
202 DCHECK_EQ(STATE_NONE
, io_state_
);
203 DCHECK(callback_
.is_null());
204 DCHECK(!callback
.is_null());
208 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS
,
209 base::Bind(&HttpRequestHeaders::NetLogCallback
,
210 base::Unretained(&headers
),
213 DVLOG(1) << __FUNCTION__
<< "()"
214 << " request_line = \"" << request_line
<< "\""
215 << " headers = \"" << headers
.ToString() << "\"";
216 response_
= response
;
218 // Put the peer's IP address and port into the response.
219 IPEndPoint ip_endpoint
;
220 int result
= connection_
->socket()->GetPeerAddress(&ip_endpoint
);
223 response_
->socket_address
= HostPortPair::FromIPEndPoint(ip_endpoint
);
225 std::string request
= request_line
+ headers
.ToString();
227 if (request_
->upload_data_stream
!= NULL
) {
228 request_body_send_buf_
= new SeekableIOBuffer(kRequestBodyBufferSize
);
229 if (request_
->upload_data_stream
->is_chunked()) {
230 // Read buffer is adjusted to guarantee that |request_body_send_buf_| is
231 // large enough to hold the encoded chunk.
232 request_body_read_buf_
=
233 new SeekableIOBuffer(kRequestBodyBufferSize
- kChunkHeaderFooterSize
);
235 // No need to encode request body, just send the raw data.
236 request_body_read_buf_
= request_body_send_buf_
;
240 io_state_
= STATE_SENDING_HEADERS
;
242 // If we have a small request body, then we'll merge with the headers into a
244 bool did_merge
= false;
245 if (ShouldMergeRequestHeadersAndBody(request
, request_
->upload_data_stream
)) {
246 size_t merged_size
= request
.size() + request_
->upload_data_stream
->size();
247 scoped_refptr
<IOBuffer
> merged_request_headers_and_body(
248 new IOBuffer(merged_size
));
249 // We'll repurpose |request_headers_| to store the merged headers and
251 request_headers_
= new DrainableIOBuffer(
252 merged_request_headers_and_body
.get(), merged_size
);
254 memcpy(request_headers_
->data(), request
.data(), request
.size());
255 request_headers_
->DidConsume(request
.size());
257 size_t todo
= request_
->upload_data_stream
->size();
259 int consumed
= request_
->upload_data_stream
260 ->Read(request_headers_
.get(), todo
, CompletionCallback());
261 DCHECK_GT(consumed
, 0); // Read() won't fail if not chunked.
262 request_headers_
->DidConsume(consumed
);
265 DCHECK(request_
->upload_data_stream
->IsEOF());
266 // Reset the offset, so the buffer can be read from the beginning.
267 request_headers_
->SetOffset(0);
271 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY
,
272 base::Bind(&NetLogSendRequestBodyCallback
,
273 request_
->upload_data_stream
->size(),
274 false, /* not chunked */
279 // If we didn't merge the body with the headers, then |request_headers_|
280 // contains just the HTTP headers.
281 scoped_refptr
<StringIOBuffer
> headers_io_buf(new StringIOBuffer(request
));
283 new DrainableIOBuffer(headers_io_buf
.get(), headers_io_buf
->size());
287 if (result
== ERR_IO_PENDING
)
288 callback_
= callback
;
290 return result
> 0 ? OK
: result
;
293 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback
& callback
) {
294 DCHECK(io_state_
== STATE_REQUEST_SENT
|| io_state_
== STATE_DONE
);
295 DCHECK(callback_
.is_null());
296 DCHECK(!callback
.is_null());
297 DCHECK_EQ(0, read_buf_unused_offset_
);
299 // This function can be called with io_state_ == STATE_DONE if the
300 // connection is closed after seeing just a 1xx response code.
301 if (io_state_
== STATE_DONE
)
302 return ERR_CONNECTION_CLOSED
;
305 io_state_
= STATE_READ_HEADERS
;
307 if (read_buf_
->offset() > 0) {
308 // Simulate the state where the data was just read from the socket.
309 result
= read_buf_
->offset();
310 read_buf_
->set_offset(0);
313 io_state_
= STATE_READ_HEADERS_COMPLETE
;
315 result
= DoLoop(result
);
316 if (result
== ERR_IO_PENDING
)
317 callback_
= callback
;
319 return result
> 0 ? OK
: result
;
322 void HttpStreamParser::Close(bool not_reusable
) {
323 if (not_reusable
&& connection_
->socket())
324 connection_
->socket()->Disconnect();
325 connection_
->Reset();
328 int HttpStreamParser::ReadResponseBody(IOBuffer
* buf
, int buf_len
,
329 const CompletionCallback
& callback
) {
330 DCHECK(io_state_
== STATE_BODY_PENDING
|| io_state_
== STATE_DONE
);
331 DCHECK(callback_
.is_null());
332 DCHECK(!callback
.is_null());
333 DCHECK_LE(buf_len
, kMaxBufSize
);
335 if (io_state_
== STATE_DONE
)
338 user_read_buf_
= buf
;
339 user_read_buf_len_
= buf_len
;
340 io_state_
= STATE_READ_BODY
;
342 int result
= DoLoop(OK
);
343 if (result
== ERR_IO_PENDING
)
344 callback_
= callback
;
349 void HttpStreamParser::OnIOComplete(int result
) {
350 result
= DoLoop(result
);
352 // The client callback can do anything, including destroying this class,
353 // so any pending callback must be issued after everything else is done.
354 if (result
!= ERR_IO_PENDING
&& !callback_
.is_null()) {
355 CompletionCallback c
= callback_
;
361 int HttpStreamParser::DoLoop(int result
) {
362 bool can_do_more
= true;
365 case STATE_SENDING_HEADERS
:
369 result
= DoSendHeaders(result
);
371 case STATE_SENDING_BODY
:
375 result
= DoSendBody(result
);
377 case STATE_SEND_REQUEST_READING_BODY
:
378 result
= DoSendRequestReadingBody(result
);
380 case STATE_REQUEST_SENT
:
381 DCHECK(result
!= ERR_IO_PENDING
);
384 case STATE_READ_HEADERS
:
385 net_log_
.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS
);
386 result
= DoReadHeaders();
388 case STATE_READ_HEADERS_COMPLETE
:
389 result
= DoReadHeadersComplete(result
);
390 net_log_
.EndEventWithNetErrorCode(
391 NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS
, result
);
393 case STATE_BODY_PENDING
:
394 DCHECK(result
!= ERR_IO_PENDING
);
397 case STATE_READ_BODY
:
398 result
= DoReadBody();
399 // DoReadBodyComplete handles error conditions.
401 case STATE_READ_BODY_COMPLETE
:
402 result
= DoReadBodyComplete(result
);
405 DCHECK(result
!= ERR_IO_PENDING
);
413 } while (result
!= ERR_IO_PENDING
&& can_do_more
);
418 int HttpStreamParser::DoSendHeaders(int result
) {
419 request_headers_
->DidConsume(result
);
420 int bytes_remaining
= request_headers_
->BytesRemaining();
421 if (bytes_remaining
> 0) {
422 // Record our best estimate of the 'request time' as the time when we send
423 // out the first bytes of the request headers.
424 if (bytes_remaining
== request_headers_
->size()) {
425 response_
->request_time
= base::Time::Now();
427 result
= connection_
->socket()
428 ->Write(request_headers_
.get(), bytes_remaining
, io_callback_
);
429 } else if (request_
->upload_data_stream
!= NULL
&&
430 (request_
->upload_data_stream
->is_chunked() ||
431 // !IsEOF() indicates that the body wasn't merged.
432 (request_
->upload_data_stream
->size() > 0 &&
433 !request_
->upload_data_stream
->IsEOF()))) {
435 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY
,
436 base::Bind(&NetLogSendRequestBodyCallback
,
437 request_
->upload_data_stream
->size(),
438 request_
->upload_data_stream
->is_chunked(),
439 false /* not merged */));
440 io_state_
= STATE_SENDING_BODY
;
443 io_state_
= STATE_REQUEST_SENT
;
448 int HttpStreamParser::DoSendBody(int result
) {
449 // |result| is the number of bytes sent from the last call to
450 // DoSendBody(), or 0 (i.e. OK).
452 // Send the remaining data in the request body buffer.
453 request_body_send_buf_
->DidConsume(result
);
454 if (request_body_send_buf_
->BytesRemaining() > 0) {
455 return connection_
->socket()
456 ->Write(request_body_send_buf_
.get(),
457 request_body_send_buf_
->BytesRemaining(),
461 if (request_
->upload_data_stream
->is_chunked() && sent_last_chunk_
) {
462 io_state_
= STATE_REQUEST_SENT
;
466 request_body_read_buf_
->Clear();
467 io_state_
= STATE_SEND_REQUEST_READING_BODY
;
468 return request_
->upload_data_stream
->Read(request_body_read_buf_
.get(),
469 request_body_read_buf_
->capacity(),
473 int HttpStreamParser::DoSendRequestReadingBody(int result
) {
474 // |result| is the result of read from the request body from the last call to
476 DCHECK_GE(result
, 0); // There won't be errors.
478 // Chunked data needs to be encoded.
479 if (request_
->upload_data_stream
->is_chunked()) {
480 if (result
== 0) { // Reached the end.
481 DCHECK(request_
->upload_data_stream
->IsEOF());
482 sent_last_chunk_
= true;
484 // Encode the buffer as 1 chunk.
485 const base::StringPiece
payload(request_body_read_buf_
->data(), result
);
486 request_body_send_buf_
->Clear();
487 result
= EncodeChunk(payload
,
488 request_body_send_buf_
->data(),
489 request_body_send_buf_
->capacity());
492 if (result
== 0) { // Reached the end.
493 // Reaching EOF means we can finish sending request body unless the data is
494 // chunked. (i.e. No need to send the terminal chunk.)
495 DCHECK(request_
->upload_data_stream
->IsEOF());
496 DCHECK(!request_
->upload_data_stream
->is_chunked());
497 io_state_
= STATE_REQUEST_SENT
;
498 } else if (result
> 0) {
499 request_body_send_buf_
->DidAppend(result
);
501 io_state_
= STATE_SENDING_BODY
;
506 int HttpStreamParser::DoReadHeaders() {
507 io_state_
= STATE_READ_HEADERS_COMPLETE
;
509 // Grow the read buffer if necessary.
510 if (read_buf_
->RemainingCapacity() == 0)
511 read_buf_
->SetCapacity(read_buf_
->capacity() + kHeaderBufInitialSize
);
513 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
514 // See if the user is passing in an IOBuffer with a NULL |data_|.
515 CHECK(read_buf_
->data());
517 return connection_
->socket()
518 ->Read(read_buf_
.get(), read_buf_
->RemainingCapacity(), io_callback_
);
521 int HttpStreamParser::DoReadHeadersComplete(int result
) {
522 DCHECK_EQ(0, read_buf_unused_offset_
);
525 result
= ERR_CONNECTION_CLOSED
;
527 if (result
< 0 && result
!= ERR_CONNECTION_CLOSED
) {
528 io_state_
= STATE_DONE
;
531 // If we've used the connection before, then we know it is not a HTTP/0.9
532 // response and return ERR_CONNECTION_CLOSED.
533 if (result
== ERR_CONNECTION_CLOSED
&& read_buf_
->offset() == 0 &&
534 connection_
->is_reused()) {
535 io_state_
= STATE_DONE
;
539 // Record our best estimate of the 'response time' as the time when we read
540 // the first bytes of the response headers.
541 if (read_buf_
->offset() == 0 && result
!= ERR_CONNECTION_CLOSED
)
542 response_
->response_time
= base::Time::Now();
544 if (result
== ERR_CONNECTION_CLOSED
) {
545 // The connection closed before we detected the end of the headers.
546 if (read_buf_
->offset() == 0) {
547 // The connection was closed before any data was sent. Likely an error
548 // rather than empty HTTP/0.9 response.
549 io_state_
= STATE_DONE
;
550 return ERR_EMPTY_RESPONSE
;
551 } else if (request_
->url
.SchemeIsSecure()) {
552 // The connection was closed in the middle of the headers. For HTTPS we
553 // don't parse partial headers. Return a different error code so that we
554 // know that we shouldn't attempt to retry the request.
555 io_state_
= STATE_DONE
;
556 return ERR_RESPONSE_HEADERS_TRUNCATED
;
558 // Parse things as well as we can and let the caller decide what to do.
560 if (response_header_start_offset_
>= 0) {
561 io_state_
= STATE_READ_BODY_COMPLETE
;
562 end_offset
= read_buf_
->offset();
564 io_state_
= STATE_BODY_PENDING
;
567 int rv
= DoParseResponseHeaders(end_offset
);
573 read_buf_
->set_offset(read_buf_
->offset() + result
);
574 DCHECK_LE(read_buf_
->offset(), read_buf_
->capacity());
575 DCHECK_GE(result
, 0);
577 int end_of_header_offset
= ParseResponseHeaders();
579 // Note: -1 is special, it indicates we haven't found the end of headers.
580 // Anything less than -1 is a net::Error, so we bail out.
581 if (end_of_header_offset
< -1)
582 return end_of_header_offset
;
584 if (end_of_header_offset
== -1) {
585 io_state_
= STATE_READ_HEADERS
;
586 // Prevent growing the headers buffer indefinitely.
587 if (read_buf_
->offset() >= kMaxHeaderBufSize
) {
588 io_state_
= STATE_DONE
;
589 return ERR_RESPONSE_HEADERS_TOO_BIG
;
592 CalculateResponseBodySize();
593 // If the body is zero length, the caller may not call ReadResponseBody,
594 // which is where any extra data is copied to read_buf_, so we move the
596 if (response_body_length_
== 0) {
597 int extra_bytes
= read_buf_
->offset() - end_of_header_offset
;
599 CHECK_GT(extra_bytes
, 0);
600 memmove(read_buf_
->StartOfBuffer(),
601 read_buf_
->StartOfBuffer() + end_of_header_offset
,
604 read_buf_
->SetCapacity(extra_bytes
);
605 if (response_
->headers
->response_code() / 100 == 1) {
606 // After processing a 1xx response, the caller will ask for the next
607 // header, so reset state to support that. We don't completely ignore a
608 // 1xx response because it cannot be returned in reply to a CONNECT
609 // request so we return OK here, which lets the caller inspect the
610 // response and reject it in the event that we're setting up a CONNECT
612 response_header_start_offset_
= -1;
613 response_body_length_
= -1;
614 io_state_
= STATE_REQUEST_SENT
;
616 io_state_
= STATE_DONE
;
621 // Note where the headers stop.
622 read_buf_unused_offset_
= end_of_header_offset
;
623 io_state_
= STATE_BODY_PENDING
;
628 int HttpStreamParser::DoReadBody() {
629 io_state_
= STATE_READ_BODY_COMPLETE
;
631 // There may be some data left over from reading the response headers.
632 if (read_buf_
->offset()) {
633 int available
= read_buf_
->offset() - read_buf_unused_offset_
;
635 CHECK_GT(available
, 0);
636 int bytes_from_buffer
= std::min(available
, user_read_buf_len_
);
637 memcpy(user_read_buf_
->data(),
638 read_buf_
->StartOfBuffer() + read_buf_unused_offset_
,
640 read_buf_unused_offset_
+= bytes_from_buffer
;
641 if (bytes_from_buffer
== available
) {
642 read_buf_
->SetCapacity(0);
643 read_buf_unused_offset_
= 0;
645 return bytes_from_buffer
;
647 read_buf_
->SetCapacity(0);
648 read_buf_unused_offset_
= 0;
652 // Check to see if we're done reading.
653 if (IsResponseBodyComplete())
656 DCHECK_EQ(0, read_buf_
->offset());
657 return connection_
->socket()
658 ->Read(user_read_buf_
.get(), user_read_buf_len_
, io_callback_
);
661 int HttpStreamParser::DoReadBodyComplete(int result
) {
662 // When the connection is closed, there are numerous ways to interpret it.
664 // - If a Content-Length header is present and the body contains exactly that
665 // number of bytes at connection close, the response is successful.
667 // - If a Content-Length header is present and the body contains fewer bytes
668 // than promised by the header at connection close, it may indicate that
669 // the connection was closed prematurely, or it may indicate that the
670 // server sent an invalid Content-Length header. Unfortunately, the invalid
671 // Content-Length header case does occur in practice and other browsers are
672 // tolerant of it. We choose to treat it as an error for now, but the
673 // download system treats it as a non-error, and URLRequestHttpJob also
674 // treats it as OK if the Content-Length is the post-decoded body content
677 // - If chunked encoding is used and the terminating chunk has been processed
678 // when the connection is closed, the response is successful.
680 // - If chunked encoding is used and the terminating chunk has not been
681 // processed when the connection is closed, it may indicate that the
682 // connection was closed prematurely or it may indicate that the server
683 // sent an invalid chunked encoding. We choose to treat it as
684 // an invalid chunked encoding.
686 // - If a Content-Length is not present and chunked encoding is not used,
687 // connection close is the only way to signal that the response is
688 // complete. Unfortunately, this also means that there is no way to detect
689 // early close of a connection. No error is returned.
690 if (result
== 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) {
691 if (chunked_decoder_
.get())
692 result
= ERR_INCOMPLETE_CHUNKED_ENCODING
;
694 result
= ERR_CONTENT_LENGTH_MISMATCH
;
698 received_bytes_
+= result
;
700 // Filter incoming data if appropriate. FilterBuf may return an error.
701 if (result
> 0 && chunked_decoder_
.get()) {
702 result
= chunked_decoder_
->FilterBuf(user_read_buf_
->data(), result
);
703 if (result
== 0 && !chunked_decoder_
->reached_eof()) {
704 // Don't signal completion of the Read call yet or else it'll look like
705 // we received end-of-file. Wait for more data.
706 io_state_
= STATE_READ_BODY
;
712 response_body_read_
+= result
;
714 if (result
<= 0 || IsResponseBodyComplete()) {
715 io_state_
= STATE_DONE
;
717 // Save the overflow data, which can be in two places. There may be
718 // some left over in |user_read_buf_|, plus there may be more
719 // in |read_buf_|. But the part left over in |user_read_buf_| must have
720 // come from the |read_buf_|, so there's room to put it back at the
722 int additional_save_amount
= read_buf_
->offset() - read_buf_unused_offset_
;
724 if (chunked_decoder_
.get()) {
725 save_amount
= chunked_decoder_
->bytes_after_eof();
726 } else if (response_body_length_
>= 0) {
727 int64 extra_data_read
= response_body_read_
- response_body_length_
;
728 if (extra_data_read
> 0) {
729 save_amount
= static_cast<int>(extra_data_read
);
731 result
-= save_amount
;
735 CHECK_LE(save_amount
+ additional_save_amount
, kMaxBufSize
);
736 if (read_buf_
->capacity() < save_amount
+ additional_save_amount
) {
737 read_buf_
->SetCapacity(save_amount
+ additional_save_amount
);
741 received_bytes_
-= save_amount
;
742 memcpy(read_buf_
->StartOfBuffer(), user_read_buf_
->data() + result
,
745 read_buf_
->set_offset(save_amount
);
746 if (additional_save_amount
) {
747 memmove(read_buf_
->data(),
748 read_buf_
->StartOfBuffer() + read_buf_unused_offset_
,
749 additional_save_amount
);
750 read_buf_
->set_offset(save_amount
+ additional_save_amount
);
752 read_buf_unused_offset_
= 0;
754 io_state_
= STATE_BODY_PENDING
;
755 user_read_buf_
= NULL
;
756 user_read_buf_len_
= 0;
762 int HttpStreamParser::ParseResponseHeaders() {
764 DCHECK_EQ(0, read_buf_unused_offset_
);
766 // Look for the start of the status line, if it hasn't been found yet.
767 if (response_header_start_offset_
< 0) {
768 response_header_start_offset_
= HttpUtil::LocateStartOfStatusLine(
769 read_buf_
->StartOfBuffer(), read_buf_
->offset());
772 if (response_header_start_offset_
>= 0) {
773 end_offset
= HttpUtil::LocateEndOfHeaders(read_buf_
->StartOfBuffer(),
775 response_header_start_offset_
);
776 } else if (read_buf_
->offset() >= 8) {
777 // Enough data to decide that this is an HTTP/0.9 response.
778 // 8 bytes = (4 bytes of junk) + "http".length()
782 if (end_offset
== -1)
785 int rv
= DoParseResponseHeaders(end_offset
);
791 int HttpStreamParser::DoParseResponseHeaders(int end_offset
) {
792 scoped_refptr
<HttpResponseHeaders
> headers
;
793 DCHECK_EQ(0, read_buf_unused_offset_
);
795 if (response_header_start_offset_
>= 0) {
796 received_bytes_
+= end_offset
;
797 headers
= new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
798 read_buf_
->StartOfBuffer(), end_offset
));
800 // Enough data was read -- there is no status line.
801 headers
= new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
804 // Check for multiple Content-Length headers with no Transfer-Encoding header.
805 // If they exist, and have distinct values, it's a potential response
807 if (!headers
->HasHeader("Transfer-Encoding")) {
808 if (HeadersContainMultipleCopiesOfField(*headers
.get(), "Content-Length"))
809 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH
;
812 // Check for multiple Content-Disposition or Location headers. If they exist,
813 // it's also a potential response smuggling attack.
814 if (HeadersContainMultipleCopiesOfField(*headers
.get(),
815 "Content-Disposition"))
816 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
;
817 if (HeadersContainMultipleCopiesOfField(*headers
.get(), "Location"))
818 return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION
;
820 response_
->headers
= headers
;
821 response_
->connection_info
= HttpResponseInfo::CONNECTION_INFO_HTTP1
;
822 response_
->vary_data
.Init(*request_
, *response_
->headers
.get());
823 DVLOG(1) << __FUNCTION__
<< "()"
824 << " content_length = \"" << response_
->headers
->GetContentLength()
827 << GetResponseHeaderLines(*response_
->headers
.get()) << "\"";
831 void HttpStreamParser::CalculateResponseBodySize() {
832 // Figure how to determine EOF:
834 // For certain responses, we know the content length is always 0. From
835 // RFC 2616 Section 4.3 Message Body:
837 // For response messages, whether or not a message-body is included with
838 // a message is dependent on both the request method and the response
839 // status code (section 6.1.1). All responses to the HEAD request method
840 // MUST NOT include a message-body, even though the presence of entity-
841 // header fields might lead one to believe they do. All 1xx
842 // (informational), 204 (no content), and 304 (not modified) responses
843 // MUST NOT include a message-body. All other responses do include a
844 // message-body, although it MAY be of zero length.
845 if (response_
->headers
->response_code() / 100 == 1) {
846 response_body_length_
= 0;
848 switch (response_
->headers
->response_code()) {
849 case 204: // No Content
850 case 205: // Reset Content
851 case 304: // Not Modified
852 response_body_length_
= 0;
856 if (request_
->method
== "HEAD")
857 response_body_length_
= 0;
859 if (response_body_length_
== -1) {
860 // "Transfer-Encoding: chunked" trumps "Content-Length: N"
861 if (response_
->headers
->IsChunkEncoded()) {
862 chunked_decoder_
.reset(new HttpChunkedDecoder());
864 response_body_length_
= response_
->headers
->GetContentLength();
865 // If response_body_length_ is still -1, then we have to wait
866 // for the server to close the connection.
871 UploadProgress
HttpStreamParser::GetUploadProgress() const {
872 if (!request_
->upload_data_stream
)
873 return UploadProgress();
875 return UploadProgress(request_
->upload_data_stream
->position(),
876 request_
->upload_data_stream
->size());
879 HttpResponseInfo
* HttpStreamParser::GetResponseInfo() {
883 bool HttpStreamParser::IsResponseBodyComplete() const {
884 if (chunked_decoder_
.get())
885 return chunked_decoder_
->reached_eof();
886 if (response_body_length_
!= -1)
887 return response_body_read_
>= response_body_length_
;
889 return false; // Must read to EOF.
892 bool HttpStreamParser::CanFindEndOfResponse() const {
893 return chunked_decoder_
.get() || response_body_length_
>= 0;
896 bool HttpStreamParser::IsMoreDataBuffered() const {
897 return read_buf_
->offset() > read_buf_unused_offset_
;
900 bool HttpStreamParser::IsConnectionReused() const {
901 ClientSocketHandle::SocketReuseType reuse_type
= connection_
->reuse_type();
902 return connection_
->is_reused() ||
903 reuse_type
== ClientSocketHandle::UNUSED_IDLE
;
906 void HttpStreamParser::SetConnectionReused() {
907 connection_
->set_reuse_type(ClientSocketHandle::REUSED_IDLE
);
910 bool HttpStreamParser::IsConnectionReusable() const {
911 return connection_
->socket() && connection_
->socket()->IsConnectedAndIdle();
914 void HttpStreamParser::GetSSLInfo(SSLInfo
* ssl_info
) {
915 if (request_
->url
.SchemeIsSecure() && connection_
->socket()) {
916 SSLClientSocket
* ssl_socket
=
917 static_cast<SSLClientSocket
*>(connection_
->socket());
918 ssl_socket
->GetSSLInfo(ssl_info
);
922 void HttpStreamParser::GetSSLCertRequestInfo(
923 SSLCertRequestInfo
* cert_request_info
) {
924 if (request_
->url
.SchemeIsSecure() && connection_
->socket()) {
925 SSLClientSocket
* ssl_socket
=
926 static_cast<SSLClientSocket
*>(connection_
->socket());
927 ssl_socket
->GetSSLCertRequestInfo(cert_request_info
);
931 int HttpStreamParser::EncodeChunk(const base::StringPiece
& payload
,
933 size_t output_size
) {
934 if (output_size
< payload
.size() + kChunkHeaderFooterSize
)
935 return ERR_INVALID_ARGUMENT
;
937 char* cursor
= output
;
939 const int num_chars
= base::snprintf(output
, output_size
,
941 static_cast<int>(payload
.size()));
943 // Add the payload if any.
944 if (payload
.size() > 0) {
945 memcpy(cursor
, payload
.data(), payload
.size());
946 cursor
+= payload
.size();
948 // Add the trailing CRLF.
949 memcpy(cursor
, "\r\n", 2);
952 return cursor
- output
;
956 bool HttpStreamParser::ShouldMergeRequestHeadersAndBody(
957 const std::string
& request_headers
,
958 const UploadDataStream
* request_body
) {
959 if (request_body
!= NULL
&&
960 // IsInMemory() ensures that the request body is not chunked.
961 request_body
->IsInMemory() &&
962 request_body
->size() > 0) {
963 size_t merged_size
= request_headers
.size() + request_body
->size();
964 if (merged_size
<= kMaxMergedHeaderAndBodySize
)