• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
Factory(net::URLRequest * request,const std::string & scheme)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
AddUrlHandler(const FilePath & base_path)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 */
GetMockUrl(const FilePath & path)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 */
GetMockViewSourceUrl(const FilePath & path)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 */
GetOnDiskPath(const FilePath & base_path,net::URLRequest * request,const std::string & scheme)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 
URLRequestMockHTTPJob(net::URLRequest * request,const FilePath & file_path)74 URLRequestMockHTTPJob::URLRequestMockHTTPJob(net::URLRequest* request,
75                                              const FilePath& file_path)
76     : net::URLRequestFileJob(request, file_path) { }
77 
78 // Public virtual version.
GetResponseInfo(net::HttpResponseInfo * info)79 void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) {
80   // Forward to private const version.
81   GetResponseInfoConst(info);
82 }
83 
IsRedirectResponse(GURL * location,int * http_status_code)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.
GetResponseInfoConst(net::HttpResponseInfo * info) const92 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 
GetMimeType(std::string * mime_type) const108 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 
GetCharset(std::string * charset)114 bool URLRequestMockHTTPJob::GetCharset(std::string* charset) {
115   net::HttpResponseInfo info;
116   GetResponseInfo(&info);
117   return info.headers && info.headers->GetCharset(charset);
118 }
119