Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2010 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 
      5 #include "chrome/browser/net/url_request_mock_http_job.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/message_loop.h"
      9 #include "base/string_util.h"
     10 #include "base/threading/thread_restrictions.h"
     11 #include "base/utf_string_conversions.h"
     12 #include "chrome/common/url_constants.h"
     13 #include "net/base/net_util.h"
     14 #include "net/http/http_response_headers.h"
     15 #include "net/url_request/url_request_filter.h"
     16 
     17 static const char kMockHostname[] = "mock.http";
     18 static const FilePath::CharType kMockHeaderFileSuffix[] =
     19     FILE_PATH_LITERAL(".mock-http-headers");
     20 
     21 FilePath URLRequestMockHTTPJob::base_path_;
     22 
     23 // static
     24 net::URLRequestJob* URLRequestMockHTTPJob::Factory(net::URLRequest* request,
     25                                                    const std::string& scheme) {
     26   return new URLRequestMockHTTPJob(request,
     27                                    GetOnDiskPath(base_path_, request, scheme));
     28 }
     29 
     30 // static
     31 void URLRequestMockHTTPJob::AddUrlHandler(const FilePath& base_path) {
     32   base_path_ = base_path;
     33 
     34   // Add kMockHostname to net::URLRequestFilter.
     35   net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
     36   filter->AddHostnameHandler("http", kMockHostname,
     37                              URLRequestMockHTTPJob::Factory);
     38 }
     39 
     40 /* static */
     41 GURL URLRequestMockHTTPJob::GetMockUrl(const FilePath& path) {
     42   std::string url = "http://";
     43   url.append(kMockHostname);
     44   url.append("/");
     45   std::string path_str = path.MaybeAsASCII();
     46   DCHECK(!path_str.empty());  // We only expect ASCII paths in tests.
     47   url.append(path_str);
     48   return GURL(url);
     49 }
     50 
     51 /* static */
     52 GURL URLRequestMockHTTPJob::GetMockViewSourceUrl(const FilePath& path) {
     53   std::string url = chrome::kViewSourceScheme;
     54   url.append(":");
     55   url.append(GetMockUrl(path).spec());
     56   return GURL(url);
     57 }
     58 
     59 /* static */
     60 FilePath URLRequestMockHTTPJob::GetOnDiskPath(const FilePath& base_path,
     61                                               net::URLRequest* request,
     62                                               const std::string& scheme) {
     63   // Conceptually we just want to "return base_path + request->url().path()".
     64   // But path in the request URL is in URL space (i.e. %-encoded spaces).
     65   // So first we convert base FilePath to a URL, then append the URL
     66   // path to that, and convert the final URL back to a FilePath.
     67   GURL file_url(net::FilePathToFileURL(base_path));
     68   std::string url = file_url.spec() + request->url().path();
     69   FilePath file_path;
     70   net::FileURLToFilePath(GURL(url), &file_path);
     71   return file_path;
     72 }
     73 
     74 URLRequestMockHTTPJob::URLRequestMockHTTPJob(net::URLRequest* request,
     75                                              const FilePath& file_path)
     76     : net::URLRequestFileJob(request, file_path) { }
     77 
     78 // Public virtual version.
     79 void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) {
     80   // Forward to private const version.
     81   GetResponseInfoConst(info);
     82 }
     83 
     84 bool URLRequestMockHTTPJob::IsRedirectResponse(GURL* location,
     85                                                int* http_status_code) {
     86   // Override the net::URLRequestFileJob implementation to invoke the default
     87   // one based on HttpResponseInfo.
     88   return net::URLRequestJob::IsRedirectResponse(location, http_status_code);
     89 }
     90 
     91 // Private const version.
     92 void URLRequestMockHTTPJob::GetResponseInfoConst(
     93     net::HttpResponseInfo* info) const {
     94   // We have to load our headers from disk, but we only use this class
     95   // from tests, so allow these IO operations to happen on any thread.
     96   base::ThreadRestrictions::ScopedAllowIO allow_io;
     97 
     98   FilePath header_file = FilePath(file_path_.value() + kMockHeaderFileSuffix);
     99   std::string raw_headers;
    100   if (!file_util::ReadFileToString(header_file, &raw_headers))
    101     return;
    102 
    103   // ParseRawHeaders expects \0 to end each header line.
    104   ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1));
    105   info->headers = new net::HttpResponseHeaders(raw_headers);
    106 }
    107 
    108 bool URLRequestMockHTTPJob::GetMimeType(std::string* mime_type) const {
    109   net::HttpResponseInfo info;
    110   GetResponseInfoConst(&info);
    111   return info.headers && info.headers->GetMimeType(mime_type);
    112 }
    113 
    114 bool URLRequestMockHTTPJob::GetCharset(std::string* charset) {
    115   net::HttpResponseInfo info;
    116   GetResponseInfo(&info);
    117   return info.headers && info.headers->GetCharset(charset);
    118 }
    119