Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: chrome/browser/local_discovery/privet_url_fetcher.cc

Issue 156143002: Add ability to get raw data and range requests to to PrivetURLFetcher (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/local_discovery/privet_url_fetcher.h" 5 #include "chrome/browser/local_discovery/privet_url_fetcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/local_discovery/privet_constants.h" 15 #include "chrome/browser/local_discovery/privet_constants.h"
15 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
16 #include "net/http/http_status_code.h" 17 #include "net/http/http_status_code.h"
17 #include "net/url_request/url_request_status.h" 18 #include "net/url_request/url_request_status.h"
18 19
19 namespace local_discovery { 20 namespace local_discovery {
20 21
21 namespace { 22 namespace {
22 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: "; 23 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: ";
24 const char kRangeHeaderFormat[] = "Range: bytes=%d-%d";
23 const char kXPrivetEmptyToken[] = "\"\""; 25 const char kXPrivetEmptyToken[] = "\"\"";
24 const int kPrivetMaxRetries = 20; 26 const int kPrivetMaxRetries = 20;
25 const int kPrivetTimeoutOnError = 5; 27 const int kPrivetTimeoutOnError = 5;
28 const int kHTTPErrorCodeInvalidXPrivetToken = 418;
29
30 std::string MakeRangeHeader(int start, int end) {
31 DCHECK(start >= 0);
Vitaly Buka (NO REVIEWS) 2014/02/07 19:47:39 DCHECK_GT?
Noam Samuel 2014/02/12 20:25:16 Done.
32 DCHECK(end > 0);
33 DCHECK(end > start);
34 return base::StringPrintf(kRangeHeaderFormat, start, end);
26 } 35 }
27 36
37 } // namespace
38
28 void PrivetURLFetcher::Delegate::OnNeedPrivetToken( 39 void PrivetURLFetcher::Delegate::OnNeedPrivetToken(
29 PrivetURLFetcher* fetcher, 40 PrivetURLFetcher* fetcher,
30 const TokenCallback& callback) { 41 const TokenCallback& callback) {
31 OnError(fetcher, TOKEN_ERROR); 42 OnError(fetcher, TOKEN_ERROR);
32 } 43 }
33 44
34 PrivetURLFetcher::PrivetURLFetcher( 45 PrivetURLFetcher::PrivetURLFetcher(
35 const std::string& token, 46 const std::string& token,
36 const GURL& url, 47 const GURL& url,
37 net::URLFetcher::RequestType request_type, 48 net::URLFetcher::RequestType request_type,
38 net::URLRequestContextGetter* request_context, 49 net::URLRequestContextGetter* request_context,
39 PrivetURLFetcher::Delegate* delegate) 50 PrivetURLFetcher::Delegate* delegate)
40 : privet_access_token_(token), url_(url), request_type_(request_type), 51 : privet_access_token_(token), url_(url), request_type_(request_type),
Vitaly Buka (NO REVIEWS) 2014/02/07 19:47:39 one per line might be more readable.
Noam Samuel 2014/02/12 20:25:16 Done.
41 request_context_(request_context), delegate_(delegate), 52 request_context_(request_context), delegate_(delegate),
42 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false), 53 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false),
43 tries_(0), weak_factory_(this) { 54 do_not_parse_data_(false), has_byte_range_(false),
Vitaly Buka (NO REVIEWS) 2014/02/07 19:47:39 probably do_not_parse_data_ is depends on delegate
Noam Samuel 2014/02/12 20:25:16 Done.
55 make_response_file_(false), byte_range_start_(0),
56 byte_range_end_(0), tries_(0), weak_factory_(this) {
44 } 57 }
45 58
46 PrivetURLFetcher::~PrivetURLFetcher() { 59 PrivetURLFetcher::~PrivetURLFetcher() {
47 } 60 }
48 61
49 void PrivetURLFetcher::DoNotRetryOnTransientError() { 62 void PrivetURLFetcher::DoNotRetryOnTransientError() {
63 DCHECK(tries_ == 0);
50 do_not_retry_on_transient_error_ = true; 64 do_not_retry_on_transient_error_ = true;
51 } 65 }
52 66
53 void PrivetURLFetcher::AllowEmptyPrivetToken() { 67 void PrivetURLFetcher::AllowEmptyPrivetToken() {
68 DCHECK(tries_ == 0);
54 allow_empty_privet_token_ = true; 69 allow_empty_privet_token_ = true;
55 } 70 }
56 71
72 void PrivetURLFetcher::DoNotParseData() {
73 DCHECK(tries_ == 0);
74 do_not_parse_data_ = true;
75 }
76
77 void PrivetURLFetcher::SaveResponseToFile() {
78 DCHECK(tries_ == 0);
79 make_response_file_ = true;
80 }
81
82 void PrivetURLFetcher::SetByteRange(int start, int end) {
83 DCHECK(tries_ == 0);
84 byte_range_start_ = start;
85 byte_range_end_ = end;
86 has_byte_range_ = true;
87 }
88
57 void PrivetURLFetcher::Try() { 89 void PrivetURLFetcher::Try() {
58 tries_++; 90 tries_++;
59 if (tries_ < kPrivetMaxRetries) { 91 if (tries_ < kPrivetMaxRetries) {
60 std::string token = privet_access_token_; 92 std::string token = privet_access_token_;
61 93
62 if (token.empty()) 94 if (token.empty())
63 token = kXPrivetEmptyToken; 95 token = kXPrivetEmptyToken;
64 96
65 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this)); 97 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this));
66 url_fetcher_->SetRequestContext(request_context_); 98 url_fetcher_->SetRequestContext(request_context_);
67 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) + 99 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) +
68 token); 100 token);
101 if (has_byte_range_) {
102 url_fetcher_->AddExtraRequestHeader(
103 MakeRangeHeader(byte_range_start_, byte_range_end_));
104 }
105
106 if (make_response_file_) {
107 url_fetcher_->SaveResponseToTemporaryFile(
108 content::BrowserThread::GetMessageLoopProxyForThread(
109 content::BrowserThread::FILE));
110 }
69 111
70 // URLFetcher requires us to set upload data for POST requests. 112 // URLFetcher requires us to set upload data for POST requests.
71 if (request_type_ == net::URLFetcher::POST) { 113 if (request_type_ == net::URLFetcher::POST) {
72 if (!upload_file_path_.empty()) { 114 if (!upload_file_path_.empty()) {
73 url_fetcher_->SetUploadFilePath( 115 url_fetcher_->SetUploadFilePath(
74 upload_content_type_, 116 upload_content_type_,
75 upload_file_path_, 117 upload_file_path_,
76 0 /*offset*/, 118 0 /*offset*/,
77 kuint64max /*length*/, 119 kuint64max /*length*/,
78 content::BrowserThread::GetMessageLoopProxyForThread( 120 content::BrowserThread::GetMessageLoopProxyForThread(
79 content::BrowserThread::FILE)); 121 content::BrowserThread::FILE));
80 } else { 122 } else {
81 url_fetcher_->SetUploadData(upload_content_type_, upload_data_); 123 url_fetcher_->SetUploadData(upload_content_type_, upload_data_);
82 } 124 }
83 } 125 }
84 126
85 url_fetcher_->Start(); 127 url_fetcher_->Start();
86 } else { 128 } else {
87 delegate_->OnError(this, RETRY_ERROR); 129 delegate_->OnError(this, RETRY_ERROR);
88 } 130 }
89 } 131 }
90 132
91 void PrivetURLFetcher::Start() { 133 void PrivetURLFetcher::Start() {
92 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. 134 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet.
93 135
136 // Byte ranges should only be used when we're not parsing the data
137 // as JSON.
138 DCHECK(!has_byte_range_ || do_not_parse_data_);
139
140 // We should only be saving raw data to a file.
141 DCHECK(!make_response_file_ || do_not_parse_data_);
142
94 if (privet_access_token_.empty() && !allow_empty_privet_token_) { 143 if (privet_access_token_.empty() && !allow_empty_privet_token_) {
95 RequestTokenRefresh(); 144 RequestTokenRefresh();
96 } else { 145 } else {
97 Try(); 146 Try();
98 } 147 }
99 } 148 }
100 149
101 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type, 150 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type,
102 const std::string& upload_data) { 151 const std::string& upload_data) {
103 DCHECK(upload_file_path_.empty()); 152 DCHECK(upload_file_path_.empty());
104 upload_content_type_ = upload_content_type; 153 upload_content_type_ = upload_content_type;
105 upload_data_ = upload_data; 154 upload_data_ = upload_data;
106 } 155 }
107 156
108 void PrivetURLFetcher::SetUploadFilePath( 157 void PrivetURLFetcher::SetUploadFilePath(
109 const std::string& upload_content_type, 158 const std::string& upload_content_type,
110 const base::FilePath& upload_file_path) { 159 const base::FilePath& upload_file_path) {
111 DCHECK(upload_data_.empty()); 160 DCHECK(upload_data_.empty());
112 upload_content_type_ = upload_content_type; 161 upload_content_type_ = upload_content_type;
113 upload_file_path_ = upload_file_path; 162 upload_file_path_ = upload_file_path;
114 } 163 }
115 164
116 void PrivetURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) { 165 void PrivetURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
117 if (source->GetResponseCode() == net::HTTP_SERVICE_UNAVAILABLE) { 166 if (source->GetResponseCode() == net::HTTP_SERVICE_UNAVAILABLE) {
118 ScheduleRetry(kPrivetTimeoutOnError); 167 ScheduleRetry(kPrivetTimeoutOnError);
119 return; 168 return;
120 } 169 }
121 170
171 if (do_not_parse_data_) {
172 OnURLFetchCompleteDoNotParseData(source);
173 } else {
174 OnURLFetchCompleteParseData(source);
175 }
176 }
177
178 void PrivetURLFetcher::OnURLFetchCompleteDoNotParseData(
179 const net::URLFetcher* source) {
180 if (source->GetResponseCode() == kHTTPErrorCodeInvalidXPrivetToken) {
181 RequestTokenRefresh();
182 return;
183 }
184
185 if (source->GetResponseCode() != net::HTTP_OK &&
186 source->GetResponseCode() != net::HTTP_PARTIAL_CONTENT) {
187 delegate_->OnError(this, RESPONSE_CODE_ERROR);
188 return;
189 }
190
191 if (make_response_file_) {
192 base::FilePath response_file_path;
193
194 if (!source->GetResponseAsFilePath(true, &response_file_path)) {
195 delegate_->OnError(this, URL_FETCH_ERROR);
196 return;
197 }
198
199 delegate_->OnRawData(this, true, std::string(), response_file_path);
200 } else {
201 std::string response_str;
202
203 if (!source->GetResponseAsString(&response_str)) {
204 delegate_->OnError(this, URL_FETCH_ERROR);
205 return;
206 }
207
208 delegate_->OnRawData(this, false, response_str, base::FilePath());
209 }
210 }
211
212 void PrivetURLFetcher::OnURLFetchCompleteParseData(
213 const net::URLFetcher* source) {
122 if (source->GetResponseCode() != net::HTTP_OK) { 214 if (source->GetResponseCode() != net::HTTP_OK) {
123 delegate_->OnError(this, RESPONSE_CODE_ERROR); 215 delegate_->OnError(this, RESPONSE_CODE_ERROR);
124 return; 216 return;
125 } 217 }
126 218
127 std::string response_str; 219 std::string response_str;
128 220
129 if (!source->GetResponseAsString(&response_str)) { 221 if (!source->GetResponseAsString(&response_str)) {
130 delegate_->OnError(this, URL_FETCH_ERROR); 222 delegate_->OnError(this, URL_FETCH_ERROR);
131 return; 223 return;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 310
219 scoped_ptr<PrivetURLFetcher> PrivetURLFetcherFactory::CreateURLFetcher( 311 scoped_ptr<PrivetURLFetcher> PrivetURLFetcherFactory::CreateURLFetcher(
220 const GURL& url, net::URLFetcher::RequestType request_type, 312 const GURL& url, net::URLFetcher::RequestType request_type,
221 PrivetURLFetcher::Delegate* delegate) const { 313 PrivetURLFetcher::Delegate* delegate) const {
222 return scoped_ptr<PrivetURLFetcher>( 314 return scoped_ptr<PrivetURLFetcher>(
223 new PrivetURLFetcher(token_, url, request_type, request_context_.get(), 315 new PrivetURLFetcher(token_, url, request_type, request_context_.get(),
224 delegate)); 316 delegate));
225 } 317 }
226 318
227 } // namespace local_discovery 319 } // namespace local_discovery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698