Search code examples
androidcurlhttpurlconnectionput

Convert cUrl put with file to Android HttpUrlConnection


There are a few questions of moving from cUrl to Android, but none that deal with file upload that I found.

This CUrl request works:

$ curl -X PUT -u user:password --data-binary @myfile.pdf "https://example.com/myurl?id=myid&filename=myfile.pdf&title=My+Title&mimetype=application/pdf"

I am trying:

String url = "https://example.com/myurl?id=myid&filename=myfile.pdf&title=My+Title&mimetype=application/pdf";
String fileUrl = "myfile.pdf";
String userPassword = "user:password";
String userpass = Base64.encodeToString(userPassword.getBytes(), Base64.DEFAULT);

File f = new File(fileUrl);
    if(f.isFile()) {
        HttpURLConnection c = null;
        URL u = null;
        try {
            u = new URL(url);
                c = (HttpURLConnection) u.openConnection();
            c.setRequestProperty("Authorization", "Basic " + userpass);
            c.setDoOutput(true);
            c.setRequestMethod("PUT");
            c.setRequestProperty("Content-Type", "multipart/form-data");

            FileInputStream fis = new FileInputStream(f);
            long fl = f.length();
            output(fis, c.getOutputStream(), fl);
        } catch (Exception e) {
            e.printStackTrace();
        }

Where output(fis, c.getOutputStream(), fl); writes inputStream to outputStream and then closes/flushes both.

I am getting a response of method not allowed, anyone know what I am doing wrong?

Edit: It is really odd (to me) that their response headers have: Allow: POST,OPTIONS,GET,HEAD but the PUT using curl works.

Edit Two:

When using curl I actually get:

Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE

But when using HttpUrlConnection, even if I set the user-agent to the curl user agent, there is no Access-Control-Allow-Methods using c.getHeaderField(). Instead the field is simply Allow, and it lacks the PUT.


Solution

  • Ok, this was stupid. There is nothing wrong with the above code, but the api showed use of a .net domain, which was not configured to accept PUT. The dev had sent me a curl example using a .com domain, when I noticed that everything worked.

    One problem is Android is full of things like mySecretWeirdProtocolHandler(), NastyBugNobodyCaresAbout.class, and package.LetMePunchYouInTheFace; so I wind up looking at everything at once not knowing if it is me or them, for a stressful good time.