Index: mojo/services/html_viewer/blink_url_request_type_converters.cc |
diff --git a/mojo/services/html_viewer/blink_url_request_type_converters.cc b/mojo/services/html_viewer/blink_url_request_type_converters.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1f6553eba83a2cecf11cc013c0900dfd9c5e15b2 |
--- /dev/null |
+++ b/mojo/services/html_viewer/blink_url_request_type_converters.cc |
@@ -0,0 +1,110 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/services/html_viewer/blink_url_request_type_converters.h" |
+ |
+#include "base/strings/string_util.h" |
+#include "mojo/public/cpp/system/data_pipe.h" |
+#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" |
+#include "third_party/WebKit/public/platform/WebURLRequest.h" |
+ |
+namespace mojo { |
+namespace { |
+ |
+// Ripped from web_url_loader_impl.cc. |
+class HeaderFlattener : public blink::WebHTTPHeaderVisitor { |
+ public: |
+ HeaderFlattener() : has_accept_header_(false) {} |
+ |
+ virtual void visitHeader(const blink::WebString& name, |
+ const blink::WebString& value) { |
+ // Headers are latin1. |
+ const std::string& name_latin1 = name.latin1(); |
+ const std::string& value_latin1 = value.latin1(); |
+ |
+ // Skip over referrer headers found in the header map because we already |
+ // pulled it out as a separate parameter. |
+ if (LowerCaseEqualsASCII(name_latin1, "referer")) |
+ return; |
+ |
+ if (LowerCaseEqualsASCII(name_latin1, "accept")) |
+ has_accept_header_ = true; |
+ |
+ buffer_.push_back(name_latin1 + ": " + value_latin1); |
+ } |
+ |
+ Array<String> GetBuffer() { |
+ // In some cases, WebKit doesn't add an Accept header, but not having the |
+ // header confuses some web servers. See bug 808613. |
+ if (!has_accept_header_) { |
+ buffer_.push_back("Accept: */*"); |
+ has_accept_header_ = true; |
+ } |
+ return buffer_.Pass(); |
+ } |
+ |
+ private: |
+ Array<String> buffer_; |
+ bool has_accept_header_; |
+}; |
+ |
+void AddRequestBody(URLRequest* url_request, |
+ const blink::WebURLRequest& request) { |
+ if (request.httpBody().isNull()) |
+ return; |
+ |
+ uint32_t i = 0; |
+ blink::WebHTTPBody::Element element; |
+ while (request.httpBody().elementAt(i++, element)) { |
+ switch (element.type) { |
+ case blink::WebHTTPBody::Element::TypeData: |
+ if (!element.data.isEmpty()) { |
+ // WebKit sometimes gives up empty data to append. These aren't |
+ // necessary so we just optimize those out here. |
+ uint32_t num_bytes = static_cast<uint32_t>(element.data.size()); |
+ MojoCreateDataPipeOptions options; |
+ options.struct_size = sizeof(MojoCreateDataPipeOptions); |
+ options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
+ options.element_num_bytes = 1; |
+ options.capacity_num_bytes = num_bytes; |
+ DataPipe data_pipe(options); |
+ url_request->body.push_back( |
+ data_pipe.consumer_handle.Pass()); |
+ WriteDataRaw(data_pipe.producer_handle.get(), |
+ element.data.data(), |
+ &num_bytes, |
+ MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); |
+ } |
+ break; |
+ case blink::WebHTTPBody::Element::TypeFile: |
+ case blink::WebHTTPBody::Element::TypeFileSystemURL: |
+ case blink::WebHTTPBody::Element::TypeBlob: |
+ // TODO(mpcomplete): handle these. |
+ NOTIMPLEMENTED(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ } |
+} |
+ |
+} // namespace |
+ |
+URLRequestPtr TypeConverter<URLRequestPtr, blink::WebURLRequest>::ConvertFrom( |
+ const blink::WebURLRequest& request) { |
+ URLRequestPtr url_request(URLRequest::New()); |
+ url_request->url = request.url().string().utf8(); |
+ url_request->method = request.httpMethod().utf8(); |
+ |
+ HeaderFlattener flattener; |
+ request.visitHTTPHeaderFields(&flattener); |
+ url_request->headers = flattener.GetBuffer().Pass(); |
+ |
+ AddRequestBody(url_request.get(), request); |
+ |
+ return url_request.Pass(); |
+} |
+ |
+} // namespace mojo |
+ |