• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "tests/cefclient/browser/scheme_test.h"
6 
7 #include <algorithm>
8 #include <string>
9 
10 #include "include/cef_browser.h"
11 #include "include/cef_callback.h"
12 #include "include/cef_frame.h"
13 #include "include/cef_request.h"
14 #include "include/cef_resource_handler.h"
15 #include "include/cef_response.h"
16 #include "include/cef_scheme.h"
17 #include "include/wrapper/cef_helpers.h"
18 #include "tests/cefclient/browser/test_runner.h"
19 #include "tests/shared/browser/resource_util.h"
20 
21 namespace client {
22 namespace scheme_test {
23 
24 namespace {
25 
26 // Implementation of the schema handler for client:// requests.
27 class ClientSchemeHandler : public CefResourceHandler {
28  public:
ClientSchemeHandler()29   ClientSchemeHandler() : offset_(0) {}
30 
Open(CefRefPtr<CefRequest> request,bool & handle_request,CefRefPtr<CefCallback> callback)31   bool Open(CefRefPtr<CefRequest> request,
32             bool& handle_request,
33             CefRefPtr<CefCallback> callback) override {
34     DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
35 
36     // The request will be continued or canceled based on the return value.
37     handle_request = true;
38 
39     bool handled = false;
40 
41     std::string url = request->GetURL();
42     if (strstr(url.c_str(), "handler.html") != nullptr) {
43       // Build the response html
44       data_ =
45           "<html><head><title>Client Scheme Handler</title></head>"
46           "<body bgcolor=\"white\">"
47           "This contents of this page page are served by the "
48           "ClientSchemeHandler class handling the client:// protocol."
49           "<br/>You should see an image:"
50           "<br/><img src=\"client://tests/logo.png\"><pre>";
51 
52       // Output a string representation of the request
53       const std::string& dump = test_runner::DumpRequestContents(request);
54       data_.append(dump);
55 
56       data_.append(
57           "</pre><br/>Try the test form:"
58           "<form method=\"POST\" action=\"handler.html\">"
59           "<input type=\"text\" name=\"field1\">"
60           "<input type=\"text\" name=\"field2\">"
61           "<input type=\"submit\">"
62           "</form></body></html>");
63 
64       handled = true;
65 
66       // Set the resulting mime type
67       mime_type_ = "text/html";
68     } else if (strstr(url.c_str(), "logo.png") != nullptr) {
69       // Load the response image
70       if (LoadBinaryResource("logo.png", data_)) {
71         handled = true;
72         // Set the resulting mime type
73         mime_type_ = "image/png";
74       }
75     }
76 
77     return handled;
78   }
79 
GetResponseHeaders(CefRefPtr<CefResponse> response,int64 & response_length,CefString & redirectUrl)80   void GetResponseHeaders(CefRefPtr<CefResponse> response,
81                           int64& response_length,
82                           CefString& redirectUrl) override {
83     CEF_REQUIRE_IO_THREAD();
84 
85     DCHECK(!data_.empty());
86 
87     response->SetMimeType(mime_type_);
88     response->SetStatus(200);
89 
90     // Set the resulting response length
91     response_length = data_.length();
92   }
93 
Cancel()94   void Cancel() override { CEF_REQUIRE_IO_THREAD(); }
95 
Read(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefResourceReadCallback> callback)96   bool Read(void* data_out,
97             int bytes_to_read,
98             int& bytes_read,
99             CefRefPtr<CefResourceReadCallback> callback) override {
100     DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO));
101 
102     bool has_data = false;
103     bytes_read = 0;
104 
105     if (offset_ < data_.length()) {
106       // Copy the next block of data into the buffer.
107       int transfer_size =
108           std::min(bytes_to_read, static_cast<int>(data_.length() - offset_));
109       memcpy(data_out, data_.c_str() + offset_, transfer_size);
110       offset_ += transfer_size;
111 
112       bytes_read = transfer_size;
113       has_data = true;
114     }
115 
116     return has_data;
117   }
118 
119  private:
120   std::string data_;
121   std::string mime_type_;
122   size_t offset_;
123 
124   IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
125   DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandler);
126 };
127 
128 // Implementation of the factory for for creating schema handlers.
129 class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
130  public:
ClientSchemeHandlerFactory()131   ClientSchemeHandlerFactory() {}
132 
133   // Return a new scheme handler instance to handle the request.
Create(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const CefString & scheme_name,CefRefPtr<CefRequest> request)134   CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
135                                        CefRefPtr<CefFrame> frame,
136                                        const CefString& scheme_name,
137                                        CefRefPtr<CefRequest> request) override {
138     CEF_REQUIRE_IO_THREAD();
139     return new ClientSchemeHandler();
140   }
141 
142   IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
143   DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerFactory);
144 };
145 
146 }  // namespace
147 
RegisterSchemeHandlers()148 void RegisterSchemeHandlers() {
149   CefRegisterSchemeHandlerFactory("client", "tests",
150                                   new ClientSchemeHandlerFactory());
151 }
152 
153 }  // namespace scheme_test
154 }  // namespace client
155