OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 "url_request_peer.h" | |
6 | |
7 #include "base/strings/string_number_conversions.h" | |
8 #include "net/base/load_flags.h" | |
9 #include "net/http/http_status_code.h" | |
10 | |
11 static const size_t kBufferSizeIncrement = 8192; | |
12 | |
13 // Fragment automatically inserted in the User-Agent header to indicate | |
14 // that the request is coming from this network stack. | |
15 static const char kUserAgentFragment[] = "; ChromiumJNI/"; | |
16 | |
17 URLRequestPeer::URLRequestPeer(URLRequestContextPeer *context, | |
18 URLRequestPeerDelegate *delegate, GURL url, | |
19 net::RequestPriority priority) | |
20 : method_("GET"), | |
21 url_request_(NULL), | |
22 read_buffer_(new net::GrowableIOBuffer()), | |
23 bytes_read_(0), | |
24 total_bytes_read_(0), | |
25 error_code_(0), | |
26 http_status_code_(0), | |
27 canceled_(false), | |
28 expected_size_(0), | |
29 streaming_upload_(false) { | |
30 context_ = context; | |
31 delegate_ = delegate; | |
32 url_ = url; | |
33 priority_ = priority; | |
34 } | |
35 | |
36 URLRequestPeer::~URLRequestPeer() { | |
37 CHECK(url_request_ == NULL); | |
38 } | |
39 | |
40 void URLRequestPeer::SetMethod(const std::string &method) { | |
41 method_ = method; | |
42 } | |
43 | |
44 void URLRequestPeer::AddHeader(const std::string &name, | |
45 const std::string &value) { | |
46 headers_.SetHeader(name, value); | |
47 } | |
48 | |
49 void URLRequestPeer::SetPostContent(const char *bytes, int bytes_len) { | |
50 if (!upload_data_stream_) { | |
51 upload_data_stream_.reset( | |
52 new net::UploadDataStream(net::UploadDataStream::CHUNKED, 0)); | |
53 } | |
54 upload_data_stream_->AppendChunk(bytes, bytes_len, true /* is_last_chunk */); | |
55 } | |
56 | |
57 void URLRequestPeer::EnableStreamingUpload() { | |
58 streaming_upload_ = true; | |
59 } | |
60 | |
61 void URLRequestPeer::AppendChunk(const char *bytes, int bytes_len, | |
62 bool is_last_chunk) { | |
63 VLOG(context_->logging_level()) | |
64 << "AppendChunk, len: " << bytes_len << ", last: " << is_last_chunk; | |
65 | |
66 context_->GetNetworkTaskRunner()->PostTask( | |
67 FROM_HERE, base::Bind(&URLRequestPeer::OnAppendChunkWrapper, this, | |
68 bytes, bytes_len, is_last_chunk)); | |
69 } | |
70 | |
71 GURL URLRequestPeer::url() const { | |
72 return url_; | |
73 } | |
74 | |
75 int URLRequestPeer::error_code() const { | |
76 return error_code_; | |
77 } | |
78 | |
79 int URLRequestPeer::http_status_code() const { | |
80 return http_status_code_; | |
81 } | |
82 | |
83 int64 URLRequestPeer::content_length() const { | |
84 return expected_size_; | |
85 } | |
86 | |
87 std::string URLRequestPeer::content_type() const { | |
88 return content_type_; | |
89 } | |
90 | |
91 void URLRequestPeer::Start() { | |
92 context_->GetNetworkTaskRunner()->PostTask( | |
93 FROM_HERE, | |
94 base::Bind(&URLRequestPeer::OnInitiateConnectionWrapper, this)); | |
95 } | |
96 | |
97 /* static */ | |
mmenke
2014/02/27 23:06:02
C++-style comments
mef
2014/03/03 19:15:13
Done.
| |
98 void URLRequestPeer::OnAppendChunkWrapper(URLRequestPeer *self, | |
99 const char *bytes, | |
100 int bytes_len, | |
101 bool is_last_chunk) { | |
102 self->OnAppendChunk(bytes, bytes_len, is_last_chunk); | |
103 } | |
104 | |
105 void URLRequestPeer::OnAppendChunk(const char *bytes, int bytes_len, | |
106 bool is_last_chunk) { | |
107 if (url_request_ != NULL) { | |
108 url_request_->AppendChunkToUpload(bytes, bytes_len, is_last_chunk); | |
109 delegate_->OnAppendChunkCompleted(this); | |
110 } | |
111 } | |
112 | |
113 /* static */ | |
mmenke
2014/02/27 23:06:02
C++-style comments
mef
2014/03/03 19:15:13
Done.
| |
114 void URLRequestPeer::OnInitiateConnectionWrapper(URLRequestPeer *self) { | |
115 self->OnInitiateConnection(); | |
116 } | |
117 | |
118 void URLRequestPeer::OnInitiateConnection() { | |
119 if (canceled_) { | |
120 return; | |
121 } | |
122 | |
123 VLOG(context_->logging_level()) | |
124 << "Starting chromium request: " << url_.possibly_invalid_spec().c_str() | |
125 << " priority: " << RequestPriorityToString(priority_); | |
126 url_request_ = | |
127 new net::URLRequest(url_, | |
128 net::DEFAULT_PRIORITY, | |
129 this, | |
130 context_->GetURLRequestContext()); | |
131 url_request_->SetLoadFlags(net::LOAD_DISABLE_CACHE | | |
132 net::LOAD_DO_NOT_SAVE_COOKIES | | |
133 net::LOAD_DO_NOT_SEND_COOKIES); | |
134 url_request_->set_method(method_); | |
135 url_request_->SetExtraRequestHeaders(headers_); | |
136 std::string user_agent; | |
137 if (headers_.HasHeader(net::HttpRequestHeaders::kUserAgent)) { | |
138 headers_.GetHeader(net::HttpRequestHeaders::kUserAgent, &user_agent); | |
139 } else { | |
140 user_agent = context_->GetUserAgent(url_); | |
141 } | |
142 size_t pos = user_agent.find(')'); | |
143 if (pos != std::string::npos) { | |
144 user_agent.insert(pos, context_->version()); | |
145 user_agent.insert(pos, kUserAgentFragment); | |
146 } | |
147 url_request_->SetExtraRequestHeaderByName(net::HttpRequestHeaders::kUserAgent, | |
148 user_agent, true /* override */); | |
149 | |
150 VLOG(context_->logging_level()) << "User agent: " << user_agent; | |
151 | |
152 if (upload_data_stream_) { | |
153 url_request_->set_upload(make_scoped_ptr(upload_data_stream_.release())); | |
154 } else if (streaming_upload_) { | |
155 url_request_->EnableChunkedUpload(); | |
156 } | |
157 | |
158 url_request_->SetPriority(priority_); | |
159 | |
160 url_request_->Start(); | |
161 } | |
162 | |
163 void URLRequestPeer::Cancel() { | |
164 if (canceled_) { | |
165 return; | |
166 } | |
167 | |
168 canceled_ = true; | |
169 | |
170 context_->GetNetworkTaskRunner()->PostTask( | |
171 FROM_HERE, base::Bind(&URLRequestPeer::OnCancelRequestWrapper, this)); | |
172 } | |
173 | |
174 /* static */ | |
175 void URLRequestPeer::OnCancelRequestWrapper(URLRequestPeer *self) { | |
mmenke
2014/02/27 23:06:02
URLRequestPeer* self
mef
2014/03/03 19:15:13
Done.
| |
176 self->OnCancelRequest(); | |
177 } | |
178 | |
179 void URLRequestPeer::OnCancelRequest() { | |
180 VLOG(context_->logging_level()) | |
181 << "Canceling chromium request: " << url_.possibly_invalid_spec(); | |
182 | |
183 if (url_request_ != NULL) { | |
184 url_request_->Cancel(); | |
185 } | |
186 | |
187 OnRequestCanceled(); | |
188 } | |
189 | |
190 void URLRequestPeer::Destroy() { | |
191 context_->GetNetworkTaskRunner()->PostTask( | |
192 FROM_HERE, base::Bind(&URLRequestPeer::OnDestroyRequest, this)); | |
193 } | |
194 | |
195 /* static */ | |
196 void URLRequestPeer::OnDestroyRequest(URLRequestPeer *self) { | |
mmenke
2014/02/27 23:06:02
URLRequestPeer* self
mef
2014/03/03 19:15:13
Done.
| |
197 VLOG(self->context_->logging_level()) | |
198 << "Destroying chromium request: " << self->url_.possibly_invalid_spec(); | |
199 delete self; | |
200 } | |
201 | |
202 void URLRequestPeer::OnResponseStarted(net::URLRequest *request) { | |
mmenke
2014/02/27 23:06:02
net::URLRequest* request
mef
2014/03/03 19:15:13
Done.
| |
203 if (request->status().status() != net::URLRequestStatus::SUCCESS) { | |
204 OnRequestFailed(); | |
205 return; | |
206 } | |
207 | |
208 http_status_code_ = request->GetResponseCode(); | |
209 VLOG(context_->logging_level()) | |
210 << "Response started with status: " << http_status_code_; | |
211 | |
212 request->GetResponseHeaderByName("Content-Type", &content_type_); | |
213 expected_size_ = request->GetExpectedContentSize(); | |
214 delegate_->OnResponseStarted(this); | |
215 | |
216 Read(); | |
217 } | |
218 | |
219 /* | |
220 * Reads all available data or starts an asynchronous read. | |
221 */ | |
mmenke
2014/02/27 23:06:02
C++ style comments
mef
2014/03/03 19:15:13
Done.
| |
222 void URLRequestPeer::Read() { | |
223 while (1) { | |
mmenke
2014/02/27 23:06:02
while (true)
mef
2014/03/03 19:15:13
Done.
| |
224 if (read_buffer_->RemainingCapacity() == 0) { | |
225 int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement; | |
226 read_buffer_->SetCapacity(new_capacity); | |
227 } | |
228 | |
229 int bytes_read; | |
230 if (url_request_->Read(read_buffer_, read_buffer_->RemainingCapacity(), | |
231 &bytes_read)) { | |
232 if (bytes_read == 0) { | |
233 OnRequestSucceeded(); | |
234 break; | |
235 } | |
236 | |
237 VLOG(context_->logging_level()) | |
238 << "Synchronously read: " << bytes_read << " bytes"; | |
239 OnBytesRead(bytes_read); | |
240 } else if (url_request_->status().status() == | |
241 net::URLRequestStatus::IO_PENDING) { | |
242 if (bytes_read_ != 0) { | |
243 VLOG(context_->logging_level()) | |
244 << "Flushing buffer: " << bytes_read_ << " bytes"; | |
245 | |
246 delegate_->OnBytesRead(this); | |
247 read_buffer_->set_offset(0); | |
248 bytes_read_ = 0; | |
249 } | |
250 VLOG(context_->logging_level()) << "Started async read" ; | |
251 break; | |
252 } else { | |
253 OnRequestFailed(); | |
254 break; | |
255 } | |
256 } | |
257 } | |
258 | |
259 void URLRequestPeer::OnReadCompleted(net::URLRequest *request, int bytes_read) { | |
260 VLOG(context_->logging_level()) | |
261 << "Asynchronously read: " << bytes_read << " bytes"; | |
262 if (bytes_read < 0) { | |
263 OnRequestFailed(); | |
264 return; | |
265 } else if (bytes_read == 0) { | |
266 OnRequestSucceeded(); | |
267 return; | |
268 } | |
269 | |
270 OnBytesRead(bytes_read); | |
271 Read(); | |
272 } | |
273 | |
274 void URLRequestPeer::OnBytesRead(int bytes_read) { | |
275 read_buffer_->set_offset(read_buffer_->offset() + bytes_read); | |
276 bytes_read_ += bytes_read; | |
277 total_bytes_read_ += bytes_read; | |
278 } | |
279 | |
280 void URLRequestPeer::OnRequestSucceeded() { | |
281 if (canceled_) { | |
282 return; | |
283 } | |
284 | |
285 VLOG(context_->logging_level()) | |
286 << "Request completed with HTTP status: " << http_status_code_ | |
287 << ". Total bytes read: " << total_bytes_read_; | |
288 | |
289 OnRequestCompleted(); | |
290 } | |
291 | |
292 void URLRequestPeer::OnRequestFailed() { | |
293 if (canceled_) { | |
294 return; | |
295 } | |
296 | |
297 error_code_ = url_request_->status().error(); | |
298 VLOG(context_->logging_level()) | |
299 << "Request failed with status: " << url_request_->status().status() | |
300 << " and error: " << net::ErrorToString(error_code_); | |
301 OnRequestCompleted(); | |
302 } | |
303 | |
304 void URLRequestPeer::OnRequestCanceled() { OnRequestCompleted(); } | |
305 | |
306 void URLRequestPeer::OnRequestCompleted() { | |
307 VLOG(context_->logging_level()) | |
308 << "Completed: " << url_.possibly_invalid_spec(); | |
309 if (url_request_ != NULL) { | |
310 delete url_request_; | |
311 url_request_ = NULL; | |
312 } | |
313 | |
314 delegate_->OnBytesRead(this); | |
315 delegate_->OnRequestFinished(this); | |
316 } | |
317 | |
318 size_t URLRequestPeer::BytesRead() const { return bytes_read_; } | |
mmenke
2014/02/27 23:06:02
Inline and rename to bytes_read?
mef
2014/03/03 19:15:13
Done.
| |
319 | |
320 unsigned char *URLRequestPeer::Data() const { | |
321 return reinterpret_cast<unsigned char *>(read_buffer_->StartOfBuffer()); | |
mmenke
2014/02/27 23:06:02
<unsigned char*>
mef
2014/03/03 19:15:13
Done.
| |
322 } | |
OLD | NEW |