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 20namespace content { 21namespace { 22 23const char kPageContent[] = "some data\r\n"; 24 25net::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 33void 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 42const char URLRequestAbortOnEndJob::k400AbortOnEndUrl[] = 43 "http://url.handled.by.abort.on.end/400"; 44 45// static 46void URLRequestAbortOnEndJob::AddUrlHandler() { 47 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 48 base::Bind(AddUrlHandlerOnIOThread)); 49} 50 51// Private const version. 52void 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 69URLRequestAbortOnEndJob::URLRequestAbortOnEndJob( 70 net::URLRequest* request, net::NetworkDelegate* network_delegate) 71 : URLRequestJob(request, network_delegate), 72 sent_data_(false), 73 weak_factory_(this) { 74} 75 76URLRequestAbortOnEndJob::~URLRequestAbortOnEndJob() { 77} 78 79void URLRequestAbortOnEndJob::GetResponseInfo(net::HttpResponseInfo* info) { 80 GetResponseInfoConst(info); 81} 82 83bool 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 89void URLRequestAbortOnEndJob::StartAsync() { 90 NotifyHeadersComplete(); 91} 92 93void URLRequestAbortOnEndJob::Start() { 94 base::MessageLoop::current()->PostTask( 95 FROM_HERE, 96 base::Bind(&URLRequestAbortOnEndJob::StartAsync, 97 weak_factory_.GetWeakPtr())); 98} 99 100bool 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