Search code examples
file-uploaddropboxaccess-tokenhttp-status-code-400

dropbox access token for others to upload to my folder


I plan to have a server program fetching my dropbox account access token and pass to

client program to uplaod to my dropbox folder. Client does not need DB account or login and is able to send file to my DB folder (thus NOT using OAuth ...). Something similar to:

this and this

but without user upload to server first, i.e., once user get the access token, they upload directly to DB.

I've tried to use Apache httpclient 4.3 to simulate a browser to perform getting request token, sending login-info to get acces token, but get stuck on upload the file via post to a form. Error is HTTP 400 Bad Request ...



    executing request:GET https://www.dropbox.com/login HTTP/1.1
    ----------------------------------------
    HTTP/1.1 200 OK
    Request Token: moiejtzdLqTA_0sh3gQyNZAI

    executing request:POST https://www.dropbox.com/login HTTP/1.1
    ----------------------------------------
    HTTP/1.1 200 OK
    Access Token: 5Ot52QKDbDPSsL1ApU4MIapJ

    executing request:POST https://dl-web.dropbox.com/upload?

    name=sample.jpg&dest=upload&cookie_t=5Ot52QKDbDP....SsJ&t=5Ot5...apJ HTTP/1.1
    ----------------------------------------
    HTTP/1.1 400 Bad Request

I used Firefox LiveHttpHeader to capture the headers as I do the login and upload file, and saw the post to file upload actually is doing this (and reflect in the code):

https://dl-web.dropbox.com/chunked_upload?
  name=tmp1.jpg
  &chunk=0
  &chunks=1
  &bjar=W3sic2Vzc1..............Q%253D%253D
  &blid=AAAw4tn................2cDxA
  &cookie_t=32yq........nw6c34o
  &dest=
  &t=32yqVof........c34o
  &reported_total_size=5611
  &upload_id=1BKGRRP5TpCEjcWSu5tmpQ
  &offset=0

So apparrently I missed some param but can't figure out what. The access token seems to be valid as I can see my account info in the return from a httpclinet post to https://www.dropbox.com/home, but the upload simply not working. Anyone has similar experience and getting HTTP 400 error ? .... Many Thanks !

Some code as below:

Constructor and main():



    // constructor ...
        public HttpClientExample() {
            gcookies = new BasicCookieStore();  
            globalConfig = RequestConfig.custom()
                    .setCookieSpec(CookieSpecs.BEST_MATCH)
                    .build();

            // Create local HTTP context
            ghttpContext = HttpClientContext.create(); 
            ghttpContext.setCookieStore(gcookies);

            //
            redirectStrategy = new LaxRedirectStrategy();  // for http redirect ...
            httpclient = HttpClients.custom()   
                    .setDefaultRequestConfig(this.globalConfig)
                    .setDefaultCookieStore(this.gcookies)
                    .setRedirectStrategy(redirectStrategy)
                    .build();       
        }  // constructor ...

        public static void main(String[] args) throws Exception {

            HttpClientExample myhttp = new HttpClientExample();
            try {

                    this.localConfig = RequestConfig.copy(this.globalConfig)
                    .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
                    .build();

                String requestToken = this.getRequestToken(httpclient, loginurl);

                theAccessToken = this.postForAccessToken(requestToken, loginurl);

                String localFileTopassIn = this.localPath ;
                this.postToUpload(httpclient, this.theAccessToken, localFileTopassIn , this.dropboxFolderOnlyName);


            }

        }

Get the request token:



