diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-28 20:30:09 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-28 20:30:09 +0000 |
commit | c2972193bd0d0c2354d0862444b7ce4662d52d77 (patch) | |
tree | a6cbb8ce07493d2dd6aa9062f44a741e5082739a /net/ftp/ftp_ctrl_response_buffer.cc | |
parent | 1b2bb88355feef67a2b67968f0c4a91d16799e38 (diff) | |
download | chromium_src-c2972193bd0d0c2354d0862444b7ce4662d52d77.zip chromium_src-c2972193bd0d0c2354d0862444b7ce4662d52d77.tar.gz chromium_src-c2972193bd0d0c2354d0862444b7ce4662d52d77.tar.bz2 |
Rework FTP control response parsing code and fix socket Write misuse.
It also fixes other minor issues in the code, and makes ftp.vim.org work!
TEST=Visit ftp.vim.org on Linux with Chromium compiled in Debug mode. You should see directory listing after a short while.
BUG=http://crbug.com/15792
Review URL: http://codereview.chromium.org/149368
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21881 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/ftp/ftp_ctrl_response_buffer.cc')
-rw-r--r-- | net/ftp/ftp_ctrl_response_buffer.cc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/net/ftp/ftp_ctrl_response_buffer.cc b/net/ftp/ftp_ctrl_response_buffer.cc new file mode 100644 index 0000000..b60ae81 --- /dev/null +++ b/net/ftp/ftp_ctrl_response_buffer.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this +// source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +#include "net/ftp/ftp_ctrl_response_buffer.h" + +#include "base/logging.h" +#include "base/string_util.h" +#include "net/base/net_errors.h" + +namespace net { + +// static +const int FtpCtrlResponse::kInvalidStatusCode = -1; + +int FtpCtrlResponseBuffer::ConsumeData(const char* data, int data_length) { + buffer_.append(std::string(data, data_length)); + ExtractFullLinesFromBuffer(); + + while (!lines_.empty()) { + ParsedLine line = lines_.front(); + lines_.pop(); + + if (line_buf_.empty()) { + if (!line.is_complete) + return ERR_INVALID_RESPONSE; + + if (line.is_multiline) { + line_buf_ = line.status_text; + response_buf_.status_code = line.status_code; + } else { + response_buf_.status_code = line.status_code; + response_buf_.lines.push_back(line.status_text); + responses_.push(response_buf_); + + // Prepare to handle following lines. + response_buf_ = FtpCtrlResponse(); + line_buf_.clear(); + } + } else { + if (!line.is_complete || line.status_code != response_buf_.status_code) { + line_buf_.append(line.raw_text); + continue; + } + + response_buf_.lines.push_back(line_buf_); + + line_buf_ = line.status_text; + DCHECK_EQ(line.status_code, response_buf_.status_code); + + if (!line.is_multiline) { + response_buf_.lines.push_back(line_buf_); + responses_.push(response_buf_); + + // Prepare to handle following lines. + response_buf_ = FtpCtrlResponse(); + line_buf_.clear(); + } + } + } + + return OK; +} + +// static +FtpCtrlResponseBuffer::ParsedLine FtpCtrlResponseBuffer::ParseLine( + const std::string& line) { + ParsedLine result; + + if (line.length() >= 3) { + if (StringToInt(line.substr(0, 3), &result.status_code)) + result.has_status_code = (100 <= result.status_code && + result.status_code <= 599); + if (result.has_status_code && line.length() >= 4 && line[3] == ' ') { + result.is_complete = true; + } else if (result.has_status_code && line.length() >= 4 && line[3] == '-') { + result.is_complete = true; + result.is_multiline = true; + } + } + + if (result.is_complete) { + result.status_text = line.substr(4); + } else { + result.status_text = line; + } + + result.raw_text = line; + + return result; +} + +void FtpCtrlResponseBuffer::ExtractFullLinesFromBuffer() { + std::string line_buf; + int cut_pos = 0; + for (size_t i = 0; i < buffer_.length(); i++) { + line_buf.push_back(buffer_[i]); + if (i >= 1 && buffer_[i - 1] == '\r' && buffer_[i] == '\n') { + lines_.push(ParseLine(line_buf.substr(0, line_buf.length() - 2))); + cut_pos = i + 1; + line_buf.clear(); + } + } + buffer_.erase(0, cut_pos); +} + +} // namespace net |