balsa_headers_test.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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 "net/tools/balsa/balsa_headers.h"
6
7#include <iterator>
8#include <string>
9#include <vector>
10
11#include "base/memory/scoped_ptr.h"
12#include "base/strings/string_piece.h"
13#include "net/tools/balsa/balsa_enums.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace net {
17
18using ::base::StringPiece;
19
20class BalsaBufferTest : public ::testing::Test {
21 public:
22  virtual void SetUp() OVERRIDE {
23    buffer_.reset(new BalsaBuffer);
24    anotherBuffer_.reset(new BalsaBuffer);
25  }
26
27 protected:
28  scoped_ptr<BalsaBuffer> buffer_;
29  scoped_ptr<BalsaBuffer> anotherBuffer_;
30};
31
32namespace {
33
34class BalsaHeadersTest: public ::testing::Test {
35 public:
36  virtual void SetUp() OVERRIDE {
37    headers_.reset(new BalsaHeaders);
38  }
39
40 protected:
41  scoped_ptr<BalsaHeaders> headers_;
42};
43
44class StringBuffer {
45 public:
46  void Write(const char* p, size_t size) {
47    string_ += std::string(p, size);
48  }
49  const std::string& string() {return string_;}
50
51 private:
52  std::string string_;
53};
54
55TEST_F(BalsaBufferTest, EmptyBuffer) {
56  ASSERT_EQ(1u, buffer_->num_blocks());
57}
58
59TEST_F(BalsaBufferTest, Write) {
60  size_t index1, index2;
61  StringPiece sp1 = buffer_->Write(StringPiece("hello"), &index1);
62  StringPiece sp2 = buffer_->Write(StringPiece(", world"), &index2);
63
64  ASSERT_EQ(2u, buffer_->num_blocks());
65  ASSERT_EQ("hello", sp1);
66  ASSERT_EQ(", world", sp2);
67  ASSERT_EQ(1u, index1);
68  ASSERT_EQ(1u, index2);
69  ASSERT_EQ("hello, world",
70            StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
71}
72
73TEST_F(BalsaBufferTest, WriteLongData) {
74  size_t index1, index2, index3;
75  std::string as(2, 'a');
76  std::string bs(BalsaBuffer::kDefaultBlocksize + 1, 'b');
77  std::string cs(4, 'c');
78
79  StringPiece sp1 = buffer_->Write(as, &index1);
80  StringPiece sp2 = buffer_->Write(bs, &index2);
81  StringPiece sp3 = buffer_->Write(cs, &index3);
82
83  ASSERT_EQ(3u, buffer_->num_blocks());
84  ASSERT_EQ(as, sp1);
85  ASSERT_EQ(bs, sp2);
86  ASSERT_EQ(cs, sp3);
87  ASSERT_EQ(1u, index1);
88  ASSERT_EQ(2u, index2);
89  ASSERT_EQ(1u, index3);
90  ASSERT_EQ("aacccc", StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
91  ASSERT_EQ(sp2, StringPiece(buffer_->GetPtr(2), buffer_->bytes_used(2)));
92}
93
94TEST_F(BalsaBufferTest, WriteToContiguousBuffer) {
95  std::string as(2, 'a');
96  std::string bs(BalsaBuffer::kDefaultBlocksize + 1, 'b');
97  std::string cs(4, 'c');
98
99  buffer_->WriteToContiguousBuffer(as);
100  buffer_->WriteToContiguousBuffer(bs);
101  buffer_->WriteToContiguousBuffer(cs);
102
103  ASSERT_EQ(1u, buffer_->num_blocks());
104  ASSERT_EQ(as + bs + cs,
105            StringPiece(buffer_->GetPtr(0), buffer_->bytes_used(0)));
106}
107
108TEST_F(BalsaBufferTest, NoMoreWriteToContiguousBuffer) {
109  size_t index1, index2;
110  StringPiece sp1 = buffer_->Write(StringPiece("hello"), &index1);
111  buffer_->NoMoreWriteToContiguousBuffer();
112  StringPiece sp2 = buffer_->Write(StringPiece(", world"), &index2);
113
114  ASSERT_EQ(2u, buffer_->num_blocks());
115  ASSERT_EQ("hello", sp1);
116  ASSERT_EQ(", world", sp2);
117  ASSERT_EQ(1u, index1);
118  ASSERT_EQ(0u, index2);
119  ASSERT_EQ(sp1, StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
120  ASSERT_EQ(sp2, StringPiece(buffer_->GetPtr(0), buffer_->bytes_used(0)));
121}
122
123TEST_F(BalsaBufferTest, Clear) {
124  buffer_->Write("hello", NULL);
125  ASSERT_EQ(2u, buffer_->num_blocks());
126  buffer_->Clear();
127  ASSERT_EQ(1u, buffer_->num_blocks());
128}
129
130TEST_F(BalsaBufferTest, Swap) {
131  buffer_->Write("hello", NULL);
132
133  ASSERT_EQ(2u, buffer_->num_blocks());
134  ASSERT_EQ(1u, anotherBuffer_->num_blocks());
135
136  buffer_->Swap(anotherBuffer_.get());
137
138  ASSERT_EQ(1u, buffer_->num_blocks());
139  ASSERT_EQ(2u, anotherBuffer_->num_blocks());
140  ASSERT_EQ("hello",
141            StringPiece(anotherBuffer_->GetPtr(1),
142                        anotherBuffer_->bytes_used(1)));
143}
144
145TEST_F(BalsaBufferTest, CopyFrom) {
146  buffer_->Write("hello", NULL);
147
148  ASSERT_EQ(2u, buffer_->num_blocks());
149  ASSERT_EQ(1u, anotherBuffer_->num_blocks());
150
151  anotherBuffer_->CopyFrom(*buffer_);
152
153  ASSERT_EQ(2u, buffer_->num_blocks());
154  ASSERT_EQ(2u, anotherBuffer_->num_blocks());
155  ASSERT_EQ("hello", StringPiece(buffer_->GetPtr(1), buffer_->bytes_used(1)));
156  ASSERT_EQ("hello",
157            StringPiece(anotherBuffer_->GetPtr(1),
158                        anotherBuffer_->bytes_used(1)));
159}
160
161TEST_F(BalsaHeadersTest, AppendHeader) {
162  headers_->AppendHeader("key1", "value1");
163  headers_->AppendHeader("key2", "value2");
164  headers_->AppendHeader("key3", "value3");
165  headers_->AppendHeader("key3", "value3.1");
166  headers_->AppendHeader("key3", "value3.2");
167
168  ASSERT_EQ(5, std::distance(headers_->header_lines_begin(),
169                             headers_->header_lines_end()));
170  ASSERT_EQ("value1", headers_->GetHeader("key1"));
171  ASSERT_EQ("value2", headers_->GetHeader("key2"));
172  ASSERT_EQ("value3", headers_->GetHeader("key3"));
173
174  std::vector<base::StringPiece> v1, v2, v3;
175  std::string s1, s2, s3;
176  headers_->GetAllOfHeader("key1", &v1);
177  headers_->GetAllOfHeader("key2", &v2);
178  headers_->GetAllOfHeader("key3", &v3);
179  headers_->GetAllOfHeaderAsString("key1", &s1);
180  headers_->GetAllOfHeaderAsString("key2", &s2);
181  headers_->GetAllOfHeaderAsString("key3", &s3);
182
183  ASSERT_EQ(1u, v1.size());
184  ASSERT_EQ(1u, v2.size());
185  ASSERT_EQ(3u, v3.size());
186  ASSERT_EQ("value1", v1[0]);
187  ASSERT_EQ("value2", v2[0]);
188  ASSERT_EQ("value3", v3[0]);
189  ASSERT_EQ("value3.1", v3[1]);
190  ASSERT_EQ("value3.2", v3[2]);
191  ASSERT_EQ("value1", s1);
192  ASSERT_EQ("value2", s2);
193  ASSERT_EQ("value3,value3.1,value3.2", s3);
194}
195
196TEST_F(BalsaHeadersTest, ReplaceOrAppendHeader) {
197  headers_->ReplaceOrAppendHeader("key1", "value1");
198  headers_->ReplaceOrAppendHeader("key1", "value2");
199
200  ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
201                             headers_->header_lines_end()));
202  ASSERT_EQ("value2", headers_->GetHeader("key1"));
203
204  std::vector<base::StringPiece> v;
205  headers_->GetAllOfHeader("key1", &v);
206
207  ASSERT_EQ(1u, v.size());
208  ASSERT_EQ("value2", v[0]);
209}
210
211TEST_F(BalsaHeadersTest, AppendToHeader) {
212  headers_->AppendToHeader("key1", "value1");
213  headers_->AppendToHeader("keY1", "value2");
214
215  ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
216                             headers_->header_lines_end()));
217  ASSERT_EQ("value1,value2", headers_->GetHeader("key1"));
218
219  std::vector<base::StringPiece> v;
220  std::string s;
221  headers_->GetAllOfHeader("key1", &v);
222  headers_->GetAllOfHeaderAsString("keY1", &s);
223
224  ASSERT_EQ(1u, v.size());
225  ASSERT_EQ("value1,value2", v[0]);
226  ASSERT_EQ("value1,value2", s);
227}
228
229TEST_F(BalsaHeadersTest, PrepentToHeader) {
230  headers_->PrependToHeader("key1", "value1");
231  headers_->PrependToHeader("key1", "value2");
232
233  ASSERT_EQ(1, std::distance(headers_->header_lines_begin(),
234                             headers_->header_lines_end()));
235  ASSERT_EQ("value2,value1", headers_->GetHeader("key1"));
236
237  std::vector<base::StringPiece> v;
238  std::string s;
239  headers_->GetAllOfHeader("key1", &v);
240  headers_->GetAllOfHeaderAsString("key1", &s);
241
242  ASSERT_EQ(1u, v.size());
243  ASSERT_EQ("value2,value1", v[0]);
244  ASSERT_EQ("value2,value1", s);
245}
246
247TEST_F(BalsaHeadersTest, HasHeader) {
248  headers_->AppendHeader("key1", "value1");
249
250  ASSERT_TRUE(headers_->HasHeader("key1"));
251  ASSERT_FALSE(headers_->HasHeader("value1"));
252  ASSERT_FALSE(headers_->HasHeader("key2"));
253}
254
255TEST_F(BalsaHeadersTest, HasNonEmptyHeader) {
256  headers_->AppendHeader("key1", "value1");
257  headers_->AppendHeader("key2", "");
258
259  ASSERT_TRUE(headers_->HasNonEmptyHeader("key1"));
260  ASSERT_FALSE(headers_->HasNonEmptyHeader("key2"));
261  ASSERT_FALSE(headers_->HasNonEmptyHeader("key3"));
262}
263
264TEST_F(BalsaHeadersTest, GetHeaderPosition) {
265  headers_->AppendHeader("key1", "value1");
266  headers_->AppendHeader("key2", "value2");
267  headers_->AppendHeader("key3", "value3");
268
269  BalsaHeaders::const_header_lines_iterator i =
270      headers_->GetHeaderPosition("key2");
271
272  ASSERT_EQ(headers_->header_lines_end(),
273            headers_->GetHeaderPosition("foobar"));
274  ASSERT_EQ(headers_->header_lines_begin(),
275            headers_->GetHeaderPosition("key1"));
276  ASSERT_NE(headers_->header_lines_end(), i);
277  ASSERT_EQ("key2", i->first);
278  ASSERT_EQ("value2", i->second);
279  ++i;
280  ASSERT_EQ("key3", i->first);
281  ASSERT_EQ("value3", i->second);
282  ++i;
283  ASSERT_EQ(headers_->header_lines_end(), i);
284}
285
286TEST_F(BalsaHeadersTest, GetIteratorForKey) {
287  headers_->AppendHeader("key1", "value1");
288  headers_->AppendHeader("key2", "value2");
289  headers_->AppendHeader("key1", "value1.1");
290  headers_->AppendHeader("key3", "value3");
291  headers_->AppendHeader("KEY1", "value1.2");
292
293  BalsaHeaders::const_header_lines_key_iterator i =
294      headers_->GetIteratorForKey("key1");
295
296  ASSERT_EQ(headers_->header_lines_key_end(),
297            headers_->GetIteratorForKey("foobar"));
298  ASSERT_NE(headers_->header_lines_key_end(), i);
299  ASSERT_EQ("key1", i->first);
300  ASSERT_EQ("value1", i->second);
301  ++i;
302  ASSERT_EQ("key1", i->first);
303  ASSERT_EQ("value1.1", i->second);
304  ++i;
305  ASSERT_EQ("KEY1", i->first);
306  ASSERT_EQ("value1.2", i->second);
307  ++i;
308  ASSERT_EQ(headers_->header_lines_key_end(), i);
309}
310
311TEST_F(BalsaHeadersTest, RemoveAllOfHeader) {
312  headers_->AppendHeader("key1", "value1");
313  headers_->AppendHeader("key2", "value2");
314  headers_->AppendHeader("key1", "value1.1");
315  headers_->AppendHeader("key3", "value3");
316  headers_->AppendHeader("key1", "value1.2");
317  headers_->AppendHeader("kEY1", "value1.3");
318
319  ASSERT_EQ(6, std::distance(headers_->header_lines_begin(),
320                             headers_->header_lines_end()));
321  headers_->RemoveAllOfHeader("key1");
322  ASSERT_EQ(2, std::distance(headers_->header_lines_begin(),
323                             headers_->header_lines_end()));
324}
325
326TEST_F(BalsaHeadersTest, RemoveAllHeadersWithPrefix) {
327  headers_->AppendHeader("1key", "value1");
328  headers_->AppendHeader("2key", "value2");
329  headers_->AppendHeader("1kEz", "value1.1");
330  headers_->AppendHeader("key3", "value3");
331  headers_->AppendHeader("1KEEjkladf", "value1.2");
332
333  ASSERT_EQ(5, std::distance(headers_->header_lines_begin(),
334                             headers_->header_lines_end()));
335  headers_->RemoveAllHeadersWithPrefix("1ke");
336  ASSERT_EQ(2, std::distance(headers_->header_lines_begin(),
337                             headers_->header_lines_end()));
338}
339
340TEST_F(BalsaHeadersTest, WriteRequestHeaderAndEndingToBuffer) {
341  headers_->AppendHeader("key1", "value1");
342  headers_->AppendHeader("key2", "value2");
343  headers_->AppendHeader("key1", "value1.1");
344
345  headers_->SetRequestFirstlineFromStringPieces("GET", "/", "HTTP/1.0");
346
347  std::string expected = "GET / HTTP/1.0\r\n"
348      "key1: value1\r\n"
349      "key2: value2\r\n"
350      "key1: value1.1\r\n\r\n";
351  StringBuffer buffer;
352  headers_->WriteHeaderAndEndingToBuffer(&buffer);
353  ASSERT_EQ(expected, buffer.string());
354}
355
356TEST_F(BalsaHeadersTest, WriteResponseHeaderAndEndingToBuffer) {
357  headers_->AppendHeader("key1", "value1");
358  headers_->AppendHeader("key2", "value2");
359  headers_->AppendHeader("key1", "value1.1");
360
361  headers_->SetResponseFirstlineFromStringPieces("HTTP/1.0", "200", "OK");
362
363  std::string expected = "HTTP/1.0 200 OK\r\n"
364      "key1: value1\r\n"
365      "key2: value2\r\n"
366      "key1: value1.1\r\n\r\n";
367  StringBuffer buffer;
368  headers_->WriteHeaderAndEndingToBuffer(&buffer);
369  ASSERT_EQ(expected, buffer.string());
370}
371
372TEST_F(BalsaHeadersTest, RequestFirstLine) {
373  headers_->SetRequestFirstlineFromStringPieces("HEAD", "/path", "HTTP/1.1");
374
375  ASSERT_EQ("HEAD /path HTTP/1.1", headers_->first_line());
376  ASSERT_EQ("HEAD", headers_->request_method());
377  ASSERT_EQ("/path", headers_->request_uri());
378  ASSERT_EQ("HTTP/1.1", headers_->request_version());
379}
380
381TEST_F(BalsaHeadersTest, ResponseFirstLine) {
382  headers_->SetRequestFirstlineFromStringPieces("HTTP/1.0", "403", "FORBIDDEN");
383
384  ASSERT_EQ("HTTP/1.0 403 FORBIDDEN", headers_->first_line());
385  ASSERT_EQ("HTTP/1.0", headers_->response_version());
386  ASSERT_EQ("403", headers_->response_code());
387  ASSERT_EQ("FORBIDDEN", headers_->response_reason_phrase());
388}
389
390}  // namespace
391
392}  // namespace net
393