private String getRequestToken(HttpClient client, String theURL) throws Exception {
    HttpGet httpget = new HttpGet(theURL);
    httpget.setConfig(localConfig);     
    httpget.setHeader("Connection", "keep-alive");

    System.out.println("\nexecuting request:" + httpget.getRequestLine());


    // Create a custom response handler
    ResponseHandler responseHandler = new ResponseHandler() {

        public String handleResponse(final HttpResponse response)
                           throws ClientProtocolException, IOException {
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 ) { // && status  cookies = gcookies.getCookies();
    for (Cookie aCookie: cookies) {
        String cookieName = aCookie.getName();
        if ( !(cookieName.lastIndexOf(gvcString) == -1) ) {
            gvc = aCookie.getValue();
        } else if ( !(cookieName.lastIndexOf(tString) == -1) ) {
            requestToken = aCookie.getValue();
        }
    }

    System.out.println("Request Token: " + requestToken );
    return  requestToken;           

}

postForAccessToken:



private String postForAccessToken(HttpClient client, String requestToken, String theURL) throws Exception{
    /*
     *  Send a post together with request token and my login to get accessToken ...
     */
    HttpPost httppost = new HttpPost(theURL); // loginurl);
    httppost.setConfig(localConfig);
    ghttpContext.setCookieStore(gcookies);

    List params = new LinkedList();
    params.add(new BasicNameValuePair("login_email", myemail));
    params.add(new BasicNameValuePair("login_password", mypasswd));
    params.add(new BasicNameValuePair("t", requestToken));

    HttpEntity postentity = new UrlEncodedFormEntity(params); 
    httppost.setEntity(postentity); 

    System.out.println("\nexecuting request:" + httppost.getRequestLine());

    // Create a custom response handler
    ResponseHandler responseHandler = new ResponseHandler() {

        public String handleResponse(final HttpResponse response)
                           throws ClientProtocolException, IOException {
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 ) { // && status  cookies = gcookies.getCookies();
    for (Cookie aCookie: cookies) {
        String cookieName = aCookie.getName();
        if ( !(cookieName.lastIndexOf(tString) == -1) ) {
            theAccessToken = aCookie.getValue();
        }
    }

    System.out.println("Access Token: " + theAccessToken );     
    return theAccessToken;
}   

postToUpload:


private String postToUpload(HttpClient client, String accessToken, String localFileInfo, String destPath) throws Exception{

    String bjarString = "bjar";
    String blidString = "blid";
    String bjar=null;
    String blid=null;
    List cookies = gcookies.getCookies();
    for (Cookie aCookie: cookies) {
        String cookieName = aCookie.getName();
        if ( !(cookieName.lastIndexOf(bjarString) == -1) ) {
            bjar = aCookie.getValue();
        } else if ( !(cookieName.lastIndexOf(blidString) == -1) ) {
            blid = aCookie.getValue();
        }
    }   

    String[] fileNameArry = localFileInfo.split("(\\\\|/)");
    String filename = fileNameArry[fileNameArry.length - 1];  // get the last part ...

    URI uri = new URIBuilder()
            .setScheme("https")
            .setHost("dl-web.dropbox.com")
            .setPath("/upload")
            .setParameter("name", filename)
            .setParameter("dest", destPath)        
            .setParameter("cookie_t", accessToken)
            .setParameter("t", accessToken)
            .build();

    HttpPost httppost = new HttpPost(uri);
    httppost.setConfig(localConfig);

    ghttpContext.setCookieStore(gcookies);

    FileBody bin = new FileBody(new File(localFileInfo));
    StringBody comment = new StringBody("A binary file of some kind", ContentType.DEFAULT_BINARY);

    HttpEntity reqEntity = MultipartEntityBuilder.create()
            .addPart("bin", bin)
            .addPart("comment", comment)
            .build();

    httppost.setEntity(reqEntity);  

    // add header
    httppost.setHeader("Host", "www.dropbox.com");
    httppost.setHeader("User-Agent", USER_AGENT);
    httppost.setHeader("Accept",
            "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    httppost.setHeader("Connection", "keep-alive");
    httppost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    httppost.setHeader("Pragma", "no-cache");
    httppost.setHeader("Cache-Control", "no-cache");

    // add entity
    System.out.println("\nexecuting request:" + httppost.getRequestLine());

    // Create a custom response handler
    ResponseHandler responseHandler = new ResponseHandler() {

        public String handleResponse(final HttpResponse response)
                           throws ClientProtocolException, IOException {
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 ) { // && status 

Solution

  • OAuth is the only way to use the Dropbox API. Once you have an OAuth access token (which you get by authenticating once, in this case with your account), you just need to do an HTTP PUT to https://api-content.dropbox.com/1/files_put/auto/<path> with the header Authorization: Bearer <token> and the contents of the file in the body.

    Note that anyone who has your access token can also delete all your files, upload their personal DVD collection, etc. So it's not recommended that you share that access token.