Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / tools / balsa / balsa_frame_test.cc
blob4a00a6608a987a18e0f1ad975674a937f6af4164
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.
5 #include "net/tools/balsa/balsa_frame.h"
7 #include <iterator>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_piece.h"
11 #include "net/tools/balsa/balsa_enums.h"
12 #include "net/tools/balsa/balsa_headers.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace net {
18 namespace {
20 using ::base::StringPiece;
21 using ::testing::_;
22 using ::testing::InSequence;
23 using ::testing::SaveArg;
25 class Visitor : public BalsaVisitorInterface {
26 public:
27 virtual ~Visitor() {}
28 MOCK_METHOD2(ProcessBodyInput, void(const char*, size_t));
29 MOCK_METHOD2(ProcessBodyData, void(const char*, size_t));
30 MOCK_METHOD2(ProcessHeaderInput, void(const char*, size_t));
31 MOCK_METHOD2(ProcessTrailerInput, void(const char*, size_t));
32 MOCK_METHOD1(ProcessHeaders, void(const BalsaHeaders&));
33 MOCK_METHOD8(ProcessRequestFirstLine, void(const char*,
34 size_t,
35 const char*,
36 size_t,
37 const char*,
38 size_t,
39 const char*,
40 size_t));
41 MOCK_METHOD8(ProcessResponseFirstLine, void(const char*,
42 size_t,
43 const char*,
44 size_t,
45 const char*,
46 size_t,
47 const char*,
48 size_t));
49 MOCK_METHOD2(ProcessChunkExtensions, void(const char*, size_t));
50 MOCK_METHOD1(ProcessChunkLength, void(size_t));
51 MOCK_METHOD0(HeaderDone, void());
52 MOCK_METHOD0(MessageDone, void());
53 MOCK_METHOD1(HandleHeaderError, void(BalsaFrame*));
54 MOCK_METHOD1(HandleHeaderWarning, void(BalsaFrame*));
55 MOCK_METHOD1(HandleChunkingError, void(BalsaFrame*));
56 MOCK_METHOD1(HandleBodyError, void(BalsaFrame*));
59 class BalsaFrameTest : public ::testing::Test {
60 public:
61 void SetUp() override {
62 frame_.reset(new BalsaFrame);
63 frame_headers_.reset(new BalsaHeaders);
64 visitor_.reset(new Visitor);
65 frame_->set_balsa_visitor(visitor_.get());
68 protected:
69 scoped_ptr<BalsaFrame> frame_;
70 scoped_ptr<BalsaHeaders> frame_headers_;
71 scoped_ptr<Visitor> visitor_;
74 TEST_F(BalsaFrameTest, EmptyFrame) {
75 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
76 frame_->ParseState());
77 ASSERT_FALSE(frame_->MessageFullyRead());
78 ASSERT_FALSE(frame_->Error());
79 ASSERT_EQ(NULL, frame_->const_balsa_headers());
80 ASSERT_EQ(NULL, frame_->balsa_headers());
81 ASSERT_EQ(NULL, frame_->headers());
82 ASSERT_EQ(NULL, frame_->mutable_headers());
83 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
84 ASSERT_TRUE(frame_->is_request());
85 ASSERT_FALSE(frame_->request_was_head());
88 TEST_F(BalsaFrameTest, EmptyRequest) {
89 const char input[] = "\r\n";
90 frame_->set_balsa_headers(frame_headers_.get());
93 InSequence s;
94 // No visitor callback should be called.
96 size_t read = frame_->ProcessInput(input, strlen(input));
97 EXPECT_EQ(2u, read);
98 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
99 frame_->ParseState());
100 ASSERT_FALSE(frame_->Error());
101 ASSERT_EQ(BalsaFrameEnums::NO_ERROR, frame_->ErrorCode());
102 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
105 TEST_F(BalsaFrameTest, GetRequest) {
106 const char input[] = "GET / HTTP/1.0\r\nkey1: value1\r\n\r\n";
107 const char* line = NULL;
108 size_t line_length = 0;
109 const char* method = NULL;
110 size_t method_length = 0;
111 const char* request_uri = NULL;
112 size_t request_uri_length = 0;
113 const char* version = NULL;
114 size_t version_length = 0;
115 const char* header = NULL;
116 size_t header_length = 0;
119 InSequence s;
120 EXPECT_CALL(*visitor_, ProcessRequestFirstLine(_, _, _, _, _, _, _, _))
121 .WillOnce(DoAll(SaveArg<0>(&line),
122 SaveArg<1>(&line_length),
123 SaveArg<2>(&method),
124 SaveArg<3>(&method_length),
125 SaveArg<4>(&request_uri),
126 SaveArg<5>(&request_uri_length),
127 SaveArg<6>(&version),
128 SaveArg<7>(&version_length)));
129 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _))
130 .WillOnce(DoAll(SaveArg<0>(&header), SaveArg<1>(&header_length)));
131 EXPECT_CALL(*visitor_, ProcessHeaders(_));
132 EXPECT_CALL(*visitor_, HeaderDone());
133 EXPECT_CALL(*visitor_, MessageDone());
136 frame_->set_balsa_headers(frame_headers_.get());
137 ASSERT_EQ(frame_headers_.get(), frame_->const_balsa_headers());
138 ASSERT_EQ(frame_headers_.get(), frame_->balsa_headers());
139 ASSERT_EQ(frame_headers_.get(), frame_->headers());
140 ASSERT_EQ(frame_headers_.get(), frame_->mutable_headers());
142 size_t read = frame_->ProcessInput(input, strlen(input));
143 ASSERT_EQ(strlen(input), read);
144 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
145 ASSERT_TRUE(frame_->MessageFullyRead());
146 ASSERT_FALSE(frame_->Error());
147 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
148 ASSERT_EQ("GET / HTTP/1.0", StringPiece(line, line_length));
149 ASSERT_EQ("GET", StringPiece(method, method_length));
150 ASSERT_EQ("/", StringPiece(request_uri, request_uri_length));
151 ASSERT_EQ("HTTP/1.0", StringPiece(version, version_length));
152 ASSERT_EQ(input, StringPiece(header, header_length));
155 TEST_F(BalsaFrameTest, HeadResponse) {
156 const char input[] = "HTTP/1.1 200 OK\r\n"
157 "Content-type: text/plain\r\n"
158 "Content-Length: 14\r\n\r\n";
159 const char* line = NULL;
160 size_t line_length = 0;
161 const char* version = NULL;
162 size_t version_length = 0;
163 const char* status = NULL;
164 size_t status_length = 0;
165 const char* reason = NULL;
166 size_t reason_length = 0;
167 const char* header = NULL;
168 size_t header_length = 0;
170 frame_->set_balsa_headers(frame_headers_.get());
171 frame_->set_is_request(false);
172 frame_->set_request_was_head(true);
175 InSequence s;
176 EXPECT_CALL(*visitor_, ProcessResponseFirstLine(_, _, _, _, _, _, _, _))
177 .WillOnce(DoAll(SaveArg<0>(&line),
178 SaveArg<1>(&line_length),
179 SaveArg<2>(&version),
180 SaveArg<3>(&version_length),
181 SaveArg<4>(&status),
182 SaveArg<5>(&status_length),
183 SaveArg<6>(&reason),
184 SaveArg<7>(&reason_length)));
185 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _))
186 .WillOnce(DoAll(SaveArg<0>(&header), SaveArg<1>(&header_length)));
187 EXPECT_CALL(*visitor_, ProcessHeaders(_));
188 EXPECT_CALL(*visitor_, HeaderDone());
189 EXPECT_CALL(*visitor_, MessageDone());
192 size_t read = frame_->ProcessInput(input, strlen(input));
193 ASSERT_EQ(strlen(input), read);
194 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
195 ASSERT_TRUE(frame_->MessageFullyRead());
196 ASSERT_FALSE(frame_->Error());
197 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
199 ASSERT_EQ("HTTP/1.1 200 OK", StringPiece(line, line_length));
200 ASSERT_EQ("HTTP/1.1", StringPiece(version, version_length));
201 ASSERT_EQ("200", StringPiece(status, status_length));
202 ASSERT_EQ("OK", StringPiece(reason, reason_length));
203 ASSERT_EQ("HTTP/1.1 200 OK\r\n"
204 "Content-type: text/plain\r\n"
205 "Content-Length: 14\r\n\r\n",
206 StringPiece(header, header_length));
209 TEST_F(BalsaFrameTest, GetResponse) {
210 const char input[] = "HTTP/1.1 200 OK\r\n"
211 "Content-type: text/plain\r\n"
212 "Content-Length: 14\r\n\r\n"
213 "hello, world\r\n";
214 const char* line = NULL;
215 size_t line_length = 0;
216 const char* version = NULL;
217 size_t version_length = 0;
218 const char* status = NULL;
219 size_t status_length = 0;
220 const char* reason = NULL;
221 size_t reason_length = 0;
222 const char* header = NULL;
223 size_t header_length = 0;
224 const char* body = NULL;
225 size_t body_length = 0;
226 const char* body_data = NULL;
227 size_t body_data_length = 0;
228 testing::MockFunction<void(int)> checkpoint;
230 frame_->set_balsa_headers(frame_headers_.get());
231 frame_->set_is_request(false);
234 InSequence s;
235 EXPECT_CALL(*visitor_, ProcessResponseFirstLine(_, _, _, _, _, _, _, _))
236 .WillOnce(DoAll(SaveArg<0>(&line),
237 SaveArg<1>(&line_length),
238 SaveArg<2>(&version),
239 SaveArg<3>(&version_length),
240 SaveArg<4>(&status),
241 SaveArg<5>(&status_length),
242 SaveArg<6>(&reason),
243 SaveArg<7>(&reason_length)));
244 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _))
245 .WillOnce(DoAll(SaveArg<0>(&header), SaveArg<1>(&header_length)));
246 EXPECT_CALL(*visitor_, ProcessHeaders(_));
247 EXPECT_CALL(*visitor_, HeaderDone());
248 EXPECT_CALL(checkpoint, Call(0));
249 EXPECT_CALL(*visitor_, ProcessBodyInput(_, _))
250 .WillOnce(DoAll(SaveArg<0>(&body), SaveArg<1>(&body_length)));
251 EXPECT_CALL(*visitor_, ProcessBodyData(_, _))
252 .WillOnce(DoAll(SaveArg<0>(&body_data), SaveArg<1>(&body_data_length)));
253 EXPECT_CALL(*visitor_, MessageDone());
256 size_t read = frame_->ProcessInput(input, strlen(input));
257 ASSERT_EQ(65u, read);
258 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
259 checkpoint.Call(0);
260 read += frame_->ProcessInput(&input[read], strlen(input) - read);
261 ASSERT_EQ(strlen(input), read);
262 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
263 ASSERT_TRUE(frame_->MessageFullyRead());
264 ASSERT_FALSE(frame_->Error());
265 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
267 ASSERT_EQ("HTTP/1.1 200 OK", StringPiece(line, line_length));
268 ASSERT_EQ("HTTP/1.1", StringPiece(version, version_length));
269 ASSERT_EQ("200", StringPiece(status, status_length));
270 ASSERT_EQ("OK", StringPiece(reason, reason_length));
271 ASSERT_EQ("HTTP/1.1 200 OK\r\n"
272 "Content-type: text/plain\r\n"
273 "Content-Length: 14\r\n\r\n",
274 StringPiece(header, header_length));
275 ASSERT_EQ("hello, world\r\n", StringPiece(body, body_length));
276 ASSERT_EQ("hello, world\r\n", StringPiece(body_data, body_data_length));
279 TEST_F(BalsaFrameTest, Reset) {
280 const char input[] = "GET / HTTP/1.0\r\nkey1: value1\r\n\r\n";
283 InSequence s;
284 EXPECT_CALL(*visitor_, ProcessRequestFirstLine(_, _, _, _, _, _, _, _));
285 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _));
286 EXPECT_CALL(*visitor_, ProcessHeaders(_));
287 EXPECT_CALL(*visitor_, HeaderDone());
288 EXPECT_CALL(*visitor_, MessageDone());
291 frame_->set_balsa_headers(frame_headers_.get());
293 size_t read = frame_->ProcessInput(input, strlen(input));
294 ASSERT_EQ(strlen(input), read);
295 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
296 ASSERT_TRUE(frame_->MessageFullyRead());
297 ASSERT_FALSE(frame_->Error());
299 frame_->Reset();
300 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
301 frame_->ParseState());
302 ASSERT_FALSE(frame_->MessageFullyRead());
303 ASSERT_FALSE(frame_->Error());
306 TEST_F(BalsaFrameTest, InvalidStatusCode) {
307 const char input[] = "HTTP/1.1 InvalidStatusCode OK\r\n"
308 "Content-type: text/plain\r\n"
309 "Content-Length: 14\r\n\r\n"
310 "hello, world\r\n";
312 frame_->set_balsa_headers(frame_headers_.get());
313 frame_->set_is_request(false);
316 InSequence s;
317 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get()));
320 size_t read = frame_->ProcessInput(input, strlen(input));
321 ASSERT_EQ(30u, read);
322 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR, frame_->ParseState());
323 ASSERT_EQ(BalsaFrameEnums::FAILED_CONVERTING_STATUS_CODE_TO_INT,
324 frame_->ErrorCode());
325 ASSERT_FALSE(frame_->MessageFullyRead());
326 ASSERT_TRUE(frame_->Error());
327 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
330 TEST_F(BalsaFrameTest, ResetError) {
331 const char input[] = "HTTP/1.1 InvalidStatusCode OK\r\n"
332 "Content-type: text/plain\r\n"
333 "Content-Length: 14\r\n\r\n"
334 "hello, world\r\n";
336 frame_->set_balsa_headers(frame_headers_.get());
337 frame_->set_is_request(false);
340 InSequence s;
341 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get()));
344 size_t read = frame_->ProcessInput(input, strlen(input));
345 ASSERT_EQ(30u, read);
346 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR, frame_->ParseState());
347 ASSERT_EQ(BalsaFrameEnums::FAILED_CONVERTING_STATUS_CODE_TO_INT,
348 frame_->ErrorCode());
349 ASSERT_FALSE(frame_->MessageFullyRead());
350 ASSERT_TRUE(frame_->Error());
351 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
353 frame_->Reset();
354 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
355 frame_->ParseState());
356 ASSERT_FALSE(frame_->MessageFullyRead());
357 ASSERT_FALSE(frame_->Error());
360 TEST_F(BalsaFrameTest, RequestURITooLong) {
361 const char input[] = "GET / HTTP/1.0\r\n\r\n";
363 frame_->set_balsa_headers(frame_headers_.get());
364 frame_->set_max_request_uri_length(0);
367 InSequence s;
368 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get()));
371 size_t read = frame_->ProcessInput(input, strlen(input));
372 ASSERT_EQ(15u, read);
373 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR, frame_->ParseState());
374 ASSERT_EQ(BalsaFrameEnums::REQUEST_URI_TOO_LONG, frame_->ErrorCode());
375 ASSERT_FALSE(frame_->MessageFullyRead());
376 ASSERT_TRUE(frame_->Error());
377 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
380 TEST_F(BalsaFrameTest, HeadersTooLong) {
381 const char input[] = "GET / HTTP/1.0\r\n\r\n";
383 frame_->set_balsa_headers(frame_headers_.get());
384 frame_->set_max_header_length(0);
387 InSequence s;
388 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get()));
391 size_t read = frame_->ProcessInput(input, strlen(input));
392 ASSERT_EQ(0u, read);
393 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR, frame_->ParseState());
394 ASSERT_EQ(BalsaFrameEnums::HEADERS_TOO_LONG, frame_->ErrorCode());
395 ASSERT_FALSE(frame_->MessageFullyRead());
396 ASSERT_TRUE(frame_->Error());
397 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
400 TEST_F(BalsaFrameTest, InvalidHeader) {
401 const char input[] = "GET / HTTP/1.0\r\n"
402 "foo bar baz\r\n"
403 "Content-Type: text/plain\r\n\r\n";
404 const char* line = NULL;
405 size_t line_length = 0;
406 const char* method = NULL;
407 size_t method_length = 0;
408 const char* request_uri = NULL;
409 size_t request_uri_length = 0;
410 const char* version = NULL;
411 size_t version_length = 0;
413 frame_->set_balsa_headers(frame_headers_.get());
416 InSequence s;
417 EXPECT_CALL(*visitor_, ProcessRequestFirstLine(_, _, _, _, _, _, _, _))
418 .WillOnce(DoAll(SaveArg<0>(&line),
419 SaveArg<1>(&line_length),
420 SaveArg<2>(&method),
421 SaveArg<3>(&method_length),
422 SaveArg<4>(&request_uri),
423 SaveArg<5>(&request_uri_length),
424 SaveArg<6>(&version),
425 SaveArg<7>(&version_length)));
426 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _));
427 EXPECT_CALL(*visitor_, HandleHeaderWarning(frame_.get()));
428 EXPECT_CALL(*visitor_, ProcessHeaders(_));
429 EXPECT_CALL(*visitor_, HeaderDone());
430 EXPECT_CALL(*visitor_, MessageDone());
433 size_t read = frame_->ProcessInput(input, strlen(input));
434 ASSERT_EQ(strlen(input), read);
435 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
436 ASSERT_EQ(BalsaFrameEnums::HEADER_MISSING_COLON, frame_->ErrorCode());
437 ASSERT_TRUE(frame_->MessageFullyRead());
438 ASSERT_FALSE(frame_->Error());
439 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
440 ASSERT_EQ("GET / HTTP/1.0", StringPiece(line, line_length));
441 ASSERT_EQ("GET", StringPiece(method, method_length));
442 ASSERT_EQ("/", StringPiece(request_uri, request_uri_length));
443 ASSERT_EQ("HTTP/1.0", StringPiece(version, version_length));
444 ASSERT_EQ(2, std::distance(frame_headers_->header_lines_begin(),
445 frame_headers_->header_lines_end()));
448 TEST_F(BalsaFrameTest, GetResponseSplit) {
449 const char input[] = "HTTP/1.1 200 OK\r\n"
450 "Content-type: text/plain\r\n"
451 "Content-Length: 14\r\n\r\n"
452 "hello";
453 const char input2[] = ", world\r\n";
454 const char* body1 = NULL;
455 size_t body1_length = 0;
456 const char* body1_data = NULL;
457 size_t body1_data_length = 0;
458 const char* body2 = NULL;
459 size_t body2_length = 0;
460 const char* body2_data = NULL;
461 size_t body2_data_length = 0;
462 testing::MockFunction<void(int)> checkpoint;
464 frame_->set_balsa_headers(frame_headers_.get());
465 frame_->set_is_request(false);
468 InSequence s;
469 EXPECT_CALL(*visitor_, ProcessResponseFirstLine(_, _, _, _, _, _, _, _));
470 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _));
471 EXPECT_CALL(*visitor_, ProcessHeaders(_));
472 EXPECT_CALL(*visitor_, HeaderDone());
473 EXPECT_CALL(checkpoint, Call(0));
474 EXPECT_CALL(*visitor_, ProcessBodyInput(_, _))
475 .WillOnce(DoAll(SaveArg<0>(&body1), SaveArg<1>(&body1_length)));
476 EXPECT_CALL(*visitor_, ProcessBodyData(_, _))
477 .WillOnce(DoAll(SaveArg<0>(&body1_data),
478 SaveArg<1>(&body1_data_length)));
479 EXPECT_CALL(checkpoint, Call(1));
480 EXPECT_CALL(*visitor_, ProcessBodyInput(_, _))
481 .WillOnce(DoAll(SaveArg<0>(&body2), SaveArg<1>(&body2_length)));
482 EXPECT_CALL(*visitor_, ProcessBodyData(_, _))
483 .WillOnce(DoAll(SaveArg<0>(&body2_data),
484 SaveArg<1>(&body2_data_length)));
485 EXPECT_CALL(*visitor_, MessageDone());
488 size_t read = frame_->ProcessInput(input, strlen(input));
489 ASSERT_EQ(65u, read);
490 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
491 checkpoint.Call(0);
492 read += frame_->ProcessInput(&input[read], strlen(input) - read);
493 ASSERT_EQ(strlen(input), read);
494 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
495 checkpoint.Call(1);
496 ASSERT_EQ(9u, frame_->BytesSafeToSplice());
497 read = frame_->ProcessInput(input2, strlen(input2));
498 ASSERT_EQ(strlen(input2), read);
500 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
501 ASSERT_TRUE(frame_->MessageFullyRead());
502 ASSERT_FALSE(frame_->Error());
503 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
504 ASSERT_EQ("hello", StringPiece(body1, body1_length));
505 ASSERT_EQ("hello", StringPiece(body1_data, body1_data_length));
506 ASSERT_EQ(", world\r\n", StringPiece(body2, body2_length));
507 ASSERT_EQ(", world\r\n", StringPiece(body2_data, body2_data_length));
510 TEST_F(BalsaFrameTest, GetResponseBytesSpliced) {
511 const char input[] = "HTTP/1.1 200 OK\r\n"
512 "Content-type: text/plain\r\n"
513 "Content-Length: 14\r\n\r\n"
514 "hello";
515 testing::MockFunction<void(int)> checkpoint;
517 frame_->set_balsa_headers(frame_headers_.get());
518 frame_->set_is_request(false);
521 InSequence s;
522 EXPECT_CALL(*visitor_, ProcessResponseFirstLine(_, _, _, _, _, _, _, _));
523 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _));
524 EXPECT_CALL(*visitor_, ProcessHeaders(_));
525 EXPECT_CALL(*visitor_, HeaderDone());
526 EXPECT_CALL(checkpoint, Call(0));
527 EXPECT_CALL(*visitor_, ProcessBodyInput(_, _));
528 EXPECT_CALL(*visitor_, ProcessBodyData(_, _));
529 EXPECT_CALL(checkpoint, Call(1));
530 EXPECT_CALL(checkpoint, Call(2));
531 EXPECT_CALL(*visitor_, MessageDone());
534 size_t read = frame_->ProcessInput(input, strlen(input));
535 ASSERT_EQ(65u, read);
536 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
537 checkpoint.Call(0);
538 read += frame_->ProcessInput(&input[read], strlen(input) - read);
539 ASSERT_EQ(strlen(input), read);
540 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
541 ASSERT_EQ(9u, frame_->BytesSafeToSplice());
542 checkpoint.Call(1);
543 frame_->BytesSpliced(5);
544 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
545 ASSERT_EQ(4u, frame_->BytesSafeToSplice());
546 checkpoint.Call(2);
547 frame_->BytesSpliced(4);
548 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ, frame_->ParseState());
550 ASSERT_TRUE(frame_->MessageFullyRead());
551 ASSERT_FALSE(frame_->Error());
552 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
555 TEST_F(BalsaFrameTest, GetResponseBytesSplicedTooMany) {
556 const char input[] = "HTTP/1.1 200 OK\r\n"
557 "Content-type: text/plain\r\n"
558 "Content-Length: 14\r\n\r\n"
559 "hello";
560 testing::MockFunction<void(int)> checkpoint;
562 frame_->set_balsa_headers(frame_headers_.get());
563 frame_->set_is_request(false);
566 InSequence s;
567 EXPECT_CALL(*visitor_, ProcessResponseFirstLine(_, _, _, _, _, _, _, _));
568 EXPECT_CALL(*visitor_, ProcessHeaderInput(_, _));
569 EXPECT_CALL(*visitor_, ProcessHeaders(_));
570 EXPECT_CALL(*visitor_, HeaderDone());
571 EXPECT_CALL(checkpoint, Call(0));
572 EXPECT_CALL(*visitor_, ProcessBodyInput(_, _));
573 EXPECT_CALL(*visitor_, ProcessBodyData(_, _));
574 EXPECT_CALL(checkpoint, Call(1));
575 EXPECT_CALL(*visitor_, HandleBodyError(frame_.get()));
578 size_t read = frame_->ProcessInput(input, strlen(input));
579 ASSERT_EQ(65u, read);
580 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
581 checkpoint.Call(0);
582 read += frame_->ProcessInput(&input[read], strlen(input) - read);
583 ASSERT_EQ(strlen(input), read);
584 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT, frame_->ParseState());
585 ASSERT_EQ(9u, frame_->BytesSafeToSplice());
586 checkpoint.Call(1);
587 frame_->BytesSpliced(99);
588 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR, frame_->ParseState());
589 ASSERT_FALSE(frame_->MessageFullyRead());
590 ASSERT_TRUE(frame_->Error());
591 ASSERT_EQ(
592 BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT,
593 frame_->ErrorCode());
594 ASSERT_EQ(0u, frame_->BytesSafeToSplice());
597 } // namespace
599 } // namespace net