diff -purN requests-ftp-0.3.1.orig/requests_ftp/ftp.py requests-ftp-0.3.1/requests_ftp/ftp.py --- requests-ftp-0.3.1.orig/requests_ftp/ftp.py 2018-08-02 10:13:15.801731787 -0400 +++ requests-ftp-0.3.1/requests_ftp/ftp.py 2018-08-02 10:14:20.633933095 -0400 @@ -9,6 +9,7 @@ from io import BytesIO import cgi import os import socket +import logging from requests.exceptions import ConnectionError, ConnectTimeout, ReadTimeout from requests.exceptions import RequestException @@ -102,6 +103,35 @@ def build_binary_response(request, data, return build_response(request, data, code, None) +def get_status_code_from_code_response(code): + ''' + The idea is to handle complicated code response (even multi lines). + We get the status code in two ways: + - extracting the code from the last valid line in the response + - getting it from the 3first digits in the code + After a comparaison between the two values, + we can safely set the code or raise a warning. + + Examples: + - get_code('200 Welcome') == 200 + + - multi_line_code = '226-File successfully transferred\n226 0.000 seconds' + get_code(multi_line_code) == 226 + + - multi_line_with_code_conflits = '200-File successfully transferred\n226 0.000 seconds' + get_code(multi_line_with_code_conflits) == 226 + ''' + last_valid_line_from_code = [line for line in code.split('\n') if line][-1] + status_code_from_last_line = int(last_valid_line_from_code.split()[0]) + status_code_from_first_digits = int(code[:3]) + if status_code_from_last_line != status_code_from_first_digits: + logging.warning( + 'Status code seems to be non consistant.\n' + 'Code received: %d, extracted: %d and %d' % ( + code, status_code_from_last_line, status_code_from_first_digits)) + return status_code_from_last_line + + def build_response(request, data, code, encoding): '''Builds a response object from the data returned by ftplib, using the specified encoding.''' @@ -113,8 +143,8 @@ def build_response(request, data, code, response.raw = data response.url = request.url response.request = request - last_valid_line_from_code = [line for line in code.split('\n') if line][-1] - response.status_code = int(last_valid_line_from_code.split()[0]) + response.status_code = get_status_code_from_code_response(code) + if hasattr(data, "content_len"): response.headers['Content-Length'] = str(data.content_len)