0

I want to implement some code that does exactly what I accomplish when I execute a CURL command in my Mac's terminal, which is to upload a .wav file to a Server. I already accomplished this for one server before, so my general thinking works (and my code too), ....but now I want to accomplish the same but on a different server. This time I am having trouble and all I get are "400:Bad Request"

This is he CURL command I want to do on Android, I have added a "-v" so you can see the verbose of my command.

curl -F file=@audio_life.wav 11.2.333.44:14141/transcribe -v

Output log in Terminal:

*   Trying 11.2.333.44...
* Connected to 11.2.333.44 (11.2.333.44) port 14141 (#0)
> POST /transcribe HTTP/1.1
> Host: 11.2.333.44:14141
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 304898
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------62142b52672c69e0
> 
* Done waiting for 100-continue
< HTTP/1.1 201 Created
< Content-Type: application/json
< Content-Length: 915

This is my code, I always get 400:Bad Request responses, as you can see I have tried to replicate the headers. What am I doing wrong? how can I close in on what the error may be?

String wavpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/ArtificialSolutions/"+StorageUtils.AUDIO_FILE_NAME+".wav"; 
                File wavfile = new File(wavpath);
                FileInputStream fileInputStream = new FileInputStream(wavpath);
                connectURL = new URL(ASR_URL_VOCITEC);
                String filevalue = StorageUtils.AUDIO_FILE_NAME+".wav";
                HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Host","11.2.333.44:14141");
                conn.setRequestProperty("User-Agent", "android");
                conn.setRequestProperty("Accept","*/*");
                conn.setRequestProperty("Transfer-Encoding", "chunked");
                conn.setRequestProperty("Expect", "100-continue");
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=------------------------f016e997e308ec07");//+boundary);
                DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"File\""+ lineEnd);
                //dos.writeBytes("Content-Disposition: form-data; File=\""+wavpath+"\""+ lineEnd);
                dos.writeBytes(lineEnd);

                dos.writeBytes(wavpath);
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                int bytesAvailable = fileInputStream.available();     
                int maxBufferSize = 1024;
                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                byte[ ] buffer = new byte[bufferSize];
                int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0){
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        Log.e("joshtag","BytesAvailable: "+bytesAvailable);
                        bufferSize = Math.min(bytesAvailable,maxBufferSize);
                        if(bytesAvailable>maxBufferSize){
                            bytesRead = fileInputStream.read(buffer, 0,bufferSize);
                        }
                        else{
                            bytesRead = fileInputStream.read(buffer, 0,bytesAvailable);
                            dos.write(buffer, 0, bytesAvailable);
                            break;
                        }
                }
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                fileInputStream.close();//63532 , 64556

                dos.flush();

                Log.e(Tag,"File Sent, Response: "+String.valueOf(conn.getResponseCode()));
                Log.e(Tag,"File Sent, ResponseMSG: "+String.valueOf(conn.getResponseMessage()));

This is a printout of the message I get back from the server:

{null=[HTTP/1.1 400 Bad Request], Content-Length=[42], Content-Type=[text/plain], X-Android-Received-Millis=[1449836192887], X-Android-Response-Source=[NETWORK 400], X-Android-Sent-Millis=[1449836192719]}

NOTE: I coded this based on the best of my knowledge and after examining related posts here on StartOverflow, the whole code is inside the doInBackground method of an AsyncTask so lets focus here. I hope can help me!! Thanks.

Josh
  • 6,251
  • 2
  • 46
  • 73
  • Can you post your url ?? and is that necessary to add host in request property – Madhu Dec 11 '15 at 12:04
  • You are missing the `Content-Length` header, and maybe the server is expecting it – user2340612 Dec 11 '15 at 12:07
  • @Madhu Hi, I may get in trouble if I post the URL here, I will try again without the Host header, I am not really sure it is necessary. – Josh Dec 11 '15 at 12:18
  • Hi @user2340612 , I have considered adding the Content-Length but I always get http exceptions saying that there's too many of too few bytes than expected. I was using the file size as a value, maybe the headers and stuff add more bytes ...how can I obtain those extra bytes? – Josh Dec 11 '15 at 12:21
  • `conn.setRequestProperty("Host","52.3.255.63:17171");` What is that for? Host and port should be in your url. If you could not show your url then why publish this? – greenapps Dec 11 '15 at 15:23
  • `This is a printout of the message I get back from the server:`. You receive that in Android? How? You are not even reading the response page that is send. Open an inputstream and read the page that is coming to you. – greenapps Dec 11 '15 at 15:26
  • 1
    `dos.write(buffer, 0, bufferSize);`. That should be `dos.write(buffer, 0, bytesRead);` – greenapps Dec 11 '15 at 15:28
  • 1
    The same for `dos.write(buffer, 0, bytesAvailable);`. – greenapps Dec 11 '15 at 15:32
  • Hi @greenapps thanks for your advice, I will try it soon. Can you help me by deleting your first comment about the Host please? – Josh Dec 11 '15 at 15:40
  • If you don't delete it from your code the why would i delete it from a comment? You first. – greenapps Dec 11 '15 at 15:41
  • I "masked" the address ok (my bad), just show some sportmanship, ok? Thanks @greenapps – Josh Dec 11 '15 at 16:13
  • What do you mean with masked? It's in full sight several times. – greenapps Dec 11 '15 at 16:56
  • Just spare you "help" @greenapps – Josh Dec 12 '15 at 09:06

