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:
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
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.