diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/net/url_request_abort_on_end_job.cc | 105 | ||||
-rw-r--r-- | content/browser/net/url_request_abort_on_end_job.h | 52 | ||||
-rw-r--r-- | content/browser/webkit_browsertest.cc | 36 | ||||
-rw-r--r-- | content/content_tests.gypi | 2 |
4 files changed, 195 insertions, 0 deletions
diff --git a/content/browser/net/url_request_abort_on_end_job.cc b/content/browser/net/url_request_abort_on_end_job.cc new file mode 100644 index 0000000..9cfd62b --- /dev/null +++ b/content/browser/net/url_request_abort_on_end_job.cc @@ -0,0 +1,105 @@ +// Copyright (c) 2011 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 class simulates what wininet does when a dns lookup fails. + +#include <algorithm> +#include <cstring> + +#include "base/compiler_specific.h" +#include "base/string_util.h" +#include "base/task.h" +#include "content/browser/net/url_request_abort_on_end_job.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_status.h" + +namespace { +const char kPageContent[] = "some data\r\n"; +} + +const char URLRequestAbortOnEndJob::k400AbortOnEndUrl[] = + "http://url.handled.by.abort.on.end/400"; + +// static +void URLRequestAbortOnEndJob::AddUrlHandler() { + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->AddUrlHandler(GURL(k400AbortOnEndUrl), + &URLRequestAbortOnEndJob::Factory); +} + +// static +net::URLRequestJob* URLRequestAbortOnEndJob::Factory( + net::URLRequest* request, + const std::string& scheme) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return new URLRequestAbortOnEndJob(request); +} + +// Private const version. +void URLRequestAbortOnEndJob::GetResponseInfoConst( + net::HttpResponseInfo* info) const { + // Send back mock headers. + std::string raw_headers; + if (LowerCaseEqualsASCII(k400AbortOnEndUrl, + request_->url().spec().c_str())) { + raw_headers.append( + "HTTP/1.1 400 This is not OK\n" + "Content-type: text/plain\n"); + } else { + NOTREACHED(); + } + // ParseRawHeaders expects \0 to end each header line. + ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1)); + info->headers = new net::HttpResponseHeaders(raw_headers); +} + +URLRequestAbortOnEndJob::URLRequestAbortOnEndJob(net::URLRequest* request) + : URLRequestJob(request), sent_data_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { +} + +URLRequestAbortOnEndJob::~URLRequestAbortOnEndJob() { +} + +void URLRequestAbortOnEndJob::GetResponseInfo(net::HttpResponseInfo* info) { + GetResponseInfoConst(info); +} + +bool URLRequestAbortOnEndJob::GetMimeType(std::string* mime_type) const { + net::HttpResponseInfo info; + GetResponseInfoConst(&info); + return info.headers && info.headers->GetMimeType(mime_type); +} + +void URLRequestAbortOnEndJob::StartAsync() { + NotifyHeadersComplete(); +} + +void URLRequestAbortOnEndJob::Start() { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&URLRequestAbortOnEndJob::StartAsync, + weak_factory_.GetWeakPtr())); +} + +bool URLRequestAbortOnEndJob::ReadRawData(net::IOBuffer* buf, + const int max_bytes, + int* bytes_read) { + if (!sent_data_) { + *bytes_read = std::max(size_t(max_bytes), sizeof(kPageContent)); + std::memcpy(buf->data(), kPageContent, *bytes_read); + sent_data_ = true; + return true; + } + + SetStatus(net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_CONNECTION_ABORTED)); + *bytes_read = -1; + return false; +} + + diff --git a/content/browser/net/url_request_abort_on_end_job.h b/content/browser/net/url_request_abort_on_end_job.h new file mode 100644 index 0000000..8bb4b93 --- /dev/null +++ b/content/browser/net/url_request_abort_on_end_job.h @@ -0,0 +1,52 @@ +// Copyright (c) 2011 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 class simulates what wininet does when a dns lookup fails. + +#ifndef CONTENT_BROWSER_NET_URL_REQUEST_ABORT_ON_END_JOB_H_ +#define CONTENT_BROWSER_NET_URL_REQUEST_ABORT_ON_END_JOB_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" +#include "net/url_request/url_request_job.h" + +// This url request simulates a network error which occurs immediately after +// receiving the very first data. + +class URLRequestAbortOnEndJob : public net::URLRequestJob { + public: + static const char k400AbortOnEndUrl[]; + + // net::URLRequestJob + virtual void Start() OVERRIDE; + virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; + virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE; + virtual bool ReadRawData(net::IOBuffer* buf, + int buf_size, + int* bytes_read) OVERRIDE; + + static net::URLRequestJob* Factory(net::URLRequest* request, + const std::string& scheme); + + CONTENT_EXPORT static void AddUrlHandler(); + + private: + explicit URLRequestAbortOnEndJob(net::URLRequest* request); + virtual ~URLRequestAbortOnEndJob(); + + void GetResponseInfoConst(net::HttpResponseInfo* info) const; + void StartAsync(); + + bool sent_data_; + + base::WeakPtrFactory<URLRequestAbortOnEndJob> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestAbortOnEndJob); +}; +#endif + diff --git a/content/browser/webkit_browsertest.cc b/content/browser/webkit_browsertest.cc new file mode 100644 index 0000000..1d6dea8 --- /dev/null +++ b/content/browser/webkit_browsertest.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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. + +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/browser/net/url_request_abort_on_end_job.h" +#include "content/browser/tab_contents/tab_contents.h" + +typedef InProcessBrowserTest WebKitBrowserTest; + +const char kAsyncScriptThatAbortsOnEndPage[] = + "files/webkit/async_script_abort_on_end.html"; + +// This is a browser test because it is hard to reproduce reliably in a +// layout test without races. http://crbug.com/75604 deals with a request +// for an async script which gets data in the response and immediately +// after aborts. This test creates that condition, and it is passed +// if chrome does not crash. + +IN_PROC_BROWSER_TEST_F(WebKitBrowserTest, AbortOnEnd) { + ASSERT_TRUE(test_server()->Start()); + URLRequestAbortOnEndJob::AddUrlHandler(); + GURL url = test_server()->GetURL(kAsyncScriptThatAbortsOnEndPage); + + ui_test_utils::NavigateToURL(browser(), url); + + TabContents* tab_contents = browser()->GetSelectedTabContents(); + // If you are seeing this test fail, please strongly investigate the + // possibility that http://crbug.com/75604 and + // https://bugs.webkit.org/show_bug.cgi?id=71122 have reverted before + // marking this as flakey. + EXPECT_FALSE(tab_contents->is_crashed()); +} + diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 1aad957..806edd73 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -38,6 +38,8 @@ 'browser/mock_content_browser_client.h', 'browser/mock_resource_context.cc', 'browser/mock_resource_context.h', + 'browser/net/url_request_abort_on_end_job.cc', + 'browser/net/url_request_abort_on_end_job.h', 'browser/renderer_host/dummy_resource_handler.cc', 'browser/renderer_host/dummy_resource_handler.h', 'browser/renderer_host/media/mock_media_observer.cc', |