posting photo(s)

2,255 views
Skip to first unread message

S. Douglass

unread,
Nov 17, 2011, 9:42:00 PM11/17/11
to Tumblr API Discussion
I know this is a well worn topic here, so my apologies for starting
yet another thread about this. I've tried to scour all the existing
threads and examples but things are still not entirely clear to me. I
was hoping that folks could settle a couple points of confusion for
me. It'd be great to have these details made plain, and not in example
code, so that anybody can look at it without having to know
programming language X or Y or Z.

1. Content-type - is it application/x-www-form-urlencoded or multipart/
form-data ???
2. How is the OAuth signature generated? The same as for every other
API call? Or differently? The Twitter documentation for their upload
API call (which looks to be using multipart/form-data) indicates that
the OAuth signature is generated differently in that case:

https://dev.twitter.com/discussions/1059

3. The binary data is supposed to be turned into a string then
encoded. Is it Base64 encoded? URL query parameter encoded? Both?
4. The parameter names, are they supposed to be named "data[0]",
"data[1]", "data[2]", etc? If I'm sending just one file do I use
"data" or "data[0]"?

I have looked at both the example gists on GitHub mentioned in
elsewhere here but it isn't clear to me from the comments if they
actually work, and also I'm not familiar with Python, so I'm not
really sure I'm interpreting the code 100% correctly. So I'm just
hoping for some non-code details about how it works. Thanks!

Steven Pears

unread,
Nov 18, 2011, 2:11:23 AM11/18/11
to Tumblr API Discussion
We do need a single place for this particular issue. This seems a very
concise post - so I suggest we keep all photo/photoset posting to here
from now.

So far my requests have been url-encoded form requests, and the
parameter names have been in the data[0] format. Because these aren't
multi-part requests they're signature'd in the same way as the other
requests.

The one issue I've had so far is that even if these points are
followed, I then get an "error saving photo" message - indicating that
it's point 3 I'm getting wrong; I'm encoding the photo incorrectly.

Hope this moves us forward a little.

Steven

Steven Pears

unread,
Nov 18, 2011, 2:44:21 AM11/18/11
to tumbl...@googlegroups.com
as a further note, i've been using http://www.convr.co.uk/test.jpg as my test image due to its encoded form being short enough to post as well as not breaking uri limits (a restriction  in my .NET library i'm hoping to work around once I have a working example)

Federico Carlos Erostarbe Candamil

unread,
Nov 18, 2011, 7:14:55 AM11/18/11
to tumbl...@googlegroups.com
It would be a great idea, i think, to use this thread as a sort of wiki. It would be awesome if the ones who managed to get this done smoothly posted a working example. The connection, the authorization header, the damn photo thing.

I'm going mad in Objective-C and haven't managed to nailed it yet.

mohacs

unread,
Nov 18, 2011, 9:15:02 AM11/18/11
to tumbl...@googlegroups.com

hello everyone,


photo is not only the problem... 


when i upload a mp3 file it returns 

{"meta":{"status":201,"msg":"Created"},"response":{"id":12967144041}}


Also the post appear on my blog however when i play it no audio.


it is same for video as well..

when i upload a video file it returns.


{"meta":{"status":201,"msg":"Created"},"response":{"id":12967187657}}


but video didn't even appear on my blog, 


i was creating iPhoto / Finder plug-ins and universal IOS application but until they came back with reasonable documentation i will give up because this became pain. 


many thanks.

-mohac.

John Bunting

unread,
Nov 18, 2011, 9:16:45 AM11/18/11
to tumbl...@googlegroups.com
Can you send me a link to those audio/video posts? Might be a different problem but i'd want to check into it regardless.

mohacs

unread,
Nov 18, 2011, 9:38:58 AM11/18/11
to tumbl...@googlegroups.com
Hi John,
latest post is the audio one http://mohacs.tumblr.com/

as i said even i got {"meta":{"status":201,"msg":"Created"},"response":{"id":12967187657}}
video didn't appear on my blog. 

thank you.
-mohacs.

John Bunting

unread,
Nov 18, 2011, 9:42:02 AM11/18/11
to tumbl...@googlegroups.com
Very  very strange. OK when I get some downtime, I'll look into this.

mohacs

unread,
Nov 18, 2011, 9:45:27 AM11/18/11
to tumbl...@googlegroups.com
thank you, any help would be grateful. 

mohacs

unread,
Nov 18, 2011, 10:23:40 AM11/18/11
to tumbl...@googlegroups.com
just noticed the videos stuck in processing q.
thanks.

S. Douglass

unread,
Nov 18, 2011, 10:29:52 AM11/18/11
to Tumblr API Discussion
Steven, thanks so much for the actual, concrete info. So to recap, for
anyone looking at this thread in the future, you're saying:

1. The Content-type should be application/x-www-form-urlencoded
2. The OAuth signature is generated the same way as for the other API
calls
3. ???
4. The parameter names should be "data[0]", "data[1]", etc. even if
there is just one photo (so with one photo, you would use "data[0]")

So the remaining issue is, how are the binary data encoded? Or maybe
rather, how are the binary data turned into characters in a string?
(It seems like if the data are passed as request parameters in an
application/x-form-urlencoded POST they should be URL encoded. But URL
encoding raw bytes doesn't seem to make sense to me, so I assume the
problem we're really having is figuring out how to turn the bytes into
a string?)

I really appreciate your response Steve. I also appreciate that lots
of people are having issues with this. It might be better for people
referring to this thread in the future though if we really tried to
stay focused on this one topic and resolving these specific details.
Most likely once we figure out how to get this to work for one binary
type we can reuse the approach for video, audio, etc.

Steven Pears

unread,
Nov 19, 2011, 5:02:53 AM11/19/11
to Tumblr API Discussion
This is accurate as far as I can tell, without those 3 set up that way
I get an error in the request, when these are set up that way I end up
just with a tumblr response, the meta containing the error about
unable to save the photo.

This is why I keep referring to the test image I've been using - I'm
sure if we could get a sample of a correctly encoded, small, image -
from another dev or from Tumblr - we could just keep looking at our
own languages until it matched and finally tick that last box.

But no matter what I try I just can't get it right.

Message has been deleted

S. Douglass

unread,
Nov 19, 2011, 11:33:59 PM11/19/11
to Tumblr API Discussion
I pasted the raw contents of a post from the Python code from one of
the Tumblr folks and the raw post made by my (Java) code here:

http://pastebin.com/fWJUBGw4

Two things are different that I see. The binary data in the request is
encoded differently (it starts with "%FF%D8%FF" in the Python version
and "%EF%BF%BD" in my version). Probably more significant is that the
oauth_signature value has an "=" in the Python version but it's been
escaped to "%3D" in the oauth_signature value in my version. Perhaps
that's the root of the problem with my posts...?

Steven Pears

unread,
Nov 20, 2011, 2:13:23 AM11/20/11
to Tumblr API Discussion
This is EXACTLY what I've been asking for, an example of a working
post - this should be the bit that really turns it!

I've got real life stuff getting in the way a little bit this morning,
but I'll get on replicating this in C# soon as I've got chance.

Just to confirm - is this with the same test image?

S. Douglass

unread,
Nov 20, 2011, 2:30:37 AM11/20/11
to Tumblr API Discussion
Yes, I have been using this 2x2 blank jpg, the one you linked to
earlier:

http://www.convr.co.uk/test.jpg

Steven Pears

unread,
Nov 20, 2011, 2:35:38 AM11/20/11
to Tumblr API Discussion
Fantastic!

I see the problem I've been having - this is a raw dump, a byte at a
time - all the Base64/URL encoding systems I've been using have
assumed the text would be handled in a double-byte format like UTF-8.

This shouldn't be difficult to sort out at all!

Right, real-life beckons.

Steven Pears

unread,
Nov 20, 2011, 5:51:10 AM11/20/11
to Tumblr API Discussion
My assumption seems correct, we have to read a byte from the photo
data at a time, then convert that number to hex and place "%" +
hexConversion into the string.

It looks like there's a special case where if it's a space character
it's getting replaced by the + sign, but I'm still working on that.

I can get the string, the issue now is that because it's url-encoded
data, my OAuth library is (quite correctly in my opinion) trying to
encode the string I've just generated. So this causes problems.

I've contacted the author to ask if there's an encoding option we can
add, but in the mean time I'm looking at working backwards to where I
need to be.

