| Index: webkit/glue/resource_handle_win.cc
|
| ===================================================================
|
| --- webkit/glue/resource_handle_win.cc (revision 3423)
|
| +++ webkit/glue/resource_handle_win.cc (working copy)
|
| @@ -1,742 +0,0 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -//
|
| -// This file replaces WebCore/platform/network/win/ResourceHandleWin.cpp with a
|
| -// platform-neutral implementation that simply defers almost entirely to
|
| -// ResouceLoaderBridge.
|
| -//
|
| -// This uses the same ResourceHandle.h header file that the rest of WebKit
|
| -// uses, allowing us to avoid complicated changes. Our specific things are
|
| -// added on ResourceHandleInternal. The ResourceHandle owns the
|
| -// ResourceHandleInternal and passes off almost all processing to it.
|
| -//
|
| -// The WebKit version of this code keeps the ResourceHandle AddRef'd when
|
| -// there are any callbacks. This prevents the callbacks from occuring into
|
| -// destroyed objects. However, our destructors should always stop callbacks
|
| -// from happening, making this (hopefully) unnecessary.
|
| -//
|
| -// We preserve this behavior for safety. A client could count on this behavior
|
| -// and fire off a request, release it, and wait for callbacks to get the data
|
| -// as long as it doesn't care about canceling the request. Although this is
|
| -// dumb, we support it. We use pending_ to indicate this extra AddRef, which
|
| -// is done in start() and released in OnCompletedRequest.
|
| -
|
| -#include "config.h"
|
| -
|
| -#pragma warning(push, 0)
|
| -#include "CString.h"
|
| -#include "Console.h"
|
| -#include "DocLoader.h"
|
| -#include "DOMWindow.h"
|
| -#include "FormData.h"
|
| -#include "FrameLoader.h"
|
| -#include "LogWin.h"
|
| -#include "Page.h"
|
| -#include "ResourceError.h"
|
| -#include "ResourceHandle.h"
|
| -#include "ResourceHandleClient.h"
|
| -#include "ResourceRequest.h"
|
| -#include "ResourceResponse.h"
|
| -#pragma warning(pop)
|
| -
|
| -#undef LOG
|
| -#include "base/logging.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/process_util.h"
|
| -#include "base/time.h"
|
| -#include "base/string_util.h"
|
| -#include "base/string_tokenizer.h"
|
| -#include "webkit/glue/feed_preview.h"
|
| -#include "webkit/glue/glue_util.h"
|
| -#include "webkit/glue/multipart_response_delegate.h"
|
| -#include "webkit/glue/resource_loader_bridge.h"
|
| -#include "webkit/glue/webframe_impl.h"
|
| -#include "net/base/data_url.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_util.h"
|
| -#include "net/base/load_flags.h"
|
| -
|
| -using webkit_glue::ResourceLoaderBridge;
|
| -using net::HttpResponseHeaders;
|
| -
|
| -namespace {
|
| -
|
| -// Extracts the information from a data: url.
|
| -bool GetInfoFromDataUrl(const GURL& url,
|
| - ResourceLoaderBridge::ResponseInfo* info,
|
| - std::string* data, URLRequestStatus* status) {
|
| - std::string mime_type;
|
| - std::string charset;
|
| - if (net::DataURL::Parse(url, &mime_type, &charset, data)) {
|
| - info->request_time = Time::Now();
|
| - info->response_time = Time::Now();
|
| - info->mime_type.swap(mime_type);
|
| - info->charset.swap(charset);
|
| - *status = URLRequestStatus(URLRequestStatus::SUCCESS, 0);
|
| - return true;
|
| - }
|
| -
|
| - *status = URLRequestStatus(URLRequestStatus::FAILED, net::ERR_INVALID_URL);
|
| - return false;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -namespace WebCore {
|
| -
|
| -static void ExtractInfoFromHeaders(const HttpResponseHeaders* headers,
|
| - HTTPHeaderMap* header_map,
|
| - int* status_code,
|
| - String* status_text,
|
| - long long* expected_content_length) {
|
| - *status_code = headers->response_code();
|
| -
|
| - // Set the status text
|
| - *status_text = webkit_glue::StdStringToString(headers->GetStatusText());
|
| -
|
| - // Set the content length.
|
| - std::string length_val;
|
| - if (headers->EnumerateHeader(NULL, "content-length", &length_val))
|
| - *expected_content_length = StringToInt64(length_val);
|
| -
|
| - // Build up the header map. Take care with duplicate headers.
|
| - void* iter = NULL;
|
| - std::string name, value;
|
| - while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
|
| - String name_str = webkit_glue::StdStringToString(name);
|
| - String value_str = webkit_glue::StdStringToString(value);
|
| -
|
| - pair<HTTPHeaderMap::iterator, bool> result =
|
| - header_map->add(name_str, value_str);
|
| - if (!result.second)
|
| - result.first->second += ", " + value_str;
|
| - }
|
| -}
|
| -
|
| -static ResourceResponse MakeResourceResponse(
|
| - const KURL& kurl,
|
| - const ResourceLoaderBridge::ResponseInfo& info) {
|
| - int status_code = 0;
|
| - long long expected_content_length = info.content_length;
|
| - String status_text;
|
| - HTTPHeaderMap header_map;
|
| -
|
| - // It's okay if there are no headers
|
| - if (info.headers)
|
| - ExtractInfoFromHeaders(info.headers,
|
| - &header_map,
|
| - &status_code,
|
| - &status_text,
|
| - &expected_content_length);
|
| -
|
| - // TODO(darin): We should leverage HttpResponseHeaders for this, and this
|
| - // should be using the same code as ResourceDispatcherHost.
|
| - std::wstring suggested_filename;
|
| - if (info.headers) {
|
| - std::string disp_val;
|
| - if (info.headers->EnumerateHeader(NULL, "content-disposition", &disp_val)) {
|
| - suggested_filename = net::GetSuggestedFilename(
|
| - webkit_glue::KURLToGURL(kurl), disp_val, std::wstring());
|
| - }
|
| - }
|
| -
|
| - ResourceResponse response(kurl,
|
| - webkit_glue::StdStringToString(info.mime_type),
|
| - expected_content_length,
|
| - webkit_glue::StdStringToString(info.charset),
|
| - webkit_glue::StdWStringToString(suggested_filename));
|
| -
|
| - if (info.headers) {
|
| - Time time_val;
|
| - if (info.headers->GetLastModifiedValue(&time_val))
|
| - response.setLastModifiedDate(time_val.ToTimeT());
|
| -
|
| - // Compute expiration date
|
| - TimeDelta freshness_lifetime =
|
| - info.headers->GetFreshnessLifetime(info.response_time);
|
| - if (freshness_lifetime != TimeDelta()) {
|
| - Time now = Time::Now();
|
| - TimeDelta current_age =
|
| - info.headers->GetCurrentAge(info.request_time, info.response_time,
|
| - now);
|
| - time_val = now + freshness_lifetime - current_age;
|
| -
|
| - response.setExpirationDate(time_val.ToTimeT());
|
| - } else {
|
| - // WebKit uses 0 as a special expiration date that means never expire.
|
| - // 1 is a small enough value to let it always expire.
|
| - response.setExpirationDate(1);
|
| - }
|
| - }
|
| -
|
| - response.setHTTPStatusCode(status_code);
|
| - response.setHTTPStatusText(status_text);
|
| - response.setSecurityInfo(webkit_glue::StdStringToCString(info.security_info));
|
| -
|
| - // WebKit doesn't provide a way for us to set expected content length after
|
| - // calling the constructor, so we parse the headers first and then swap in
|
| - // our HTTP header map. Ideally we would like a setter for expected content
|
| - // length (perhaps by abstracting ResourceResponse interface into
|
| - // ResourceResponseBase) but that would require forking.
|
| - const_cast<HTTPHeaderMap*>(&response.httpHeaderFields())->swap(header_map);
|
| -
|
| - return response;
|
| -}
|
| -
|
| -class ResourceHandleInternal : public ResourceLoaderBridge::Peer {
|
| - public:
|
| - ResourceHandleInternal(ResourceHandle* job, const ResourceRequest& r,
|
| - ResourceHandleClient* c);
|
| - ~ResourceHandleInternal();
|
| -
|
| - // If the response parameter is null, then an asynchronous load is started.
|
| - bool Start(ResourceLoaderBridge::SyncLoadResponse* response);
|
| -
|
| - // Used to cancel an asynchronous load.
|
| - void Cancel();
|
| -
|
| - // Used to suspend/resume an asynchronous load.
|
| - void SetDefersLoading(bool value);
|
| -
|
| - // ResourceLoaderBridge::Peer implementation
|
| - virtual void OnReceivedRedirect(const GURL& new_url);
|
| - virtual void OnReceivedResponse(
|
| - const ResourceLoaderBridge::ResponseInfo& info,
|
| - bool content_filtered);
|
| - virtual void OnReceivedData(const char* data, int len);
|
| - virtual void OnCompletedRequest(const URLRequestStatus& status);
|
| - virtual std::string GetURLForDebugging();
|
| -
|
| - // Handles a data: url internally instead of calling the bridge.
|
| - void HandleDataUrl();
|
| -
|
| - // This is the bridge implemented by the embedder.
|
| - // The bridge is kept alive as long as the request is valid and we
|
| - // are ready for callbacks.
|
| - scoped_ptr<ResourceLoaderBridge> bridge_;
|
| -
|
| - // The resource loader that owns us
|
| - ResourceHandle* job_;
|
| -
|
| - // This is the object that receives various status messages (such as when the
|
| - // loader has received data). See definition for the exact messages that are
|
| - // sent to it.
|
| - ResourceHandleClient* client_;
|
| -
|
| - ResourceRequest request_;
|
| -
|
| - // Runnable Method Factory used to invoke later HandleDataUrl().
|
| - ScopedRunnableMethodFactory<ResourceHandleInternal> data_url_factory_;
|
| -
|
| - int load_flags_;
|
| -
|
| - private:
|
| - // Set to true when we're waiting for data from the bridge, also indicating
|
| - // we have addrefed our job.
|
| - bool pending_;
|
| -
|
| - // Expected content length of the response
|
| - long long expected_content_length_;
|
| -
|
| - // NULL unless we are handling a multipart/x-mixed-replace request
|
| - scoped_ptr<MultipartResponseDelegate> multipart_delegate_;
|
| -
|
| - // NULL unless we are handling a feed:// request.
|
| - scoped_ptr<FeedClientProxy> feed_client_proxy_;
|
| -};
|
| -
|
| -ResourceHandleInternal::ResourceHandleInternal(ResourceHandle* job,
|
| - const ResourceRequest& r,
|
| - ResourceHandleClient* c)
|
| - : job_(job),
|
| - client_(c),
|
| - request_(r),
|
| -MSVC_SUPPRESS_WARNING(4355) // can use this
|
| - data_url_factory_(this),
|
| - load_flags_(net::LOAD_NORMAL),
|
| - pending_(false),
|
| - expected_content_length_(-1),
|
| - multipart_delegate_(NULL) {
|
| -}
|
| -
|
| -ResourceHandleInternal::~ResourceHandleInternal() {
|
| - DCHECK(!pending_);
|
| -}
|
| -
|
| -void ResourceHandleInternal::HandleDataUrl() {
|
| - ResourceLoaderBridge::ResponseInfo info;
|
| - URLRequestStatus status;
|
| - std::string data;
|
| -
|
| - if (GetInfoFromDataUrl(webkit_glue::KURLToGURL(request_.url()), &info, &data,
|
| - &status)) {
|
| - OnReceivedResponse(info, false);
|
| -
|
| - if (data.size())
|
| - OnReceivedData(data.c_str(), data.size());
|
| - }
|
| -
|
| - OnCompletedRequest(status);
|
| -
|
| - // We are done using the object. ResourceHandle and ResourceHandleInternal
|
| - // might be destroyed now.
|
| - job_->deref();
|
| -}
|
| -
|
| -bool ResourceHandleInternal::Start(
|
| - ResourceLoaderBridge::SyncLoadResponse* sync_load_response) {
|
| - DCHECK(!bridge_.get());
|
| -
|
| - // The WebFrame is the Frame's FrameWinClient
|
| - WebFrameImpl* webframe =
|
| - request_.frame() ? WebFrameImpl::FromFrame(request_.frame()) : NULL;
|
| -
|
| - CString method = request_.httpMethod().latin1();
|
| - GURL referrer(webkit_glue::StringToStdString(request_.httpReferrer()));
|
| -
|
| - // Compute the URL of the load.
|
| - GURL url = webkit_glue::KURLToGURL(request_.url());
|
| - if (url.SchemeIs("feed:")) {
|
| - // Feed URLs are special, they actually mean "http".
|
| - url_canon::Replacements<char> replacements;
|
| - replacements.SetScheme("http", url_parse::Component(0, 4));
|
| - url = url.ReplaceComponents(replacements);
|
| -
|
| - // Replace our client with a client that understands previewing feeds
|
| - // and forwards the feeds along to the original client.
|
| - feed_client_proxy_.reset(new FeedClientProxy(client_));
|
| - client_ = feed_client_proxy_.get();
|
| - }
|
| -
|
| - // Inherit the policy URL from the request's frame. However, if the request
|
| - // is for a main frame, the current document's policyBaseURL is the old
|
| - // document, so we leave policyURL empty to indicate that the request is a
|
| - // first-party request.
|
| - GURL policy_url;
|
| - if (request_.resourceType() != ResourceType::MAIN_FRAME &&
|
| - request_.frame() && request_.frame()->document()) {
|
| - policy_url = GURL(webkit_glue::StringToStdString(
|
| - request_.frame()->document()->policyBaseURL()));
|
| - }
|
| -
|
| - // Translate the table of request headers to a formatted string blob
|
| - String headerBuf;
|
| - const HTTPHeaderMap& headerMap = request_.httpHeaderFields();
|
| -
|
| - // In some cases, WebCore doesn't add an Accept header, but not having the
|
| - // header confuses some web servers. See bug 808613.
|
| - // Note: headerMap uses case-insenstive keys, so this will find Accept as
|
| - // as well.
|
| - if (!headerMap.contains("accept"))
|
| - request_.addHTTPHeaderField("Accept", "*/*");
|
| -
|
| - const String crlf("\r\n");
|
| - const String sep(": ");
|
| - for (HTTPHeaderMap::const_iterator it = headerMap.begin();
|
| - it != headerMap.end(); ++it) {
|
| - // Skip over referrer headers found in the header map because we already
|
| - // pulled it out as a separate parameter. We likewise prune the UA since
|
| - // that will be added back by the network layer.
|
| - if (equalIgnoringCase((*it).first, "referer") ||
|
| - equalIgnoringCase((*it).first, "user-agent"))
|
| - continue;
|
| - // WinInet dies if blank headers are set. TODO(darin): Is this still an
|
| - // issue now that we are using WinHTTP?
|
| - if ((*it).first.isEmpty()) {
|
| - webframe->frame()->domWindow()->console()->addMessage(
|
| - JSMessageSource,
|
| - ErrorMessageLevel,
|
| - "Refused to set blank header",
|
| - 1,
|
| - String());
|
| - continue;
|
| - }
|
| - if (!headerBuf.isEmpty())
|
| - headerBuf.append(crlf);
|
| - headerBuf.append((*it).first + sep + (*it).second);
|
| - }
|
| -
|
| - switch (request_.cachePolicy()) {
|
| - case ReloadIgnoringCacheData:
|
| - // Required by LayoutTests/http/tests/misc/refresh-headers.php
|
| - load_flags_ |= net::LOAD_VALIDATE_CACHE;
|
| - break;
|
| - case ReturnCacheDataElseLoad:
|
| - load_flags_ |= net::LOAD_PREFERRING_CACHE;
|
| - break;
|
| - case ReturnCacheDataDontLoad:
|
| - load_flags_ |= net::LOAD_ONLY_FROM_CACHE;
|
| - break;
|
| - case UseProtocolCachePolicy:
|
| - break;
|
| - }
|
| -
|
| - // TODO(jcampan): in the non out-of-process plugin case the request does not
|
| - // have a origin_pid. Find a better place to set this.
|
| - int origin_pid = request_.originPid();
|
| - if (origin_pid == 0)
|
| - origin_pid = process_util::GetCurrentProcId();
|
| -
|
| - bool mixed_content =
|
| - webkit_glue::KURLToGURL(request_.mainDocumentURL()).SchemeIsSecure() &&
|
| - !url.SchemeIsSecure();
|
| -
|
| - if (url.SchemeIs("data")) {
|
| - if (sync_load_response) {
|
| - // This is a sync load. Do the work now.
|
| - sync_load_response->url = url;
|
| - std::string data;
|
| - GetInfoFromDataUrl(sync_load_response->url, sync_load_response,
|
| - &sync_load_response->data,
|
| - &sync_load_response->status);
|
| - } else {
|
| - pending_ = true;
|
| - job_->ref(); // to be released when we get a OnCompletedRequest.
|
| - job_->ref(); // to be released when HandleDataUrl is completed.
|
| - MessageLoop::current()->PostTask(FROM_HERE,
|
| - data_url_factory_.NewRunnableMethod(
|
| - &ResourceHandleInternal::HandleDataUrl));
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - // TODO(darin): is latin1 really correct here? It is if the strings are
|
| - // already ASCII (i.e., if they are already escaped properly).
|
| - // TODO(brettw) this should take parameter encoding into account when
|
| - // creating the GURLs.
|
| - bridge_.reset(ResourceLoaderBridge::Create(
|
| - webframe,
|
| - webkit_glue::CStringToStdString(method),
|
| - url,
|
| - policy_url,
|
| - referrer,
|
| - webkit_glue::CStringToStdString(headerBuf.latin1()),
|
| - load_flags_,
|
| - origin_pid,
|
| - request_.resourceType(),
|
| - mixed_content));
|
| - if (!bridge_.get())
|
| - return false;
|
| -
|
| - if (request_.httpBody()) {
|
| - // GET and HEAD requests shouldn't have http bodies.
|
| - DCHECK(method != "GET" && method != "HEAD");
|
| - const Vector<FormDataElement>& elements = request_.httpBody()->elements();
|
| - size_t n = elements.size();
|
| - for (size_t i = 0; i < n; ++i) {
|
| - const FormDataElement& e = elements[static_cast<unsigned>(i)];
|
| - if (e.m_type == FormDataElement::data) {
|
| - if (e.m_data.size() > 0) {
|
| - // WebKit sometimes gives up empty data to append. These aren't
|
| - // necessary so we just optimize those out here.
|
| - bridge_->AppendDataToUpload(e.m_data.data(),
|
| - static_cast<int>(e.m_data.size()));
|
| - }
|
| - } else {
|
| - bridge_->AppendFileToUpload(
|
| - webkit_glue::StringToStdWString(e.m_filename));
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (sync_load_response) {
|
| - bridge_->SyncLoad(sync_load_response);
|
| - return true;
|
| - }
|
| -
|
| - bool rv = bridge_->Start(this);
|
| - if (rv) {
|
| - pending_ = true;
|
| - job_->ref(); // to be released when we get a OnCompletedRequest.
|
| - } else {
|
| - bridge_.reset();
|
| - }
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -void ResourceHandleInternal::Cancel() {
|
| - // The bridge will still send OnCompletedRequest, which will deref() us,
|
| - // so we don't do that here.
|
| - if (bridge_.get())
|
| - bridge_->Cancel();
|
| -
|
| - // Ensure that we do not notify the multipart delegate anymore as it has
|
| - // its own pointer to the client.
|
| - multipart_delegate_.reset();
|
| -
|
| - // Do not make any further calls to the client.
|
| - client_ = NULL;
|
| -}
|
| -
|
| -void ResourceHandleInternal::SetDefersLoading(bool value) {
|
| - if (bridge_.get())
|
| - bridge_->SetDefersLoading(value);
|
| -}
|
| -
|
| -// ResourceLoaderBridge::Peer impl --------------------------------------------
|
| -
|
| -void ResourceHandleInternal::OnReceivedRedirect(const GURL& new_url) {
|
| - DCHECK(pending_);
|
| -
|
| - KURL url = webkit_glue::GURLToKURL(new_url);
|
| -
|
| - // TODO(darin): need a way to properly initialize a ResourceResponse
|
| - ResourceResponse response(request_.url(), String(), -1, String(), String());
|
| -
|
| - ResourceRequest new_request(url);
|
| -
|
| - // TODO(darin): we need to setup new_request to reflect the fact that we
|
| - // for example drop the httpBody when following a POST request that is
|
| - // redirected to a GET request.
|
| -
|
| - if (client_)
|
| - client_->willSendRequest(job_, new_request, response);
|
| -
|
| - //
|
| - // TODO(darin): since new_request is sent as a mutable reference, it is
|
| - // possible that willSendRequest may expect to be able to modify it.
|
| - //
|
| - // andresca on #webkit confirms that that is intentional, so we'll need
|
| - // to rework the ResourceLoaderBridge to give us control over what URL
|
| - // is really loaded (and with what headers) when a redirect is encountered.
|
| - //
|
| -
|
| - request_ = new_request;
|
| -}
|
| -
|
| -void ResourceHandleInternal::OnReceivedResponse(
|
| - const ResourceLoaderBridge::ResponseInfo& info,
|
| - bool content_filtered) {
|
| - DCHECK(pending_);
|
| -
|
| - // TODO(darin): need a way to properly initialize a ResourceResponse
|
| - ResourceResponse response = MakeResourceResponse(request_.url(), info);
|
| - response.setIsContentFiltered(content_filtered);
|
| -
|
| - expected_content_length_ = response.expectedContentLength();
|
| -
|
| - if (client_)
|
| - client_->didReceiveResponse(job_, response);
|
| -
|
| - // we may have been cancelled after didReceiveResponse, which would leave us
|
| - // without a client and therefore without much need to do multipart handling.
|
| -
|
| - DCHECK(!multipart_delegate_.get());
|
| - if (client_ && info.headers && response.isMultipart()) {
|
| - std::string content_type;
|
| - info.headers->EnumerateHeader(NULL, "content-type", &content_type);
|
| -
|
| - std::string boundary = net::GetHeaderParamValue(content_type, "boundary");
|
| - TrimString(boundary, " \"", &boundary);
|
| - // If there's no boundary, just handle the request normally. In the gecko
|
| - // code, nsMultiMixedConv::OnStartRequest throws an exception.
|
| - if (!boundary.empty()) {
|
| - multipart_delegate_.reset(new MultipartResponseDelegate(client_, job_,
|
| - response, boundary));
|
| - }
|
| - }
|
| -
|
| - // TODO(darin): generate willCacheResponse callback. debug mac webkit to
|
| - // determine when it should be called.
|
| -}
|
| -
|
| -void ResourceHandleInternal::OnReceivedData(const char* data, int data_len) {
|
| - DCHECK(pending_);
|
| -
|
| - if (client_) {
|
| - // TODO(darin): figure out what to pass for lengthReceived. from reading
|
| - // the loader code, it looks like this is supposed to be the content-length
|
| - // value, but it seems really wacky to include that here! we have to debug
|
| - // webkit on mac to figure out what this should be.
|
| -
|
| - // TODO(jackson): didReceiveData expects an int, but an expected content
|
| - // length is an int64, so we do our best to fit it inside an int. The only
|
| - // code that cares currently about this value is the Inspector, so beware
|
| - // that the Inspector's network panel might under-represent the size of
|
| - // some resources if they're larger than a gigabyte.
|
| - int lengthReceived = static_cast<int>(expected_content_length_);
|
| - if (lengthReceived != expected_content_length_) // overflow occurred
|
| - lengthReceived = -1;
|
| -
|
| - if (!multipart_delegate_.get()) {
|
| - client_->didReceiveData(job_, data, data_len, lengthReceived);
|
| - } else {
|
| - // AddData will make the appropriate calls to client_->didReceiveData
|
| - // and client_->didReceiveResponse
|
| - multipart_delegate_->OnReceivedData(data, data_len);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ResourceHandleInternal::OnCompletedRequest(
|
| - const URLRequestStatus& status) {
|
| - if (multipart_delegate_.get()) {
|
| - multipart_delegate_->OnCompletedRequest();
|
| - multipart_delegate_.reset(NULL);
|
| - }
|
| -
|
| - pending_ = false;
|
| -
|
| - if (client_) {
|
| - if (status.status() != URLRequestStatus::SUCCESS) {
|
| - int error_code;
|
| - if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) {
|
| - // By marking this request as aborted we insure that we don't navigate
|
| - // to an error page.
|
| - error_code = net::ERR_ABORTED;
|
| - } else {
|
| - error_code = status.os_error();
|
| - }
|
| - // TODO(tc): fill in these fields properly
|
| - ResourceError error(net::kErrorDomain,
|
| - error_code,
|
| - request_.url().string(),
|
| - String() /*localized description*/);
|
| - client_->didFail(job_, error);
|
| - } else {
|
| - client_->didFinishLoading(job_);
|
| - }
|
| - }
|
| -
|
| - job_->deref(); // may destroy our owner and hence |this|
|
| -}
|
| -
|
| -std::string ResourceHandleInternal::GetURLForDebugging() {
|
| - return webkit_glue::CStringToStdString(request_.url().string().latin1());
|
| -}
|
| -
|
| -// ResourceHandle -------------------------------------------------------------
|
| -
|
| -ResourceHandle::ResourceHandle(const ResourceRequest& request,
|
| - ResourceHandleClient* client,
|
| - bool defersLoading,
|
| - bool shouldContentSniff,
|
| - bool mightDownloadFromHandle)
|
| -MSVC_SUPPRESS_WARNING(4355) // it's okay to pass |this| here!
|
| - : d(new ResourceHandleInternal(this, request, client)) {
|
| - // TODO(darin): figure out what to do with the two bool params
|
| -}
|
| -
|
| -PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request,
|
| - ResourceHandleClient* client,
|
| - Frame* deprecated,
|
| - bool defersLoading,
|
| - bool shouldContentSniff,
|
| - bool mightDownloadFromHandle) {
|
| - RefPtr<ResourceHandle> newHandle =
|
| - adoptRef(new ResourceHandle(request, client, defersLoading,
|
| - shouldContentSniff, mightDownloadFromHandle));
|
| -
|
| - if (newHandle->start(NULL))
|
| - return newHandle.release();
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -const ResourceRequest& ResourceHandle::request() const {
|
| - return d->request_;
|
| -}
|
| -
|
| -ResourceHandleClient* ResourceHandle::client() const {
|
| - return d->client_;
|
| -}
|
| -
|
| -void ResourceHandle::setClient(ResourceHandleClient* client) {
|
| - d->client_ = client;
|
| -}
|
| -
|
| -void ResourceHandle::setDefersLoading(bool value) {
|
| - d->SetDefersLoading(value);
|
| -}
|
| -
|
| -bool ResourceHandle::start(Frame* deprecated) {
|
| - return d->Start(NULL);
|
| -}
|
| -
|
| -void ResourceHandle::clearAuthentication() {
|
| - // TODO(darin): do something here. it looks like the ResourceLoader calls
|
| - // this method when it is canceled. i have no idea why it does this.
|
| -}
|
| -
|
| -void ResourceHandle::cancel() {
|
| - d->Cancel();
|
| -}
|
| -
|
| -ResourceHandle::~ResourceHandle() {
|
| -}
|
| -
|
| -PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() {
|
| - return NULL;
|
| -}
|
| -
|
| -/*static*/ bool ResourceHandle::loadsBlocked() {
|
| - return false; // this seems to be related to sync XMLHttpRequest...
|
| -}
|
| -
|
| -/*static*/ bool ResourceHandle::supportsBufferedData() {
|
| - return false; // the loader will buffer manually if it needs to
|
| -}
|
| -
|
| -/*static*/ void ResourceHandle::loadResourceSynchronously(
|
| - const ResourceRequest& request, ResourceError& error,
|
| - ResourceResponse& response, Vector<char>& data, Frame*) {
|
| -
|
| - RefPtr<ResourceHandle> handle =
|
| - new ResourceHandle(request, NULL, false, false, false);
|
| -
|
| - ResourceLoaderBridge::SyncLoadResponse sync_load_response;
|
| - if (!handle->d->Start(&sync_load_response)) {
|
| - response =
|
| - ResourceResponse(request.url(), String(), 0, String(), String());
|
| - // TODO(darin): what should the error code really be?
|
| - error = ResourceError(net::kErrorDomain,
|
| - net::ERR_FAILED,
|
| - request.url().string(),
|
| - String() /* localized description */);
|
| - return;
|
| - }
|
| -
|
| - KURL kurl = webkit_glue::GURLToKURL(sync_load_response.url);
|
| -
|
| - // TODO(tc): For file loads, we may want to include a more descriptive
|
| - // status code or status text.
|
| - const URLRequestStatus::Status& status = sync_load_response.status.status();
|
| - if (status != URLRequestStatus::SUCCESS &&
|
| - status != URLRequestStatus::HANDLED_EXTERNALLY) {
|
| - response = ResourceResponse(kurl, String(), 0, String(), String());
|
| - error = ResourceError(net::kErrorDomain,
|
| - sync_load_response.status.os_error(),
|
| - kurl.string(),
|
| - String() /* localized description */);
|
| - return;
|
| - }
|
| -
|
| - response = MakeResourceResponse(kurl, sync_load_response);
|
| -
|
| - data.clear();
|
| - data.append(sync_load_response.data.data(),
|
| - sync_load_response.data.size());
|
| -}
|
| -
|
| -// static
|
| -bool ResourceHandle::willLoadFromCache(ResourceRequest& request) {
|
| - //
|
| - // This method is used to determine if a POST request can be repeated from
|
| - // cache, but you cannot really know until you actually try to read from the
|
| - // cache. Even if we checked now, something else could come along and wipe
|
| - // out the cache entry by the time we fetch it.
|
| - //
|
| - // So, we always say yes here, which allows us to generate an ERR_CACHE_MISS
|
| - // if the request cannot be serviced from cache. We force the 'DontLoad'
|
| - // cache policy at this point to ensure that we never hit the network for
|
| - // this request.
|
| - //
|
| - DCHECK(request.httpMethod() == "POST");
|
| - request.setCachePolicy(ReturnCacheDataDontLoad);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace WebCore
|
| -
|
|
|