summaryrefslogtreecommitdiffstats
path: root/net/ftp/ftp_ctrl_response_buffer.cc
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-28 20:30:09 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-28 20:30:09 +0000
commitc2972193bd0d0c2354d0862444b7ce4662d52d77 (patch)
treea6cbb8ce07493d2dd6aa9062f44a741e5082739a /net/ftp/ftp_ctrl_response_buffer.cc
parent1b2bb88355feef67a2b67968f0c4a91d16799e38 (diff)
downloadchromium_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.cc107
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