1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_STREAM_PARSER_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_STREAM_PARSER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/completion_callback.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/upload_data_stream.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_chunked_decoder.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ClientSocketHandle; 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass DrainableIOBuffer; 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass GrowableIOBuffer; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct HttpRequestInfo; 234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass HttpRequestHeaders; 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpResponseInfo; 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass IOBuffer; 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SSLCertRequestInfo; 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SSLInfo; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass HttpStreamParser : public ChunkCallback { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Any data in |read_buffer| will be used before reading from the socket 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and any data left over after parsing the stream will be put into 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |read_buffer|. The left over data will start at offset 0 and the 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // buffer's offset will be set to the first free byte. |read_buffer| may 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // have its capacity changed. 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpStreamParser(ClientSocketHandle* connection, 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpRequestInfo* request, 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GrowableIOBuffer* read_buffer, 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~HttpStreamParser(); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // These functions implement the interface described in HttpStream with 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // some additional functionality 444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int SendRequest(const std::string& request_line, 454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HttpRequestHeaders& headers, 464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch UploadDataStream* request_body, 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpResponseInfo* response, CompletionCallback* callback); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ReadResponseHeaders(CompletionCallback* callback); 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ReadResponseBody(IOBuffer* buf, int buf_len, 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void Close(bool not_reusable); 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 GetUploadProgress() const; 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpResponseInfo* GetResponseInfo(); 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsResponseBodyComplete() const; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool CanFindEndOfResponse() const; 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsMoreDataBuffered() const; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool IsConnectionReused() const; 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetConnectionReused(); 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool IsConnectionReusable() const; 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void GetSSLInfo(SSLInfo* ssl_info); 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ChunkCallback methods. 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnChunkAvailable(); 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // FOO_COMPLETE states implement the second half of potentially asynchronous 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // operations and don't necessarily mean that FOO is complete. 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum State { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_NONE, 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_SENDING_HEADERS, 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_SENDING_BODY, 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_REQUEST_SENT, 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_READ_HEADERS, 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_READ_HEADERS_COMPLETE, 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_BODY_PENDING, 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_READ_BODY, 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_READ_BODY_COMPLETE, 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_DONE 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The number of bytes by which the header buffer is grown when it reaches 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // capacity. 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { kHeaderBufInitialSize = 4096 }; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |kMaxHeaderBufSize| is the number of bytes that the response headers can 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // grow to. If the body start is not found within this range of the 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // response, the transaction will fail with ERR_RESPONSE_HEADERS_TOO_BIG. 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: |kMaxHeaderBufSize| should be a multiple of |kHeaderBufInitialSize|. 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { kMaxHeaderBufSize = 256 * 1024 }; // 256 kilobytes. 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The maximum sane buffer size. 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { kMaxBufSize = 2 * 1024 * 1024 }; // 2 megabytes. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Handle callbacks. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void OnIOComplete(int result); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Try to make progress sending/receiving the request/response. 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoLoop(int result); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The implementations of each state of the state machine. 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoSendHeaders(int result); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoSendBody(int result); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoReadHeaders(); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoReadHeadersComplete(int result); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoReadBody(); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoReadBodyComplete(int result); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Examines |read_buf_| to find the start and end of the headers. If they are 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // found, parse them with DoParseResponseHeaders(). Return the offset for 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the end of the headers, or -1 if the complete headers were not found, or 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // with a net::Error if we encountered an error during parsing. 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ParseResponseHeaders(); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Parse the headers into response_. Returns OK on success or a net::Error on 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // failure. 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int DoParseResponseHeaders(int end_of_header_offset); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Examine the parsed headers to try to determine the response body size. 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CalculateResponseBodySize(); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Current state of the request. 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott State io_state_; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request to send. 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const HttpRequestInfo* request_; 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request header data. 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<DrainableIOBuffer> request_headers_; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The request body data. 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<UploadDataStream> request_body_; 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Temporary buffer for reading. 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<GrowableIOBuffer> read_buf_; 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Offset of the first unused byte in |read_buf_|. May be nonzero due to 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a 1xx header, or body data in the same packet as header data. 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int read_buf_unused_offset_; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The amount beyond |read_buf_unused_offset_| where the status line starts; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // -1 if not found yet. 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int response_header_start_offset_; 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The parsed response headers. Owned by the caller. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpResponseInfo* response_; 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Indicates the content length. If this value is less than zero 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (and chunked_decoder_ is null), then we must read until the server 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // closes the connection. 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 response_body_length_; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Keep track of the number of response body bytes read so far. 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 response_body_read_; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper if the data is chunked. 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<HttpChunkedDecoder> chunked_decoder_; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Where the caller wants the body data. 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<IOBuffer> user_read_buf_; 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int user_read_buf_len_; 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The callback to notify a user that their request or response is 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // complete or there was an error 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* user_callback_; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // In the client callback, the client can do anything, including 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // destroying this class, so any pending callback must be issued 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // after everything else is done. When it is time to issue the client 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callback, move it from |user_callback_| to |scheduled_callback_|. 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* scheduled_callback_; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The underlying socket. 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ClientSocketHandle* const connection_; 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog net_log_; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Callback to be used when doing IO. 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallbackImpl<HttpStreamParser> io_callback_; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Stores an encoded chunk for chunked uploads. 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Note: This should perhaps be improved to not create copies of the data. 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<IOBuffer> chunk_buf_; 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t chunk_length_; 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t chunk_length_without_encoding_; 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool sent_last_chunk_; 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(HttpStreamParser); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_HTTP_STREAM_PARSER_H_ 207