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

Side by Side Diff: trunk/src/sync/internal_api/attachments/attachment_uploader_impl.cc

Issue 316413002: Revert 275293 "Add authentication support to AttachmentUploaderI..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 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
« no previous file with comments | « no previous file | trunk/src/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "sync/internal_api/public/attachments/attachment_uploader_impl.h" 5 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/threading/non_thread_safe.h" 9 #include "base/threading/non_thread_safe.h"
10 #include "google_apis/gaia/gaia_constants.h"
11 #include "net/base/load_flags.h" 10 #include "net/base/load_flags.h"
12 #include "net/http/http_status_code.h" 11 #include "net/http/http_status_code.h"
13 #include "net/url_request/url_fetcher.h" 12 #include "net/url_request/url_fetcher.h"
14 #include "net/url_request/url_fetcher_delegate.h" 13 #include "net/url_request/url_fetcher_delegate.h"
15 #include "sync/api/attachments/attachment.h" 14 #include "sync/api/attachments/attachment.h"
16 #include "sync/protocol/sync.pb.h" 15 #include "sync/protocol/sync.pb.h"
17 #include "url/gurl.h" 16 #include "url/gurl.h"
18 17
19 namespace { 18 namespace {
20 19
21 const char kContentType[] = "application/octet-stream"; 20 const char kContentType[] = "application/octet-stream";
22 21
23 } // namespace 22 } // namespace
24 23
25 namespace syncer { 24 namespace syncer {
26 25
27 // Encapsulates all the state associated with a single upload. 26 // Encapsulates all the state associated with a single upload.
28 class AttachmentUploaderImpl::UploadState : public net::URLFetcherDelegate, 27 class AttachmentUploaderImpl::UploadState : public net::URLFetcherDelegate,
29 public OAuth2TokenService::Consumer,
30 public base::NonThreadSafe { 28 public base::NonThreadSafe {
31 public: 29 public:
32 // Construct an UploadState. 30 // Construct an UploadState.
33 // 31 //
34 // |owner| is a pointer to the object that will own (and must outlive!) this 32 // |owner| is a pointer to the object that will own (and must outlive!) this
35 // |UploadState. 33 // |UploadState.
36 UploadState( 34 UploadState(const GURL& upload_url,
37 const GURL& upload_url, 35 const scoped_refptr<net::URLRequestContextGetter>&
38 const scoped_refptr<net::URLRequestContextGetter>& 36 url_request_context_getter,
39 url_request_context_getter, 37 const Attachment& attachment,
40 const Attachment& attachment, 38 const UploadCallback& user_callback,
41 const UploadCallback& user_callback, 39 AttachmentUploaderImpl* owner);
42 const std::string& account_id,
43 const OAuth2TokenService::ScopeSet& scopes,
44 OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
45 AttachmentUploaderImpl* owner);
46 40
47 virtual ~UploadState(); 41 virtual ~UploadState();
48 42
49 // Add |user_callback| to the list of callbacks to be invoked when this upload 43 // Add |user_callback| to the list of callbacks to be invoked when this upload
50 // completed. 44 // completed.
51 void AddUserCallback(const UploadCallback& user_callback); 45 void AddUserCallback(const UploadCallback& user_callback);
52 46
53 // Return the Attachment this object is uploading. 47 // Return the Attachment this object is uploading.
54 const Attachment& GetAttachment(); 48 const Attachment& GetAttachment();
55 49
56 // URLFetcher implementation. 50 // URLFetcher implementation.
57 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 51 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
58 52
59 // OAuth2TokenService::Consumer.
60 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
61 const std::string& access_token,
62 const base::Time& expiration_time) OVERRIDE;
63 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
64 const GoogleServiceAuthError& error) OVERRIDE;
65
66 private: 53 private:
67 typedef std::vector<UploadCallback> UploadCallbackList; 54 typedef std::vector<UploadCallback> UploadCallbackList;
68 55
69 void GetToken();
70
71 void ReportResult(const UploadResult& result,
72 const AttachmentId& attachment_id);
73
74 GURL upload_url_; 56 GURL upload_url_;
75 const scoped_refptr<net::URLRequestContextGetter>& 57 const scoped_refptr<net::URLRequestContextGetter>&
76 url_request_context_getter_; 58 url_request_context_getter_;
77 Attachment attachment_; 59 Attachment attachment_;
78 UploadCallbackList user_callbacks_; 60 UploadCallbackList user_callbacks_;
79 scoped_ptr<net::URLFetcher> fetcher_; 61 scoped_ptr<net::URLFetcher> fetcher_;
80 std::string account_id_;
81 OAuth2TokenService::ScopeSet scopes_;
82 std::string access_token_;
83 OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider_;
84 // Pointer to the AttachmentUploaderImpl that owns this object. 62 // Pointer to the AttachmentUploaderImpl that owns this object.
85 AttachmentUploaderImpl* owner_; 63 AttachmentUploaderImpl* owner_;
86 scoped_ptr<OAuth2TokenServiceRequest> access_token_request_;
87 64
88 DISALLOW_COPY_AND_ASSIGN(UploadState); 65 DISALLOW_COPY_AND_ASSIGN(UploadState);
89 }; 66 };
90 67
91 AttachmentUploaderImpl::UploadState::UploadState( 68 AttachmentUploaderImpl::UploadState::UploadState(
92 const GURL& upload_url, 69 const GURL& upload_url,
93 const scoped_refptr<net::URLRequestContextGetter>& 70 const scoped_refptr<net::URLRequestContextGetter>&
94 url_request_context_getter, 71 url_request_context_getter,
95 const Attachment& attachment, 72 const Attachment& attachment,
96 const UploadCallback& user_callback, 73 const UploadCallback& user_callback,
97 const std::string& account_id,
98 const OAuth2TokenService::ScopeSet& scopes,
99 OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
100 AttachmentUploaderImpl* owner) 74 AttachmentUploaderImpl* owner)
101 : OAuth2TokenService::Consumer("attachment-uploader-impl"), 75 : upload_url_(upload_url),
102 upload_url_(upload_url),
103 url_request_context_getter_(url_request_context_getter), 76 url_request_context_getter_(url_request_context_getter),
104 attachment_(attachment), 77 attachment_(attachment),
105 user_callbacks_(1, user_callback), 78 user_callbacks_(1, user_callback),
106 account_id_(account_id),
107 scopes_(scopes),
108 token_service_provider_(token_service_provider),
109 owner_(owner) { 79 owner_(owner) {
80 DCHECK(url_request_context_getter_);
110 DCHECK(upload_url_.is_valid()); 81 DCHECK(upload_url_.is_valid());
111 DCHECK(url_request_context_getter_);
112 DCHECK(!account_id_.empty());
113 DCHECK(!scopes_.empty());
114 DCHECK(token_service_provider_);
115 DCHECK(owner_); 82 DCHECK(owner_);
116 GetToken(); 83 fetcher_.reset(
84 net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this));
85 fetcher_->SetRequestContext(url_request_context_getter_.get());
86 // TODO(maniscalco): Is there a better way? Copying the attachment data into
87 // a string feels wrong given how large attachments may be (several MBs). If
88 // we may end up switching from URLFetcher to URLRequest, this copy won't be
89 // necessary.
90 scoped_refptr<base::RefCountedMemory> memory = attachment.GetData();
91 const std::string upload_content(memory->front_as<char>(), memory->size());
92 fetcher_->SetUploadData(kContentType, upload_content);
93 // TODO(maniscalco): Add authentication support (bug 371516).
94 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
95 net::LOAD_DO_NOT_SEND_COOKIES |
96 net::LOAD_DISABLE_CACHE);
97 // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and
98 // Content-length) on the request and include the content's MD5,
99 // AttachmentId's unique_id and the "sync birthday" (bug 371521).
100 fetcher_->Start();
117 } 101 }
118 102
119 AttachmentUploaderImpl::UploadState::~UploadState() { 103 AttachmentUploaderImpl::UploadState::~UploadState() {
120 } 104 }
121 105
122 void AttachmentUploaderImpl::UploadState::AddUserCallback( 106 void AttachmentUploaderImpl::UploadState::AddUserCallback(
123 const UploadCallback& user_callback) { 107 const UploadCallback& user_callback) {
124 DCHECK(CalledOnValidThread()); 108 DCHECK(CalledOnValidThread());
125 user_callbacks_.push_back(user_callback); 109 user_callbacks_.push_back(user_callback);
126 } 110 }
127 111
128 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() { 112 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() {
129 DCHECK(CalledOnValidThread()); 113 DCHECK(CalledOnValidThread());
130 return attachment_; 114 return attachment_;
131 } 115 }
132 116
133 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete( 117 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete(
134 const net::URLFetcher* source) { 118 const net::URLFetcher* source) {
135 DCHECK(CalledOnValidThread()); 119 DCHECK(CalledOnValidThread());
120 // TODO(maniscalco): Once the protocol is better defined, deal with the
121 // various HTTP response code we may encounter.
136 UploadResult result = UPLOAD_UNSPECIFIED_ERROR; 122 UploadResult result = UPLOAD_UNSPECIFIED_ERROR;
137 AttachmentId attachment_id = attachment_.GetId();
138 if (source->GetResponseCode() == net::HTTP_OK) { 123 if (source->GetResponseCode() == net::HTTP_OK) {
139 result = UPLOAD_SUCCESS; 124 result = UPLOAD_SUCCESS;
140 // TODO(maniscalco): Update the attachment id with server address
141 // information before passing it to the callback (bug 371522).
142 } else if (source->GetResponseCode() == net::HTTP_UNAUTHORIZED) {
143 // TODO(maniscalco): One possibility is that we received a 401 because our
144 // access token has expired. We should probably fetch a new access token
145 // and retry this upload before giving up and reporting failure to our
146 // caller (bug 380437).
147 OAuth2TokenServiceRequest::InvalidateToken(
148 token_service_provider_, account_id_, scopes_, access_token_);
149 } else {
150 // TODO(maniscalco): Once the protocol is better defined, deal with the
151 // various HTTP response codes we may encounter.
152 } 125 }
153 ReportResult(result, attachment_id); 126 // TODO(maniscalco): Update the attachment id with server address information
154 } 127 // before passing it to the callback (bug 371522).
155 128 AttachmentId updated_id = attachment_.GetId();
156 void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess(
157 const OAuth2TokenService::Request* request,
158 const std::string& access_token,
159 const base::Time& expiration_time) {
160 DCHECK_EQ(access_token_request_.get(), request);
161 access_token_request_.reset();
162 access_token_ = access_token;
163 fetcher_.reset(
164 net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this));
165 fetcher_->SetRequestContext(url_request_context_getter_.get());
166 // TODO(maniscalco): Is there a better way? Copying the attachment data into
167 // a string feels wrong given how large attachments may be (several MBs). If
168 // we may end up switching from URLFetcher to URLRequest, this copy won't be
169 // necessary.
170 scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData();
171 const std::string upload_content(memory->front_as<char>(), memory->size());
172 fetcher_->SetUploadData(kContentType, upload_content);
173 const std::string auth_header("Authorization: Bearer " + access_token_);
174 fetcher_->AddExtraRequestHeader(auth_header);
175 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
176 net::LOAD_DO_NOT_SEND_COOKIES |
177 net::LOAD_DISABLE_CACHE);
178 // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and
179 // Content-length) on the request and include the content's MD5,
180 // AttachmentId's unique_id and the "sync birthday" (bug 371521).
181 fetcher_->Start();
182 }
183
184 void AttachmentUploaderImpl::UploadState::OnGetTokenFailure(
185 const OAuth2TokenService::Request* request,
186 const GoogleServiceAuthError& error) {
187 DCHECK_EQ(access_token_request_.get(), request);
188 access_token_request_.reset();
189 ReportResult(UPLOAD_UNSPECIFIED_ERROR, attachment_.GetId());
190 }
191
192 void AttachmentUploaderImpl::UploadState::GetToken() {
193 access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart(
194 token_service_provider_, account_id_, scopes_, this);
195 }
196
197 void AttachmentUploaderImpl::UploadState::ReportResult(
198 const UploadResult& result,
199 const AttachmentId& attachment_id) {
200 UploadCallbackList::const_iterator iter = user_callbacks_.begin(); 129 UploadCallbackList::const_iterator iter = user_callbacks_.begin();
201 UploadCallbackList::const_iterator end = user_callbacks_.end(); 130 UploadCallbackList::const_iterator end = user_callbacks_.end();
202 for (; iter != end; ++iter) { 131 for (; iter != end; ++iter) {
203 base::MessageLoop::current()->PostTask( 132 base::MessageLoop::current()->PostTask(
204 FROM_HERE, base::Bind(*iter, result, attachment_id)); 133 FROM_HERE, base::Bind(*iter, result, updated_id));
205 } 134 }
206 // Destroy this object and return immediately. 135 // Destroy this object and return immediately.
207 owner_->DeleteUploadStateFor(attachment_.GetId().GetProto().unique_id()); 136 owner_->DeleteUploadStateFor(attachment_.GetId().GetProto().unique_id());
208 return; 137 return;
209 } 138 }
210 139
211 AttachmentUploaderImpl::AttachmentUploaderImpl( 140 AttachmentUploaderImpl::AttachmentUploaderImpl(
212 const std::string& url_prefix, 141 const std::string& url_prefix,
213 const scoped_refptr<net::URLRequestContextGetter>& 142 const scoped_refptr<net::URLRequestContextGetter>&
214 url_request_context_getter, 143 url_request_context_getter)
215 const std::string& account_id,
216 const OAuth2TokenService::ScopeSet& scopes,
217 scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider>
218 token_service_provider)
219 : url_prefix_(url_prefix), 144 : url_prefix_(url_prefix),
220 url_request_context_getter_(url_request_context_getter), 145 url_request_context_getter_(url_request_context_getter) {
221 account_id_(account_id),
222 scopes_(scopes),
223 token_service_provider_(token_service_provider.Pass()) {
224 DCHECK(CalledOnValidThread()); 146 DCHECK(CalledOnValidThread());
225 DCHECK(token_service_provider_);
226 } 147 }
227 148
228 AttachmentUploaderImpl::~AttachmentUploaderImpl() { 149 AttachmentUploaderImpl::~AttachmentUploaderImpl() {
229 DCHECK(CalledOnValidThread()); 150 DCHECK(CalledOnValidThread());
230 } 151 }
231 152
232 void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment, 153 void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment,
233 const UploadCallback& callback) { 154 const UploadCallback& callback) {
234 DCHECK(CalledOnValidThread()); 155 DCHECK(CalledOnValidThread());
235 const AttachmentId attachment_id = attachment.GetId(); 156 const AttachmentId attachment_id = attachment.GetId();
236 const std::string unique_id = attachment_id.GetProto().unique_id(); 157 const std::string unique_id = attachment_id.GetProto().unique_id();
237 DCHECK(!unique_id.empty()); 158 DCHECK(!unique_id.empty());
238 StateMap::iterator iter = state_map_.find(unique_id); 159 StateMap::iterator iter = state_map_.find(unique_id);
239 if (iter == state_map_.end()) { 160 if (iter == state_map_.end()) {
240 const GURL url = GetUploadURLForAttachmentId(attachment_id); 161 const GURL url = GetUploadURLForAttachmentId(attachment_id);
241 scoped_ptr<UploadState> upload_state( 162 scoped_ptr<UploadState> upload_state(new UploadState(
242 new UploadState(url, 163 url, url_request_context_getter_, attachment, callback, this));
243 url_request_context_getter_,
244 attachment,
245 callback,
246 account_id_,
247 scopes_,
248 token_service_provider_.get(),
249 this));
250 state_map_.add(unique_id, upload_state.Pass()); 164 state_map_.add(unique_id, upload_state.Pass());
251 } else { 165 } else {
252 DCHECK( 166 DCHECK(
253 attachment.GetData()->Equals(iter->second->GetAttachment().GetData())); 167 attachment.GetData()->Equals(iter->second->GetAttachment().GetData()));
254 // We already have an upload for this attachment. "Join" it. 168 // We already have an upload for this attachment. "Join" it.
255 iter->second->AddUserCallback(callback); 169 iter->second->AddUserCallback(callback);
256 } 170 }
257 } 171 }
258 172
259 GURL AttachmentUploaderImpl::GetUploadURLForAttachmentId( 173 GURL AttachmentUploaderImpl::GetUploadURLForAttachmentId(
260 const AttachmentId& attachment_id) const { 174 const AttachmentId& attachment_id) const {
261 return GURL(url_prefix_ + attachment_id.GetProto().unique_id()); 175 return GURL(url_prefix_ + attachment_id.GetProto().unique_id());
262 } 176 }
263 177
264 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) { 178 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) {
265 state_map_.erase(unique_id); 179 state_map_.erase(unique_id);
266 } 180 }
267 181
268 } // namespace syncer 182 } // namespace syncer
OLDNEW
« no previous file with comments | « no previous file | trunk/src/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698