Home | History | Annotate | Download | only in ftp
      1 // Copyright (c) 2009 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/ftp/ftp_ctrl_response_buffer.h"
      6 
      7 #include <string.h>
      8 
      9 #include "net/base/net_errors.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 namespace {
     13 
     14 class FtpCtrlResponseBufferTest : public testing::Test {
     15  public:
     16   FtpCtrlResponseBufferTest() : buffer_(net::BoundNetLog()) {
     17   }
     18 
     19  protected:
     20   int PushDataToBuffer(const char* data) {
     21     return buffer_.ConsumeData(data, strlen(data));
     22   }
     23 
     24   net::FtpCtrlResponseBuffer buffer_;
     25 };
     26 
     27 TEST_F(FtpCtrlResponseBufferTest, Basic) {
     28   EXPECT_FALSE(buffer_.ResponseAvailable());
     29 
     30   EXPECT_EQ(net::OK, PushDataToBuffer("200 Status Text\r\n"));
     31   EXPECT_TRUE(buffer_.ResponseAvailable());
     32 
     33   net::FtpCtrlResponse response = buffer_.PopResponse();
     34   EXPECT_FALSE(buffer_.ResponseAvailable());
     35   EXPECT_EQ(200, response.status_code);
     36   ASSERT_EQ(1U, response.lines.size());
     37   EXPECT_EQ("Status Text", response.lines[0]);
     38 }
     39 
     40 TEST_F(FtpCtrlResponseBufferTest, Chunks) {
     41   EXPECT_EQ(net::OK, PushDataToBuffer("20"));
     42   EXPECT_FALSE(buffer_.ResponseAvailable());
     43   EXPECT_EQ(net::OK, PushDataToBuffer("0 Status"));
     44   EXPECT_FALSE(buffer_.ResponseAvailable());
     45   EXPECT_EQ(net::OK, PushDataToBuffer(" Text"));
     46   EXPECT_FALSE(buffer_.ResponseAvailable());
     47   EXPECT_EQ(net::OK, PushDataToBuffer("\r"));
     48   EXPECT_FALSE(buffer_.ResponseAvailable());
     49   EXPECT_EQ(net::OK, PushDataToBuffer("\n"));
     50   EXPECT_TRUE(buffer_.ResponseAvailable());
     51 
     52   net::FtpCtrlResponse response = buffer_.PopResponse();
     53   EXPECT_FALSE(buffer_.ResponseAvailable());
     54   EXPECT_EQ(200, response.status_code);
     55   ASSERT_EQ(1U, response.lines.size());
     56   EXPECT_EQ("Status Text", response.lines[0]);
     57 }
     58 
     59 TEST_F(FtpCtrlResponseBufferTest, Continuation) {
     60   EXPECT_EQ(net::OK, PushDataToBuffer("230-FirstLine\r\n"));
     61   EXPECT_FALSE(buffer_.ResponseAvailable());
     62 
     63   EXPECT_EQ(net::OK, PushDataToBuffer("230-SecondLine\r\n"));
     64   EXPECT_FALSE(buffer_.ResponseAvailable());
     65 
     66   EXPECT_EQ(net::OK, PushDataToBuffer("230 LastLine\r\n"));
     67   EXPECT_TRUE(buffer_.ResponseAvailable());
     68 
     69   net::FtpCtrlResponse response = buffer_.PopResponse();
     70   EXPECT_FALSE(buffer_.ResponseAvailable());
     71   EXPECT_EQ(230, response.status_code);
     72   ASSERT_EQ(3U, response.lines.size());
     73   EXPECT_EQ("FirstLine", response.lines[0]);
     74   EXPECT_EQ("SecondLine", response.lines[1]);
     75   EXPECT_EQ("LastLine", response.lines[2]);
     76 }
     77 
     78 TEST_F(FtpCtrlResponseBufferTest, MultilineContinuation) {
     79   EXPECT_EQ(net::OK, PushDataToBuffer("230-FirstLine\r\n"));
     80   EXPECT_FALSE(buffer_.ResponseAvailable());
     81 
     82   EXPECT_EQ(net::OK, PushDataToBuffer("Continued\r\n"));
     83   EXPECT_FALSE(buffer_.ResponseAvailable());
     84 
     85   EXPECT_EQ(net::OK, PushDataToBuffer("230-SecondLine\r\n"));
     86   EXPECT_FALSE(buffer_.ResponseAvailable());
     87 
     88   EXPECT_EQ(net::OK, PushDataToBuffer("215 Continued\r\n"));
     89   EXPECT_FALSE(buffer_.ResponseAvailable());
     90 
     91   EXPECT_EQ(net::OK, PushDataToBuffer("230 LastLine\r\n"));
     92   EXPECT_TRUE(buffer_.ResponseAvailable());
     93 
     94   net::FtpCtrlResponse response = buffer_.PopResponse();
     95   EXPECT_FALSE(buffer_.ResponseAvailable());
     96   EXPECT_EQ(230, response.status_code);
     97   ASSERT_EQ(3U, response.lines.size());
     98   EXPECT_EQ("FirstLineContinued", response.lines[0]);
     99   EXPECT_EQ("SecondLine215 Continued", response.lines[1]);
    100   EXPECT_EQ("LastLine", response.lines[2]);
    101 }
    102 
    103 TEST_F(FtpCtrlResponseBufferTest, MultilineContinuationZeroLength) {
    104   // For the corner case from bug 29322.
    105   EXPECT_EQ(net::OK, PushDataToBuffer("230-\r\n"));
    106   EXPECT_FALSE(buffer_.ResponseAvailable());
    107 
    108   EXPECT_EQ(net::OK, PushDataToBuffer("example.com\r\n"));
    109   EXPECT_FALSE(buffer_.ResponseAvailable());
    110 
    111   EXPECT_EQ(net::OK, PushDataToBuffer("230 LastLine\r\n"));
    112   EXPECT_TRUE(buffer_.ResponseAvailable());
    113 
    114   net::FtpCtrlResponse response = buffer_.PopResponse();
    115   EXPECT_FALSE(buffer_.ResponseAvailable());
    116   EXPECT_EQ(230, response.status_code);
    117   ASSERT_EQ(2U, response.lines.size());
    118   EXPECT_EQ("example.com", response.lines[0]);
    119   EXPECT_EQ("LastLine", response.lines[1]);
    120 }
    121 
    122 TEST_F(FtpCtrlResponseBufferTest, SimilarContinuation) {
    123   EXPECT_EQ(net::OK, PushDataToBuffer("230-FirstLine\r\n"));
    124   EXPECT_FALSE(buffer_.ResponseAvailable());
    125 
    126   // Notice the space at the start of the line. It should be recognized
    127   // as a continuation, and not the last line.
    128   EXPECT_EQ(net::OK, PushDataToBuffer(" 230 Continued\r\n"));
    129   EXPECT_FALSE(buffer_.ResponseAvailable());
    130 
    131   EXPECT_EQ(net::OK, PushDataToBuffer("230 TrueLastLine\r\n"));
    132   EXPECT_TRUE(buffer_.ResponseAvailable());
    133 
    134   net::FtpCtrlResponse response = buffer_.PopResponse();
    135   EXPECT_FALSE(buffer_.ResponseAvailable());
    136   EXPECT_EQ(230, response.status_code);
    137   ASSERT_EQ(2U, response.lines.size());
    138   EXPECT_EQ("FirstLine 230 Continued", response.lines[0]);
    139   EXPECT_EQ("TrueLastLine", response.lines[1]);
    140 }
    141 
    142 // The nesting of multi-line responses is not allowed.
    143 TEST_F(FtpCtrlResponseBufferTest, NoNesting) {
    144   EXPECT_EQ(net::OK, PushDataToBuffer("230-FirstLine\r\n"));
    145   EXPECT_FALSE(buffer_.ResponseAvailable());
    146 
    147   EXPECT_EQ(net::OK, PushDataToBuffer("300-Continuation\r\n"));
    148   EXPECT_FALSE(buffer_.ResponseAvailable());
    149 
    150   EXPECT_EQ(net::OK, PushDataToBuffer("300 Still continuation\r\n"));
    151   EXPECT_FALSE(buffer_.ResponseAvailable());
    152 
    153   EXPECT_EQ(net::OK, PushDataToBuffer("230 Real End\r\n"));
    154   ASSERT_TRUE(buffer_.ResponseAvailable());
    155 
    156   net::FtpCtrlResponse response = buffer_.PopResponse();
    157   EXPECT_FALSE(buffer_.ResponseAvailable());
    158   EXPECT_EQ(230, response.status_code);
    159   ASSERT_EQ(2U, response.lines.size());
    160   EXPECT_EQ("FirstLine300-Continuation300 Still continuation",
    161             response.lines[0]);
    162   EXPECT_EQ("Real End", response.lines[1]);
    163 }
    164 
    165 TEST_F(FtpCtrlResponseBufferTest, NonNumericResponse) {
    166   EXPECT_EQ(net::ERR_INVALID_RESPONSE, PushDataToBuffer("Non-numeric\r\n"));
    167   EXPECT_FALSE(buffer_.ResponseAvailable());
    168 }
    169 
    170 TEST_F(FtpCtrlResponseBufferTest, OutOfRangeResponse) {
    171   EXPECT_EQ(net::ERR_INVALID_RESPONSE, PushDataToBuffer("777 OK?\r\n"));
    172   EXPECT_FALSE(buffer_.ResponseAvailable());
    173 }
    174 
    175 }  // namespace
    176