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

Side by Side Diff: net/base/sdch_dictionary_fetcher.cc

Issue 495523003: Change SDCHDictionaryFetcher to use URLRequest instead of URLFetcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DoLoop implementation. Created 6 years, 3 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 2014 The Chromium Authors. All rights reserved. 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 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 "net/base/sdch_dictionary_fetcher.h" 5 #include "net/base/sdch_dictionary_fetcher.h"
6 6
7 #include <stdint.h>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h" 11 #include "base/thread_task_runner_handle.h"
10 #include "net/base/load_flags.h" 12 #include "net/base/load_flags.h"
11 #include "net/url_request/url_fetcher.h" 13 #include "net/url_request/url_request_context.h"
12 #include "net/url_request/url_request_context_getter.h"
13 #include "net/url_request/url_request_status.h" 14 #include "net/url_request/url_request_status.h"
15 #include "net/url_request/url_request_throttler_manager.h"
16
17 namespace {
18
19 const int kBufferSize = 4096;
20
21 } // namespace
14 22
15 namespace net { 23 namespace net {
16 24
17 SdchDictionaryFetcher::SdchDictionaryFetcher( 25 SdchDictionaryFetcher::SdchDictionaryFetcher(
18 SdchManager* manager, 26 SdchManager* manager,
19 scoped_refptr<URLRequestContextGetter> context) 27 URLRequestContext* context)
20 : manager_(manager), 28 : next_state_(STATE_NONE),
21 weak_factory_(this), 29 manager_(manager),
22 task_is_pending_(false), 30 context_(context),
23 context_(context) { 31 weak_factory_(this) {
24 DCHECK(CalledOnValidThread()); 32 DCHECK(CalledOnValidThread());
25 DCHECK(manager); 33 DCHECK(manager);
34 DCHECK(context);
26 } 35 }
27 36
28 SdchDictionaryFetcher::~SdchDictionaryFetcher() { 37 SdchDictionaryFetcher::~SdchDictionaryFetcher() {
29 DCHECK(CalledOnValidThread()); 38 DCHECK(CalledOnValidThread());
30 } 39 }
31 40
32 void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) { 41 void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) {
33 DCHECK(CalledOnValidThread()); 42 DCHECK(CalledOnValidThread());
34 43
35 // Avoid pushing duplicate copy onto queue. We may fetch this url again later 44 // Avoid pushing duplicate copy onto queue. We may fetch this url again later
36 // and get a different dictionary, but there is no reason to have it in the 45 // and get a different dictionary, but there is no reason to have it in the
37 // queue twice at one time. 46 // queue twice at one time.
38 if (!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) { 47 if (!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) {
39 SdchManager::SdchErrorRecovery( 48 SdchManager::SdchErrorRecovery(
40 SdchManager::DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD); 49 SdchManager::DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD);
41 return; 50 return;
42 } 51 }
43 if (attempted_load_.find(dictionary_url) != attempted_load_.end()) { 52 if (attempted_load_.find(dictionary_url) != attempted_load_.end()) {
44 SdchManager::SdchErrorRecovery( 53 SdchManager::SdchErrorRecovery(
45 SdchManager::DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD); 54 SdchManager::DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD);
46 return; 55 return;
47 } 56 }
48 attempted_load_.insert(dictionary_url); 57 attempted_load_.insert(dictionary_url);
49 fetch_queue_.push(dictionary_url); 58 fetch_queue_.push(dictionary_url);
50 ScheduleDelayedRun(); 59
60 next_state_ = STATE_IDLE;
61 DoLoop(OK);
51 } 62 }
52 63
53 void SdchDictionaryFetcher::Cancel() { 64 void SdchDictionaryFetcher::Cancel() {
54 DCHECK(CalledOnValidThread()); 65 DCHECK(CalledOnValidThread());
55 66
67 next_state_ = STATE_NONE;
68
56 while (!fetch_queue_.empty()) 69 while (!fetch_queue_.empty())
57 fetch_queue_.pop(); 70 fetch_queue_.pop();
58 attempted_load_.clear(); 71 attempted_load_.clear();
59 weak_factory_.InvalidateWeakPtrs(); 72 weak_factory_.InvalidateWeakPtrs();
60 current_fetch_.reset(NULL); 73 current_request_.reset(NULL);
74 buffer_ = NULL;
75 dictionary_.clear();
61 } 76 }
62 77
63 void SdchDictionaryFetcher::ScheduleDelayedRun() { 78 int SdchDictionaryFetcher::DoLoop(int rv) {
64 if (fetch_queue_.empty() || current_fetch_.get() || task_is_pending_) 79 do {
65 return; 80 if (rv != OK) {
66 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, 81 HandleResult(rv);
67 base::Bind(&SdchDictionaryFetcher::StartFetching, 82 rv = OK;
68 weak_factory_.GetWeakPtr()), 83 }
Ryan Sleevi 2014/09/02 20:04:18 This doesn't seem right. Normally we pass the prev
Randy Smith (Not in Mondays) 2014/09/02 23:34:32 Done.
69 base::TimeDelta::FromMilliseconds(kMsDelayFromRequestTillDownload)); 84
70 task_is_pending_ = true; 85 State state = next_state_;
86 next_state_ = STATE_NONE;
87 switch (state) {
88 case STATE_IDLE:
89 rv = DoDispatchRequest();
90 break;
91 case STATE_REQUEST_READING:
92 rv = DoRead();
93 break;
94 case STATE_REQUEST_COMPLETE:
95 rv = DoCompleteRequest();
96 break;
97 case STATE_NONE:
98 NOTREACHED();
99 }
100 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
101
102 return rv;
71 } 103 }
72 104
73 void SdchDictionaryFetcher::StartFetching() { 105 int SdchDictionaryFetcher::DoDispatchRequest() {
74 DCHECK(CalledOnValidThread()); 106 DCHECK(CalledOnValidThread());
75 DCHECK(task_is_pending_);
76 task_is_pending_ = false;
77 107
78 // Handle losing the race against Cancel(). 108 if (fetch_queue_.empty() || current_request_.get()) {
79 if (fetch_queue_.empty()) 109 next_state_ = STATE_NONE;
80 return; 110 return OK;
111 }
81 112
82 DCHECK(context_.get()); 113 current_request_ = context_->CreateRequest(
83 current_fetch_.reset(URLFetcher::Create( 114 fetch_queue_.front(), IDLE, this, NULL);
84 fetch_queue_.front(), URLFetcher::GET, this)); 115 current_request_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES |
116 LOAD_DO_NOT_SAVE_COOKIES);
117 buffer_ = new IOBuffer(kBufferSize);
85 fetch_queue_.pop(); 118 fetch_queue_.pop();
86 current_fetch_->SetRequestContext(context_.get()); 119
87 current_fetch_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES | 120 next_state_ = STATE_REQUEST_READING;
88 LOAD_DO_NOT_SAVE_COOKIES); 121
89 current_fetch_->Start(); 122 current_request_->Start();
123
124 return ERR_IO_PENDING; // TODO(rdsmith): Is this correct?
Ryan Sleevi 2014/09/02 20:04:18 I guess that's the question for URLRequest::Delega
Randy Smith (Not in Mondays) 2014/09/02 23:34:32 I'm afraid I don't follow. At least in the future
90 } 125 }
91 126
92 void SdchDictionaryFetcher::OnURLFetchComplete( 127 int SdchDictionaryFetcher::DoRead() {
93 const URLFetcher* source) {
94 DCHECK(CalledOnValidThread()); 128 DCHECK(CalledOnValidThread());
95 if ((200 == source->GetResponseCode()) && 129
96 (source->GetStatus().status() == URLRequestStatus::SUCCESS)) { 130 next_state_ = STATE_REQUEST_READING;
97 std::string data; 131 int bytes_read = 0;
98 source->GetResponseAsString(&data); 132 if (!current_request_->Read(buffer_.get(), kBufferSize, &bytes_read)) {
99 manager_->AddSdchDictionary(data, source->GetURL()); 133 if (current_request_->status().is_io_pending())
134 return ERR_IO_PENDING;
135
136 DCHECK_NE(current_request_->status().error(), OK);
137
138 return current_request_->status().error();
100 } 139 }
101 current_fetch_.reset(NULL); 140
102 ScheduleDelayedRun(); 141 if (bytes_read != 0)
142 dictionary_.append(buffer_->data(), bytes_read);
143 else
144 next_state_ = STATE_REQUEST_COMPLETE;
145
146 return OK;
147 }
148
149 int SdchDictionaryFetcher::DoCompleteRequest() {
150 DCHECK(CalledOnValidThread());
151
152 manager_->AddSdchDictionary(dictionary_, current_request_->url());
153 current_request_.reset();
154 buffer_ = NULL;
155 dictionary_.clear();
156
157 next_state_ = STATE_IDLE;
158
159 return OK;
160 }
161
162 void SdchDictionaryFetcher::HandleResult(int rv) {
163 DCHECK(CalledOnValidThread());
164
165 current_request_.reset();
166 buffer_ = NULL;
167 next_state_ = STATE_IDLE;
168 DoLoop(OK);
169 }
170
171 void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request) {
172 DCHECK(CalledOnValidThread());
173 DCHECK_EQ(request, current_request_.get());
174
175 // TODO(rdsmith): Break potential infinite recursion.
176 DoLoop(OK);
Ryan Sleevi 2014/09/02 20:04:18 Right, this has the same issue, in that it's conti
Randy Smith (Not in Mondays) 2014/09/02 23:34:32 Yep, but again, I really don't think I should be c
177 }
178
179 void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request,
180 int bytes_read) {
181 DCHECK(CalledOnValidThread());
182 DCHECK_EQ(request, current_request_.get());
183 DCHECK_EQ(next_state_, STATE_REQUEST_READING);
184
185 if (request->status().is_success())
186 dictionary_.append(buffer_->data(), bytes_read);
187
188 DoLoop(request->status().error());
103 } 189 }
104 190
105 } // namespace net 191 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698