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

Unified Diff: sync/internal_api/attachments/attachment_uploader_impl.cc

Issue 304253010: Add authentication support to AttachmentUploaderImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Apply more CR feedback from pavely 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sync/internal_api/attachments/attachment_uploader_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sync/internal_api/attachments/attachment_uploader_impl.cc
diff --git a/sync/internal_api/attachments/attachment_uploader_impl.cc b/sync/internal_api/attachments/attachment_uploader_impl.cc
index 25630dcaba8b2a71f79192b91921497bb17587bd..90c620e5802864cba4629bdfff72ec57cac32596 100644
--- a/sync/internal_api/attachments/attachment_uploader_impl.cc
+++ b/sync/internal_api/attachments/attachment_uploader_impl.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/non_thread_safe.h"
+#include "google_apis/gaia/gaia_constants.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
@@ -25,18 +26,23 @@ namespace syncer {
// Encapsulates all the state associated with a single upload.
class AttachmentUploaderImpl::UploadState : public net::URLFetcherDelegate,
+ public OAuth2TokenService::Consumer,
public base::NonThreadSafe {
public:
// Construct an UploadState.
//
// |owner| is a pointer to the object that will own (and must outlive!) this
// |UploadState.
- UploadState(const GURL& upload_url,
- const scoped_refptr<net::URLRequestContextGetter>&
- url_request_context_getter,
- const Attachment& attachment,
- const UploadCallback& user_callback,
- AttachmentUploaderImpl* owner);
+ UploadState(
+ const GURL& upload_url,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter,
+ const Attachment& attachment,
+ const UploadCallback& user_callback,
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
+ AttachmentUploaderImpl* owner);
virtual ~UploadState();
@@ -50,17 +56,34 @@ class AttachmentUploaderImpl::UploadState : public net::URLFetcherDelegate,
// URLFetcher implementation.
virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+ // OAuth2TokenService::Consumer.
+ virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+ const std::string& access_token,
+ const base::Time& expiration_time) OVERRIDE;
+ virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+ const GoogleServiceAuthError& error) OVERRIDE;
+
private:
typedef std::vector<UploadCallback> UploadCallbackList;
+ void GetToken();
+
+ void ReportResult(const UploadResult& result,
+ const AttachmentId& attachment_id);
+
GURL upload_url_;
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter_;
Attachment attachment_;
UploadCallbackList user_callbacks_;
scoped_ptr<net::URLFetcher> fetcher_;
+ std::string account_id_;
+ OAuth2TokenService::ScopeSet scopes_;
+ std::string access_token_;
+ OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider_;
// Pointer to the AttachmentUploaderImpl that owns this object.
AttachmentUploaderImpl* owner_;
+ scoped_ptr<OAuth2TokenServiceRequest> access_token_request_;
DISALLOW_COPY_AND_ASSIGN(UploadState);
};
@@ -71,33 +94,26 @@ AttachmentUploaderImpl::UploadState::UploadState(
url_request_context_getter,
const Attachment& attachment,
const UploadCallback& user_callback,
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
AttachmentUploaderImpl* owner)
- : upload_url_(upload_url),
+ : OAuth2TokenService::Consumer("attachment-uploader-impl"),
+ upload_url_(upload_url),
url_request_context_getter_(url_request_context_getter),
attachment_(attachment),
user_callbacks_(1, user_callback),
+ account_id_(account_id),
+ scopes_(scopes),
+ token_service_provider_(token_service_provider),
owner_(owner) {
- DCHECK(url_request_context_getter_);
DCHECK(upload_url_.is_valid());
+ DCHECK(url_request_context_getter_);
+ DCHECK(!account_id_.empty());
+ DCHECK(!scopes_.empty());
+ DCHECK(token_service_provider_);
DCHECK(owner_);
- fetcher_.reset(
- net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this));
- fetcher_->SetRequestContext(url_request_context_getter_.get());
- // TODO(maniscalco): Is there a better way? Copying the attachment data into
- // a string feels wrong given how large attachments may be (several MBs). If
- // we may end up switching from URLFetcher to URLRequest, this copy won't be
- // necessary.
- scoped_refptr<base::RefCountedMemory> memory = attachment.GetData();
- const std::string upload_content(memory->front_as<char>(), memory->size());
- fetcher_->SetUploadData(kContentType, upload_content);
- // TODO(maniscalco): Add authentication support (bug 371516).
- fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DISABLE_CACHE);
- // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and
- // Content-length) on the request and include the content's MD5,
- // AttachmentId's unique_id and the "sync birthday" (bug 371521).
- fetcher_->Start();
+ GetToken();
}
AttachmentUploaderImpl::UploadState::~UploadState() {
@@ -117,20 +133,75 @@ const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() {
void AttachmentUploaderImpl::UploadState::OnURLFetchComplete(
const net::URLFetcher* source) {
DCHECK(CalledOnValidThread());
- // TODO(maniscalco): Once the protocol is better defined, deal with the
- // various HTTP response code we may encounter.
UploadResult result = UPLOAD_UNSPECIFIED_ERROR;
+ AttachmentId attachment_id = attachment_.GetId();
if (source->GetResponseCode() == net::HTTP_OK) {
result = UPLOAD_SUCCESS;
+ // TODO(maniscalco): Update the attachment id with server address
+ // information before passing it to the callback (bug 371522).
+ } else if (source->GetResponseCode() == net::HTTP_UNAUTHORIZED) {
+ // TODO(maniscalco): One possibility is that we received a 401 because our
+ // access token has expired. We should probably fetch a new access token
+ // and retry this upload before giving up and reporting failure to our
+ // caller (bug 380437).
+ OAuth2TokenServiceRequest::InvalidateToken(
+ token_service_provider_, account_id_, scopes_, access_token_);
+ } else {
+ // TODO(maniscalco): Once the protocol is better defined, deal with the
+ // various HTTP response codes we may encounter.
}
- // TODO(maniscalco): Update the attachment id with server address information
- // before passing it to the callback (bug 371522).
- AttachmentId updated_id = attachment_.GetId();
+ ReportResult(result, attachment_id);
+}
+
+void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess(
+ const OAuth2TokenService::Request* request,
+ const std::string& access_token,
+ const base::Time& expiration_time) {
+ DCHECK_EQ(access_token_request_.get(), request);
+ access_token_request_.reset();
+ access_token_ = access_token;
+ fetcher_.reset(
+ net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this));
+ fetcher_->SetRequestContext(url_request_context_getter_.get());
+ // TODO(maniscalco): Is there a better way? Copying the attachment data into
+ // a string feels wrong given how large attachments may be (several MBs). If
+ // we may end up switching from URLFetcher to URLRequest, this copy won't be
+ // necessary.
+ scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData();
+ const std::string upload_content(memory->front_as<char>(), memory->size());
+ fetcher_->SetUploadData(kContentType, upload_content);
+ const std::string auth_header("Authorization: Bearer " + access_token_);
+ fetcher_->AddExtraRequestHeader(auth_header);
+ fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DISABLE_CACHE);
+ // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and
+ // Content-length) on the request and include the content's MD5,
+ // AttachmentId's unique_id and the "sync birthday" (bug 371521).
+ fetcher_->Start();
+}
+
+void AttachmentUploaderImpl::UploadState::OnGetTokenFailure(
+ const OAuth2TokenService::Request* request,
+ const GoogleServiceAuthError& error) {
+ DCHECK_EQ(access_token_request_.get(), request);
+ access_token_request_.reset();
+ ReportResult(UPLOAD_UNSPECIFIED_ERROR, attachment_.GetId());
+}
+
+void AttachmentUploaderImpl::UploadState::GetToken() {
+ access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart(
+ token_service_provider_, account_id_, scopes_, this);
+}
+
+void AttachmentUploaderImpl::UploadState::ReportResult(
+ const UploadResult& result,
+ const AttachmentId& attachment_id) {
UploadCallbackList::const_iterator iter = user_callbacks_.begin();
UploadCallbackList::const_iterator end = user_callbacks_.end();
for (; iter != end; ++iter) {
base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(*iter, result, updated_id));
+ FROM_HERE, base::Bind(*iter, result, attachment_id));
}
// Destroy this object and return immediately.
owner_->DeleteUploadStateFor(attachment_.GetId().GetProto().unique_id());
@@ -140,10 +211,18 @@ void AttachmentUploaderImpl::UploadState::OnURLFetchComplete(
AttachmentUploaderImpl::AttachmentUploaderImpl(
const std::string& url_prefix,
const scoped_refptr<net::URLRequestContextGetter>&
- url_request_context_getter)
+ url_request_context_getter,
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider>
+ token_service_provider)
: url_prefix_(url_prefix),
- url_request_context_getter_(url_request_context_getter) {
+ url_request_context_getter_(url_request_context_getter),
+ account_id_(account_id),
+ scopes_(scopes),
+ token_service_provider_(token_service_provider.Pass()) {
DCHECK(CalledOnValidThread());
+ DCHECK(token_service_provider_);
}
AttachmentUploaderImpl::~AttachmentUploaderImpl() {
@@ -159,8 +238,15 @@ void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment,
StateMap::iterator iter = state_map_.find(unique_id);
if (iter == state_map_.end()) {
const GURL url = GetUploadURLForAttachmentId(attachment_id);
- scoped_ptr<UploadState> upload_state(new UploadState(
- url, url_request_context_getter_, attachment, callback, this));
+ scoped_ptr<UploadState> upload_state(
+ new UploadState(url,
+ url_request_context_getter_,
+ attachment,
+ callback,
+ account_id_,
+ scopes_,
+ token_service_provider_.get(),
+ this));
state_map_.add(unique_id, upload_state.Pass());
} else {
DCHECK(
« no previous file with comments | « no previous file | sync/internal_api/attachments/attachment_uploader_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698