This is a lot of messing around compared to a multi-part request or
base64 encoding, it really is, but I feel like it's progress at least.

Steven Pears

unread,
Nov 20, 2011, 8:20:07 AM11/20/11
to Tumblr API Discussion
OK - I was right the first time, the encoding is simple url encoding,
but on a single-byte at a time read of the file.

This is a bit of a problem. If you're using a library (I guess most
people aren't implementing their own OAuth code) then most of that
code is going to be assuming double-byte encoding, probably UTF-8.

If you change the encoding of the request, then you're limiting the
characters that can be entered into the text-based fields - and
therefore the language you can say you support. Normally it's UTF-8 so
it handles pretty much anything you can throw at it.

I would be interested in the other languages, because for me this may
end up being a show stopper. UTF-8 is so standard across the web that
Silverlight/Windows Phone 7 doesn't implement a single-bye encoding. I
may have to try and implement codepage 1252 (the most likely encoding
candidate) myself so that my OAuth library can handle it.

Does anyone have any idea why UTF-8 is accceptable on every other call
in this API, but not on the binary URL encoding? No wonder we've been
having trouble.

Steven

wyvern

unread,
Nov 20, 2011, 1:35:40 PM11/20/11
to Tumblr API Discussion
I've already mentioned same things before at
http://groups.google.com/group/tumblr-api/browse_thread/thread/16f1131f825a8d81

>If sending parameters in the application/www-form-urlencoded in the
>body of request. One big problem come arise when posting photo(binary
>values?),
>Those parameters has to be included in the process of generating
>signature base string of OAuth.

>The problem is most OAuth client libarary expects to takes parameters
>as *string* or treats them as *string* internally. so when signing
>request,
>those binary paramaters are handled incorrectly(that is, UTF8 encoding
>are applied to those binary parameters incorrectly).

most OAuth library expects to takes parameters as string(that is input
parameters is declared as string type).
so binary parameters can't passed directly :(

of course, if u url-encoded binary parameters to string, pass it as
input parameters, this causes wrong result.

Steven Pears

unread,
Nov 20, 2011, 1:46:45 PM11/20/11
to Tumblr API Discussion
Apologies Wyvern, I didn't get that from your explanation!

Guess this is the bigger question to put forward to the Tumblr team
then:


How can we post a photo into API V2 while still using UTF-8 encoding?


This is one I would really like the Tumblr guys to get back to us on!

Steven Pears

wyvern

unread,
Nov 20, 2011, 2:54:58 PM11/20/11
to Tumblr API Discussion
sorry, I'm not good at English. :(

