Home | History | Annotate | Download | only in balsa
      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