1

I'm trying to upload some photos on a ftps server from an Android application. All seems be working until the call of storeFile(remote, input) which creates an error javax.net.ssl.SSLException about a Broken pipe, and so the photo isn't uploaded on the server. Please can you help me to find why I've this error ? Thank you in advance !

In the server's FTP log files, it is only written an error of Closed Connection without explanations and not the javax.net.ssl.SSLException as in Android Studio.

BackgroundWorker:

private class BackGroundWorker extends AsyncTask<String, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d(TAG,"BackGroundWorker is running");
        }

        @Override
        protected Void doInBackground(String... params) {
            String local = params[1];
            String remote = params[2];

            String server = "[HIDDEN]";
            int port = 21;
            String user = "[HIDDEN]";
            String pass = "[HIDDEN]";

            FTPSClient ftp = new FTPSClient("SSL");
            //ftp.setAuthValue("SSL");

            ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));

            try
            {
                int reply;
                ftp.connect(server, port);
                System.out.println("Connected to " + server + " on " + port);

                // After connection attempt, you should check the reply code to verify
                // success.
                reply = ftp.getReplyCode();

                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftp.disconnect();
                    System.err.println("FTP server refused connection.");
                    Log.e(TAG, "Error");
                }
            }
            catch (IOException e){
                if (ftp.isConnected()){
                    try{
                        ftp.disconnect();
                    }
                    catch (IOException f){
                    }
                }
                System.err.println("Could not connect to server.");
                e.printStackTrace();
            }

            try{
                if (!ftp.login(user, pass)){
                    ftp.logout();
                }

                System.out.println("Remote system is " + ftp.getSystemType());
                //ftp.setBufferSize(1000);
                ftp.execPBSZ(0);
                ftp.execPROT("P");

                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                ftp.enterLocalPassiveMode();

                // transfer files
                InputStream input;
                input = new FileInputStream(local);

                ftp.storeFile(remote, input);

                /* SECOND METHOD, same error
                OutputStream outputStream = ftp.storeFileStream(remote);
                byte[] bytesIn = new byte[4096];
                int read = 0;

                while ((read = input.read(bytesIn)) != -1) {
                    outputStream.write(bytesIn, 0, read);
                }
                outputStream.close();
                */

                input.close();

                ftp.noop(); // check that control connection is working OK
                ftp.logout();
            }
            catch (FTPConnectionClosedException e){
                System.err.println("Server closed connection.");
                e.printStackTrace();
            }
            catch (IOException e){
                e.printStackTrace();
            }
            finally{
                if (ftp.isConnected()){
                    try{
                        ftp.disconnect();
                    }
                    catch (IOException f){
                        //do nothing
                    }
                }
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Log.d(TAG,"BackGroundWorker is finished");
        }
    }
}

Logcat:

