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