In Android - how to build OkHttp request to upload image to flickr? - android

I'd appreciate any help with building the OkHttp request to upload an image to flickr.
i've searched stackoverflow, google, yahoo and everywhere else but can't seem to find a solution.
i succeed in completing the oauth authorization process, can search and download image data, etc but am stumped with trying to upload an image using OkHttp. i guess i'd manage to upload the image using plain old httpUrlConnection but i want to do it with OkHttp.
i suspect my problem lies with me not building the request/requestBody in OkHttp correctly (i don't have much knowledge of http, multiforms, etc). this is how i built my request:
final RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"photo\""),
RequestBody.create(MEDIA_TYPE_PNG, imageFile))
.build();
Request request = new Request.Builder()
.url(uri.toString())
.post(requestBody)
.build();
This is the error i get from flickr:
<rsp stat="fail">
<err code="100" msg="Invalid API Key (Key has invalid format)" />
</rsp>
(by the way i'm able to successfully upload images to imgur).
i doubt that it has anything to do with the API key as this is used successfully with the authorization for search. i think the problem may lie with the way OkHttp "builds the request".
here's what it should look like according to flickr:
If you're constructing the POST query manually instead of using some sort of service library, it should look something like this. All line endings must be \r\n.
POST /services/upload/ HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d44e178b0434
Host: api.flickr.com
Content-Length: 35261
-----------------------------7d44e178b0434
Content-Disposition: form-data; name="api_key"
3632623532453245
-----------------------------7d44e178b0434
Content-Disposition: form-data; name="auth_token"
436436545
-----------------------------7d44e178b0434
Content-Disposition: form-data; name="api_sig"
43732850932746573245
-----------------------------7d44e178b0434
Content-Disposition: form-data; name="photo"; filename="C:\test.jpg"
Content-Type: image/jpeg
{RAW JFIF DATA}
-----------------------------7d44e178b0434--
The multipart boundary should be randomly generated and should not occur anywhere inside the payload data. Also, don't forget the line ending after your RAW JFIF DATA and before the final boundary.
so my question is, how can i build the OkHttp request to match the above? i only have to include the "photo" parameter, filename and file in building the OkHttp request. all other parameters are included in the uri passed to my request.
thanks in advance

Not sure that is what you want to do here.
You would use the Flickr API's to make those requests.
https://www.flickr.com/services/developer/api/
Any site that requires login you generally have to use their API's to get an authentication token.
Hope this helps.

Related

Dealing with multipart responses

I'm playing with Amazon Alexa (AVS) and the service mostly sends multipart responses.
For example a response can contain an application/json part associated with an application/octet-stream (MP3 data) part.
For now I don't have any idea the way to write my Retrofit2 service method for it to handle it correctly.
I guess an AlexaMultiPartResponse object here won't work:
#Multipart
#Post("/path")
Call<AlexaMultiPartResponse> getAnswer(#Part("metadata") RequestBody metadata, #Part("audio") RequestBody audio);
Do you have any idea?
Regards.
According to this: https://github.com/square/retrofit/issues/2164 there is no elegant way to do it with Retrofit2.
So I ended up parsing the multipart response with Apache FileUpload MultipartStream (https://commons.apache.org/proper/commons-fileupload/apidocs/org/apache/commons/fileupload/MultipartStream.html)

MultipartEntity Android always return server error

I have two days facing a problem sending Multipart form request that include data and images, and server always give me error "Unsupported Media Type"
I have tried 3 version of apache httpclient which are (4.1, 4.3, 4.5)
Here is my code
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.addTextBody("CategoryId", String.valueOf(categoryId), ContentType.TEXT_PLAIN);
multipartEntity.addBinaryBody("PrimaryImage", primaryImage, ContentType.create("image/jpeg") , "test.jpg");
I have added the following headers
request.setHeader("Accept", "application/json");
request.setHeader("Content-Disposition","form-data");
request.setHeader("Content-type","multipart/form-data");
request.setHeader("enctype", "multipart/form-data");
I am using POST Request with Digest Authentication
When I print the content of multipart form request I found the following data
--2gj-9i6ivyDT_6wE0ck0DTKUV_hwUu-6m7
Content-Disposition: form-data; name="CategoryId"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
1
--2gj-9i6ivyDT_6wE0ck0DTKUV_hwUu-6m7
Content-Disposition: form-data; name="PrimaryImage"; filename="test.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
����-�Exif
The server is keep sending me error and server admin told me that the server can't parse form-data and that the format of my request is wrong
can anyone help please
EDIT 1
When I remove the headers from my request and remove the image also the server is able to read all text parameter.
When I remove the headers from my request and keep sending then image I got SocketTimeoutException.
I don't know what is the problem

Android HttpResponseCache and "Authorization" request header

I'm trying to get HttpResponseCache to cache responses to requests that include an "Authorization" header. I'm including this header because the API I am calling uses basic authentication.
HttpUrlConnection connection = initialiseConnection();
String usernameAndPasswordString = Base64.encodeToString(String.format("%s:%s", username, password).getBytes(), Base64.NO_WRAP);
connection.setRequestProperty("Authorization", String.format("basic %s", usernameAndPasswordString));`
To test this, I'm making the request with WiFi turned on. I'm then turning off WiFi and data and making the request again. I then get a FileNotFoundException when trying to read the response body.
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
If I do the same thing but without the "Authorization" header (to an app on a different server that doesn't use basic auth), my code is able to read the response from the cache.
I am aware that an HTTP cache is not meant to cache a response that was the result of a request including an "Authorization" header, but does that mean that I just can't cache any responses from this server without writing my own cache? Is there any known way around this or to override this behaviour in HttpUrlConnection / HttpResponseCache?
Thanks in advance!
I managed to get to the bottom of this by going through the source code of HttpResponseCache (via https://github.com/candrews/HttpResponseCache, a custom version of the class by candrews taken from the Android source :) ). Including "public", "must-revalidate" or "s-maxage" directives in the Cache-Control header of the response will allow caching by HttpResponseCache even if the Authorization header was included in the request.

Android Https signing parameters

Good day!
I have a trouble with sending https request from android application with signing parameters.
I have source which allows me to send secure http request, but authentification does not work.
I need to send request to some url with port number.
By using
HttpEntity entity = new UrlEncodedFormEntity(params, "utf-8");
After this, I retrieve this parameters in string format like
param2=param1&param2=param2%20p - encoded format
Next I need take md5 hash and again introduce it in httpbody param without encoding
Example of request:
HTTP method - POST
Headers: Content-Length - 275
Content-Type - application/x-www-form-urlencoded
параметры в HTTP body -
PHONE=2583838&ORDER_STATE_ID=31&SOURCE=улица%20Жандосова,%20188&DESTINATION=Тепличная%20улица,%202а&CLIENTID=62&SOURCE_TIME=20130807120054&IS_PRIOR=true&NOTE=This%20is%20comment&PHONE_TO_DIAL=8(701)746-90-26&CUSTOMER=Anna%20Ahmatova&signature=ed4aaef27e2d46a46f449903f3524788
Help me please. This post request working but everytime I have trouble with authentification

No auth in c2dm response

When I'm trying to use POST to get the Auth token from the ac2dm service I only get the SID and LSID, not the Auth, has this happened to anyone else, if yes, how did you solve this?
I'm using .NET (C#) on the server side, I have tried to send the post call with fiddler to but I'm getting the same result.
Post call in fiddler:
Content-Type:
application/x-www-form-urlencoded
Host: www.google.com Content-Length:
125 Expect: 100-continue
accountType=HOSTED_OR_GOOGLE&Email=myRegistredMail&Passwd=myPassword&Service=ac2dm&source=myAppPackageName
and the response (i get response code 200 so it should work):
SID=DQAAAMgAAADhKR...
LSID=DQAAAMoAAACCR...
as you can see there is no Auth token in the response...
Its as simple as big and small letters...
It should be service with a small "s" and Source with a big "S".
Thanx to MightyPush at android-c2dm group for pointing this out:)
Also if you are seeing the spanish documentation, instead of service it is wrote that you must use servicio, but this does not work.So for this to work, the keywords are
accountType
Email
Passwd
service
source

Categories

Resources