summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-13 09:01:28 +0000
committerbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-13 09:01:28 +0000
commit34b6db5e3093d11b88a925001a0230f81bf844f9 (patch)
tree8c1891417e7a5178b36ed367141737a307c647a2 /net
parent462232c4cf79e1b51d9a2f721c26f812172ad640 (diff)
downloadchromium_src-34b6db5e3093d11b88a925001a0230f81bf844f9.zip
chromium_src-34b6db5e3093d11b88a925001a0230f81bf844f9.tar.gz
chromium_src-34b6db5e3093d11b88a925001a0230f81bf844f9.tar.bz2
Revert 92331 - Fix leaking request IDs in webRequest API
The current webRequest API did not guarantee that either onCompleted or onErrorOccurred is called for each request. If an extension fills a REQUEST_ID -> URL hashmap for all requests at the onBeforeRequest event, and tried to delete the entries on onCompleted and onErrorOccurred, some entries remained in the hashmap. BUG=86139 TEST=execute example extension attached to bug Review URL: http://codereview.chromium.org/7190007 TBR=battre@chromium.org Review URL: http://codereview.chromium.org/7351011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92339 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/url_request/url_request.cc92
-rw-r--r--net/url_request/url_request.h40
-rw-r--r--net/url_request/url_request_http_job.cc22
-rw-r--r--net/url_request/url_request_job.cc67
-rw-r--r--net/url_request/url_request_job.h14
-rw-r--r--net/url_request/url_request_test_util.cc4
-rw-r--r--net/url_request/url_request_test_util.h2
-rw-r--r--net/url_request/url_request_unittest.cc21
8 files changed, 53 insertions, 209 deletions
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 40e1be6..7b55201 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -124,8 +124,7 @@ URLRequest::URLRequest(const GURL& url, Delegate* delegate)
priority_(LOWEST),
identifier_(GenerateURLRequestIdentifier()),
ALLOW_THIS_IN_INITIALIZER_LIST(
- before_request_callback_(this, &URLRequest::BeforeRequestComplete)),
- has_notified_completion_(false) {
+ before_request_callback_(this, &URLRequest::BeforeRequestComplete)) {
SIMPLE_STATS_COUNTER("URLRequestCount");
// Sanity check out environment.
@@ -136,11 +135,11 @@ URLRequest::URLRequest(const GURL& url, Delegate* delegate)
}
URLRequest::~URLRequest() {
- Cancel();
-
if (context_ && context_->network_delegate())
context_->network_delegate()->NotifyURLRequestDestroyed(this);
+ Cancel();
+
if (job_)
OrphanJob();
@@ -370,10 +369,6 @@ GURL URLRequest::GetSanitizedReferrer() const {
return ret;
}
-void URLRequest::set_delegate(Delegate* delegate) {
- delegate_ = delegate;
-}
-
void URLRequest::Start() {
response_info_.request_time = Time::Now();
@@ -484,11 +479,6 @@ void URLRequest::DoCancel(int os_error, const SSLInfo& ssl_info) {
job_->Kill();
- // We need to notify about the end of this job here synchronously. The
- // Job sends an asynchronous notification but by the time this is processed,
- // our |context_| is NULL.
- NotifyRequestCompleted();
-
// The Job will call our NotifyDone method asynchronously. This is done so
// that the Delegate implementation can call Cancel without having to worry
// about being called recursively.
@@ -514,8 +504,6 @@ bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) {
bool rv = job_->Read(dest, dest_size, bytes_read);
// If rv is false, the status cannot be success.
DCHECK(rv || status_.status() != URLRequestStatus::SUCCESS);
- if (rv && *bytes_read <= 0 && status_.is_success())
- NotifyRequestCompleted();
return rv;
}
@@ -524,8 +512,7 @@ void URLRequest::StopCaching() {
job_->StopCaching();
}
-void URLRequest::NotifyReceivedRedirect(const GURL& location,
- bool* defer_redirect) {
+void URLRequest::ReceivedRedirect(const GURL& location, bool* defer_redirect) {
URLRequestJob* job =
URLRequestJobManager::GetInstance()->MaybeInterceptRedirect(this,
location);
@@ -536,7 +523,7 @@ void URLRequest::NotifyReceivedRedirect(const GURL& location,
}
}
-void URLRequest::NotifyResponseStarted() {
+void URLRequest::ResponseStarted() {
scoped_refptr<NetLog::EventParameters> params;
if (!status_.is_success())
params = new NetLogIntegerParameter("net_error", status_.os_error());
@@ -547,22 +534,10 @@ void URLRequest::NotifyResponseStarted() {
if (job) {
RestartWithJob(job);
} else {
- if (delegate_) {
- // In some cases (e.g. an event was canceled), we might have sent the
- // completion event and receive a NotifyResponseStarted() later.
- if (!has_notified_completion_ && status_.is_success()) {
- if (context_ && context_->network_delegate())
- context_->network_delegate()->NotifyResponseStarted(this);
- }
-
- // Notify in case the entire URL Request has been finished.
- if (!has_notified_completion_ && !status_.is_success())
- NotifyRequestCompleted();
-
+ if (context_ && context_->network_delegate())
+ context_->network_delegate()->NotifyResponseStarted(this);
+ if (delegate_)
delegate_->OnResponseStarted(this);
- // Nothing may appear below this line as OnResponseStarted may delete
- // |this|.
- }
}
}
@@ -722,55 +697,4 @@ void URLRequest::SetUserData(const void* key, UserData* data) {
user_data_[key] = linked_ptr<UserData>(data);
}
-void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) {
- if (delegate_)
- delegate_->OnAuthRequired(this, auth_info);
-}
-
-void URLRequest::NotifyCertificateRequested(
- SSLCertRequestInfo* cert_request_info) {
- if (delegate_)
- delegate_->OnCertificateRequested(this, cert_request_info);
-}
-
-void URLRequest::NotifySSLCertificateError(int cert_error,
- X509Certificate* cert) {
- if (delegate_)
- delegate_->OnSSLCertificateError(this, cert_error, cert);
-}
-
-bool URLRequest::CanGetCookies() {
- if (delegate_)
- return delegate_->CanGetCookies(this);
- return false;
-}
-
-bool URLRequest::CanSetCookie(const std::string& cookie_line,
- CookieOptions* options) {
- if (delegate_)
- return delegate_->CanSetCookie(this, cookie_line, options);
- return false;
-}
-
-
-void URLRequest::NotifyReadCompleted(int bytes_read) {
- if (delegate_)
- delegate_->OnReadCompleted(this, bytes_read);
-
- // Notify in case the entire URL Request has been finished.
- if (bytes_read <= 0)
- NotifyRequestCompleted();
-}
-
-void URLRequest::NotifyRequestCompleted() {
- // TODO(battre): Get rid of this check, according to willchan it should
- // not be needed.
- if (has_notified_completion_)
- return;
-
- has_notified_completion_ = true;
- if (context_ && context_->network_delegate())
- context_->network_delegate()->NotifyCompleted(this);
-}
-
} // namespace net
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index cbd7bab..bf1cb84 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -306,9 +306,10 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
// Returns the referrer header with potential username and password removed.
GURL GetSanitizedReferrer() const;
- // Sets the delegate of the request. This value may be changed at any time,
+ // The delegate of the request. This value may be changed at any time,
// and it is permissible for it to be null.
- void set_delegate(Delegate* delegate);
+ Delegate* delegate() const { return delegate_; }
+ void set_delegate(Delegate* delegate) { delegate_ = delegate; }
// The data comprising the request message body is specified as a sequence of
// data segments and/or files containing data to upload. These methods may
@@ -576,7 +577,11 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
int Redirect(const GURL& location, int http_status_code);
// Called by URLRequestJob to allow interception when a redirect occurs.
- void NotifyReceivedRedirect(const GURL& location, bool* defer_redirect);
+ void ReceivedRedirect(const GURL& location, bool* defer_redirect);
+
+ // Called by URLRequestJob to allow interception when the final response
+ // occurs.
+ void ResponseStarted();
// Allow an interceptor's URLRequestJob to restart this request.
// Should only be called if the original job has not started a response.
@@ -584,7 +589,6 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
private:
friend class URLRequestJob;
-
typedef std::map<const void*, linked_ptr<UserData> > UserDataMap;
// Resumes or blocks a request paused by the NetworkDelegate::OnBeforeRequest
@@ -610,27 +614,6 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
// passed values.
void DoCancel(int os_error, const SSLInfo& ssl_info);
- // Notifies the network delegate that the request has been completed.
- // This does not imply a successful completion. Also a canceled request is
- // considered completed.
- void NotifyRequestCompleted();
-
- // Called by URLRequestJob to allow interception when the final response
- // occurs.
- void NotifyResponseStarted();
-
- bool has_delegate() const { return delegate_ != NULL; }
-
- // These functions delegate to |delegate_| and may only be used if
- // |delegate_| is not NULL. See URLRequest::Delegate for the meaning
- // of these functions.
- void NotifyAuthRequired(AuthChallengeInfo* auth_info);
- void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
- void NotifySSLCertificateError(int cert_error, X509Certificate* cert);
- bool CanGetCookies();
- bool CanSetCookie(const std::string& cookie_line, CookieOptions* options);
- void NotifyReadCompleted(int bytes_read);
-
// Contextual information used for this request (can be NULL). This contains
// most of the dependencies which are shared between requests (disk cache,
// cookie store, socket pool, etc.)
@@ -650,8 +633,6 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
int load_flags_; // Flags indicating the request type for the load;
// expected values are LOAD_* enums above.
- // Never access methods of the |delegate_| directly. Always use the
- // Notify... methods for this.
Delegate* delegate_;
// Current error status of the job. When no error has been encountered, this
@@ -691,11 +672,6 @@ class NET_API URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe) {
// is ready to be resumed or canceled.
CompletionCallbackImpl<URLRequest> before_request_callback_;
- // Safe-guard to ensure that we do not send multiple "I am completed"
- // messages to network delegate.
- // TODO(battre): Remove this. http://crbug.com/89049
- bool has_notified_completion_;
-
DISALLOW_COPY_AND_ASSIGN(URLRequest);
};
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index c3f354c..d36de09 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -504,8 +504,9 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
return;
bool allow = true;
- if ((request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) ||
- !CanGetCookies()) {
+ if (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES ||
+ (request_->delegate() &&
+ !request_->delegate()->CanGetCookies(request_))) {
allow = false;
}
@@ -561,11 +562,12 @@ void URLRequestHttpJob::SaveNextCookie() {
CookieOptions options;
if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) &&
- request_->context()->cookie_store()) {
+ request_->delegate() && request_->context()->cookie_store()) {
CookieOptions options;
options.set_include_httponly();
- if (CanSetCookie(
- response_cookies_[response_cookies_save_index_], &options)) {
+ if (request_->delegate()->CanSetCookie(
+ request_,
+ response_cookies_[response_cookies_save_index_], &options)) {
request_->context()->cookie_store()->SetCookieWithOptions(
request_->url(), response_cookies_[response_cookies_save_index_],
options);
@@ -686,7 +688,7 @@ void URLRequestHttpJob::OnStartCompleted(int result) {
RecordTimer();
// If the request was destroyed, then there is no more work to do.
- if (!request_)
+ if (!request_ || !request_->delegate())
return;
// If the transaction was destroyed, then the job was cancelled, and
@@ -729,11 +731,11 @@ void URLRequestHttpJob::OnStartCompleted(int result) {
// what we should do.
// TODO(wtc): also pass ssl_info.cert_status, or just pass the whole
// ssl_info.
- NotifySSLCertificateError(
- result, transaction_->GetResponseInfo()->ssl_info.cert);
+ request_->delegate()->OnSSLCertificateError(
+ request_, result, transaction_->GetResponseInfo()->ssl_info.cert);
} else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
- NotifyCertificateRequested(
- transaction_->GetResponseInfo()->cert_request_info);
+ request_->delegate()->OnCertificateRequested(
+ request_, transaction_->GetResponseInfo()->cert_request_info);
} else {
NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
}
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index cd02911..b664c6c 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -44,7 +44,6 @@ void URLRequestJob::SetExtraRequestHeaders(const HttpRequestHeaders& headers) {
}
void URLRequestJob::Kill() {
- method_factory_.RevokeAll();
// Make sure the request is notified that we are done. We assume that the
// request took care of setting its error status before calling Kill.
if (request_)
@@ -214,39 +213,8 @@ URLRequestJob::~URLRequestJob() {
base::SystemMonitor::Get()->RemoveObserver(this);
}
-void URLRequestJob::NotifyCertificateRequested(
- SSLCertRequestInfo* cert_request_info) {
- if (!request_)
- return; // The request was destroyed, so there is no more work to do.
-
- request_->NotifyCertificateRequested(cert_request_info);
-}
-
-void URLRequestJob::NotifySSLCertificateError(int cert_error,
- X509Certificate* cert) {
- if (!request_)
- return; // The request was destroyed, so there is no more work to do.
-
- request_->NotifySSLCertificateError(cert_error, cert);
-}
-
-bool URLRequestJob::CanGetCookies() {
- if (!request_)
- return false; // The request was destroyed, so there is no more work to do.
-
- return request_->CanGetCookies();
-}
-
-bool URLRequestJob::CanSetCookie(const std::string& cookie_line,
- CookieOptions* options) {
- if (!request_)
- return false; // The request was destroyed, so there is no more work to do.
-
- return request_->CanSetCookie(cookie_line, options);
-}
-
void URLRequestJob::NotifyHeadersComplete() {
- if (!request_ || !request_->has_delegate())
+ if (!request_ || !request_->delegate())
return; // The request was destroyed, so there is no more work to do.
if (has_handled_response_)
@@ -284,11 +252,10 @@ void URLRequestJob::NotifyHeadersComplete() {
}
bool defer_redirect = false;
- request_->NotifyReceivedRedirect(new_location, &defer_redirect);
+ request_->ReceivedRedirect(new_location, &defer_redirect);
- // Ensure that the request wasn't detached or destroyed in
- // NotifyReceivedRedirect
- if (!request_ || !request_->has_delegate())
+ // Ensure that the request wasn't detached or destroyed in ReceivedRedirect
+ if (!request_ || !request_->delegate())
return;
// If we were not cancelled, then maybe follow the redirect.
@@ -307,7 +274,7 @@ void URLRequestJob::NotifyHeadersComplete() {
// Need to check for a NULL auth_info because the server may have failed
// to send a challenge with the 401 response.
if (auth_info) {
- request_->NotifyAuthRequired(auth_info);
+ request_->delegate()->OnAuthRequired(request_, auth_info);
// Wait for SetAuth or CancelAuth to be called.
return;
}
@@ -324,11 +291,11 @@ void URLRequestJob::NotifyHeadersComplete() {
base::StringToInt64(content_length, &expected_content_size_);
}
- request_->NotifyResponseStarted();
+ request_->ResponseStarted();
}
void URLRequestJob::NotifyReadComplete(int bytes_read) {
- if (!request_ || !request_->has_delegate())
+ if (!request_ || !request_->delegate())
return; // The request was destroyed, so there is no more work to do.
// TODO(darin): Bug 1004233. Re-enable this test once all of the chrome
@@ -358,10 +325,10 @@ void URLRequestJob::NotifyReadComplete(int bytes_read) {
// Filter the data.
int filter_bytes_read = 0;
if (ReadFilteredData(&filter_bytes_read)) {
- request_->NotifyReadCompleted(filter_bytes_read);
+ request_->delegate()->OnReadCompleted(request_, filter_bytes_read);
}
} else {
- request_->NotifyReadCompleted(bytes_read);
+ request_->delegate()->OnReadCompleted(request_, bytes_read);
}
DVLOG(1) << __FUNCTION__ << "() "
<< "\"" << (request_ ? request_->url().spec() : "???") << "\""
@@ -375,7 +342,7 @@ void URLRequestJob::NotifyStartError(const URLRequestStatus &status) {
has_handled_response_ = true;
if (request_) {
request_->set_status(status);
- request_->NotifyResponseStarted();
+ request_->ResponseStarted();
}
}
@@ -403,6 +370,11 @@ void URLRequestJob::NotifyDone(const URLRequestStatus &status) {
request_->set_status(status);
}
+ if (request_ && request_->context() &&
+ request_->context()->network_delegate()) {
+ request_->context()->network_delegate()->NotifyCompleted(request_);
+ }
+
// Complete this notification later. This prevents us from re-entering the
// delegate if we're done because of a synchronous call.
MessageLoop::current()->PostTask(
@@ -414,22 +386,23 @@ void URLRequestJob::CompleteNotifyDone() {
// Check if we should notify the delegate that we're done because of an error.
if (request_ &&
!request_->status().is_success() &&
- request_->has_delegate()) {
+ request_->delegate()) {
// We report the error differently depending on whether we've called
// OnResponseStarted yet.
if (has_handled_response_) {
// We signal the error by calling OnReadComplete with a bytes_read of -1.
- request_->NotifyReadCompleted(-1);
+ request_->delegate()->OnReadCompleted(request_, -1);
} else {
has_handled_response_ = true;
- request_->NotifyResponseStarted();
+ request_->ResponseStarted();
}
}
}
void URLRequestJob::NotifyCanceled() {
if (!done_) {
- NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED));
+ NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED,
+ ERR_ABORTED));
}
}
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index e9887ad..d2261ca 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -24,11 +24,9 @@
namespace net {
class AuthChallengeInfo;
-class CookieOptions;
class HttpRequestHeaders;
class HttpResponseInfo;
class IOBuffer;
-class SSLCertRequestInfo;
class URLRequest;
class UploadData;
class URLRequestStatus;
@@ -192,18 +190,6 @@ class NET_API URLRequestJob : public base::RefCounted<URLRequestJob>,
friend class base::RefCounted<URLRequestJob>;
virtual ~URLRequestJob();
- // Notifies the job that a certificate is requested.
- void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
-
- // Notifies the job about an SSL certificate error.
- void NotifySSLCertificateError(int cert_error, X509Certificate* cert);
-
- // Delegates to URLRequest::Delegate.
- bool CanGetCookies();
-
- // Delegates to URLRequest::Delegate.
- bool CanSetCookie(const std::string& cookie_line, CookieOptions* options);
-
// Notifies the job that headers have been received.
void NotifyHeadersComplete();
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 716e1e7..0bfe9447 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -244,8 +244,7 @@ TestNetworkDelegate::TestNetworkDelegate()
: last_os_error_(0),
error_count_(0),
created_requests_(0),
- destroyed_requests_(0),
- completed_requests_(0) {
+ destroyed_requests_(0) {
}
TestNetworkDelegate::~TestNetworkDelegate() {}
@@ -287,7 +286,6 @@ void TestNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
}
void TestNetworkDelegate::OnCompleted(net::URLRequest* request) {
- completed_requests_++;
if (request->status().status() == net::URLRequestStatus::FAILED) {
error_count_++;
last_os_error_ = request->status().os_error();
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 74d8fab..f7755b8 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -179,7 +179,6 @@ class TestNetworkDelegate : public net::NetworkDelegate {
int error_count() const { return error_count_; }
int created_requests() const { return created_requests_; }
int destroyed_requests() const { return destroyed_requests_; }
- int completed_requests() const { return completed_requests_; }
protected:
// net::NetworkDelegate:
@@ -207,7 +206,6 @@ class TestNetworkDelegate : public net::NetworkDelegate {
int error_count_;
int created_requests_;
int destroyed_requests_;
- int completed_requests_;
};
#endif // NET_URL_REQUEST_URL_REQUEST_TEST_UTIL_H_
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 281daaf..6e51ff6 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -298,7 +298,8 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) {
EXPECT_EQ(0, d.received_redirect_count());
EXPECT_EQ(1, network_delegate.error_count());
- EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, network_delegate.last_os_error());
+ EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED,
+ network_delegate.last_os_error());
}
}
@@ -2458,7 +2459,8 @@ TEST_F(URLRequestTest, NetworkDelegateProxyError) {
TestURLRequest req(GURL("http://example.com"), &d);
req.set_method("GET");
- scoped_ptr<MockHostResolverBase> host_resolver(new MockHostResolver);
+ scoped_ptr<MockHostResolverBase> host_resolver(
+ new MockHostResolver);
host_resolver->rules()->AddSimulatedFailure("*");
scoped_refptr<TestURLRequestContext> context(
new TestURLRequestContext("myproxy:70", host_resolver.release()));
@@ -2475,7 +2477,6 @@ TEST_F(URLRequestTest, NetworkDelegateProxyError) {
EXPECT_EQ(1, network_delegate.error_count());
EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_os_error());
- EXPECT_EQ(1, network_delegate.completed_requests());
}
// Check that it is impossible to change the referrer in the extra headers of
@@ -2523,20 +2524,6 @@ TEST_F(URLRequestTest, DoNotOverrideReferrer) {
}
}
-// Make sure that net::NetworkDelegate::NotifyCompleted is called if
-// content is empty.
-TEST_F(URLRequestTest, RequestCompletionForEmptyResponse) {
- TestNetworkDelegate network_delegate;
- TestDelegate d;
- TestURLRequest req(GURL("data:,"), &d);
- req.set_context(new TestURLRequestContext());
- req.context()->set_network_delegate(&network_delegate);
- req.Start();
- MessageLoop::current()->Run();
- EXPECT_EQ("", d.data_received());
- EXPECT_EQ(1, network_delegate.completed_requests());
-}
-
class URLRequestTestFTP : public URLRequestTest {
public:
URLRequestTestFTP() : test_server_(TestServer::TYPE_FTP, FilePath()) {