1 // Copyright (c) 2010 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 "base/strings/string_util.h"
6 #include "content/renderer/npapi/webplugin_impl.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/WebKit/public/platform/WebCString.h"
9 #include "third_party/WebKit/public/platform/WebString.h"
10 #include "third_party/WebKit/public/platform/WebURLRequest.h"
11
12 using blink::WebHTTPBody;
13 using blink::WebString;
14 using blink::WebURLRequest;
15
16 namespace content {
17
18 namespace {
19
GetHeader(const WebURLRequest & request,const char * name)20 std::string GetHeader(const WebURLRequest& request, const char* name) {
21 std::string result;
22 base::TrimWhitespace(
23 request.httpHeaderField(WebString::fromUTF8(name)).utf8(),
24 base::TRIM_ALL,
25 &result);
26 return result;
27 }
28
GetBodyText(const WebURLRequest & request)29 std::string GetBodyText(const WebURLRequest& request) {
30 const WebHTTPBody& body = request.httpBody();
31 if (body.isNull())
32 return std::string();
33
34 std::string result;
35 size_t i = 0;
36 WebHTTPBody::Element element;
37 while (body.elementAt(i++, element)) {
38 if (element.type == WebHTTPBody::Element::TypeData) {
39 result.append(element.data.data(), element.data.size());
40 } else {
41 NOTREACHED() << "unexpected element type encountered!";
42 }
43 }
44 return result;
45 }
46
47 } // namespace
48
49 // The Host functions for NPN_PostURL and NPN_PostURLNotify
50 // need to parse out some HTTP headers. Make sure it works
51 // with the following tests
52
TEST(WebPluginImplTest,PostParserSimple)53 TEST(WebPluginImplTest, PostParserSimple) {
54 // Test a simple case with headers & data
55 const char *ex1 = "foo: bar\nContent-length: 10\n\nabcdefghij";
56 WebURLRequest request;
57 request.initialize();
58 bool rv = WebPluginImpl::SetPostData(&request, ex1,
59 static_cast<uint32>(strlen(ex1)));
60 EXPECT_TRUE(rv);
61 EXPECT_EQ("bar", GetHeader(request, "foo"));
62 EXPECT_EQ(0U, GetHeader(request, "bar").length());
63 EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
64 EXPECT_EQ("abcdefghij", GetBodyText(request));
65 }
66
TEST(WebPluginImplTest,PostParserLongHeader)67 TEST(WebPluginImplTest, PostParserLongHeader) {
68 // Test a simple case with long headers
69 const char *ex1 = "foo: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n\nabcdefghij";
70 WebURLRequest request;
71 request.initialize();
72 bool rv = WebPluginImpl::SetPostData(&request, ex1,
73 static_cast<uint32>(strlen(ex1)));
74 EXPECT_TRUE(rv);
75 EXPECT_EQ(100U, GetHeader(request, "foo").length());
76 }
77
TEST(WebPluginImplTest,PostParserManyHeaders)78 TEST(WebPluginImplTest, PostParserManyHeaders) {
79 // Test a simple case with long headers
80 const char *ex1 = "h1:h1\nh2:h2\nh3:h3\nh4:h4\nh5:h5\nh6:h6\nh7:h7\nh8:h8\nh9:h9\nh10:h10\n\nbody";
81 WebURLRequest request;
82 request.initialize();
83 bool rv = WebPluginImpl::SetPostData(&request, ex1,
84 static_cast<uint32>(strlen(ex1)));
85 EXPECT_TRUE(rv);
86 EXPECT_EQ("h1", GetHeader(request, "h1"));
87 EXPECT_EQ("h2", GetHeader(request, "h2"));
88 EXPECT_EQ("h3", GetHeader(request, "h3"));
89 EXPECT_EQ("h4", GetHeader(request, "h4"));
90 EXPECT_EQ("h5", GetHeader(request, "h5"));
91 EXPECT_EQ("h6", GetHeader(request, "h6"));
92 EXPECT_EQ("h7", GetHeader(request, "h7"));
93 EXPECT_EQ("h8", GetHeader(request, "h8"));
94 EXPECT_EQ("h9", GetHeader(request, "h9"));
95 EXPECT_EQ("h10", GetHeader(request, "h10"));
96 EXPECT_EQ("body", GetBodyText(request));
97 }
98
TEST(WebPluginImplTest,PostParserDuplicateHeaders)99 TEST(WebPluginImplTest, PostParserDuplicateHeaders) {
100 // Test a simple case with long headers
101 // What value gets returned doesn't really matter. It shouldn't error
102 // out.
103 const char *ex1 = "h1:h1\nh1:h2\n\nbody";
104 WebURLRequest request;
105 request.initialize();
106 bool rv = WebPluginImpl::SetPostData(&request, ex1,
107 static_cast<uint32>(strlen(ex1)));
108 EXPECT_TRUE(rv);
109 }
110
TEST(WebPluginImplTest,PostParserNoHeaders)111 TEST(WebPluginImplTest, PostParserNoHeaders) {
112 // Test a simple case with no headers but with data
113 const char *ex1 = "\nabcdefghij";
114 WebURLRequest request;
115 request.initialize();
116 bool rv = WebPluginImpl::SetPostData(&request, ex1,
117 static_cast<uint32>(strlen(ex1)));
118 EXPECT_TRUE(rv);
119 EXPECT_EQ(0U, GetHeader(request, "foo").length());
120 EXPECT_EQ(0U, GetHeader(request, "bar").length());
121 EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
122 EXPECT_EQ("abcdefghij", GetBodyText(request));
123 }
124
TEST(WebPluginImplTest,PostParserNoBody)125 TEST(WebPluginImplTest, PostParserNoBody) {
126 // Test a simple case with headers and no body
127 const char *ex1 = "Foo:bar\n\n";
128 WebURLRequest request;
129 request.initialize();
130 bool rv = WebPluginImpl::SetPostData(&request, ex1,
131 static_cast<uint32>(strlen(ex1)));
132 EXPECT_TRUE(rv);
133 EXPECT_EQ("bar", GetHeader(request, "foo"));
134 EXPECT_EQ(0U, GetHeader(request, "bar").length());
135 EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
136 EXPECT_EQ(0U, GetBodyText(request).length());
137 }
138
TEST(WebPluginImplTest,PostParserBodyWithNewLines)139 TEST(WebPluginImplTest, PostParserBodyWithNewLines) {
140 // Test a simple case with headers and no body
141 const char *ex1 = "Foo:bar\n\n\n\nabcdefg\n\nabcdefg";
142 WebURLRequest request;
143 request.initialize();
144 bool rv = WebPluginImpl::SetPostData(&request, ex1,
145 static_cast<uint32>(strlen(ex1)));
146 EXPECT_TRUE(rv);
147 EXPECT_EQ(GetBodyText(request), "\n\nabcdefg\n\nabcdefg");
148 }
149
TEST(WebPluginImplTest,PostParserErrorNoBody)150 TEST(WebPluginImplTest, PostParserErrorNoBody) {
151 // Test with headers and no body
152 const char *ex1 = "Foo:bar\n";
153 WebURLRequest request;
154 request.initialize();
155 bool rv = WebPluginImpl::SetPostData(&request, ex1,
156 static_cast<uint32>(strlen(ex1)));
157 EXPECT_TRUE(rv);
158 }
159
TEST(WebPluginImplTest,PostParserErrorEmpty)160 TEST(WebPluginImplTest, PostParserErrorEmpty) {
161 // Test with an empty string
162 const char *ex1 = "";
163 WebURLRequest request;
164 request.initialize();
165 bool rv = WebPluginImpl::SetPostData(&request, ex1,
166 static_cast<uint32>(strlen(ex1)));
167 EXPECT_TRUE(rv);
168 }
169
TEST(WebPluginImplTest,PostParserEmptyName)170 TEST(WebPluginImplTest, PostParserEmptyName) {
171 // Test an error case with an empty header name field
172 const char *ex1 = "foo:bar\n:blat\n\nbody";
173 WebURLRequest request;
174 request.initialize();
175 bool rv = WebPluginImpl::SetPostData(&request, ex1,
176 static_cast<uint32>(strlen(ex1)));
177 EXPECT_TRUE(rv);
178 EXPECT_EQ("bar", GetHeader(request, "foo"));
179 EXPECT_EQ("body", GetBodyText(request));
180 }
181
TEST(WebPluginImplTest,PostParserEmptyValue)182 TEST(WebPluginImplTest, PostParserEmptyValue) {
183 // Test an error case with an empty value field
184 const char *ex1 = "foo:bar\nbar:\n\nbody";
185 WebURLRequest request;
186 request.initialize();
187 bool rv = WebPluginImpl::SetPostData(&request, ex1,
188 static_cast<uint32>(strlen(ex1)));
189 EXPECT_TRUE(rv);
190 EXPECT_EQ("bar", GetHeader(request, "foo"));
191 EXPECT_EQ(0U, GetHeader(request, "bar").length());
192 EXPECT_EQ("body", GetBodyText(request));
193 }
194
TEST(WebPluginImplTest,PostParserCRLF)195 TEST(WebPluginImplTest, PostParserCRLF) {
196 // Test an error case with an empty value field
197 const char *ex1 = "foo: bar\r\nbar:\r\n\r\nbody\r\n\r\nbody2";
198 WebURLRequest request;
199 request.initialize();
200 bool rv = WebPluginImpl::SetPostData(&request, ex1,
201 static_cast<uint32>(strlen(ex1)));
202 EXPECT_TRUE(rv);
203 EXPECT_EQ("bar", GetHeader(request, "foo"));
204 EXPECT_EQ(0U, GetHeader(request, "bar").length());
205 EXPECT_EQ("body\r\n\r\nbody2", GetBodyText(request));
206 }
207
TEST(WebPluginImplTest,PostParserBodyWithBinaryData)208 TEST(WebPluginImplTest, PostParserBodyWithBinaryData) {
209 // Test a simple case with headers and binary data.
210 char ex1[33] = "foo: bar\nContent-length: 10\n\n";
211 unsigned int binary_data = 0xFFFFFFF0;
212 memcpy(ex1 + strlen("foo: bar\nContent-length: 10\n\n"), &binary_data,
213 sizeof(binary_data));
214
215 WebURLRequest request;
216 request.initialize();
217 bool rv = WebPluginImpl::SetPostData(&request, ex1,
218 sizeof(ex1)/sizeof(ex1[0]));
219 EXPECT_TRUE(rv);
220 EXPECT_EQ("bar", GetHeader(request, "foo"));
221 EXPECT_EQ(0U, GetHeader(request, "bar").length());
222 EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
223
224 std::string body = GetBodyText(request);
225
226 EXPECT_EQ(0xF0, (unsigned char)body[0]);
227 EXPECT_EQ(0xFF, (unsigned char)body[1]);
228 EXPECT_EQ(0xFF, (unsigned char)body[2]);
229 EXPECT_EQ(0xFF, (unsigned char)body[3]);
230 }
231
232 } // namespace content
233