Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / services / html_viewer / blink_url_request_type_converters.cc
1 // Copyright 2014 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 "mojo/services/html_viewer/blink_url_request_type_converters.h"
6
7 #include "base/strings/string_util.h"
8 #include "mojo/public/cpp/system/data_pipe.h"
9 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
10 #include "third_party/WebKit/public/platform/WebURLRequest.h"
11
12 namespace mojo {
13 namespace {
14
15 // Ripped from web_url_loader_impl.cc.
16 class HeaderFlattener : public blink::WebHTTPHeaderVisitor {
17  public:
18   HeaderFlattener() : has_accept_header_(false) {}
19
20   virtual void visitHeader(const blink::WebString& name,
21                            const blink::WebString& value) {
22     // Headers are latin1.
23     const std::string& name_latin1 = name.latin1();
24     const std::string& value_latin1 = value.latin1();
25
26     // Skip over referrer headers found in the header map because we already
27     // pulled it out as a separate parameter.
28     if (LowerCaseEqualsASCII(name_latin1, "referer"))
29       return;
30
31     if (LowerCaseEqualsASCII(name_latin1, "accept"))
32       has_accept_header_ = true;
33
34     buffer_.push_back(name_latin1 + ": " + value_latin1);
35   }
36
37   Array<String> GetBuffer() {
38     // In some cases, WebKit doesn't add an Accept header, but not having the
39     // header confuses some web servers.  See bug 808613.
40     if (!has_accept_header_) {
41       buffer_.push_back("Accept: */*");
42       has_accept_header_ = true;
43     }
44     return buffer_.Pass();
45   }
46
47  private:
48   Array<String> buffer_;
49   bool has_accept_header_;
50 };
51
52 void AddRequestBody(URLRequest* url_request,
53                     const blink::WebURLRequest& request) {
54   if (request.httpBody().isNull())
55     return;
56
57   uint32_t i = 0;
58   blink::WebHTTPBody::Element element;
59   while (request.httpBody().elementAt(i++, element)) {
60     switch (element.type) {
61       case blink::WebHTTPBody::Element::TypeData:
62         if (!element.data.isEmpty()) {
63           // WebKit sometimes gives up empty data to append. These aren't
64           // necessary so we just optimize those out here.
65           uint32_t num_bytes = static_cast<uint32_t>(element.data.size());
66           MojoCreateDataPipeOptions options;
67           options.struct_size = sizeof(MojoCreateDataPipeOptions);
68           options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
69           options.element_num_bytes = 1;
70           options.capacity_num_bytes = num_bytes;
71           DataPipe data_pipe(options);
72           url_request->body.push_back(
73               data_pipe.consumer_handle.Pass());
74           WriteDataRaw(data_pipe.producer_handle.get(),
75                        element.data.data(),
76                        &num_bytes,
77                        MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
78         }
79         break;
80       case blink::WebHTTPBody::Element::TypeFile:
81       case blink::WebHTTPBody::Element::TypeFileSystemURL:
82       case blink::WebHTTPBody::Element::TypeBlob:
83         // TODO(mpcomplete): handle these.
84         NOTIMPLEMENTED();
85         break;
86       default:
87         NOTREACHED();
88     }
89   }
90 }
91
92 } // namespace
93
94 URLRequestPtr TypeConverter<URLRequestPtr, blink::WebURLRequest>::ConvertFrom(
95     const blink::WebURLRequest& request) {
96   URLRequestPtr url_request(URLRequest::New());
97   url_request->url = request.url().string().utf8();
98   url_request->method = request.httpMethod().utf8();
99
100   HeaderFlattener flattener;
101   request.visitHTTPHeaderFields(&flattener);
102   url_request->headers = flattener.GetBuffer().Pass();
103
104   AddRequestBody(url_request.get(), request);
105
106   return url_request.Pass();
107 }
108
109 }  // namespace mojo
110