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