OAuth image upload: how does Twitter want to see multi-part post OAuth parts?

1,075 views
Skip to first unread message

Andrew Arnott

unread,
Jan 9, 2010, 7:59:58 PM1/9/10
to twitter-development-talk

Can anyone from Twitter, or someone who's successfully done it with a consumer library, please lay out the exact format of the HTTP request Twitter expects for an OAuth-signed image upload?  By my reading the OAuth spec allows several possibilities, assuming multi-part POST:

  1. Only the the image (and tile) parameters are in the POST entity.  All the OAuth-specific parameters are in the HTTP Authorization header, thereby allowing them to be signed.
  2. All the parameters, OAuth ones and image ones, are in the POST entity, leaving nothing by the HTTP method and URL to be signed using the OAuth signature.
  3. The OAuth specific parameters appear in the query string of the POST url, and once again the image parameter appears in the POST entity.
Which of these does Twitter support?  I'm trying #1 without any success.  Before investing in upgrading my library to support each of these scenarios, I'd like to know which one will end up successful.  Right now I'm getting Status 500 errors.

Thanks.

Andrew Arnott

unread,
Jan 10, 2010, 9:37:15 PM1/10/10
to twitter-development-talk
Still trying to post images to Twitter using OAuth unsuccessfully.  Can someone please help?

My latest attempt is inline with what I can gather from other people who claim to do it successfully: put ALL parameters in the multipart entity and have a very simple OAuth signature base string:.

The signature was constructed based on this signature base string:
POST&http%3A%2F%2Ftwitter.com%2Faccount%2Fupdate_profile_image.xml&
And here is the raw text I sent:

POST /account/update_profile_image.xml HTTP/1.1
Content-Type: multipart/form-data; boundary=2e280788-b8f5-4c5e-a05b-9be7ad76fac7
User-Agent: DotNetOpenAuth/3.4.0.10010
Cache-Control: no-store,no-cache
Pragma: no-cache
Content-Length: 20134


--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_token"

14821025-bq1rTNjyfQrOtb181Alwt0UHPJTffxXDOahZtBrK8
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_consumer_key"

ONxVX5b14DpiVGlprq1yA
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_nonce"

zvj9dhYY
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_signature_method"

HMAC-SHA1
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_signature"

IKIkDXQC6JPELXTUv8oU7byaXSU=
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_version"

1.0
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="oauth_timestamp"

1263176820
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7
Content-Disposition: form-data; name="image"; filename="thomas jefferson.jpg"
Content-Type: image/jpg
Content-Transfer-Encoding: binary

<beginning of raw binary data>
--2e280788-b8f5-4c5e-a05b-9be7ad76fac7


--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre

Yusuke

unread,
Jan 11, 2010, 5:46:00 PM1/11/10
to Twitter Development Talk
If you are familiar with Java, try Twitter4J.
The latest snapshot supports image upload with OAuth.
http://groups.google.com/group/twitter4j/browse_thread/thread/d548993dd3a4fc84

> On Sat, Jan 9, 2010 at 4:59 PM, Andrew Arnott <andrewarn...@gmail.com>wrote:
>
>
>
> > Can anyone from Twitter, or someone who's successfully done it with a
> > consumer library, please lay out the exact format of the HTTP request
> > Twitter expects for an OAuth-signed image upload?  By my reading the OAuth
> > spec allows several possibilities, assuming multi-part POST:
>

> >    1. Only the the image (and tile) parameters are in the POST entity.


> >     All the OAuth-specific parameters are in the HTTP Authorization header,
> >    thereby allowing them to be signed.

> >    2. All the parameters, OAuth ones and image ones, are in the POST


> >    entity, leaving nothing by the HTTP method and URL to be signed using the
> >    OAuth signature.

> >    3. The OAuth specific parameters appear in the query string of the POST

Vikram

unread,
Jan 11, 2010, 11:30:25 PM1/11/10
to Twitter Development Talk

Yusuke,

Can you please share with us the raw text of your request? I am not
familiar with Java. I am working with C++(.NET)

Raffi Krikorian

unread,
Jan 12, 2010, 1:58:06 AM1/12/10
to twitter-deve...@googlegroups.com
i suggest taking a look at 


as it has a pretty good walk through of how to construct the parameters.  one point of note is that when the Content-Type of the request is -not- application/x-www-form-urlencoded, then the POST body should -not- be included as part of the signature.  so, assuming you're using multi-part and the image is in the POST body, do not include it in the signature block.

--
Raffi Krikorian
Twitter Platform Team
http://twitter.com/raffi

Vikram

unread,
Jan 12, 2010, 1:01:04 PM1/12/10
to Twitter Development Talk
Hey Raffi,

