OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | |
6 | |
7 #include "base/metrics/histogram.h" | |
8 #include "base/stringprintf.h" | |
9 #include "net/base/load_flags.h" | |
10 #include "net/disk_cache/histogram_macros.h" | |
11 | |
12 namespace chrome_browser_net { | |
13 | |
14 HttpPipeliningCompatibilityClient::HttpPipeliningCompatibilityClient() | |
15 : num_finished_(0) { | |
16 } | |
17 | |
18 void HttpPipeliningCompatibilityClient::Start( | |
19 const std::string& base_url, | |
20 std::vector<RequestInfo>& requests, | |
21 const net::CompletionCallback& callback, | |
22 net::URLRequestContext* url_request_context) { | |
23 finished_callback_ = callback; | |
24 for (size_t i = 0; i < requests.size(); ++i) { | |
25 requests_.push_back(new Request(i, base_url, requests[i], this, | |
26 url_request_context)); | |
27 } | |
28 } | |
29 | |
30 void HttpPipeliningCompatibilityClient::Finished(int request_id, | |
31 Status status) { | |
32 // The CACHE_HISTOGRAM_* macros are used, because they allow dynamic metric | |
33 // names. | |
34 CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "Status"), | |
35 status, STATUS_MAX); | |
36 ++num_finished_; | |
37 if (num_finished_ == requests_.size()) { | |
38 finished_callback_.Run(0); | |
39 } | |
40 } | |
41 | |
42 void HttpPipeliningCompatibilityClient::ReportNetworkError(int request_id, | |
43 int error_code) { | |
44 CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "NetworkError"), | |
45 -error_code, 900); | |
46 } | |
47 | |
48 void HttpPipeliningCompatibilityClient::ReportResponseCode(int request_id, | |
49 int response_code) { | |
50 CACHE_HISTOGRAM_ENUMERATION(GetMetricName(request_id, "ResponseCode"), | |
51 response_code, 600); | |
52 } | |
53 | |
54 std::string HttpPipeliningCompatibilityClient::GetMetricName( | |
55 int request_id, const char* description) { | |
56 return base::StringPrintf("NetConnectivity.Pipeline.%d.%s", | |
57 request_id, description); | |
58 } | |
59 | |
60 HttpPipeliningCompatibilityClient::Request::Request( | |
61 int request_id, | |
62 const std::string& base_url, | |
63 const RequestInfo& info, | |
64 HttpPipeliningCompatibilityClient* client, | |
65 net::URLRequestContext* url_request_context) | |
66 : request_id_(request_id), | |
mmenke
2012/02/01 19:08:07
nit: 4-space indent.
James Simonsen
2012/02/07 00:01:37
Done.
| |
67 request_(GURL(base_url + info.filename), this), | |
68 info_(info), | |
69 client_(client), | |
70 finished_(false) { | |
71 request_.set_context(url_request_context); | |
72 // TODO(simonjam): Force pipelining. | |
73 request_.set_load_flags(net::LOAD_BYPASS_CACHE | | |
74 net::LOAD_DISABLE_CACHE | | |
75 net::LOAD_DO_NOT_SAVE_COOKIES | | |
76 net::LOAD_DO_NOT_SEND_COOKIES | | |
77 net::LOAD_DO_NOT_SEND_AUTH_DATA); | |
mmenke
2012/02/01 19:08:07
Think you might want to add net::DO_NOT_PROMPT_FOR
James Simonsen
2012/02/07 00:01:37
Done.
| |
78 request_.Start(); | |
79 } | |
80 | |
81 void HttpPipeliningCompatibilityClient::Request::OnReceivedRedirect( | |
82 net::URLRequest* request, | |
83 const GURL& new_url, | |
84 bool* defer_redirect) { | |
85 *defer_redirect = true; | |
86 request->Cancel(); | |
87 Finished(REDIRECTED); | |
88 } | |
89 | |
90 void HttpPipeliningCompatibilityClient::Request::OnSSLCertificateError( | |
91 net::URLRequest* request, | |
92 const net::SSLInfo& ssl_info, | |
93 bool fatal) { | |
94 Finished(CERT_ERROR); | |
95 } | |
96 | |
97 void HttpPipeliningCompatibilityClient::Request::OnResponseStarted( | |
98 net::URLRequest* request) { | |
99 if (finished_) { | |
100 return; | |
101 } | |
102 int response_code = request->GetResponseCode(); | |
103 if (response_code > 0) { | |
104 client_->ReportResponseCode(request_id_, response_code); | |
105 } | |
106 if (response_code == 200) { | |
107 read_buffer_ = new net::IOBuffer(info_.expected_response.length()); | |
108 DoRead(); | |
109 } else { | |
110 Finished(BAD_RESPONSE_CODE); | |
111 } | |
112 } | |
113 | |
114 void HttpPipeliningCompatibilityClient::Request::OnReadCompleted( | |
115 net::URLRequest* request, | |
116 int bytes_read) { | |
117 if (bytes_read == 0) { | |
118 DoReadFinished(); | |
119 } else if (bytes_read < 0) { | |
120 Finished(NETWORK_ERROR); | |
121 } else { | |
122 response_.append(read_buffer_->data(), bytes_read); | |
123 if (response_.length() <= info_.expected_response.length()) { | |
124 DoRead(); | |
125 } else { | |
126 Finished(TOO_LARGE); | |
127 } | |
128 } | |
129 } | |
130 | |
131 void HttpPipeliningCompatibilityClient::Request::DoRead() { | |
132 int bytes_read = 0; | |
133 if (request_.Read(read_buffer_.get(), info_.expected_response.length(), | |
134 &bytes_read)) { | |
135 OnReadCompleted(&request_, bytes_read); | |
136 } | |
137 } | |
138 | |
139 void HttpPipeliningCompatibilityClient::Request::DoReadFinished() { | |
140 if (response_.length() != info_.expected_response.length()) { | |
141 Finished(TOO_SMALL); | |
mmenke
2012/02/01 19:08:07
Is there a meaningful difference between when we g
James Simonsen
2012/02/07 00:01:37
In practice, it probably doesn't matter. I just th
| |
142 } else if (response_ == info_.expected_response) { | |
143 Finished(SUCCESS); | |
144 } else { | |
145 Finished(CONTENT_MISMATCH); | |
146 } | |
147 } | |
148 | |
149 void HttpPipeliningCompatibilityClient::Request::Finished(Status result) { | |
150 if (finished_) { | |
151 return; | |
152 } | |
153 finished_ = true; | |
154 net::URLRequestStatus status = request_.status(); | |
155 if (status.status() == net::URLRequestStatus::FAILED) { | |
mmenke
2012/02/01 19:08:07
It seems a little weird to me that we're completel
James Simonsen
2012/02/07 00:01:37
I figured the network errors trump all others. For
mmenke
2012/02/07 15:17:39
Suggest you at least put a small comment here abou
James Simonsen
2012/02/07 22:40:40
Done.
| |
156 client_->ReportNetworkError(request_id_, status.error()); | |
157 client_->Finished(request_id_, NETWORK_ERROR); | |
158 return; | |
159 } | |
160 client_->Finished(request_id_, result); | |
161 } | |
162 | |
163 } // namespace chrome_browser_net | |
OLD | NEW |