1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_FLIP_NETWORK_TRANSACTION_H_
#define NET_FLIP_NETWORK_TRANSACTION_H_
#include <string>
#include <deque>
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"
#include "net/flip/flip_session.h"
#include "net/http/http_response_info.h"
#include "net/http/http_transaction.h"
namespace net {
class FlipSession;
class HttpNetworkSession;
class UploadDataStream;
// FlipStreamParser is a class to encapsulate the IO of a FLIP
// stream on top of a FlipSession. All read/writes go through
// the FlipStreamParser.
class FlipStreamParser : public FlipDelegate {
public:
FlipStreamParser();
~FlipStreamParser();
// Creates a FLIP stream from |flip| and send the HTTP request over it.
// |request|'s lifetime must persist longer than |this|. This always
// completes asynchronously, so |callback| must be non-NULL. Returns a net
// error code.
int SendRequest(FlipSession* flip, const HttpRequestInfo* request,
CompletionCallback* callback);
// Reads the response headers. Returns a net error code.
int ReadResponseHeaders(CompletionCallback* callback);
// Reads the response body. Returns a net error code or the number of bytes
// read.
int ReadResponseBody(
IOBuffer* buf, int buf_len, CompletionCallback* callback);
// Returns the number of bytes uploaded.
uint64 GetUploadProgress() const;
const HttpResponseInfo* GetResponseInfo() const;
// FlipDelegate methods:
virtual const HttpRequestInfo* request() const;
virtual const UploadDataStream* data() const;
virtual void OnResponseReceived(HttpResponseInfo* response);
virtual void OnDataReceived(const char* buffer, int bytes);
virtual void OnWriteComplete(int status);
virtual void OnClose(int status);
private:
friend class FlipStreamParserPeer;
enum State {
STATE_NONE,
STATE_SENDING_HEADERS,
STATE_HEADERS_SENT,
STATE_SENDING_BODY,
STATE_REQUEST_SENT,
STATE_READ_HEADERS,
STATE_READ_HEADERS_COMPLETE,
STATE_BODY_PENDING,
STATE_READ_BODY,
STATE_READ_BODY_COMPLETE,
STATE_DONE
};
// Try to make progress sending/receiving the request/response.
int DoLoop(int result);
// The implementations of each state of the state machine.
int DoSendHeaders(int result);
int DoHeadersSent(int result);
int DoSendBody(int result);
int DoReadHeaders();
int DoReadHeadersComplete(int result);
int DoReadBody();
int DoReadBodyComplete(int result);
void DoCallback(int rv);
// The Flip request id for this request.
scoped_refptr<FlipSession> flip_;
flip::FlipStreamId flip_stream_id_;
const HttpRequestInfo* request_;
scoped_ptr<HttpResponseInfo> response_;
scoped_ptr<UploadDataStream> request_body_stream_;
bool response_complete_; // TODO(mbelshe): fold this into the io_state.
State io_state_;
// We buffer the response body as it arrives asynchronously from the stream.
// TODO(mbelshe): is this infinite buffering?
std::deque<scoped_refptr<IOBufferWithSize> > response_body_;
// Since we buffer the response, we also buffer the response status.
// Not valid until response_complete_ is true.
int response_status_;
CompletionCallback* user_callback_;
// User provided buffer for the ReadResponseBody() response.
scoped_refptr<IOBuffer> user_buffer_;
int user_buffer_len_;
DISALLOW_COPY_AND_ASSIGN(FlipStreamParser);
};
// A FlipNetworkTransaction can be used to fetch HTTP conent.
// The FlipDelegate is the consumer of events from the FlipSession.
class FlipNetworkTransaction : public HttpTransaction {
public:
explicit FlipNetworkTransaction(HttpNetworkSession* session);
virtual ~FlipNetworkTransaction();
// HttpTransaction methods:
virtual int Start(const HttpRequestInfo* request_info,
CompletionCallback* callback,
LoadLog* load_log);
virtual int RestartIgnoringLastError(CompletionCallback* callback);
virtual int RestartWithCertificate(X509Certificate* client_cert,
CompletionCallback* callback);
virtual int RestartWithAuth(const std::wstring& username,
const std::wstring& password,
CompletionCallback* callback);
virtual bool IsReadyToRestartForAuth() { return false; }
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
virtual const HttpResponseInfo* GetResponseInfo() const;
virtual LoadState GetLoadState() const;
virtual uint64 GetUploadProgress() const;
protected:
friend class FlipNetworkTransactionTest;
// Provide access to the session for testing.
FlipSession* GetFlipSession() { return flip_.get(); }
private:
enum State {
STATE_INIT_CONNECTION,
STATE_INIT_CONNECTION_COMPLETE,
STATE_SEND_REQUEST,
STATE_SEND_REQUEST_COMPLETE,
STATE_READ_HEADERS,
STATE_READ_HEADERS_COMPLETE,
STATE_READ_BODY,
STATE_READ_BODY_COMPLETE,
STATE_NONE
};
void DoCallback(int result);
void OnIOComplete(int result);
// Runs the state transition loop.
int DoLoop(int result);
// Each of these methods corresponds to a State value. Those with an input
// argument receive the result from the previous state. If a method returns
// ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
// next state method as the result arg.
int DoInitConnection();
int DoInitConnectionComplete(int result);
int DoSendRequest();
int DoSendRequestComplete(int result);
int DoReadHeaders();
int DoReadHeadersComplete(int result);
int DoReadBody();
int DoReadBodyComplete(int result);
// The Flip session servicing this request. If NULL, the request has not
// started.
scoped_refptr<FlipSession> flip_;
CompletionCallbackImpl<FlipNetworkTransaction> io_callback_;
CompletionCallback* user_callback_;
// Used to pass onto the FlipStreamParser.
scoped_refptr<IOBuffer> user_buffer_;
int user_buffer_len_;
scoped_refptr<HttpNetworkSession> session_;
const HttpRequestInfo* request_;
// The time the Start method was called.
base::TimeTicks start_time_;
// The next state in the state machine.
State next_state_;
scoped_ptr<FlipStreamParser> flip_stream_parser_;
DISALLOW_COPY_AND_ASSIGN(FlipNetworkTransaction);
};
} // namespace net
#endif // NET_HTTP_NETWORK_TRANSACTION_H_
|