Skip to content

Commit

Permalink
feat: handle weird ftp server (#40)
Browse files Browse the repository at this point in the history
* feat: handle weird ftp server

* chore: meh

* chore: PROTOCOL_TLSv1 is not supported on ubuntu 20.04

* chore: fix for mypy

* chore: ignore line from coverage

* chore: bump pypi version number
  • Loading branch information
fspot authored Feb 22, 2021
1 parent 776b46b commit 7fed8de
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: ['3.6', '3.7', '3.8']

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

Expand Down
28 changes: 24 additions & 4 deletions peakina/io/ftp/ftp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from contextlib import contextmanager, suppress
from datetime import datetime
from functools import partial
from ipaddress import ip_address
from os.path import basename, join
from time import sleep
from typing import Dict, List, Optional
Expand All @@ -19,20 +20,39 @@


class FTPS(ftplib.FTP_TLS):
ssl_version = ssl.PROTOCOL_TLSv1_2

def connect(self, host, port, timeout):
self.host = host
self.port = port or 990
self.timeout = timeout

self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
self.sock = ssl.wrap_socket(
self.sock, self.keyfile, self.certfile, ssl_version=ssl.PROTOCOL_TLSv1
)
self.sock = self.context.wrap_socket(self.sock, server_hostname=self.host)
self.file = self.sock.makefile('r')
self.welcome = self.getresp()
return self.welcome

def ntransfercmd(self, cmd, rest=None):
# override ntransfercmd so it reuses the sock session, to prevent SSLEOFError.
# cf. https://stackoverflow.com/questions/40536061/ssleoferror-on-ftps-using-python-ftplib
conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = self.context.wrap_socket(
conn, server_hostname=self.host, session=self.sock.session
) # this is the fix
return conn, size

def makepasv(self):
# override makepasv so it rewrites the dst address if the server gave a broken one.
# Inspired by:
# https://github.com/lavv17/lftp/blob/d67fc14d085849a6b0418bb3e912fea2e94c18d1/src/ftpclass.cc#L774
host, port = super().makepasv()
if self.af == socket.AF_INET and ip_address(host).is_private: # pragma: no cover
host = self.sock.getpeername()[0]
return host, port


@contextmanager
def ftps_client(params: ParseResult):
Expand Down Expand Up @@ -69,7 +89,7 @@ def sftp_client(params: ParseResult):
try:
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(
hostname=params.hostname,
hostname=params.hostname, # type: ignore
username=params.username,
password=params.password,
port=port,
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ long-description-content-type = text/markdown; charset=UTF-8
author = Toucan Toco
author_email = [email protected]
url = https://github.com/ToucanToco/peakina
version = 0.5.5
version = 0.5.6
license = BSD
classifiers=
Intended Audience :: Developers
Expand Down

0 comments on commit 7fed8de

Please sign in to comment.