問題
Pythonにはftplibというライブラリが標準で準備されており、FTPやFTPSを実装することができる。
但し、FTPSサーバ側がMSFTPS(Microsoft Windows server)の場合に、データ転送が上手くできない事象が発生した。
また、この問題はstorbinaryでのみ発生し、他のメソッドについては、問題なく実行できる。
エラー内容
Traceback (most recent call last): File "/var/jenkins_home/workspace/amb100-sales-ftp-merge/ecb-smile-sales-amb100-split-ambstore/csv_split_main.py", line 235, insession.ftp_storbinary(WORKDIR + FOLDER_SIG + FTP_LOCAL_GEN_DIR + FOLDER_SIG + append_file_name, append_file_name) File "/var/jenkins_home/workspace/amb100-sales-ftp-merge/ecb-smile-sales-amb100-split-ambstore/manuplate_ftp.py", line 143, in ftp_storbinary self.ftp_session.storbinary("STOR " + Remote_File_Name, fp) File "/usr/lib/python3.9/ftplib.py", line 501, in storbinary conn.unwrap() File "/usr/lib/python3.9/ssl.py", line 1285, in unwrap s = self._sslobj.shutdown() ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2745)
Pythonコンソールには、上記のエラーが表示される。実際には実行後すぐにエラーが出力されるわけではなく、FTPSがタイムアウトするタイミングでエラーが出力され、FTPSサーバ上に作成されるtmpファイルが削除され、FTPSが失敗する。
ftplib.pyのconnはsocketであり、データ送信が完了した後、SSLソケットが存在すれば、 SSLSocketのunwrap(終了)を実行しているが、その中の処理でshutdownが上手く行えず、停止している。
そのため、データを送信し終わった途端に、動作が停止してしまったように見えている。
conn.unwrap() をpass に置き換えた関数を準備するか、ftplib.pyを書き換える事で、
WindowsServerのFTPSでバイナリ書き込みを行う事でこの問題は迂回することができる。
対処
対処方法には、自作のFTPS用のクラスを作成し、その中で自作したstorbinaryでラップするか、別名の自作関数を準備し,呼び出す方法が考えられる。クラスを作成する例を下記する。
この問題への対処には他にも、サーバ側システムの変更、Python以外のプログラム言語を利用する方法等でも解決できる。