1 // Copyright 2013 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 "content/renderer/pepper/url_response_info_util.h" 6 7 #include "base/bind.h" 8 #include "base/files/file_path.h" 9 #include "base/message_loop/message_loop.h" 10 #include "content/public/renderer/renderer_ppapi_host.h" 11 #include "content/renderer/pepper/pepper_file_ref_renderer_host.h" 12 #include "content/renderer/pepper/renderer_ppapi_host_impl.h" 13 #include "ipc/ipc_message.h" 14 #include "ppapi/proxy/ppapi_messages.h" 15 #include "ppapi/shared_impl/url_response_info_data.h" 16 #include "third_party/WebKit/public/platform/WebCString.h" 17 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" 18 #include "third_party/WebKit/public/platform/WebString.h" 19 #include "third_party/WebKit/public/platform/WebURL.h" 20 #include "third_party/WebKit/public/platform/WebURLResponse.h" 21 22 using blink::WebHTTPHeaderVisitor; 23 using blink::WebString; 24 using blink::WebURLResponse; 25 26 namespace content { 27 28 namespace { 29 30 class HeaderFlattener : public WebHTTPHeaderVisitor { 31 public: 32 const std::string& buffer() const { return buffer_; } 33 34 virtual void visitHeader(const WebString& name, const WebString& value) { 35 if (!buffer_.empty()) 36 buffer_.append("\n"); 37 buffer_.append(name.utf8()); 38 buffer_.append(": "); 39 buffer_.append(value.utf8()); 40 } 41 42 private: 43 std::string buffer_; 44 }; 45 46 bool IsRedirect(int32_t status) { return status >= 300 && status <= 399; } 47 48 void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data, 49 const base::FilePath& external_path, 50 int renderer_pending_host_id, 51 const DataFromWebURLResponseCallback& callback, 52 const std::vector<int>& browser_pending_host_ids) { 53 DCHECK_EQ(1U, browser_pending_host_ids.size()); 54 int browser_pending_host_id = 0; 55 56 if (browser_pending_host_ids.size() == 1) 57 browser_pending_host_id = browser_pending_host_ids[0]; 58 59 ppapi::URLResponseInfoData data = in_data; 60 61 data.body_as_file_ref = 62 ppapi::MakeExternalFileRefCreateInfo(external_path, 63 std::string(), 64 browser_pending_host_id, 65 renderer_pending_host_id); 66 callback.Run(data); 67 } 68 69 } // namespace 70 71 void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, 72 PP_Instance pp_instance, 73 const WebURLResponse& response, 74 const DataFromWebURLResponseCallback& callback) { 75 ppapi::URLResponseInfoData data; 76 data.url = response.url().spec(); 77 data.status_code = response.httpStatusCode(); 78 data.status_text = response.httpStatusText().utf8(); 79 if (IsRedirect(data.status_code)) { 80 data.redirect_url = 81 response.httpHeaderField(WebString::fromUTF8("Location")).utf8(); 82 } 83 84 HeaderFlattener flattener; 85 response.visitHTTPHeaderFields(&flattener); 86 data.headers = flattener.buffer(); 87 88 WebString file_path = response.downloadFilePath(); 89 if (!file_path.isEmpty()) { 90 base::FilePath external_path = base::FilePath::FromUTF16Unsafe(file_path); 91 // TODO(teravest): Write a utility function to create resource hosts in the 92 // renderer and browser. 93 PepperFileRefRendererHost* renderer_host = 94 new PepperFileRefRendererHost(host_impl, pp_instance, 0, external_path); 95 int renderer_pending_host_id = 96 host_impl->GetPpapiHost()->AddPendingResourceHost( 97 scoped_ptr<ppapi::host::ResourceHost>(renderer_host)); 98 99 std::vector<IPC::Message> create_msgs; 100 create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(external_path)); 101 host_impl->CreateBrowserResourceHosts(pp_instance, 102 create_msgs, 103 base::Bind(&DidCreateResourceHosts, 104 data, 105 external_path, 106 renderer_pending_host_id, 107 callback)); 108 } else { 109 base::MessageLoop::current()->PostTask(FROM_HERE, 110 base::Bind(callback, data)); 111 } 112 } 113 114 } // namespace content 115