Although I don't know which OAuth library u are using, When passsing
parameters to your OAuth library, u always need to pass them as
string(in case of C#, string type(UTF16-Unicode)) right??

There's no overloaded method to pass them as Byte array or Stream
class?

if theres no such methods, ur oauth library can't handle binary
values(photo data) correctly.

This is what i mean by "most OAuth library expects to takes parameters
as string".

In this case, If convert binary value(photo) to string using
urlencoding by force and passing it as string to your oauth library,
this result in wrong singature.

because converted data is ***again*** encoded using UTF8 internally in
OAuth library u using.

Look at section 3.6. Percent Encoding in RFC5849 http://tools.ietf.org/html/rfc5849.

It says 1. Text values are first encoded as UTF-8 octets per
[RFC3629] if
they are not already. This does not include binary values that
are not intended for human consumption.

Your OAuth library handle all parameters as Text values and can't
distinguish which Text values and Binary values.


umm. can't explain well.

Steven Pears

unread,
Nov 20, 2011, 3:08:44 PM11/20/11
to Tumblr API Discussion
Wyvern

I see what you mean - my library assumes files will be sent via multi-
part form data, so yes - you're spot on.

Steven

S. Douglass

unread,
Nov 21, 2011, 1:22:52 AM11/21/11
to Tumblr API Discussion
The library I'm using uses UTF-8 as well. When I check what the
default encoding is for Python on my system it says "ascii". Even if I
tell my Java code to read in the file data and convert it to a string
using ASCII, that string will then be converted to UTF-8 by the
library I'm using before being percent encoded, as per Section 3.6. So
I guess I am out of luck.

I suppose I could try to bypass the library I'm using and try to
figure out how to make sure the binary data never gets UTF-8 encoded?

It would be really great if the Tumblr API supported multipart POSTs
like Twitter's API.

Steven Pears

unread,
Nov 21, 2011, 1:48:39 AM11/21/11
to tumbl...@googlegroups.com
It seems like the python library is the exception rather than the rule in terms of binary encoding.

Tumblr team: is there any chance binary  API calls, or right now this one call,  could be changed to accept either multi-part or UTF-8 requests?

From: S. Douglass
Sent: 21/11/2011 06:23
To: Tumblr API Discussion
Subject: Re: posting photo(s)

wyvern

unread,
Nov 21, 2011, 8:37:11 AM11/21/11
to Tumblr API Discussion
OAuth 1.0 spec itself support binary values.

so OAuth library itself needs to distinguish between Text and Binary
values, that is,
for example, It needs to hold binary values as Byte array for Binary
values internally in addition to String for Text values.

This is what i mean by "most OAuth client libarary expects to
treats(handle) them as *string* internally".

My own OAuth implemetation also was one of such libraries.

But Adapting it to support binary values is not so hard job.

Steven Pears

unread,
Nov 21, 2011, 11:06:45 AM11/21/11
to Tumblr API Discussion
Wyvern - I'm not talking about OAuth implementation, that's not my
problem. The library I use DOES handle binary data, it handles it the
way the internet has accepted you handle binary data by default, by
creating a multi-part form request!

This way it's able to handle the binary data in a way which is
specifically built to do so in a common, easy to read and pretty
efficient format.

By asking for the data to be submitted through a url-encoded request,
you are asking the system to assume the data is a string. In that case
the most accepted practice is that you fallback to what other systems
do for such a decision and Base64 encode the data. Suddenly you're ok
for web services and emails and other text-based systems that need to
handle binary. I'd have no problems whatsoever with this decision.

Instead the system is relying on a single-byte encoding of the binary
data, a very arbitary approach, and I don't believe it's acceptable to
punch a hole into each OAuth provider for this when most OAuth
libraries and developers do have to work with multiple social
networks, and this is the only one that asks it's devs to do so.

S. Douglass

unread,
Nov 21, 2011, 11:15:23 AM11/21/11
to Tumblr API Discussion
Wyvern, thanks for the information. Do you have any specific details
about how you adapted your OAuth library to support binary data? The
binary data has to be encoded somehow, to be used in the OAuth
signature base string, and to go into the request body. It's still not
clear to me what the encoding schemes are for those cases for binary
data. If I know what the encoding schemes are I can try to hack them
in to my OAuth library.

Mohac Bilecen

unread,
Nov 21, 2011, 11:53:13 AM11/21/11
to tumbl...@googlegroups.com
Steven,
i have managed to send single photo still unable to post two and still strongly believe the APi is not working properly.
you might want to see ASIHTTPRequest class. have sniff request on NIC card, i hope you can see on right format on PC.

- (void)appendPostDataFromFile:(NSString *)file

{

[self setupPostBody];

NSInputStream *stream = [[[NSInputStream alloc] initWithFileAtPath:file] autorelease];

[stream open];

NSUInteger bytesRead;

while ([stream hasBytesAvailable]) {

unsigned char buffer[1024*256];

bytesRead = [stream read:buffer maxLength:sizeof(buffer)];

if (bytesRead == 0) {

break;

}

if ([self shouldStreamPostDataFromDisk]) {

[[self postBodyWriteStream] write:buffer maxLength:bytesRead];

} else {

[[self postBody] appendData:[NSData dataWithBytes:buffer length:bytesRead]];

}

}

[stream close];

}




--
Mohac BILECEN

dump.txt

S. Douglass

unread,
Nov 21, 2011, 12:16:58 PM11/21/11
to Tumblr API Discussion
For future reference I finally found info about how the data is
encoded.

http://stackoverflow.com/questions/7405655/how-to-urlencode-an-actionscript-bytearray

If I turn the test file's bytes into a string using Latin 1, then use
Latin 1 when URL encoding, I wind up with the same string
representation of the file ("%FF%D8%FF...") as the Python code. So I
guess for any request involving binary data I have to kludge things to
use Latin 1 encoding all the way through, instead of UTF-8/ASCII...?

Steven Pears

unread,
Nov 21, 2011, 12:18:42 PM11/21/11
to tumbl...@googlegroups.com
Thank you mohac!

The fact you're using data[1] makes it look like it's not a 0-based array, that would have caused me trouble!

Will attempt implementing this tonight, thank you!!

Sent from my Windows Phone

From: Mohac Bilecen
Sent: 21/11/2011 16:53
To: tumbl...@googlegroups.com
Subject: Re: posting photo(s)

Steven,
i have managed to send single photo still unable to post two and still strongly believe the APi is not working properly.
you might want to see ASIHTTPRequest class. have sniff request on NIC card, i hope you can see on right format on PC.

- (void)appendPostDataFromFile:(NSString *)file

{

[self setupPostBody];

NSInputStream *stream = [[[NSInputStream alloc] initWithFileAtPath:file] autorelease];

[stream open];

NSUInteger bytesRead;

while ([stream hasBytesAvailable]) {

unsigned char buffer[1024*256];

bytesRead = [stream read:buffer maxLength:sizeof(buffer)];

if (bytesRead == 0) {

break;

}

if ([self shouldStreamPostDataFromDisk]) {

[[self postBodyWriteStream] write:buffer maxLength:bytesRead];

} else {

[[self postBody] appendData:[NSData dataWithBytes:buffer length:bytesRead]];

}

}

[stream close];

}






On Mon, Nov 21, 2011 at 6:15 PM, S. Douglass <sdougl...@gmail.com> wrote:
Wyvern, thanks for the information. Do you have any specific details
about how you adapted your OAuth library to support binary data? The
binary data has to be encoded somehow, to be used in the OAuth
signature base string, and to go into the request body. It's still not
clear to me what the encoding schemes are for those cases for binary
data. If I know what the encoding schemes are I can try to hack them
in to my OAuth library.

On Nov 21, 5:37 am, wyvern <wyvern1...@gmail.com> wrote:
> OAuth 1.0 spec itself support binary values.
>
> so OAuth library itself needs to distinguish between Text and Binary
> values, that is,
> for example, It needs to hold binary values as Byte array for Binary
> values internally in addition to String for Text values.
>
> This is what i mean by "most OAuth client libarary expects to
> treats(handle) them as *string* internally".
>
> My own OAuth implemetation also was one of such libraries.
>
> But Adapting it to support binary values is not so hard job.



--
Mohac BILECEN

Mohac Bilecen

unread,
Nov 21, 2011, 12:51:56 PM11/21/11
to tumbl...@googlegroups.com
Steven,
data, data[0], data[1] or data[hello] doesn't matter always get 1st attached one. but i am sure this ASIhttpRequest does right encoding because i can upload audio and video with it no problem. 
i'll share if i can find further.
best,
-mohac.


--
Mohac BILECEN

S. Douglass

unread,
Nov 21, 2011, 1:14:20 PM11/21/11
to Tumblr API Discussion
I'm a little confused about the content type. In Mohac's example code
he uses multipart. Does that actually work? I thought folks had
already established the content type was supposed to be form encoded,
like in the Python example from the Tumblr team?

On Nov 21, 9:51 am, Mohac Bilecen <moh...@gmail.com> wrote:
> Steven,
> data, data[0], data[1] or data[hello] doesn't matter always get 1st
> attached one. but i am sure this ASIhttpRequest does right encoding because
> i can upload audio and video with it no problem.
> i'll share if i can find further.
> best,
> -mohac.
>

> On Mon, Nov 21, 2011 at 7:18 PM, Steven Pears <steven.pe...@live.co.uk>wrote:
>
>
>
>
>
>
>
>
>
> >  Thank you mohac!
>
> > The fact you're using data[1] makes it look like it's not a 0-based array,
> > that would have caused me trouble!
>
> > Will attempt implementing this tonight, thank you!!
>
> > Sent from my Windows Phone

> >  ------------------------------

Mohac Bilecen

unread,
Nov 21, 2011, 1:56:24 PM11/21/11
to tumbl...@googlegroups.com
Hi, yes it is working but no photo-set, it is able to submit only single photo. there is also working IPhoto plug-in out there i spoke with author of the plug-in he confirmed the plug-in able to upload photo but only one, i have tested it myself. you can see here http://un.exposedcontents.com/whileyouwereout/about.php
FAQ http://un.exposedcontents.com/whileyouwereout/faq.php

all except submitting data URL encoded work but if you want to submit photo, audio or video only multi-part work. of course there is a way to encode data to URLEncoded way but we do not know yet. 

i also ran that python example on my MAC, successfully got token and token key however second part couldn't upload photo. just got authentication error.

Best,
-mohac.


--
Mohac BILECEN

wyvern

unread,
Nov 21, 2011, 2:34:10 PM11/21/11
to Tumblr API Discussion
I know application/x-www-form-urlencoded is not suitable for sending
binary values and
Instead, sending it with multipart type is used commonly but it's not
required. Internet related spec is really confusion and messy.

But Tumblr API seems only accept application/x-www-form-urlencoded so
all we can do is
to ask Tumblr team to accept multipart type or to ask your OAuth
library implmentater to adapt it for supporting binary values.

According to OAuth spec,

only if sending parameters with application/x-www-form-urlencoded,
those parameters has to be included for generating singnature.

It just seems Your OAuth library ignores binary values for application/
x-www-form-urlencoded.

Steven Pears

unread,
Nov 21, 2011, 3:23:45 PM11/21/11
to tumbl...@googlegroups.com
No - again, my OAuth provider is accepting them, I don't know how to make it any clearer - it's not my OAuth provider!
 
The issue I have is that Tumblr is using a single-byte encoding for their data (clarified in another post to be Latin-1). Single-byte encoding is not supported by WP7 or Silveright, so the implementation is not only non-standard, but completely cuts out microsoft web technology and, thanks to Nokia moving to WP7 rather than Symbian for future phones, an upcoming web operating system.
 
Now it seems there may be a multi-part option available, but that it's not fully implemented - so currently I'm looking into that, but I'm not holding out much hope.
 
As a developer for one of the few dedicated Tumblr apps in the WP7 marketplace right now, this is a problem for me.

S. Douglass

unread,
Nov 21, 2011, 3:34:50 PM11/21/11
to Tumblr API Discussion
I'm with Steven, I think the root of the issue is that Tumblr is
expecting Latin 1 when they should be expecting UTF-8. I have a
working Java version of the Python Gist that Derek from Tumblr shared
that I'm going to try to clean up and make available somewhere to show
exactly what I had to do to get it to work. In Java I have to specify
the character set for every conversion between bytes and characters,
so it should illustrate exactly how the data is being handled.

Steven Pears

unread,
Nov 21, 2011, 3:57:25 PM11/21/11
to Tumblr API Discussion
Mohac

I've tried to get my request to look as close to yours as possible
with my little test image and all I get is "not authorized" errors

POST http://api.tumblr.com/v2/blog/justaddmuse.tumblr.com/post HTTP/
1.1
Accept: */*
Referer: file:///Applications/Install/F200CA02-F63B-46DC-AC29-27AA1AD47030/Install/
Content-Length: 765
Accept-Encoding: gzip
Authorization: OAuth
oauth_consumer_key="xxxxx",oauth_nonce="nri1vh4m4cuylc32",oauth_signature="xxxx",oauth_signature_method="HMAC-
SHA1",oauth_timestamp="1321908715",oauth_token="xxx",oauth_version="1.0"
Content-Type: multipart/form-data; charset=utf-8;
boundary=5cee46f6-6d50-42c3-81de-3f811a541e83
User-Agent: DashBuddy
Host: api.tumblr.com
Connection: Keep-Alive
Pragma: no-cache

--5cee46f6-6d50-42c3-81de-3f811a541e83
Content-Disposition: form-data; name="type"

photo
--5cee46f6-6d50-42c3-81de-3f811a541e83
Content-Disposition: form-data; name="data"; filename="photo.jpg"
Content-Type: image/jpg

����� JFIF� �H�H�����C�

���C


��� � � � ��� � ��������������� ��� ������������������� ������������������� �������������������
� �?�T���
--5cee46f6-6d50-42c3-81de-3f811a541e83
Content-Disposition: form-data; name="state"

draft
--5cee46f6-6d50-42c3-81de-3f811a541e83
Content-Disposition: form-data; name="caption"

DashBuddy Test Photo Post
--5cee46f6-6d50-42c3-81de-3f811a541e83--

Mohac Bilecen

unread,
Nov 21, 2011, 4:40:32 PM11/21/11
to tumbl...@googlegroups.com
Hi Steven,
for binary posts i am using followings on base string to create signature. if i add binary data to base string it doesn't work. 

POST&http://api.tumblr.com/v2/blog/mohacs.tumblr.com/post&caption=* Photo 1 Throught API&oauth_consumer_key=xxxxxxxxxxx&oauth_nonce=fRHRCYyVTLZEHowL&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1321910962&oauth_token=xxxxxxxxxxxx&oauth_version=1.0&tags=test, API test, more test&type=photo


of course double url encoded version

POST&http%3A%2F%2Fapi.tumblr.com%2Fv2%2Fblog%2Fmohacs.tumblr.com%2Fpost&caption%3D%252A%2520Photo%25201%2520Throught%2520API%26oauth_consumer_key%3Dxxxxxxxxxxxxxxxxxxxxx%26oauth_nonce%3DfRHRCYyVTLZEHowL%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1321910962%26oauth_token%xxxxxxxxxxxx%26oauth_version%3D1.0%26tags%3Dtest%252C%2520API%2520test%252C%2520more%2520test%26type%3Dphoto


i took screenshot from my request just before start it. post body is kind of data and it is 0 byte. binary data attached as array.
i am sorry last week i lost my virtual machine installation i can't run VS to compare. 

best,
-mohac/
--
Mohac BILECEN

Screen Shot 2011-11-21 at 11.36.07 PM.png

wyvern

unread,
Nov 21, 2011, 5:40:41 PM11/21/11
to Tumblr API Discussion
It just looks like Using Latin1 encoding produces same results as raw
bytes(I'm not sure it completely produces same results).
Naturally, Handling binary values as string type involves wrong,
unnecessary char <-> bytes conversion, which results in data loss.
Reliable approach is handing binary values as Byte array or Stream
class and so on.

for example, take a example of .NET HttpUtility class. This class has
methods for urlencoding.

If all parameters to be passed is text, Only using
HttpUtility.UrlEncode(string, [encoding Encoding]) is enough.

But if some of them are binary, overloaded version
HttpUtility.UrlEncode(byte Bytes[]) has to be used together.

Why this Byte array overloaded version exists? Its primarily for
binary parameters. no encoding parameter!!

You are just going to convert binary values to Latin 1 *in force* and
handle it, which might produces same results as raw bytes but
mentioned eariler, it really dangerous approach.

anyway, it seems better wait for Tumblr team anwser.

>Steven Pears
View profile
> More options Nov 22, 5:23 am


>No - again, my OAuth provider is accepting them, I don't know how to make it any clearer - it's not my OAuth provider!

Which library u using, can u give me a link? then i can check.

Thx.

anyway,

Alayna Fox

unread,
Nov 21, 2011, 5:58:33 PM11/21/11
to tumbl...@googlegroups.com
Can you take my email off of this please?

Mohac Bilecen

unread,
Nov 21, 2011, 6:13:30 PM11/21/11
to tumbl...@googlegroups.com
Alayna,
and unsubscribe yourself we can't.

Steven Pears

unread,
Nov 21, 2011, 6:13:54 PM11/21/11
to tumbl...@googlegroups.com
I've explained this in other posts I think, byt If you'd looked at HttpUtility UrlEncode or Uri.EncodeDataString properly, you'd see there's an in-built limit when it breaks the length for a valid Uri, resulting in an exception.

You're left looking at manual encoding because these functions are for textual streams, such as querystring parameters, not megabytes of binary!

Steven


Sent from my Windows Phone

From: wyvern
Sent: 21/11/2011 22:40

To: Tumblr API Discussion
Subject: Re: posting photo(s)

Steven Pears

unread,
Nov 21, 2011, 6:22:13 PM11/21/11
to tumbl...@googlegroups.com
Also, these encode using double-byte encoding, so with binary data they actually produce the wrong result.

As I've said several times now, silverlight/WP7 has no single-byte encoding, so again - manual is all you're left with.

I hope this puts to rest the idea I've just missed something in Silverlight/WP7 that will work easily, there are good reasons for asking for supported UTF-8, Base64 or multi-part requests and I promise you it wasn't due to lack of trying.

If I've misunderstood the API calls, that's a different matter entirely, and am thankful to the other devs for helping me in that regard.

Goodnight from the UK

S. Douglass

unread,
Nov 21, 2011, 9:08:18 PM11/21/11
to Tumblr API Discussion
So, I have things working now for posting photos, including sending
multiple photos.

There are two problems with Tumblr's API that I had to work around.

1. The Tumblr API does not appear to expect the use of the UTF-8
character set for all byte/character conversions. I had to make sure
to use Latin 1 (ISO 8859-1) when:
- initially reading in the binary file's bytes and converting them to
characters
- URL encoding those characters to put the file into the POST contents
- percent encoding "data" parameter names and values for OAuth (see
http://tools.ietf.org/html/rfc5849#section-3.6 )

2. The Tumblr API appears to expect "data" parameter names used in the
OAuth base signature string to be singly percent encoded, but they
should be doubly percent encoded. For example, with a parameter name
of "data[0]", what should be in the OAuth base signature string is
"%255B0%255D", but what the Tumblr API expects is "data%5B0%5D".
- The first percent encoding happens to parameter names and values
during "Parameters Normalization" (see http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
)
-- "1. First, the name and value of each parameter are encoded"
- The second percent encoding happens to the normalized parameter
string as part of "String Construction" (see http://tools.ietf.org/html/rfc5849#section-3.4.1.1
)
-- "5. ... after being encoded",

If Tumblr could resolve these two issues, then I imagine more OAuth
libraries would work "out of the box" with their API.

It'd be great too if they could add support for multipart POSTs too,
which as has been stated here already would make it much more
straightforward to send binary data to the API.

Thanks for all your help everybody on this thread. Is there somewhere
I can file a bug with Tumblr about these issues...? I've seen they
have use getsatisfaction.com ( http://getsatisfaction.com/tumblr ) so
maybe I'll try to post something there about this stuff.

S. Douglass

unread,
Nov 21, 2011, 9:13:58 PM11/21/11
to Tumblr API Discussion
Posted to getsatisfaction.com here:

http://getsatisfaction.com/tumblr/topics/tumblr_v2_api_issues_when_posting_binary_data_e_g_photos


On Nov 21, 6:08 pm, "S. Douglass" <sdouglass...@gmail.com> wrote:
> So, I have things working now for posting photos, including sending
> multiple photos.
>
> There are two problems with Tumblr's API that I had to work around.
>
> 1. The Tumblr API does not appear to expect the use of the UTF-8
> character set for all byte/character conversions. I had to make sure
> to use Latin 1 (ISO 8859-1) when:
> - initially reading in the binary file's bytes and converting them to
> characters
> - URL encoding those characters to put the file into the POST contents
> - percent encoding "data" parameter names and values for OAuth (seehttp://tools.ietf.org/html/rfc5849#section-3.6)
>
> 2. The Tumblr API appears to expect "data" parameter names used in the
> OAuth base signature string to be singly percent encoded, but they
> should be doubly percent encoded. For example, with a parameter name
> of "data[0]", what should be in the OAuth base signature string is
> "%255B0%255D", but what the Tumblr API expects is "data%5B0%5D".
> - The first percent encoding happens to parameter names and values

> during "Parameters Normalization" (seehttp://tools.ietf.org/html/rfc5849#section-3.4.1.3.2


> )
> -- "1. First, the name and value of each parameter are encoded"
> - The second percent encoding happens to the normalized parameter

> string as part of "String Construction" (seehttp://tools.ietf.org/html/rfc5849#section-3.4.1.1


> )
> -- "5. ... after being encoded",
>
> If Tumblr could resolve these two issues, then I imagine more OAuth
> libraries would work "out of the box" with their API.
>
> It'd be great too if they could add support for multipart POSTs too,
> which as has been stated here already would make it much more
> straightforward to send binary data to the API.
>
> Thanks for all your help everybody on this thread. Is there somewhere
> I can file a bug with Tumblr about these issues...? I've seen they

> have use getsatisfaction.com (http://getsatisfaction.com/tumblr) so

wyvern

unread,
Nov 21, 2011, 9:23:47 PM11/21/11
to Tumblr API Discussion
you all going wrong way...

>2. The Tumblr API appears to expect "data" parameter names used in the
>OAuth base signature string to be singly percent encoded, but they
>should be doubly percent encoded. For example, with a parameter name
>of "data[0]", what should be in the OAuth base signature string is
>"%255B0%255D", but what the Tumblr API expects is "data%5B0%5D".

When collecting parameters, it must be decoded...

Look at section 3.4.1.3.1

3.4.1.3.1. Parameter Sources


The parameters from the following sources are collected into a
single
list of name/value pairs:

o The query component of the HTTP request URI as defined by
[RFC3986], Section 3.4. The query component is parsed into a
list
of name/value pairs by treating it as an
"application/x-www-form-urlencoded" string, separating the names
and values and decoding them as defined by
[W3C.REC-html40-19980424], Section 17.13.4.

o The OAuth HTTP "Authorization" header field (Section 3.5.1) if
present. The header's content is parsed into a list of name/
value
pairs excluding the "realm" parameter if present. The parameter
values are decoded as defined by Section 3.5.1.

o The HTTP request entity-body, but only if all of the following
conditions are met:

* The entity-body is single-part.

* The entity-body follows the encoding requirements of the
"application/x-www-form-urlencoded" content-type as defined
by
[W3C.REC-html40-19980424].

* The HTTP request entity-header includes the "Content-Type"
header field set to "application/x-www-form-urlencoded".

The entity-body is parsed into a list of decoded name/value
pairs
as described in [W3C.REC-html40-19980424], Section 17.13.4.

The "oauth_signature" parameter MUST be excluded from the signature
base string if present. Parameters not explicitly included in the
request MUST be excluded from the signature base string (e.g., the
"oauth_version" parameter when omitted).

It says The entity-body is parsed into a list of decoded name/value
pairs
as described in [W3C.REC-html40-19980424], Section 17.13.4.

So "data%5B0%5D" is correct..

S. Douglass

unread,
Nov 21, 2011, 9:49:11 PM11/21/11
to Tumblr API Discussion
I think that "data%5B0%5D" was the correct value for the request
entity-body but not for the OAuth signature base string. "data%5B0%5D"
would initially be decoded, as per the spec that you quoted, using
[W3C.REC-html40-19980424], Section 17.13.4, back to "data[0]". But I
think that during the construction of the signature base string, it
would be percent encoded -twice- first during "Parameters
Normalization" then again during "String Construction", as per the
spec sections that I mentioned. So I think it should be "data
%255B0%255D" in the signature base string. That's why my OAuth library
(Spring Social http://www.springsource.org/spring-social ) tries to
use and I'm pretty sure that it's written according to the OAuth
spec.

wyvern

unread,
Nov 21, 2011, 10:07:54 PM11/21/11
to Tumblr API Discussion
OOps. sorry, I misundertood ur quesiton because im not good at
English.

>what should be in the OAuth base signature string is

>"%255B0%255D", but what the Tumblr API expects is "data%5B0%5D"?

How do u know/check Tumblr API expects is "data%5B0%5D"?

wyvern

unread,
Nov 21, 2011, 10:31:25 PM11/21/11
to Tumblr API Discussion
Yes.

In my own implementation, data%255B0%255D is produced for singature
base string

S. Douglass

unread,
Nov 22, 2011, 12:19:00 AM11/22/11
to Tumblr API Discussion
Using the Python code posted here from Derek from the Tumblr team:

https://raw.github.com/gist/1198576/0a04d2400582adb72bc8de33c3cc6989202766d6/gistfile1.py

I added a line to print out the signature base string, right before
"base64.encodestring(hmac.new(...))". I see "data[0]=" get turned into
"data%5B0%5D%3D" in the signature base string and the post works. If I
change the code so that it encodes the "data[0]" another time (which I
think it should, based on the OAuth spec), I see it get turned into
"data%255B0%255D" in the signature base string and the post fails. My
Java code was always turning the parameter name to "data%255B0%255D"
and always failed. Part of how I got my code to work was by putting in
a special check for parameter names starting with "data" to avoid
double encoding them, to match the Python code.

jola...@aol.co.uk

unread,
Nov 22, 2011, 1:51:55 AM11/22/11
to tumbl...@googlegroups.com
Can you please take me out of these emails. Sorry :)
Sent from my BlackBerry® wireless device

-----Original Message-----
From: "S. Douglass" <sdougl...@gmail.com>
Sender: tumbl...@googlegroups.com
Date: Mon, 21 Nov 2011 21:19:00
To: Tumblr API Discussion<tumbl...@googlegroups.com>
Reply-To: tumbl...@googlegroups.com
Subject: Re: posting photo(s)

funfu...@gmail.com

unread,
Nov 22, 2011, 3:04:22 AM11/22/11
to tumbl...@googlegroups.com
Apparently you're supposed to send to them an email with the title stop and the body unsubscribe but it doesn't seem to be working.
Sent via my BlackBerry from Vodacom - let your email find you!

mohacs

unread,
Nov 22, 2011, 7:02:10 PM11/22/11
to tumbl...@googlegroups.com
Douglass hi,
i am passing authentication when i use data%5B0%5D%3D in my base string. i have tried this very early stage of my project however still getting 

{"meta":{"status":400,"msg":"Bad Request"},"response":{"errors":["Error uploading photo."]}}

i have tried base64 and many more methods to encode my binary what is the catch here sorry i am lost. 

P.S i am able to post single photo with multipart...

thank you.
-mohac.

S. Douglass

unread,
Nov 22, 2011, 8:50:40 PM11/22/11
to Tumblr API Discussion
Try using the test JPG that's been mentioned in this thread, and try
to get your base signature string to look something like this:

POST&http%3A%2F%2Fapi.tumblr.com%3A65029%2Fv2%2Fblog
%2FYOURBLOGHERE.tumblr.com%2Fpost&data%5B0%5D%3D%25FF%25D8%25FF
%25E0%2500%2510JFIF%2500%2501%2501%2501%2500H%2500H%2500%2500%25FF%25DB
%2500C
%2500%2506%2504%2504%2504%2505%2504%2506%2505%2505%2506%2509%2506%2505%2506%2509%250B
%2508%2506%2506%2508%250B%250C%250A%250A%250B%250A%250A%250C%2510%250C
%250C%250C%250C%250C%250C%2510%250C%250E%250F%2510%250F%250E%250C
%2513%2513%2514%2514%2513%2513%251C%251B%251B%251B%251C
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF%25DB%2500C
%2501%2507%2507%2507%250D%250C%250D%2518%2510%2510%2518%251A
%2515%2511%2515%251A
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF
%25C0%2500%2511%2508%2500%2502%2500%2502%2503%2501%2511%2500%2502%2511%2501%2503%2511%2501%25FF
%25C4%2500%2514%2500%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2508%25FF
%25C4%2500%2514%2510%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25C4%2500%2514%2501%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25C4%2500%2514%2511%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25DA%2500%250C%2503%2501%2500%2502%2511%2503%2511%2500%253F%2500T
%2583%25FF%25D9%26oauth_consumer_key%3DYOURKEY%26oauth_nonce
%3D31.1555291231%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp
%3D1321925551%26oauth_token%3DYOURTOKEN%26oauth_version%3D1.0%26type
%3Dphoto

I had to make sure to use the Latin 1 character set when percent
encoding the binary data, and I had to make sure that the binary data
got percent encoded twice, but that "data[0]" only got percent encoded
once.

mohacs

unread,
Nov 23, 2011, 4:57:37 AM11/23/11
to tumbl...@googlegroups.com
hi again,
i am really messed up.

this is yours:

data%5B0%5D%3D%25FF%25D8%25FF%25E0%2500%2510JFIF%2500%2501%2501%2501%2500H%2500H%2500%2500%25FF%25DB%2500C%2500%
2506%2504%2504%2504%2505%2504%2506%2505%2505%2506%2509%2506%2505%2506%2509%250B%2508%2506%2506%2508%250B%250C
%250A%250A%250B%250A%250A%250C%2510%250C%250C%250C%250C%250C%250C%2510%250C%250E%250F%2510%250F%250E%250C%2513%2513%2514%2514%2513%2513%251C%251B%251B%251B%251C
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF%25DB%2500C%2501%2507%2507%2507%250D%250C%250D%2518%2510%2510%2518%251A%2515%2511%2515%251A
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF%25C0%2500%2511%2508%2500%2502%2500%2502%2503%2501%2511%2500%2502%2511%2501%2503%2511%2501%25FF
%25C4%2500%2514%2500%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2508%25FF
%25C4%2500%2514%2510%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25C4%2500%2514%2501%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25C4%2500%2514%2511%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25DA%2500%250C%2503%2501%2500%2502%2511%2503%2511%2500%253F%2500T%2583%25FF%25D9

and this is mine, this is printed out just before create signature. i am signing with this however still getting Not Authorized

data%5B0%5D%3D%25FF%25D8%25FF%25E0%2500%2510JFIF%2500%2501%2501%2501%2500H%2500H%2500%2500%25FF%25DB%2500C%2500%
2506%2504%2504%2504%2505%2504%2506%2505%2505%2506%2509%2506%2505%2506%2509%250B%2508%2506%2506%2508%250B%250C
%250A%250A%250B%250A%250A%250C%2510%250C%250C%250C%250C%250C%250C%2510%250C%250E%250F%2510%250F%250E%250C%2513%2513%2514%2514%2513%2513%251C%251B%251B%251B%251C%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF%25DB%2500C%2501%2507%2507%2507%250D%250C%250D%2518%2510%2510%2518%251A%2515%2511%2515%251A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520
%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%25FF%25C0%2500%2511%2508%2500%2502%2500%2502%2503%2501%2511%2500%2502%2511%2501%2503%2511%2501%25FF%25C4%2500%2514%2500%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2508%25FF%25C4%2500%2514%2510%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF%25C4%2500%2514%2501%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF%25C4%2500%2514%2511%2501%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%25FF
%25DA%2500%250C%2503%2501%2500%2502%2511%2503%2511%2500%253F%2500T%2583%25FF%25D9

thank you.

mohacs

unread,
Nov 23, 2011, 6:59:22 AM11/23/11
to tumbl...@googlegroups.com
please check the base signature string 
here 
this base string validator can't even validate the base string. 

and here


is this your code working and you can submit photo sets right?

best,

S. Douglass

unread,
Nov 23, 2011, 11:52:53 AM11/23/11
to Tumblr API Discussion
Yes, I posted this photoset using my code:

http://sdouglassdev.tumblr.com/post/13137807163/snow-in-ct

(One normal photo and the test 2x2 white JPG file mentioned earlier in
this thread.)

You are correct, the base signature string I used is invalid. When I
put it into that first "oauthTester" you linked to, it complains that
"data[0]" should be encoded. If you change "data%5B0%5D" to "data
%255B0%255D" in the base string then the validator says it is valid.
Posts with valid base strings never worked for me though. I could only
get the posts to work by using the invalid "data%5B0%5D" in the base
string.

It would be great if the Tumblr team could address that issue, as well
as either specifying what character sets people should use (e.g. Latin
1) or changing to using UTF-8. Another option would be to switch to
multipart form data for binary posts.


On Nov 23, 3:59 am, mohacs <moh...@gmail.com> wrote:
> please check the base signature string

> herehttp://quonos.nl/oauthTester/

Steven Pears

unread,
Nov 23, 2011, 11:58:33 AM11/23/11
to Tumblr API Discussion
I know I've been out of the loop for the last few days, but you guys
have moved forward with such a large amount of test data and bottoming
out the inconsistencies I'm astonished and really pleased it's gotten
to where it has.

That said - it does sound like it's getting to a stage where a note or
comment from the Tumblr team would be good about now before we start
implementing what seems to be a less than perfect implementation.

Tumblr? Have you been monitoring this thread?

Mohac Bilecen

unread,
Nov 23, 2011, 2:20:58 PM11/23/11
to tumbl...@googlegroups.com
hi, i have intervened to OAuth signing void and if the key is data i have replaced data%255B0%255D with data%5B0%5D just before generate signature... this time i am getting authentication error from web service. as per your advise binary double url encoded in the body... i am 40 and last 20 years i am writing code and i am not not perfect also not bad at all either. first time i felt like this way :) 
  


--
-mohacs

Mohac Bilecen

unread,
Nov 23, 2011, 2:21:27 PM11/23/11
to tumbl...@googlegroups.com
Hi Steven,
yes they are watching and laugh!!!
cheers.
--
-mohacs

eros...@gmail.com

unread,
Nov 23, 2011, 2:28:14 PM11/23/11
to tumbl...@googlegroups.com
60 mails in this thread and no response from Tumblr, i say it is a miracle we have an API.
Enviado desde mi BlackBerry de Personal

From: Mohac Bilecen <moh...@gmail.com>
Date: Wed, 23 Nov 2011 21:21:27 +0200
Subject: Re: posting photo(s)

Mohac Bilecen

unread,
Nov 23, 2011, 2:48:33 PM11/23/11
to tumbl...@googlegroups.com
please do not be unfair, once they sent a fancy note, they said a lot without saying anything. 
--
-mohacs

Mohac Bilecen

unread,
Nov 23, 2011, 2:58:29 PM11/23/11
to tumbl...@googlegroups.com
i know what is coming next, we are complaining about lack of support here. soon enough group admins will come and send a message here to say "this is API discussion group bla bla bla please do not send something other than technical talk" and they will delete / lock these... voila problem solved. 

--
-mohacs

Mohac Bilecen

unread,
Nov 23, 2011, 3:49:51 PM11/23/11
to tumbl...@googlegroups.com
I am sorry for hassle one last question. what is the format of the request post body mine look like this. 

type=photo&data%5B0%5D=%25FF%25D8%...................

ps: not for body string to generate signature. 
many thanks.


On Wed, Nov 23, 2011 at 6:52 PM, S. Douglass <sdougl...@gmail.com> wrote:



--
-mohacs

John Bunting

unread,
Nov 23, 2011, 4:43:28 PM11/23/11
to tumbl...@googlegroups.com
Hey Everyone, 

So I finally had sometime to figure out a couple things. First things first, I fixed the lingering issues in the python script


This will post single photos or multiple photos. It should have a bit more clarity and will be able to explain exactly how to upload the photo.

If you need more in-depth help about how the body of the request looks, just tcpdump this file while making calls and you'll be able to see the nitty gritty of what's going on.

My apologies for not being able to do this sooner! As Derek and David has stated before, we don't have a devoted engineer to the api so it becomes difficult to get time to do this. Let me know if you have any questions, I can't promise I'll get to them right away, but I'll do what I can.

Thanks again,

~John

mohacs

unread,
Nov 23, 2011, 9:44:06 PM11/23/11
to tumbl...@googlegroups.com
Amen, that was only our wish, a working tcpdump. i am done now.
it was little bit late but accurate this time. 
thank you John!!!

p.s: this is not Oauh then something custom. maybe you should consider to push it to standard way.

cheers.
-mohac.

Steven Pears

unread,
Nov 24, 2011, 3:17:29 AM11/24/11
to tumbl...@googlegroups.com
Thank you John, no issue manually wiring this one call if I'm sure of the request I'm basing it on :)

En route to the office, guess i know what I'm doing first!


Sent from my Windows Phone

From: John Bunting
Sent: 23/11/2011 21:43

To: tumbl...@googlegroups.com
Subject: Re: posting photo(s)

Mohac Bilecen

unread,
Nov 24, 2011, 7:04:17 AM11/24/11
to tumbl...@googlegroups.com
Steven / Douglass / Wyvern and et al.

thank you for starting this topic and for great contributions. 

cheers.
--
-mohacs

Steven Pears

unread,
Dec 10, 2011, 12:26:54 PM12/10/11
to Tumblr API Discussion
John

The python script you've given us and my C# interpretation of that
script both continue to give me 401 issues. I can't think of anything
different in this information to any other app, other than the fact
that my tokens are authorised via XAuth - but that shouldn't make a
difference.

Can you please confirm that there's no issue with the photo upload
implementation and XAuth apps, and is there anything else that could
be causing this?

Thanks in advance

Steven

John Bunting

unread,
Dec 12, 2011, 10:06:12 AM12/12/11
to tumbl...@googlegroups.com
I think we'll have to start debugging this off list Steven. Do me a favor and email me jo...@tumblr.com.

We'll get this sorted.
--
John Bunting

Simplicity is prerequisite for reliability
    --Edsger W. Dijkstra


Message has been deleted

tiome

unread,
Mar 14, 2012, 6:59:04 PM3/14/12
to tumbl...@googlegroups.com
I did some tests with a Java client and the problem to upload a photo with XAuth apps still exists.
Have you found a workaround ?

Steven Pears

unread,
Mar 16, 2012, 1:27:53 PM3/16/12
to tumbl...@googlegroups.com
Sorry to disturb on this old post but I thought I'd take one last punt at trying to get the python script to work on my windows machine so I can look at getting my C# example running (I come back to it every few weeks for a few hours) - dashboard and text posts work great through the python script, but the encoding that python is giving me for my pictures is totally different to the TCP dumps I've re-downloaded from here.
 
I'm starting to think the reason I'm having trouble getting the python to work is due to the windows file system encoding - so the file.read method is not returning the same binary data you guys are getting, which is why I'm getting "Error Uploading Photo" messages.
 
Problem is - my lack of python knowledge is a huge hurdle. Is there any way I can force the encoding the file.read uses so I can remove it as a possible cause? I'm guessing it needs to be forced to latin-1, would that be right?
 
Any help would, as always, be appreciated. I'd really like to be able to get a C# example up for the people who have been messaging me asking if I ever cracked this!
 
Steven

John Bunting

unread,
Mar 16, 2012, 1:41:29 PM3/16/12
to tumbl...@googlegroups.com
try this:


file(sys.argv[x], 'rb').read()

This forces us to read the file in binary. Python docs say that there is a difference between *Nix machines and windows machines when reading in files http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files.

See if that works for ya.

Steven Pears

unread,
Mar 16, 2012, 4:19:37 PM3/16/12
to tumbl...@googlegroups.com
John - you're the man! Replacing the file.read from the original with that line allows the code to work in Windows as well
 
Now have a guaranteed script to use in order to check my C# code against I can't wait to write an example in .NET - I can see a busy weekend ahead of me!
 
Thank you for all your help on this John, I know I've not been the easiest developer to support ;)
 
Steven

Steven Pears

unread,
Mar 17, 2012, 4:40:24 PM3/17/12
to tumbl...@googlegroups.com
My test 2x2 test jpg now posts, progress!

The 20kb image I'm using as a second test had some small encoding issues I'm working through but there is definitely light appearing at the end of this particular tunnel. Happy days :)

Steven


Sent from my Windows Phone

From: John Bunting
Sent: 16/03/2012 17:41

To: tumbl...@googlegroups.com
Subject: Re: posting photo(s)

Steven Pears

unread,
Mar 18, 2012, 12:48:53 PM3/18/12
to tumbl...@googlegroups.com
It's done, it's actually working!
 
 
I've finally got my C# code, working with the Hammock library, to post a photoset to Tumblr in the V2 API from my WP7 app.
 
Thank you everyone who has helped with this. Now I know it works I'll look at pulling together the small changes so I can create a github fork of the Hammock repository. The OAuth library has .NET/Silverlight/WP7 versions so it should be straight forward to port from what I've done to whatever infrastructure you need.
 
I'll post the URL here once it's ready, probably sometime next week.
 
Thanks again!
 
Steven

Steven Pears

unread,
Mar 21, 2012, 9:45:46 AM3/21/12
to tumbl...@googlegroups.com
I've just dumped the .NET function I'm using to encode binary data for my OAuth process into a gist here:
 
 
I haven't had time to wire up a cradle to grave example yet as my day job is going a little mad right now. You want UrlEncode(bytes,false,false) for the OAuth signature and UrlEncode(bytes,true,true) for the body content (yes, I can now refactor to one parameter when I have time).
 
Fair warning though - there'a reason other APIs use multi-part posts for binary data; although this works great on a PC, the same code on my WP7 was so slow I'm looking at ways of pushing it into the background or making my app work under the phone's lock screen!
 
Hope this helps you .NET guys.
 
Steven

Justin Lee

unread,
Mar 21, 2012, 12:14:53 PM3/21/12
to tumbl...@googlegroups.com
Thanks, Steven.  I've been banging my head against photo posts from java for the last few days.  I'll port this to java and see how it fares.  What I have now *looks* correct but I keep getting 401s back from tumblr.  Very, very frustrating.
--
You can find me on the net at:

Steven Pears

unread,
Mar 21, 2012, 12:25:19 PM3/21/12
to tumbl...@googlegroups.com
Justin
 
I certainly know the feeling on that one! If you want to send me the base signature and body text you're able to produce for the little 2x2 test image we've been using on here (avaialble at http://www.convr.co.uk/test.jpg ) then I'll be happy to compare your output with mine. I found starting with this really tiny image and building from there was a good progression.
 
Steven

Justin Lee

unread,
Mar 21, 2012, 12:31:29 PM3/21/12
to tumbl...@googlegroups.com
I'll rerun my test with this image and see.  I've been using 10x10 png i created.  I did have one thought, could tumblr be complaining because it doesn't support pngs?  Anyway, I'll retry with this and get you that text if it fails for me.

Justin Lee

unread,
Mar 22, 2012, 8:45:33 AM3/22/12
to tumbl...@googlegroups.com
Forcing a predictable nonce, I've verified that my java code is producing the same bits as John's PHP version.  I've captured the outgoing traffic via ngrep and attached both the php and java outputs for comparison.  In this run, I did not force a given nonce/timestamp so those will differ as expected.  This is using the 2x2 image as well.
java.out
php.out

Justin Lee

unread,
Apr 4, 2012, 3:58:44 PM4/4/12
to tumbl...@googlegroups.com
I'm still banging my head against this one.  Can I get *anything* more meaningful than a 401 back from the server?  Does tumblr care about the keep-alive headers?  Does the order of the fields in Authorization matter?  I've resorted to using a raw socket and building the http request by hand and still get this error.  I can't see any difference on my end that has any meaningful chance of being wrong.  Can I get deeper input from the tumblr side of the world?
--
-- 
You can find me on the net at:

John Bunting

unread,
Apr 4, 2012, 4:37:16 PM4/4/12
to tumbl...@googlegroups.com
Honestly, nothing is really jumping out at me when looking at your results. I don't really do a whole lot of Java so I wouldn't really be able to help you there. The only actual difference here is your Keep-Alive header, but that shouldn't matter. Sorry, email me off list with some more information such as code, consumer keys etc, and I may be able to help you figure this out. 

felix schwermut

unread,
Apr 4, 2012, 4:40:23 PM4/4/12
to tumbl...@googlegroups.com
Without seeing any code it's hard to guess at this. But I can say I have observed:

1. Tumblr's API server seems to ignore HTTP Keep-Alive & does not implement Keep-Alive. It always sends back the header "Connection: close"
2. The order of fields in the "Authorization" header doesn't matter

One possibility is you are not generating the signature correctly. This seems to be the tricky bit for a lot of people, if they aren't using a good library that properly implements OAuth1.0

Felix

John Bunting

unread,
Apr 4, 2012, 4:45:44 PM4/4/12
to tumbl...@googlegroups.com
Agreed. Without code for us to actually look at, I can't really tell you what's going on. Yep and sigs are pretty much the most annoying part of this entire process.

felix schwermut

unread,
Apr 4, 2012, 5:34:51 PM4/4/12
to tumbl...@googlegroups.com
2 things strike me in these ".out" Files.  But the problems I see are in both files, so I'm not sure how helpful that is.

1. the oauth_foo_bar=  fields should be wrapped in quotes, per the OAuth Spec
eg, oauth_nonce="1332419923984",oauth_signature_method="HMAC-SHA1"

etc

2. Your oauth_signature=gJZrUpqDkJ6L9SFI0gKltJff5cs=    Is not "Percent encoded"  It needs to be. That "=" on the end should be a "%3D"

In fact, all of the oauth_foo_bar=   fields needs to be "percent encoded"  But the signature is usually the only one with characters that need to be encoded.  See the OAuth Spec.

See if that gets you anywhere.

Justin Lee

unread,
Apr 9, 2012, 1:51:49 PM4/9/12
to tumbl...@googlegroups.com
OK.  I've spent the last couple of days extracting out the oauth and rewriting it all pretty much from scratch trying to isolate what's different in what the java code is doing.  Using a hardcoded nonce, i can get a byte for byte match with the PHP code.  Both the php and java failed due to the nonce being reused (which is apparently verboten).  Freeing up the nonce to be generated, the PHP code worked while the Java code didn't.  This was infuriating because the *only* difference between the bits being sent were the nonce (and the generated sig of course).  So given *that* notion, i started looking at the nonce.  John's PHP sample uses time() which is seconds since the epoch.  My java code was using System.currentTimemillis() which is, of course, milliseconds since the epoch.  Half hopeful, half appalled, I divided my nonce by 1000 to get it to seconds since the epoch.  AND THEN IT WORKED! fuuuuuuuuuuuuu......

So my question is, why should the nonce have mattered like that?  It's just a numeric value to be ANDed and XORed and bit crammed with the various keys and secrets.  I just don't see why the scale of the number should've made any difference whatsoever.  Regardless, it now works so hooray for the home team, I guess.

And another thing.  Why are errors returned from the the api with a 200 code even though the body lists a 401 (or whatever)?  Why isn't *that* response code part of the response header like it should be?  These are HTTP calls and I expect the response code to reflect the server response.  Masking everything with that 200 code just obscures stuff and complicates response/error parsing.
--
-- 
You can find me on the net at:

felix bonkoski

unread,
Apr 10, 2012, 2:42:59 AM4/10/12
to tumbl...@googlegroups.com
Hard to say. Theoretically (according to the OAuth1.0 spec) the nonce can be any string of characters. It doesn't have to have anything at all to do with the timestamp.  My code doesn't use a timestamp to generate the nonce at all, and it works fine.

The spec does specify that the timestamp must be the *seconds* since the epoch.

So, based on your results I can't give you any feedback. I've never had a problem with the nonce, using any string of characters.

GG

unread,
Aug 29, 2012, 1:16:05 PM8/29/12
to tumbl...@googlegroups.com
Thanks to the info in this thread I finally got this working in javascript.  It wasn't without suffering however.  Documented here:

RickF

unread,
Mar 6, 2013, 2:15:22 PM3/6/13
to tumbl...@googlegroups.com
I have been through this thread top to bottom.  You guys did a lot of work figuring this out.  What I never found is any Java code.  Do one of you guys have some Java code the shows how all the special encoding is handled?
Thanks

Rick 

John Bunting

unread,
Mar 6, 2013, 2:16:16 PM3/6/13
to tumbl...@googlegroups.com
We released an official Java client here: https://github.com/tumblr/jumblr

--
You received this message because you are subscribed to the Google Groups "Tumblr API Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tumblr-api+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

ramon

unread,
Apr 14, 2013, 11:08:23 PM4/14/13
to tumbl...@googlegroups.com
Hi John,
thank you for your link to Jumblr. I'm trying to integrate Jumblr into my Android project and it works fine with text posts.
But when I try to post images to Tumblr I get an "Authentication challenge is null" error.
That error also occurs with your Photoset branch of Jumblr.

Have you experienced something like this before? Do your photo uploads work with Jumblr?

I hope you can help me with this.

Thanks in advance!

Ramon

John Crepezzi

unread,
Apr 15, 2013, 4:52:24 AM4/15/13
to tumbl...@googlegroups.com
Hey Ramon,

Jumblr uploads photos well for me.
Can you check the time on the device and make sure that it is set correctly?

Thanks,
John C

ramon

unread,
Apr 15, 2013, 7:11:45 AM4/15/13
to tumbl...@googlegroups.com
Hi John,
thanks for your response. I checked the time of the device and it's set to "automatic" and set to the time zone I am in now.

Do you have or know a code snipped I can try? :)

Thank you very much for your help, I really appreciate it!

Ramon

ramon

unread,
Apr 15, 2013, 8:14:36 AM4/15/13
to tumbl...@googlegroups.com
It works in Java 1.6 on my desktop, but when I run this code on Android there is an exception.

My call in code, start() is called in a different thread since it's network code:

public void start(){

JumblrClient client = new JumblrClient("myConsumerkey", "myConsumerSecret", "myToken", "mySecret");

try {

PhotoPost pp = client.newPost(client.user().getName(), PhotoPost.class);

// Photo photo = new Photo(mImagePath);

pp.setCaption("Test");

// pp.setPhoto(photo);

pp.setSource("http://images.wikia.com/dragonball/images/5/5e/Naruto-Shippuden-UNS-3_Goku-752x600.jpg");

pp.setClient(client);

pp.save();

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InstantiationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}




My Log:

W/dalvikvm(16029): threadid=11: thread exiting with uncaught exception (group=0x40b471f8)
E/AndroidRuntime(16029): FATAL EXCEPTION: Thread-17271
E/AndroidRuntime(16029): org.scribe.exceptions.OAuthConnectionException: There was a problem while creating a connection to the remote service.
E/AndroidRuntime(16029): at org.scribe.model.Request.send(Request.java:74)
E/AndroidRuntime(16029): at org.scribe.model.Request.send(Request.java:80)
E/AndroidRuntime(16029): at com.tumblr.jumblr.request.RequestBuilder.postMultipart(RequestBuilder.java:57)
E/AndroidRuntime(16029): at com.tumblr.jumblr.JumblrClient.postCreate(JumblrClient.java:351)
E/AndroidRuntime(16029): at com.tumblr.jumblr.types.Post.save(Post.java:253)
E/AndroidRuntime(16029): at com.postly.PostlyMainActivity.start(PostlyMainActivity.java:414)
E/AndroidRuntime(16029): at com.postly.PostlyMainActivity$6.run(PostlyMainActivity.java:601)
E/AndroidRuntime(16029): at java.lang.Thread.run(Thread.java:856)
Caused by: java.io.IOException: Received authentication challenge is null
E/AndroidRuntime(16029): at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
E/AndroidRuntime(16029): at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
E/AndroidRuntime(16029): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
E/AndroidRuntime(16029): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
E/AndroidRuntime(16029): at org.scribe.model.Response.<init>(Response.java:33)
E/AndroidRuntime(16029): at org.scribe.model.Request.doSend(Request.java:120)
E/AndroidRuntime(16029): at org.scribe.model.Request.send(Request.java:70) 

John Crepezzi

unread,
Apr 17, 2013, 8:37:57 AM4/17/13
to tumbl...@googlegroups.com
I haven't personally tried Jumblr on Android yet (although I can soon) but I know
others have.  I know this problem happens around time mistakes, but I won't know
much more until I can get this up and running on Android myself

Stay tuned!


--

ramon

unread,
Apr 18, 2013, 3:08:15 AM4/18/13
to tumbl...@googlegroups.com
Hi John,
thanks for your response! I took a look at the request headers in my pure Java App and in my Android App, although the time was ok in both it only worked in the pure Java App. I will use the next weekend and try again.

Text posts work in both versions.

If anyone has any hint I'd be really thankful! :)

Ramon

Jabari Hunt

unread,
Jan 7, 2014, 2:23:08 AM1/7/14
to tumbl...@googlegroups.com
Hello All,

I'm replying to this post because it helped steer me in the right direction to a solution.  I'm using Java with the Scribe library and can reliably post photos now.  I detailed what I did here: https://groups.google.com/d/msg/tumblr-api/0QxFn79B2n4/6MHC4GNHqp8J

I hope this helps!

 

On Thursday, November 17, 2011 8:42:00 PM UTC-6, S. Douglass wrote:
I know this is a well worn topic here, so my apologies for starting
yet another thread about this. I've tried to scour all the existing
threads and examples but things are still not entirely clear to me. I
was hoping that folks could settle a couple points of confusion for
me. It'd be great to have these details made plain, and not in example
code, so that anybody can look at it without having to know
programming language X or Y or Z.

1. Content-type - is it application/x-www-form-urlencoded or multipart/
form-data ???
2. How is the OAuth signature generated? The same as for every other
API call? Or differently? The Twitter documentation for their upload
API call (which looks to be using multipart/form-data) indicates that
the OAuth signature is generated differently in that case:

https://dev.twitter.com/discussions/1059

3. The binary data is supposed to be turned into a string then
encoded. Is it Base64 encoded? URL query parameter encoded? Both?
4. The parameter names, are they supposed to be named "data[0]",
"data[1]", "data[2]", etc? If I'm sending just one file do I use
"data" or "data[0]"?

I have looked at both the example gists on GitHub mentioned in
elsewhere here but it isn't clear to me from the comments if they
actually work, and also I'm not familiar with Python, so I'm not
really sure I'm interpreting the code 100% correctly. So I'm just
hoping for some non-code details about how it works. Thanks!
Reply all
Reply to author
Forward
0 new messages