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_frame.h" 6 7 #include <iterator> 8 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" 15 16 namespace net { 17 18 namespace { 19 20 using ::base::StringPiece; 21 using ::testing::_; 22 using ::testing::InSequence; 23 using ::testing::SaveArg; 24 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*)); 57 }; 58 59 class BalsaFrameTest : public ::testing::Test { 60 public: 61 virtual 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()); 66 }; 67 68 protected: 69 scoped_ptr<BalsaFrame> frame_; 70 scoped_ptr<BalsaHeaders> frame_headers_; 71 scoped_ptr<Visitor> visitor_; 72 }; 73 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()); 86 } 87 88 TEST_F(BalsaFrameTest, EmptyRequest) { 89 const char input[] = "\r\n"; 90 frame_->set_balsa_headers(frame_headers_.get()); 91 92 { 93 InSequence s; 94 // No visitor callback should be called. 95 } 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()); 103 } 104 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; 117 118 { 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()); 134 } 135 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()); 141 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)); 153 } 154 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; 169 170 frame_->set_balsa_headers(frame_headers_.get()); 171 frame_->set_is_request(false); 172 frame_->set_request_was_head(true); 173 174 { 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()); 190 } 191 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()); 198 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)); 207 } 208 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; 229 230 frame_->set_balsa_headers(frame_headers_.get()); 231 frame_->set_is_request(false); 232 233 { 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()); 254 } 255 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()); 266 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)); 277 } 278 279 TEST_F(BalsaFrameTest, Reset) { 280 const char input[] = "GET / HTTP/1.0\r\nkey1: value1\r\n\r\n"; 281 282 { 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()); 289 } 290 291 frame_->set_balsa_headers(frame_headers_.get()); 292 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()); 298 299 frame_->Reset(); 300 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE, 301 frame_->ParseState()); 302 ASSERT_FALSE(frame_->MessageFullyRead()); 303 ASSERT_FALSE(frame_->Error()); 304 } 305 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"; 311 312 frame_->set_balsa_headers(frame_headers_.get()); 313 frame_->set_is_request(false); 314 315 { 316 InSequence s; 317 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get())); 318 } 319 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()); 328 } 329 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"; 335 336 frame_->set_balsa_headers(frame_headers_.get()); 337 frame_->set_is_request(false); 338 339 { 340 InSequence s; 341 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get())); 342 } 343 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()); 352 353 frame_->Reset(); 354 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE, 355 frame_->ParseState()); 356 ASSERT_FALSE(frame_->MessageFullyRead()); 357 ASSERT_FALSE(frame_->Error()); 358 } 359 360 TEST_F(BalsaFrameTest, RequestURITooLong) { 361 const char input[] = "GET / HTTP/1.0\r\n\r\n"; 362 363 frame_->set_balsa_headers(frame_headers_.get()); 364 frame_->set_max_request_uri_length(0); 365 366 { 367 InSequence s; 368 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get())); 369 } 370 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()); 378 } 379 380 TEST_F(BalsaFrameTest, HeadersTooLong) { 381 const char input[] = "GET / HTTP/1.0\r\n\r\n"; 382 383 frame_->set_balsa_headers(frame_headers_.get()); 384 frame_->set_max_header_length(0); 385 386 { 387 InSequence s; 388 EXPECT_CALL(*visitor_, HandleHeaderError(frame_.get())); 389 } 390 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()); 398 } 399 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; 412 413 frame_->set_balsa_headers(frame_headers_.get()); 414 415 { 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()); 431 } 432 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())); 446 } 447 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; 463 464 frame_->set_balsa_headers(frame_headers_.get()); 465 frame_->set_is_request(false); 466 467 { 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()); 486 } 487 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); 499 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)); 508 } 509 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; 516 517 frame_->set_balsa_headers(frame_headers_.get()); 518 frame_->set_is_request(false); 519 520 { 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()); 532 } 533 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()); 549 550 ASSERT_TRUE(frame_->MessageFullyRead()); 551 ASSERT_FALSE(frame_->Error()); 552 ASSERT_EQ(0u, frame_->BytesSafeToSplice()); 553 } 554 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; 561 562 frame_->set_balsa_headers(frame_headers_.get()); 563 frame_->set_is_request(false); 564 565 { 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())); 576 } 577 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()); 595 } 596 597 } // namespace 598 599 } // namespace net 600