1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // This class simulates what wininet does when a dns lookup fails. 5 6 #include <algorithm> 7 #include <cstring> 8 9 #include "base/compiler_specific.h" 10 #include "base/strings/string_util.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "content/test/net/url_request_abort_on_end_job.h" 13 #include "net/base/io_buffer.h" 14 #include "net/base/net_errors.h" 15 #include "net/http/http_response_headers.h" 16 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request_filter.h" 18 #include "net/url_request/url_request_status.h" 19 20 namespace content { 21 namespace { 22 23 const char kPageContent[] = "some data\r\n"; 24 25 net::URLRequestJob* JobFactory( 26 net::URLRequest* request, 27 net::NetworkDelegate* network_delegate, 28 const std::string& scheme) { 29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 30 return new URLRequestAbortOnEndJob(request, network_delegate); 31 } 32 33 void AddUrlHandlerOnIOThread() { 34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 35 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); 36 filter->AddUrlHandler(GURL(URLRequestAbortOnEndJob::k400AbortOnEndUrl), 37 &JobFactory); 38 } 39 40 } // anonymous namespace 41 42 const char URLRequestAbortOnEndJob::k400AbortOnEndUrl[] = 43 "http://url.handled.by.abort.on.end/400"; 44 45 // static 46 void URLRequestAbortOnEndJob::AddUrlHandler() { 47 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 48 base::Bind(AddUrlHandlerOnIOThread)); 49 } 50 51 // Private const version. 52 void URLRequestAbortOnEndJob::GetResponseInfoConst( 53 net::HttpResponseInfo* info) const { 54 // Send back mock headers. 55 std::string raw_headers; 56 if (LowerCaseEqualsASCII(k400AbortOnEndUrl, 57 request_->url().spec().c_str())) { 58 raw_headers.append( 59 "HTTP/1.1 400 This is not OK\n" 60 "Content-type: text/plain\n"); 61 } else { 62 NOTREACHED(); 63 } 64 // ParseRawHeaders expects \0 to end each header line. 65 ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1)); 66 info->headers = new net::HttpResponseHeaders(raw_headers); 67 } 68 69 URLRequestAbortOnEndJob::URLRequestAbortOnEndJob( 70 net::URLRequest* request, net::NetworkDelegate* network_delegate) 71 : URLRequestJob(request, network_delegate), 72 sent_data_(false), 73 weak_factory_(this) { 74 } 75 76 URLRequestAbortOnEndJob::~URLRequestAbortOnEndJob() { 77 } 78 79 void URLRequestAbortOnEndJob::GetResponseInfo(net::HttpResponseInfo* info) { 80 GetResponseInfoConst(info); 81 } 82 83 bool URLRequestAbortOnEndJob::GetMimeType(std::string* mime_type) const { 84 net::HttpResponseInfo info; 85 GetResponseInfoConst(&info); 86 return info.headers.get() && info.headers->GetMimeType(mime_type); 87 } 88 89 void URLRequestAbortOnEndJob::StartAsync() { 90 NotifyHeadersComplete(); 91 } 92 93 void URLRequestAbortOnEndJob::Start() { 94 base::MessageLoop::current()->PostTask( 95 FROM_HERE, 96 base::Bind(&URLRequestAbortOnEndJob::StartAsync, 97 weak_factory_.GetWeakPtr())); 98 } 99 100 bool URLRequestAbortOnEndJob::ReadRawData(net::IOBuffer* buf, 101 const int max_bytes, 102 int* bytes_read) { 103 if (!sent_data_) { 104 *bytes_read = std::min(size_t(max_bytes), sizeof(kPageContent)); 105 std::memcpy(buf->data(), kPageContent, *bytes_read); 106 sent_data_ = true; 107 return true; 108 } 109 110 SetStatus(net::URLRequestStatus(net::URLRequestStatus::FAILED, 111 net::ERR_CONNECTION_ABORTED)); 112 *bytes_read = -1; 113 return false; 114 } 115 116 } // namespace content 117