Search code examples
javauploadflickr

Uploading photos to flickr (Java)


I'm a beginner trying to figure out the Flickr API. I'm trying to create a simple app that uploads pics to Flickr.

While trying to send my request to upload a photo I get an "Invalid signature" response.

This is my base string for my signature:

POST&http%3A%2F%2Fapi.flickr.com%2Fservices%2Fupload&oauth_consumer_key%3D3f1e1948c1db9a45ca95febef6f5590e%26oauth_nonce%3D6151b3221a15f56c82ba0df47d57637e%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1366133923%26oauth_token%3D72157633261587382-7dcbe2359dbcfb06%26oauth_version%3D1.0

I basically did the same thing I did when I requested the user's authentication, but with the access token as an argument.

This is my code for the request:

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;

import org.apache.commons.codec.DecoderException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

public class Test {

  /**
   * @param args
 * @throws DecoderException 
 * @throws SignatureException 
 * @throws NoSuchAlgorithmException 
   */
  public static void main(String[] args) throws NoSuchAlgorithmException, SignatureException, DecoderException {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://api.flickr.com/services/upload");

    try {
      FileBody bin = new FileBody(new File("/Users/[MYUSERNAME]/Desktop/Untitled-1.png"));

      MultipartEntity reqEntity = new MultipartEntity();
      reqEntity.addPart("photo", bin);

      reqEntity.addPart("api_key", new StringBody(Utils.consumer_key));
      reqEntity.addPart("oauth_token", new StringBody(Utils.oauth_token));
      reqEntity.addPart("api_sig", new StringBody(Request.sig()));
      httppost.setEntity(reqEntity);

      System.out.println("Requesting : " + httppost.getRequestLine());
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      String responseBody = httpclient.execute(httppost, responseHandler);

      System.out.println("responseBody : " + responseBody);

    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      httpclient.getConnectionManager().shutdown();
    }
  }

}

Do I have a problem with my understanding of sending a MIME request, or is it just the signature? If so, how should I construct my signature? Thank you.


Solution

  • I believe the problem is with the FileBody Constructor

    FileBody bin = new FileBody(new File("/Users/[MYUSERNAME]/Desktop/Untitled-1.png"));

    If this constructor is used than the result of MultiPart Encoding is

    Content-Disposition: form-data; name="photo";

    Whereas the expected request should be of the form

    Content-Disposition: form-data; name="photo"; filename="Untitled-1.png"

    So the correct constructor to be used here is

    new FileBody(new File("/Users/[MYUSERNAME]/Desktop/Untitled-1.png"),ContentType.APPLICATION_OCTET_STREAM, "Untitled-1.png")

    Although i haven't tried executing your code myself but hopefully this should fix your problem.