diff --git a/libcef/browser/url_network_delegate.cc b/libcef/browser/url_network_delegate.cc index 1f6b6ac76..3fb9c7a99 100644 --- a/libcef/browser/url_network_delegate.cc +++ b/libcef/browser/url_network_delegate.cc @@ -107,12 +107,16 @@ class CefBeforeResourceLoadCallbackImpl : public CefRequestCallback { CEF_REQUIRE_IOT(); if (allow) { - const GURL& old_url = request->url(); - GURL url = GURL(cef_request->GetURL().ToString()); - if (old_url != url) - new_url->Swap(&url); + // Update the URLRequest with only the values that have been changed by + // the client. + cef_request->Get(request, true); - cef_request->Get(request); + if (!!(cef_request->GetChanges() & CefRequestImpl::kChangedUrl)) { + // If the URL was changed then redirect the request. + GURL url = GURL(cef_request->GetURL().ToString()); + DCHECK_NE(url, request->url()); + new_url->Swap(&url); + } } // Remove the association between the URLRequest and this object. @@ -238,6 +242,7 @@ int CefNetworkDelegate::OnBeforeURLRequest( // Populate the request data. CefRefPtr requestPtr(new CefRequestImpl()); requestPtr->Set(request); + requestPtr->SetTrackChanges(true); CefRefPtr callbackImpl( new CefBeforeResourceLoadCallbackImpl(requestPtr, new_url, request, diff --git a/libcef/browser/url_request_interceptor.cc b/libcef/browser/url_request_interceptor.cc index 5258eec74..1e5934179 100644 --- a/libcef/browser/url_request_interceptor.cc +++ b/libcef/browser/url_request_interceptor.cc @@ -111,16 +111,17 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse( CefRefPtr frame = browser->GetFrameForRequest(request); - CefRefPtr cefRequest = new CefRequestImpl(); - static_cast(cefRequest.get())->Set(request); + CefRefPtr cefRequest = new CefRequestImpl(); + cefRequest->Set(request); + cefRequest->SetTrackChanges(true); - CefRefPtr cefResponse = new CefResponseImpl(); - static_cast(cefResponse.get())->Set(request); - static_cast(cefResponse.get())->SetReadOnly(true); + CefRefPtr cefResponse = new CefResponseImpl(); + cefResponse->Set(request); + cefResponse->SetReadOnly(true); // Give the client an opportunity to retry or redirect the request. - if (!handler->OnResourceResponse(browser.get(), frame, cefRequest, - cefResponse)) { + if (!handler->OnResourceResponse(browser.get(), frame, cefRequest.get(), + cefResponse.get())) { return NULL; } @@ -129,34 +130,14 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse( // reset sooner so that we can modify the request headers without asserting. request->set_is_pending(false); - // Update the request headers to match the CefRequest. - CefRequest::HeaderMap cefHeaders; - cefRequest->GetHeaderMap(cefHeaders); + // Update the URLRequest with only the values that have been changed by the + // client. + cefRequest->Get(request, true); - CefString referrerStr; - referrerStr.FromASCII(net::HttpRequestHeaders::kReferer); - CefRequest::HeaderMap::iterator it = cefHeaders.find(referrerStr); - if (it != cefHeaders.end()) { - request->SetReferrer(it->second); - cefHeaders.erase(it); - } - - net::HttpRequestHeaders netHeaders; - netHeaders.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(cefHeaders)); - request->SetExtraRequestHeaders(netHeaders); - - // Update the request body to match the CefRequest. - CefRefPtr post_data = cefRequest->GetPostData(); - if (post_data.get()) { - request->set_upload( - make_scoped_ptr(static_cast(post_data.get())->Get())); - } else if (request->get_upload()) { - request->set_upload(scoped_ptr()); - } - - // If the URL was modified redirect the request. - const GURL url(cefRequest->GetURL().ToString()); - if (url != request->url()) { + // If the URL was changed then redirect the request. + if (!!(cefRequest->GetChanges() & CefRequestImpl::kChangedUrl)) { + const GURL url(cefRequest->GetURL().ToString()); + DCHECK_NE(url, request->url()); return new net::URLRequestRedirectJob( request, network_delegate, url, net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, diff --git a/libcef/common/request_impl.cc b/libcef/common/request_impl.cc index 8d0721926..957b72878 100644 --- a/libcef/common/request_impl.cc +++ b/libcef/common/request_impl.cc @@ -102,7 +102,8 @@ CefRefPtr CefRequest::Create() { // CefRequestImpl ------------------------------------------------------------- CefRequestImpl::CefRequestImpl() - : read_only_(false) { + : read_only_(false), + track_changes_(false) { base::AutoLock lock_scope(lock_); Reset(); } @@ -120,7 +121,10 @@ CefString CefRequestImpl::GetURL() { void CefRequestImpl::SetURL(const CefString& url) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); - url_ = url; + if (url_ != url) { + url_ = url; + Changed(kChangedUrl); + } } CefString CefRequestImpl::GetMethod() { @@ -131,7 +135,10 @@ CefString CefRequestImpl::GetMethod() { void CefRequestImpl::SetMethod(const CefString& method) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); - method_ = method; + if (method_ != method) { + method_ = method; + Changed(kChangedMethod); + } } CefRefPtr CefRequestImpl::GetPostData() { @@ -143,6 +150,7 @@ void CefRequestImpl::SetPostData(CefRefPtr postData) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); postdata_ = postData; + Changed(kChangedPostData); } void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) { @@ -154,6 +162,7 @@ void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); headermap_ = headerMap; + Changed(kChangedHeaderMap); } void CefRequestImpl::Set(const CefString& url, @@ -162,30 +171,45 @@ void CefRequestImpl::Set(const CefString& url, const HeaderMap& headerMap) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); - url_ = url; - method_ = method; + if (url_ != url) { + url_ = url; + Changed(kChangedUrl); + } + if (method_ != method) { + method_ = method; + Changed(kChangedMethod); + } postdata_ = postData; headermap_ = headerMap; + Changed(kChangedPostData | kChangedHeaderMap); } int CefRequestImpl::GetFlags() { base::AutoLock lock_scope(lock_); return flags_; } + void CefRequestImpl::SetFlags(int flags) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); - flags_ = flags; + if (flags_ != flags) { + flags_ = flags; + Changed(kChangedFlags); + } } CefString CefRequestImpl::GetFirstPartyForCookies() { base::AutoLock lock_scope(lock_); return first_party_for_cookies_; } + void CefRequestImpl::SetFirstPartyForCookies(const CefString& url) { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); - first_party_for_cookies_ = url; + if (first_party_for_cookies_ != url) { + first_party_for_cookies_ = url; + Changed(kChangedFirstPartyForCookies); + } } CefRequestImpl::ResourceType CefRequestImpl::GetResourceType() { @@ -250,34 +274,41 @@ void CefRequestImpl::Set(net::URLRequest* request) { } } -void CefRequestImpl::Get(net::URLRequest* request) { +void CefRequestImpl::Get(net::URLRequest* request, bool changed_only) const { base::AutoLock lock_scope(lock_); - request->set_method(method_); - if (!first_party_for_cookies_.empty()) { + if (ShouldSet(kChangedMethod, changed_only)) + request->set_method(method_); + + if (!first_party_for_cookies_.empty() && + ShouldSet(kChangedFirstPartyForCookies, changed_only)) { request->set_first_party_for_cookies( GURL(std::string(first_party_for_cookies_))); } - CefString referrerStr; - referrerStr.FromASCII(net::HttpRequestHeaders::kReferer); - HeaderMap headerMap = headermap_; - HeaderMap::iterator it = headerMap.find(referrerStr); - if (it == headerMap.end()) { - request->SetReferrer(""); - } else { - request->SetReferrer(it->second); - headerMap.erase(it); + if (ShouldSet(kChangedHeaderMap, changed_only)) { + CefString referrerStr; + referrerStr.FromASCII(net::HttpRequestHeaders::kReferer); + HeaderMap headerMap = headermap_; + HeaderMap::iterator it = headerMap.find(referrerStr); + if (it == headerMap.end()) { + request->SetReferrer(std::string()); + } else { + request->SetReferrer(it->second); + headerMap.erase(it); + } + net::HttpRequestHeaders headers; + headers.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(headerMap)); + request->SetExtraRequestHeaders(headers); } - net::HttpRequestHeaders headers; - headers.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(headerMap)); - request->SetExtraRequestHeaders(headers); - if (postdata_.get()) { - request->set_upload( - make_scoped_ptr(static_cast(postdata_.get())->Get())); - } else if (request->get_upload()) { - request->set_upload(scoped_ptr()); + if (ShouldSet(kChangedPostData, changed_only)) { + if (postdata_.get()) { + request->set_upload(make_scoped_ptr( + static_cast(postdata_.get())->Get())); + } else if (request->get_upload()) { + request->set_upload(scoped_ptr()); + } } } @@ -333,38 +364,49 @@ void CefRequestImpl::Set(const blink::WebURLRequest& request) { first_party_for_cookies_ = request.firstPartyForCookies().spec().utf16(); } -void CefRequestImpl::Get(blink::WebURLRequest& request) { +void CefRequestImpl::Get(blink::WebURLRequest& request, + bool changed_only) const { request.initialize(); base::AutoLock lock_scope(lock_); - GURL gurl = GURL(url_.ToString()); - request.setURL(blink::WebURL(gurl)); - - std::string method(method_); - request.setHTTPMethod(blink::WebString::fromUTF8(method.c_str())); - - blink::WebHTTPBody body; - if (postdata_.get()) { - body.initialize(); - static_cast(postdata_.get())->Get(body); - request.setHTTPBody(body); + if (ShouldSet(kChangedUrl, changed_only)) { + GURL gurl = GURL(url_.ToString()); + request.setURL(blink::WebURL(gurl)); } - SetHeaderMap(headermap_, request); + if (ShouldSet(kChangedMethod, changed_only)) { + std::string method(method_); + request.setHTTPMethod(blink::WebString::fromUTF8(method.c_str())); + } - request.setCachePolicy((flags_ & UR_FLAG_SKIP_CACHE) ? - blink::WebURLRequest::ReloadIgnoringCacheData : - blink::WebURLRequest::UseProtocolCachePolicy); + if (ShouldSet(kChangedPostData, changed_only)) { + blink::WebHTTPBody body; + if (postdata_.get()) { + body.initialize(); + static_cast(postdata_.get())->Get(body); + request.setHTTPBody(body); + } + } - #define SETBOOLFLAG(obj, flags, method, FLAG) \ - obj.method((flags & (FLAG)) == (FLAG)) + if (ShouldSet(kChangedHeaderMap, changed_only)) + SetHeaderMap(headermap_, request); - SETBOOLFLAG(request, flags_, setAllowStoredCredentials, - UR_FLAG_ALLOW_CACHED_CREDENTIALS); - SETBOOLFLAG(request, flags_, setReportUploadProgress, - UR_FLAG_REPORT_UPLOAD_PROGRESS); + if (ShouldSet(kChangedFlags, changed_only)) { + request.setCachePolicy((flags_ & UR_FLAG_SKIP_CACHE) ? + blink::WebURLRequest::ReloadIgnoringCacheData : + blink::WebURLRequest::UseProtocolCachePolicy); - if (!first_party_for_cookies_.empty()) { + #define SETBOOLFLAG(obj, flags, method, FLAG) \ + obj.method((flags & (FLAG)) == (FLAG)) + + SETBOOLFLAG(request, flags_, setAllowStoredCredentials, + UR_FLAG_ALLOW_CACHED_CREDENTIALS); + SETBOOLFLAG(request, flags_, setReportUploadProgress, + UR_FLAG_REPORT_UPLOAD_PROGRESS); + } + + if (!first_party_for_cookies_.empty() && + ShouldSet(kChangedFirstPartyForCookies, changed_only)) { GURL gurl = GURL(first_party_for_cookies_.ToString()); request.setFirstPartyForCookies(blink::WebURL(gurl)); } @@ -381,6 +423,31 @@ void CefRequestImpl::SetReadOnly(bool read_only) { static_cast(postdata_.get())->SetReadOnly(read_only); } +void CefRequestImpl::SetTrackChanges(bool track_changes) { + base::AutoLock lock_scope(lock_); + if (track_changes_ == track_changes) + return; + + track_changes_ = track_changes; + changes_ = kChangedNone; + + if (postdata_.get()) { + static_cast(postdata_.get())-> + SetTrackChanges(track_changes); + } +} + +uint8 CefRequestImpl::GetChanges() const { + base::AutoLock lock_scope(lock_); + + uint8 changes = changes_; + if (postdata_.get() && + static_cast(postdata_.get())->HasChanges()) { + changes |= kChangedPostData; + } + return changes; +} + // static void CefRequestImpl::GetHeaderMap(const net::HttpRequestHeaders& headers, HeaderMap& map) { @@ -424,6 +491,38 @@ void CefRequestImpl::SetHeaderMap(const HeaderMap& map, base::string16(it->second)); } +void CefRequestImpl::Changed(uint8 changes) { + lock_.AssertAcquired(); + if (track_changes_) + changes_ |= changes; +} + +bool CefRequestImpl::ShouldSet(uint8 changes, bool changed_only) const { + lock_.AssertAcquired(); + + // Always change if changes are not being tracked. + if (!track_changes_) + return true; + + // Always change if changed-only was not requested. + if (!changed_only) + return true; + + // Change if the |changes| bit flag has been set. + if ((changes_ & changes) == changes) + return true; + + if ((changes & kChangedPostData) == kChangedPostData) { + // Change if the post data object was modified directly. + if (postdata_.get() && + static_cast(postdata_.get())->HasChanges()) { + return true; + } + } + + return false; +} + void CefRequestImpl::Reset() { lock_.AssertAcquired(); DCHECK(!read_only_); @@ -437,6 +536,8 @@ void CefRequestImpl::Reset() { identifier_ = 0U; flags_ = UR_FLAG_NONE; first_party_for_cookies_.clear(); + + changes_ = kChangedNone; } // CefPostData ---------------------------------------------------------------- @@ -451,7 +552,9 @@ CefRefPtr CefPostData::Create() { // CefPostDataImpl ------------------------------------------------------------ CefPostDataImpl::CefPostDataImpl() - : read_only_(false) { + : read_only_(false), + track_changes_(false), + has_changes_(false) { } bool CefPostDataImpl::IsReadOnly() { @@ -477,6 +580,7 @@ bool CefPostDataImpl::RemoveElement(CefRefPtr element) { for (; it != elements_.end(); ++it) { if (it->get() == element.get()) { elements_.erase(it); + Changed(); return true; } } @@ -499,8 +603,10 @@ bool CefPostDataImpl::AddElement(CefRefPtr element) { } } - if (!found) + if (!found) { elements_.push_back(element); + Changed(); + } return !found; } @@ -509,6 +615,7 @@ void CefPostDataImpl::RemoveElements() { base::AutoLock lock_scope(lock_); CHECK_READONLY_RETURN_VOID(); elements_.clear(); + Changed(); } void CefPostDataImpl::Set(const net::UploadData& data) { @@ -544,12 +651,13 @@ void CefPostDataImpl::Set(const net::UploadDataStream& data_stream) { for (; it != elements->end(); ++it) { postelem = CefPostDataElement::Create(); static_cast(postelem.get())->Set(**it); - AddElement(postelem); + if (postelem->GetType() != PDE_TYPE_EMPTY) + AddElement(postelem); } } } -void CefPostDataImpl::Get(net::UploadData& data) { +void CefPostDataImpl::Get(net::UploadData& data) const { base::AutoLock lock_scope(lock_); ScopedVector data_elements; @@ -562,7 +670,7 @@ void CefPostDataImpl::Get(net::UploadData& data) { data.swap_elements(&data_elements); } -net::UploadDataStream* CefPostDataImpl::Get() { +net::UploadDataStream* CefPostDataImpl::Get() const { base::AutoLock lock_scope(lock_); ScopedVector element_readers; @@ -593,11 +701,11 @@ void CefPostDataImpl::Set(const blink::WebHTTPBody& data) { } } -void CefPostDataImpl::Get(blink::WebHTTPBody& data) { +void CefPostDataImpl::Get(blink::WebHTTPBody& data) const { base::AutoLock lock_scope(lock_); blink::WebHTTPBody::Element element; - ElementVector::iterator it = elements_.begin(); + ElementVector::const_iterator it = elements_.begin(); for (; it != elements_.end(); ++it) { static_cast(it->get())->Get(element); if (element.type == blink::WebHTTPBody::Element::TypeData) { @@ -623,6 +731,42 @@ void CefPostDataImpl::SetReadOnly(bool read_only) { } } +void CefPostDataImpl::SetTrackChanges(bool track_changes) { + base::AutoLock lock_scope(lock_); + if (track_changes_ == track_changes) + return; + + track_changes_ = track_changes; + has_changes_ = false; + + ElementVector::const_iterator it = elements_.begin(); + for (; it != elements_.end(); ++it) { + static_cast(it->get())-> + SetTrackChanges(track_changes); + } +} + +bool CefPostDataImpl::HasChanges() const { + base::AutoLock lock_scope(lock_); + if (has_changes_) + return true; + + ElementVector::const_iterator it = elements_.begin(); + for (; it != elements_.end(); ++it) { + if (static_cast(it->get())->HasChanges()) + return true; + } + + return false; +} + +void CefPostDataImpl::Changed() { + lock_.AssertAcquired(); + if (track_changes_ && !has_changes_) + has_changes_ = true; +} + + // CefPostDataElement --------------------------------------------------------- // static @@ -636,7 +780,9 @@ CefRefPtr CefPostDataElement::Create() { CefPostDataElementImpl::CefPostDataElementImpl() : type_(PDE_TYPE_EMPTY), - read_only_(false) { + read_only_(false), + track_changes_(false), + has_changes_(false) { memset(&data_, 0, sizeof(data_)); } @@ -654,6 +800,7 @@ void CefPostDataElementImpl::SetToEmpty() { CHECK_READONLY_RETURN_VOID(); Cleanup(); + Changed(); } void CefPostDataElementImpl::SetToFile(const CefString& fileName) { @@ -666,6 +813,8 @@ void CefPostDataElementImpl::SetToFile(const CefString& fileName) { // Assign the new data type_ = PDE_TYPE_FILE; cef_string_copy(fileName.c_str(), fileName.length(), &data_.filename); + + Changed(); } void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes) { @@ -686,6 +835,8 @@ void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes) { type_ = PDE_TYPE_BYTES; data_.bytes.bytes = data; data_.bytes.size = size; + + Changed(); } CefPostDataElement::Type CefPostDataElementImpl::GetType() { @@ -758,10 +909,11 @@ void CefPostDataElementImpl::Set( return; } - NOTREACHED(); + // Chunked uploads cannot currently be represented. + SetToEmpty(); } -void CefPostDataElementImpl::Get(net::UploadElement& element) { +void CefPostDataElementImpl::Get(net::UploadElement& element) const { base::AutoLock lock_scope(lock_); if (type_ == PDE_TYPE_BYTES) { @@ -774,7 +926,7 @@ void CefPostDataElementImpl::Get(net::UploadElement& element) { } } -net::UploadElementReader* CefPostDataElementImpl::Get() { +net::UploadElementReader* CefPostDataElementImpl::Get() const { base::AutoLock lock_scope(lock_); if (type_ == PDE_TYPE_BYTES) { @@ -809,7 +961,7 @@ void CefPostDataElementImpl::Set(const blink::WebHTTPBody::Element& element) { } } -void CefPostDataElementImpl::Get(blink::WebHTTPBody::Element& element) { +void CefPostDataElementImpl::Get(blink::WebHTTPBody::Element& element) const { base::AutoLock lock_scope(lock_); if (type_ == PDE_TYPE_BYTES) { @@ -832,6 +984,26 @@ void CefPostDataElementImpl::SetReadOnly(bool read_only) { read_only_ = read_only; } +void CefPostDataElementImpl::SetTrackChanges(bool track_changes) { + base::AutoLock lock_scope(lock_); + if (track_changes_ == track_changes) + return; + + track_changes_ = track_changes; + has_changes_ = false; +} + +bool CefPostDataElementImpl::HasChanges() const { + base::AutoLock lock_scope(lock_); + return has_changes_; +} + +void CefPostDataElementImpl::Changed() { + lock_.AssertAcquired(); + if (track_changes_ && !has_changes_) + has_changes_ = true; +} + void CefPostDataElementImpl::Cleanup() { if (type_ == PDE_TYPE_EMPTY) return; diff --git a/libcef/common/request_impl.h b/libcef/common/request_impl.h index c96090716..47ef9e5d8 100644 --- a/libcef/common/request_impl.h +++ b/libcef/common/request_impl.h @@ -31,6 +31,16 @@ class WebURLRequest; // Implementation of CefRequest class CefRequestImpl : public CefRequest { public: + enum Changes { + kChangedNone = 0, + kChangedUrl = 1 << 0, + kChangedMethod = 1 << 1, + kChangedPostData = 1 << 2, + kChangedHeaderMap = 1 << 3, + kChangedFlags = 1 << 4, + kChangedFirstPartyForCookies = 1 << 5, + }; + CefRequestImpl(); bool IsReadOnly() override; @@ -58,7 +68,8 @@ class CefRequestImpl : public CefRequest { void Set(net::URLRequest* request); // Populate the URLRequest object from this object. - void Get(net::URLRequest* request); + // If |changed_only| is true then only the changed fields will be updated. + void Get(net::URLRequest* request, bool changed_only) const; // Populate this object from the NavigationParams object. // TODO(cef): Remove the |is_main_frame| argument once NavigationParams is @@ -70,10 +81,14 @@ class CefRequestImpl : public CefRequest { void Set(const blink::WebURLRequest& request); // Populate the WebURLRequest object from this object. - void Get(blink::WebURLRequest& request); + // If |changed_only| is true then only the changed fields will be updated. + void Get(blink::WebURLRequest& request, bool changed_only) const; void SetReadOnly(bool read_only); + void SetTrackChanges(bool track_changes); + uint8 GetChanges() const; + static void GetHeaderMap(const net::HttpRequestHeaders& headers, HeaderMap& map); static void GetHeaderMap(const blink::WebURLRequest& request, @@ -82,6 +97,9 @@ class CefRequestImpl : public CefRequest { blink::WebURLRequest& request); private: + void Changed(uint8 changes); + bool ShouldSet(uint8 changes, bool changed_only) const; + void Reset(); CefString url_; @@ -99,7 +117,13 @@ class CefRequestImpl : public CefRequest { // True if this object is read-only. bool read_only_; - base::Lock lock_; + // True if this object should track changes. + bool track_changes_; + + // Bitmask of |Changes| values which indicate which fields have changed. + uint8 changes_; + + mutable base::Lock lock_; IMPLEMENT_REFCOUNTING(CefRequestImpl); }; @@ -118,20 +142,31 @@ class CefPostDataImpl : public CefPostData { void Set(const net::UploadData& data); void Set(const net::UploadDataStream& data_stream); - void Get(net::UploadData& data); - net::UploadDataStream* Get(); + void Get(net::UploadData& data) const; + net::UploadDataStream* Get() const; void Set(const blink::WebHTTPBody& data); - void Get(blink::WebHTTPBody& data); + void Get(blink::WebHTTPBody& data) const; void SetReadOnly(bool read_only); + void SetTrackChanges(bool track_changes); + bool HasChanges() const; + private: + void Changed(); + ElementVector elements_; // True if this object is read-only. bool read_only_; - base::Lock lock_; + // True if this object should track changes. + bool track_changes_; + + // True if this object has changes. + bool has_changes_; + + mutable base::Lock lock_; IMPLEMENT_REFCOUNTING(CefPostDataImpl); }; @@ -155,14 +190,18 @@ class CefPostDataElementImpl : public CefPostDataElement { void Set(const net::UploadElement& element); void Set(const net::UploadElementReader& element_reader); - void Get(net::UploadElement& element); - net::UploadElementReader* Get(); + void Get(net::UploadElement& element) const; + net::UploadElementReader* Get() const; void Set(const blink::WebHTTPBody::Element& element); - void Get(blink::WebHTTPBody::Element& element); + void Get(blink::WebHTTPBody::Element& element) const; void SetReadOnly(bool read_only); + void SetTrackChanges(bool track_changes); + bool HasChanges() const; + private: + void Changed(); void Cleanup(); Type type_; @@ -177,7 +216,13 @@ class CefPostDataElementImpl : public CefPostDataElement { // True if this object is read-only. bool read_only_; - base::Lock lock_; + // True if this object should track changes. + bool track_changes_; + + // True if this object has changes. + bool has_changes_; + + mutable base::Lock lock_; IMPLEMENT_REFCOUNTING(CefPostDataElementImpl); }; diff --git a/libcef/renderer/render_urlrequest_impl.cc b/libcef/renderer/render_urlrequest_impl.cc index e71a00b9b..742d3e726 100644 --- a/libcef/renderer/render_urlrequest_impl.cc +++ b/libcef/renderer/render_urlrequest_impl.cc @@ -107,7 +107,7 @@ class CefRenderURLRequest::Context url_client_.reset(new CefWebURLLoaderClient(this, request_->GetFlags())); WebURLRequest urlRequest; - static_cast(request_.get())->Get(urlRequest); + static_cast(request_.get())->Get(urlRequest, false); if (urlRequest.reportUploadProgress()) { // Attempt to determine the upload data size.