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"
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"
20 using ::base::StringPiece
;
22 using ::testing::InSequence
;
23 using ::testing::SaveArg
;
25 class Visitor
: public BalsaVisitorInterface
{
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*,
41 MOCK_METHOD8(ProcessResponseFirstLine
, void(const char*,
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
{
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());
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());
94 // No visitor callback should be called.
96 size_t read
= frame_
->ProcessInput(input
, strlen(input
));
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;
120 EXPECT_CALL(*visitor_
, ProcessRequestFirstLine(_
, _
, _
, _
, _
, _
, _
, _
))
121 .WillOnce(DoAll(SaveArg
<0>(&line
),
122 SaveArg
<1>(&line_length
),
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);
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
),
182 SaveArg
<5>(&status_length
),
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"
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);
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
),
241 SaveArg
<5>(&status_length
),
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());
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";
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());
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"
312 frame_
->set_balsa_headers(frame_headers_
.get());
313 frame_
->set_is_request(false);
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"
336 frame_
->set_balsa_headers(frame_headers_
.get());
337 frame_
->set_is_request(false);
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());
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);
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);
388 EXPECT_CALL(*visitor_
, HandleHeaderError(frame_
.get()));
391 size_t read
= frame_
->ProcessInput(input
, strlen(input
));
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"
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());
417 EXPECT_CALL(*visitor_
, ProcessRequestFirstLine(_
, _
, _
, _
, _
, _
, _
, _
))
418 .WillOnce(DoAll(SaveArg
<0>(&line
),
419 SaveArg
<1>(&line_length
),
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"
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);
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());
492 read
+= frame_
->ProcessInput(&input
[read
], strlen(input
) - read
);
493 ASSERT_EQ(strlen(input
), read
);
494 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT
, frame_
->ParseState());
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"
515 testing::MockFunction
<void(int)> checkpoint
;
517 frame_
->set_balsa_headers(frame_headers_
.get());
518 frame_
->set_is_request(false);
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());
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());
543 frame_
->BytesSpliced(5);
544 ASSERT_EQ(BalsaFrameEnums::READING_CONTENT
, frame_
->ParseState());
545 ASSERT_EQ(4u, frame_
->BytesSafeToSplice());
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"
560 testing::MockFunction
<void(int)> checkpoint
;
562 frame_
->set_balsa_headers(frame_headers_
.get());
563 frame_
->set_is_request(false);
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());
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());
587 frame_
->BytesSpliced(99);
588 ASSERT_EQ(BalsaFrameEnums::PARSE_ERROR
, frame_
->ParseState());
589 ASSERT_FALSE(frame_
->MessageFullyRead());
590 ASSERT_TRUE(frame_
->Error());
592 BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT
,
593 frame_
->ErrorCode());
594 ASSERT_EQ(0u, frame_
->BytesSafeToSplice());