I know about the basics of oAuth I already working code for posting
tweets with OAuth. I have few doubts with respect to building
signature for multi part requests.

1. What all parameters should be part of the signature base string?

2. Where should the parameters and the signature be placed in the
request stream?

3. How should the file data be sent?


Please help me out.

Raffi Krikorian

unread,
Jan 12, 2010, 1:28:06 PM1/12/10
to twitter-deve...@googlegroups.com
i haven't actually written code to upload profile images recently, but what i would try is the following (and i apologise if i'm slightly incorrect as i'm doing this from memory):
 
1. What all parameters should be part of the signature base string?

oauth_consumer_key
oauth_signature_method
oauth_timestamp
oauth_nonce
oauth_version
oauth_token

of course, the request type and URL comprise the block that needs to be signed

2. Where should the parameters and the signature be placed in the
request stream?

the authorization header would be the best place to stick it.
 
3. How should the file data be sent?

multipart/form-data, i believe.

Vikram

unread,
Jan 12, 2010, 1:50:18 PM1/12/10
to Twitter Development Talk
Raffi,

If you have ever worked with DotNet then please help me.

What I do currently is as follows:

- Set the request type to POST.
- ContentType to "multipart/form-data; boundary=" + boundary
(generated);
- Then I add this to the request stream

L"--"+boundary+L"\r\n"+L"Content-Disposition: form-data;
name=\"image\"; filename=\"test.JPG\" " + L"\r\n"+L"Content-Type:
image/jpg"+L"\r\n\r\n";
- followed by the bytestream of the image.
- Then I continue to add the OAuth params/signature to the stream

All the above are URL encoded.

Twitter responds with a 401 to this request.

What do I have to correct.

Raffi Krikorian

unread,
Jan 12, 2010, 4:44:09 PM1/12/10
to twitter-deve...@googlegroups.com
i've never used dot.net, however, it looks suspicious to me that the bytestream of the image is coming before the oauth params/signature in your example.  i would expect the oauth params/signature to be in the Authorization header, and the image to be in the body of the POST.

Vikram

unread,
Jan 13, 2010, 12:32:01 PM1/13/10
to Twitter Development Talk
Raffi,

After modifications, this is how my request looks like

OAuth signature base:

POST&http%3A%2F%2Ftwitter.com%2Faccount
%2Fupdate_profile_background_image.xml&oauth_consumer_key
%3DgUutCG9HjEOT0N8IxvW9w%26oauth_nonce
%3Dt64bID6gIVtpU6t7m3dsTrTUOhubJizM%26oauth_signature_method%3DHMAC-
SHA1%26oauth_timestamp%3D1263403749%26oauth_token
%3D29191067-7Gl0rjc5KegDdw5p0FJqcBLTmKFF8rCr9Kb3Yt7ZE%26oauth_version
%3D1.0a

I sign this and then add all the parameters to the request stream,
this is how my stream looks like:

oauth_consumer_key=gUutCG9HjEOT0N8IxvW9w&oauth_nonce=t64bID6gIVtpU6t7m3dsTrTUOhubJizM&oauth_signature=TE0lfX3WZwYAr1812GNP8uYJGKc
%3D&oauth_signature_method=HMAC-
SHA1&oauth_timestamp=1263403749&oauth_token=29191067-7Gl0rjc5KegDdw5p0FJqcBLTmKFF8rCr9Kb3Yt7ZE&oauth_version=1.0a&image=


This is followed by the byte stream of the image.

I still get a 401 as response.

Can tell me what I need to change?

Vikram

unread,
Jan 13, 2010, 12:15:53 PM1/13/10
to Twitter Development Talk

Rafi,


Can you please share the raw text of a successful image update request
for oauth?

Vikram

unread,
Jan 13, 2010, 12:40:05 PM1/13/10
to Twitter Development Talk

Raffi Krikorian

unread,
Jan 17, 2010, 6:47:42 PM1/17/10
to twitter-deve...@googlegroups.com
i wrote a simple ruby script and posted it at http://mehack.com/uploading-a-background-image-to-twitter-using (which may be having DNS issues at the moment, and if so, just go see the code directly at http://gist.github.com/279650) -- that code demonstrates how to construct the oauth signature and upload a background image to Twitter.  i tested it on my test account, and it seems to work well.

while that code is written in ruby, i tried to take care to write it clearly enough so that even non-ruby programmers should be able to follow it.  let me know if there are any questions!

ps. as yusuke mentioned earlier on this thread, Twitter4J (http://yusuke.homeip.net/twitter4j/en/index.html) has support for setting background images via OAuth.  FWIW, that library is -very- clearly written, and should be relatively easy for programmers (especially those who are attempting to construct their own OAuth signatures) to follow.
Reply all
Reply to author
Forward
0 new messages