Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/ftp/ftp_network_transaction.h" | 5 #include "net/ftp/ftp_network_transaction.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "net/base/address_list.h" | 16 #include "net/base/address_list.h" |
| 17 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "net/base/parse_number.h" | |
| 19 #include "net/base/port_util.h" | 20 #include "net/base/port_util.h" |
| 20 #include "net/base/url_util.h" | 21 #include "net/base/url_util.h" |
| 21 #include "net/ftp/ftp_request_info.h" | 22 #include "net/ftp/ftp_request_info.h" |
| 22 #include "net/ftp/ftp_util.h" | 23 #include "net/ftp/ftp_util.h" |
| 23 #include "net/log/net_log.h" | 24 #include "net/log/net_log.h" |
| 24 #include "net/log/net_log_event_type.h" | 25 #include "net/log/net_log_event_type.h" |
| 25 #include "net/log/net_log_source.h" | 26 #include "net/log/net_log_source.h" |
| 26 #include "net/socket/client_socket_factory.h" | 27 #include "net/socket/client_socket_factory.h" |
| 27 #include "net/socket/stream_socket.h" | 28 #include "net/socket/stream_socket.h" |
| 28 #include "url/url_constants.h" | 29 #include "url/url_constants.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 } | 117 } |
| 117 } | 118 } |
| 118 | 119 |
| 119 // From RFC 2428 Section 3: | 120 // From RFC 2428 Section 3: |
| 120 // The text returned in response to the EPSV command MUST be: | 121 // The text returned in response to the EPSV command MUST be: |
| 121 // <some text> (<d><d><d><tcp-port><d>) | 122 // <some text> (<d><d><d><tcp-port><d>) |
| 122 // <d> is a delimiter character, ideally to be | | 123 // <d> is a delimiter character, ideally to be | |
| 123 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) { | 124 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) { |
| 124 if (response.lines.size() != 1) | 125 if (response.lines.size() != 1) |
| 125 return false; | 126 return false; |
| 126 const char* ptr = response.lines[0].c_str(); | 127 |
| 127 while (*ptr && *ptr != '(') | 128 base::StringPiece epsv_line(response.lines[0]); |
| 128 ++ptr; | 129 size_t start = epsv_line.find('('); |
| 129 if (!*ptr) | 130 // If the line doesn't have a '(' or doesn't have enough characters after the |
| 130 return false; | 131 // first '(', fail. |
| 131 char sep = *(++ptr); | 132 if (start == epsv_line.npos || epsv_line.length() - start < 6) |
|
eroman
2016/11/28 22:51:57
This is more commonly written as |StringPiece::npo
mmenke
2016/11/28 23:15:48
Done.
| |
| 132 if (!sep || isdigit(sep) || *(++ptr) != sep || *(++ptr) != sep) | |
| 133 return false; | |
| 134 if (!isdigit(*(++ptr))) | |
| 135 return false; | |
| 136 *port = *ptr - '0'; | |
| 137 while (isdigit(*(++ptr))) { | |
| 138 *port *= 10; | |
| 139 *port += *ptr - '0'; | |
| 140 } | |
| 141 if (*ptr != sep) | |
| 142 return false; | 133 return false; |
| 143 | 134 |
| 144 return true; | 135 // Make sure we have "(<d><d><d>...", where <d> is not a number. |
| 136 if (isdigit(epsv_line[start + 1]) || | |
| 137 epsv_line[start + 1] != epsv_line[start + 2] || | |
| 138 epsv_line[start + 1] != epsv_line[start + 3]) { | |
|
mmenke
2016/11/28 22:28:18
This is still ugly, but it seems a bit better to m
eroman
2016/11/28 22:51:57
Can you extract epsv_line[start+1] to a variable?
mmenke
2016/11/28 23:15:48
Done.
| |
| 139 return false; | |
| 140 } | |
| 141 | |
| 142 // Skip over those characters. | |
| 143 start += 4; | |
| 144 | |
| 145 // Make sure there's a terminal <d>. | |
| 146 size_t end = epsv_line.find(epsv_line[start - 1], start); | |
|
eroman
2016/11/28 22:51:57
Same comment. Rather than using epsv_line[start-1]
mmenke
2016/11/28 23:15:48
Done.
| |
| 147 if (end == epsv_line.npos) | |
|
eroman
2016/11/28 22:51:57
StringPiece::npos
mmenke
2016/11/28 23:15:48
Done.
| |
| 148 return false; | |
| 149 | |
| 150 return ParseInt32(epsv_line.substr(start, end - start), | |
| 151 ParseIntFormat::NON_NEGATIVE, port); | |
| 145 } | 152 } |
| 146 | 153 |
| 147 // There are two way we can receive IP address and port. | 154 // There are two way we can receive IP address and port. |
| 148 // (127,0,0,1,23,21) IP address and port encapsulated in (). | 155 // (127,0,0,1,23,21) IP address and port encapsulated in (). |
| 149 // 127,0,0,1,23,21 IP address and port without (). | 156 // 127,0,0,1,23,21 IP address and port without (). |
| 150 // | 157 // |
| 151 // See RFC 959, Section 4.1.2 | 158 // See RFC 959, Section 4.1.2 |
| 152 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) { | 159 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) { |
| 153 if (response.lines.size() != 1) | 160 if (response.lines.size() != 1) |
| 154 return false; | 161 return false; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 184 // Split the line into comma-separated pieces and extract | 191 // Split the line into comma-separated pieces and extract |
| 185 // the last two. | 192 // the last two. |
| 186 std::vector<base::StringPiece> pieces = base::SplitStringPiece( | 193 std::vector<base::StringPiece> pieces = base::SplitStringPiece( |
| 187 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 194 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 188 if (pieces.size() != 6) | 195 if (pieces.size() != 6) |
| 189 return false; | 196 return false; |
| 190 | 197 |
| 191 // Ignore the IP address supplied in the response. We are always going | 198 // Ignore the IP address supplied in the response. We are always going |
| 192 // to connect back to the same server to prevent FTP PASV port scanning. | 199 // to connect back to the same server to prevent FTP PASV port scanning. |
| 193 int p0, p1; | 200 int p0, p1; |
| 194 if (!base::StringToInt(pieces[4], &p0)) | 201 if (!ParseInt32(pieces[4], ParseIntFormat::NON_NEGATIVE, &p0)) |
|
eroman
2016/11/28 22:51:57
ParseUint32() ?
or should we add a ParseUint8() ?
mmenke
2016/11/28 23:15:48
Went with ParseUint32 (Don't think adding a new me
| |
| 195 return false; | 202 return false; |
| 196 if (!base::StringToInt(pieces[5], &p1)) | 203 if (!ParseInt32(pieces[5], ParseIntFormat::NON_NEGATIVE, &p1)) |
| 197 return false; | 204 return false; |
| 205 if (p0 >= 256 || p1 >= 256) | |
|
eroman
2016/11/28 22:51:57
optional nit: I think it would be clearer writte a
mmenke
2016/11/28 23:15:48
Done.
| |
| 206 return false; | |
| 207 | |
| 198 *port = (p0 << 8) + p1; | 208 *port = (p0 << 8) + p1; |
| 199 | |
| 200 return true; | 209 return true; |
| 201 } | 210 } |
| 202 | 211 |
| 203 } // namespace | 212 } // namespace |
| 204 | 213 |
| 205 FtpNetworkTransaction::FtpNetworkTransaction( | 214 FtpNetworkTransaction::FtpNetworkTransaction( |
| 206 HostResolver* resolver, | 215 HostResolver* resolver, |
| 207 ClientSocketFactory* socket_factory) | 216 ClientSocketFactory* socket_factory) |
| 208 : command_sent_(COMMAND_NONE), | 217 : command_sent_(COMMAND_NONE), |
| 209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, | 218 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
| (...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 if (!had_error_type[type]) { | 1352 if (!had_error_type[type]) { |
| 1344 had_error_type[type] = true; | 1353 had_error_type[type] = true; |
| 1345 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1354 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
| 1346 type, NUM_OF_NET_ERROR_TYPES); | 1355 type, NUM_OF_NET_ERROR_TYPES); |
| 1347 } | 1356 } |
| 1348 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1357 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
| 1349 type, NUM_OF_NET_ERROR_TYPES); | 1358 type, NUM_OF_NET_ERROR_TYPES); |
| 1350 } | 1359 } |
| 1351 | 1360 |
| 1352 } // namespace net | 1361 } // namespace net |
| OLD | NEW |