07-16 13:44:53.040 8030-8056/com.example.test D/FTPfunctions3: BackGroundWorker is running
07-16 13:44:53.040 8030-8056/com.example.test I/System.out: 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
07-16 13:44:53.041 8030-8056/com.example.test I/System.out: 220-You are user number 1 of 50 allowed.
07-16 13:44:53.041 8030-8056/com.example.test I/System.out: 220-Local time is now 15:45. Server port: 21.
07-16 13:44:53.041 8030-8056/com.example.test I/System.out: 220-This is a private system - No anonymous login
07-16 13:44:53.041 8030-8056/com.example.test I/System.out: 220-IPv6 connections are also welcome on this server.
07-16 13:44:53.041 8030-8056/com.example.test I/System.out: 220 You will be disconnected after 15 minutes of inactivity.
07-16 13:44:53.042 8030-8056/com.example.test I/System.out: AUTH TLS
07-16 13:44:53.054 8030-8056/com.example.test I/System.out: 234 AUTH TLS OK.
07-16 13:44:53.071 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.094 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.097 8030-8056/com.example.test I/System.out: Connected to [HIDDEN] on 21
07-16 13:44:53.101 8030-8056/com.example.test I/System.out: USER *******
07-16 13:44:53.114 8030-8056/com.example.test I/System.out: 331 User [HIDDEN] OK. Password required
07-16 13:44:53.116 8030-8056/com.example.test I/System.out: PASS *******
07-16 13:44:53.118 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.186 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.205 8030-8056/com.example.test I/System.out: 230 OK. Current restricted directory is /
07-16 13:44:53.206 8030-8056/com.example.test I/System.out: SYST
07-16 13:44:53.221 8030-8056/com.example.test I/System.out: 215 UNIX Type: L8
07-16 13:44:53.221 8030-8056/com.example.test I/System.out: Remote system is UNIX Type: L8
07-16 13:44:53.222 8030-8056/com.example.test I/System.out: PBSZ 0
07-16 13:44:53.232 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.235 8030-8056/com.example.test I/System.out: 200 PBSZ=0
07-16 13:44:53.235 8030-8056/com.example.test I/System.out: PROT P
07-16 13:44:53.247 8030-8056/com.example.test I/System.out: 200 Data protection level set to "private"
07-16 13:44:53.249 8030-8056/com.example.test I/System.out: TYPE I
07-16 13:44:53.256 8030-8048/com.example.test D/EGL_emulation: eglMakeCurrent: 0xadc34d60: ver 2 0 (tinfo 0xadc39430)
07-16 13:44:53.262 8030-8056/com.example.test I/System.out: 200 TYPE is now 8-bit binary
07-16 13:44:53.267 8030-8056/com.example.test I/System.out: PASV
07-16 13:44:53.280 8030-8056/com.example.test I/System.out: 227 Entering Passive Mode (5,134,13,241,172,5)
07-16 13:44:53.300 8030-8056/com.example.test I/System.out: STOR pictures/test 16.07 1422/test 16.07 1422_16.6.2019_0.22.21.848.jpg
07-16 13:44:53.311 8030-8056/com.example.test I/System.out: 150 Accepted data connection
07-16 13:44:53.444 8030-8056/com.example.test W/System.err: javax.net.ssl.SSLException: Write error: ssl=0xadc87e00: I/O error during system call, Broken pipe
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:765)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at java.io.FilterOutputStream.close(FilterOutputStream.java:61)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at java.io.BufferedOutputStream.close(BufferedOutputStream.java:152)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:688)
07-16 13:44:53.445 8030-8056/com.example.test W/System.err:     at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:639)
07-16 13:44:53.446 8030-8056/com.example.test W/System.err:     at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:2030)
07-16 13:44:53.446 8030-8056/com.example.test W/System.err:     at com.example.test.functions.FTPfunctions3$BackGroundWorker.doInBackground(FTPfunctions3.java:102)
07-16 13:44:53.446 8030-8056/com.example.test W/System.err:     at com.example.test.functions.FTPfunctions3$BackGroundWorker.doInBackground(FTPfunctions3.java:35)
07-16 13:44:53.446 8030-8056/com.example.test W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
07-16 13:44:53.446 8030-8056/com.example.test W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-16 13:44:53.447 8030-8056/com.example.test W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-16 13:44:53.451 8030-8056/com.example.test W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-16 13:44:53.453 8030-8056/com.example.test W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-16 13:44:53.453 8030-8056/com.example.test W/System.err:     at java.lang.Thread.run(Thread.java:818)
07-16 13:44:53.475 8030-8030/com.example.test D/FTPfunctions3: BackGroundWorker is finished

Edited :

I've tried to use PatchedFTPSClient to reuse the same FTPS connection, but I still have an error, now I always have the error : java.lang.NoSuchFieldException: sessionHostPortCache. Is there somebody who understand why, please ??

Source of PatchedFTPSClient: Transfer files from android with FTPS to the server

Community
  • 1
  • 1
LeclerT
  • 21
  • 1
  • 5
  • Did you check FTP server log file? Doesn't the server require TLS/SSL session reuse? See [How to connect to FTPS server with data connection using same TLS session?](https://stackoverflow.com/q/32398754/850848) – Martin Prikryl Jul 16 '19 at 15:45
  • Thank you for your response, I'm trying to access to my company FTP server log file, if I have news I will tell you – LeclerT Jul 19 '19 at 09:39
  • Otherwise I've tried your suggestion about using the same TLS session, but I have not really understand how they want me to do. For `_prepareDataSocket_` what is the socket I need to pass in argument ? – LeclerT Jul 19 '19 at 09:44
  • It's a virtual method (a hook) that is called by `FTPSClient`. You do not call it. It gets called. What you need to do, is to implement a class that *"extends Commons Net `FTPSClient`"* and add that method to its implementation. - See the `PatchedFTPSClient` class in https://stackoverflow.com/a/48859402/850848. – Martin Prikryl Jul 19 '19 at 10:20
  • Ok thank you, so I've tried as they say with this class `PatchedFTPSClient` but it makes the error `java.lang.NoSuchFieldException: sessionHostPortCache` for me about the first line in the `try`.. – LeclerT Jul 19 '19 at 13:37
  • Furthermore I found the log files on the server and nothing speaks about my connections tentatives from the emulator – LeclerT Jul 19 '19 at 13:39
  • What version of Java are you using? + I have no idea what you mean by *"connections tentatives"*. If you mean that the log does not show anything at all about your connection, then you have a wrong log. – Martin Prikryl Jul 19 '19 at 14:24
  • Sorry I wanted to say "connections attempts", that's what I was thinking but there are no other log files. The log files for ftp are only from January or June, and no ftp file from July and I've tried in July – LeclerT Jul 19 '19 at 14:36
  • For Java I'm using Android studio in latest version so JDK 8 (1.8) – LeclerT Jul 19 '19 at 14:41

0 Answers0