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/renderer/pepper/ppb_file_ref_impl.h" 11 #include "ppapi/shared_impl/url_response_info_data.h" 12 #include "third_party/WebKit/public/platform/WebCString.h" 13 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" 14 #include "third_party/WebKit/public/platform/WebString.h" 15 #include "third_party/WebKit/public/platform/WebURL.h" 16 #include "third_party/WebKit/public/platform/WebURLResponse.h" 17 18 using WebKit::WebHTTPHeaderVisitor; 19 using WebKit::WebString; 20 using WebKit::WebURLResponse; 21 22 namespace content { 23 24 namespace { 25 26 class HeaderFlattener : public WebHTTPHeaderVisitor { 27 public: 28 const std::string& buffer() const { return buffer_; } 29 30 virtual void visitHeader(const WebString& name, const WebString& value) { 31 if (!buffer_.empty()) 32 buffer_.append("\n"); 33 buffer_.append(name.utf8()); 34 buffer_.append(": "); 35 buffer_.append(value.utf8()); 36 } 37 38 private: 39 std::string buffer_; 40 }; 41 42 bool IsRedirect(int32_t status) { 43 return status >= 300 && status <= 399; 44 } 45 46 } // namespace 47 48 void DataFromWebURLResponse(PP_Instance pp_instance, 49 const WebURLResponse& response, 50 const DataFromWebURLResponseCallback& callback) { 51 ppapi::URLResponseInfoData data; 52 53 data.url = response.url().spec(); 54 data.status_code = response.httpStatusCode(); 55 data.status_text = response.httpStatusText().utf8(); 56 if (IsRedirect(data.status_code)) { 57 data.redirect_url = response.httpHeaderField( 58 WebString::fromUTF8("Location")).utf8(); 59 } 60 61 HeaderFlattener flattener; 62 response.visitHTTPHeaderFields(&flattener); 63 data.headers = flattener.buffer(); 64 65 WebString file_path = response.downloadFilePath(); 66 if (!file_path.isEmpty()) { 67 scoped_refptr<PPB_FileRef_Impl> file_ref( 68 PPB_FileRef_Impl::CreateExternal( 69 pp_instance, 70 base::FilePath::FromUTF16Unsafe(file_path), 71 std::string())); 72 data.body_as_file_ref = file_ref->GetCreateInfo(); 73 file_ref->GetReference(); // The returned data has one ref for the plugin. 74 } 75 76 // We post data to a callback instead of returning it here because the new 77 // implementation for FileRef is asynchronous when creating the resource. 78 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, data)); 79 } 80 81 } // namespace content 82