1 Answers1

1

After much fiddling with the code, I found a way to upload a wav file with URLConnection, and using multipartentity. Here is the code, enjoy:

public int uploadWav(String sourceFileUri) {  
    String wavpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/myAppFolder/"+StorageUtils.AUDIO_FILE_NAME+".wav";
    String filename=wavpath;
    HttpURLConnection conn = null;
    DataOutputStream dos = null;  
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "------------------------afb19f4aeefb356c";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024; 
    File sourceFile = new File(fileName); 
    Log.e("joshtag", "Uploading: sourcefileURI, "+fileName);

    if (!sourceFile.isFile()) {                                
         Log.e("uploadFile", "Source File not exist :"+wavpath);//FullPath);                        
         return 0;  //RETURN #1
         }
    else{
        try{        
             Log.v("joshtag","UPLOADING .WAV FILE");
             FileInputStream fileInputStream = new FileInputStream(sourceFile);   
             URL url = new URL(SERVER_URL);
             Log.v("joshtag","UL URL: "+url.toString());

             // Open a HTTP  connection to  the URL
             conn = (HttpURLConnection) url.openConnection(); 
             conn.setDoInput(true); // Allow Inputs
             conn.setDoOutput(true); // Allow Outputs
             conn.setUseCaches(false); // Don't use a Cached Copy            s       
             conn.setRequestMethod("POST");                     
            // conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("ENCTYPE", "multipart/form-data");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);     
             conn.setRequestProperty("file", sourceFile.getName()); 
             //so on and so forth...
             //conn.setRequestProperty("param", "value");  
             conn.setRequestProperty("connection", "close");
             dos = new DataOutputStream(conn.getOutputStream());          
             dos.writeBytes(twoHyphens + boundary + lineEnd); 
             dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + sourceFile.getName() + "\"" + lineEnd);                    
             dos.writeBytes(lineEnd);      

             // create a buffer of  maximum size
             bytesAvailable = fileInputStream.available();           
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             buffer = new byte[bufferSize];         
             // read file and write it into form...
             bytesRead = fileInputStream.read(buffer, 0, bufferSize);   

             while (bytesRead > 0) {                        
                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    Log.i("joshtag","->");
                    }
             Log.i("joshtag","->->");
             // send multipart form data necesssary after file data...
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
             conn.connect();
             Log.i("joshtag","->->->");
             // Responses from the server (code and message)
             serverResponseCode = conn.getResponseCode();
             Log.i("joshtag","->->->->");
             String serverResponseMessage = conn.getResponseMessage().toString();     

             Log.i("joshtag","->->->->->");
             Log.i("joshtag", "HTTP Response is : "  + serverResponseMessage + ": " + serverResponseCode);   

             // ------------------ read the SERVER RESPONSE
             DataInputStream inStream;
             String str="";
             String response="";
             try {
                 Log.i("joshtag","->->->->->->");
                 inStream = new DataInputStream(conn.getInputStream());

                 while ((str = inStream.readLine()) != null) {
                     Log.e("joshtag", "SOF Server Response" + str);
                     response=str;
                    }
                 inStream.close();
                }
             catch (IOException ioex) {
                Log.e("joshtag", "SOF error: " + ioex.getMessage(), ioex);
                }
             conn.disconnect();
             conn=null;                       
             //close the streams //
             fileInputStream.close();
             dos.flush();
             dos.close();    

             if(serverResponseCode == 201){       
                 loge("*** SERVER RESPONSE: 201"+response);
                }//END IF Response code 201  
            // conn.disconnect();
            }//END TRY - FILE READ      
        catch (MalformedURLException ex) {
            ex.printStackTrace();   
            Log.e("joshtag", "UL error: " + ex.getMessage(), ex);  
            } //CATCH - URL Exception

         catch (Exception e) {           
            e.printStackTrace();             
            Log.e("Upload file to server Exception", "Exception : "+ e.getMessage(), e);
            } 

        return serverResponseCode; //after try       
        }//END ELSE, if file exists.
    }
Josh
  • 6,251
  • 2
  • 46
  • 73