C# + OAuth + account/update_profile_image = 500 Internal Server Error

175 views
Skip to first unread message

David Carson

unread,
Aug 17, 2009, 4:00:21 AM8/17/09
to Twitter Development Talk
Hi,

I'm trying to implement a simple little app which can (a) send status
updates and (b) modify the user's profile image.

I started off using Shannon Whitley's code from http://www.voiceoftech.com/swhitley/?p=681
which got me up and running just fine for the statuses/update method.

However I needed to add multipart/form-data POST handling to it in
order to the account/update_profile_image call. Every example I could
find of this involved basic authentication, not OAuth, so I'm not sure
if I'm doing it right.

Anyway, all I can get from it is "500 Internal Server Error" - does
anyone have any ideas? Below it my HTTP request dumped out using
Fiddler (I replaced the binary data of the file with "(there's a few K
of binary data here, the contents of the file)" and the OAuth keys
with X's)


POST /account/update_profile_image.xml HTTP/1.1
Content-Type: multipart/form-data;
boundary=----------------------------8cbed79c91b24f3
Host: twitter.com
Content-Length: 3863


------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_consumer_key";

XXXXXXXXXXXXXXXXXXXXX
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_nonce";

8684173
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_signature_method";

HMAC-SHA1
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_timestamp";

1250495190
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_token";

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_version";

1.0
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="oauth_signature";

XXXXXXXXXXXXXXXXXXXXXXXXXXXX
------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="image"; filename="test.jpg"
Content-Type: image/jpeg

(there's a few K of binary data here, the contents of the file)
------------------------------8cbed79c91b24f3

David Carson

unread,
Aug 20, 2009, 1:40:03 AM8/20/09
to Twitter Development Talk
Got this sorted out and working, and thought I should share the two
pitfalls which were causing me problems.

First of all, unbelievably, the 500 Internal Server Error was being
caused by an extra carriage return between my last HTTP header and the
first multipart boundary. Seriously. I had two blank lines in there
instead of one. Removed the extra carriage return, and my 500
vanished, being replaced by a more reasonable "(401) Unauthorized -
Incorrect signature" error.

Secondly, the OAuth documentation seems a bit shaky when it comes to
multipart/form-data POSTs. But basically, you do NOT use any of the
POST parameters when creating your signature. And this includes all of
the OAuth-specific parameters like oauth_consumer_key,
oauth_signature_method, etc. Bit of a security hole imho, OAuth
implements all this complexity to avoid man-in-the-middle or replay
attacks, and as soon as you do a multipart POST it's all negated.

So, my signature base was literally:

POST&http%3A%2F%2Ftwitter.com%2Faccount%2Fupdate_profile_image.xml&

Just the HTTP method and the URL. No parameters.

Once I made that change to the signature generation, my request went
through fine and my avatar changed.

Hope this helps someone!

Cheers,
David...

Andrew Badera

unread,
Aug 20, 2009, 4:52:51 AM8/20/09
to twitter-deve...@googlegroups.com

Gotta love HTTP. In many ways very forgiving, in other ways very, very
picky. Glad you got it worked out. FYI I believe LinqToTwitter offers
the same image upload/change functionality on top of the same
OAuthBase work by Eran & Shannon.

∞ Andy Badera
∞ This email is: [ ] bloggable [x] ask first [ ] private
∞ Google me: http://www.google.com/search?q=(andrew+badera)+OR+(andy+badera)

Zaudio

unread,
Oct 18, 2009, 5:42:13 PM10/18/09
to Twitter Development Talk
Hi David,

I found your excellent post hoping that it would solve the same
challenge for my app: updating profile image via Oauth... using
similar .net base to yourself...
BUT I just get the 401 all the time... despite taking your advice to
just sign with the HTTPmethod & URL.... My post data is laid out much
like yours... though I never got that 500 error...

I've tried all sorts... dropping the & off the end.... different
encodings...

What encoding did you use to encode your image, and then to post the
request?

Does it still work for you... or did this get broken when Twitter
'fixed' their Oauth implementation?

Can anyone else advise if they have got this working and where I might
be going wrong?

Thanks

Simon (Zaudio)

Nicholas Granado

unread,
Oct 18, 2009, 8:11:11 PM10/18/09
to twitter-deve...@googlegroups.com
Simon,

I believe the body of your post might be incorrect. It should look like this:

POST /account/update_profile_image.
xml HTTP/1.1
Content-Type: multipart/form-data;
boundary=----------------------------8cbed79c91b24f3
Host: twitter.com
Content-Length: 3863(this will probably change now..)


------------------------------8cbed79c91b24f3
Content-Disposition: form-data; name="image"; filename="test.jpg"
Content-Type: image/jpeg

(there's a few K of binary data here, the contents of the file)
------------------------------8cbed79c91b24f3


The rest of the OAuth variables should be passed on the query string.

I hope this helps.

Cheers,
Nicholas
---
Nicholas Granado
email:  ngra...@gmail.com
twitter: heatxsink
web:    http://nickgranado.com

Zaudio

unread,
Oct 19, 2009, 9:38:38 AM10/19/09
to Twitter Development Talk
Nicholas,
That's great feedback!

In you opinion, how do I then sign the request? Do I use all the usual
for the signaturebase... ie postmethod&url&nonce&etc etc
or just postmethod&url& as David suggested?

I trust that the image data does not come into the signing process,
and that I still can post the data using iso-8859-1 encoding as I
would normally do for uploading files?

If you have these answers, then I should be able to nail this for
our .net case.Oauth's been working great for us until this hitch...

Thanks

Simon


On Oct 18, 6:11 pm, Nicholas Granado <ngran...@gmail.com> wrote:
> Simon,
>
> I believe the body of your post might be incorrect. It should look like
> this:
>
> POST /account/update_profile_image.xml HTTP/1.1
> Content-Type: multipart/form-data;
> boundary=----------------------------8cbed79c91b24f3
> Host: twitter.com
> Content-Length: 3863(this will probably change now..)
>
> ------------------------------8cbed79c91b24f3
> Content-Disposition: form-data; name="image"; filename="test.jpg"
> Content-Type: image/jpeg
>
> (there's a few K of binary data here, the contents of the file)
> ------------------------------8cbed79c91b24f3
>
> The rest of the OAuth variables should be passed on the query string.
>
> I hope this helps.
>
> Cheers,
> Nicholas
> ---
> Nicholas Granado
> email: ngran...@gmail.com

Nicholas Granado

unread,
Oct 19, 2009, 10:32:09 AM10/19/09
to twitter-deve...@googlegroups.com
Simon,

You would sign the request with all of the usual "oauth param" suspects.  If I recall correctly this endpoint has no other params other than the 'image' param in the multi-part post body whose value would be the bytes of the image file.  Typically I've only seen the post params passed into the oauth signing rigmarole when the post body is urlencoded.

I hope this helps, this whole OAuth thing can be very confusing at first glance.  If you are in C# I have my own lib for twitter basic auth/oauth that I've baked up, if you like I could pass you the bits.

Nicholas
---
Nicholas Granado
email:  ngra...@gmail.com

twitter: heatxsink
web:    http://nickgranado.com


Thomas Hübner

unread,
Oct 19, 2009, 5:39:45 PM10/19/09
to twitter-deve...@googlegroups.com
You can use TwitterVB which covers nearly the complete API in .NET
(OAuth included). U find it on codeplex http://twittervb.codeplex.com/

Cheers,
Thomas

Nicholas Granado schrieb:


> Simon,
>
> You would sign the request with all of the usual "oauth param"
> suspects. If I recall correctly this endpoint has no other params other
> than the 'image' param in the multi-part post body whose value would be
> the bytes of the image file. Typically I've only seen the post params
> passed into the oauth signing rigmarole when the post body is urlencoded.
>
> I hope this helps, this whole OAuth thing can be very confusing at first
> glance. If you are in C# I have my own lib for twitter basic auth/oauth
> that I've baked up, if you like I could pass you the bits.
>
> Nicholas
> ---
> Nicholas Granado

> email: ngra...@gmail.com <mailto:ngra...@gmail.com>


> twitter: heatxsink
> web: http://nickgranado.com
>
>
> On Mon, Oct 19, 2009 at 6:38 AM, Zaudio <si...@z-audio.co.uk
> <mailto:si...@z-audio.co.uk>> wrote:
>
>
> Nicholas,
> That's great feedback!
>
> In you opinion, how do I then sign the request? Do I use all the usual
> for the signaturebase... ie postmethod&url&nonce&etc etc
> or just postmethod&url& as David suggested?
>
> I trust that the image data does not come into the signing process,
> and that I still can post the data using iso-8859-1 encoding as I
> would normally do for uploading files?
>
> If you have these answers, then I should be able to nail this for
> our .net case.Oauth's been working great for us until this hitch...
>
> Thanks
>
> Simon
>
>
> On Oct 18, 6:11 pm, Nicholas Granado <ngran...@gmail.com

> <mailto:ngran...@gmail.com>> wrote:
> > Simon,
> >
> > I believe the body of your post might be incorrect. It should look
> like
> > this:
> >
> > POST /account/update_profile_image.xml HTTP/1.1
> > Content-Type: multipart/form-data;
> > boundary=----------------------------8cbed79c91b24f3

> > Host: twitter.com <http://twitter.com>


> > Content-Length: 3863(this will probably change now..)
> >
> > ------------------------------8cbed79c91b24f3
> > Content-Disposition: form-data; name="image"; filename="test.jpg"
> > Content-Type: image/jpeg
> >
> > (there's a few K of binary data here, the contents of the file)
> > ------------------------------8cbed79c91b24f3
> >
> > The rest of the OAuth variables should be passed on the query string.
> >
> > I hope this helps.
> >
> > Cheers,
> > Nicholas
> > ---
> > Nicholas Granado

> > email: ngran...@gmail.com <mailto:ngran...@gmail.com>


> > twitter: heatxsink
> > web: http://nickgranado.com
> >
> > On Sun, Oct 18, 2009 at 2:42 PM, Zaudio <si...@z-audio.co.uk
> <mailto:si...@z-audio.co.uk>> wrote:
> >
> > > Hi David,
> >
> > > I found your excellent post hoping that it would solve the same
> > > challenge for my app: updating profile image via Oauth... using
> > > similar .net base to yourself...
> > > BUT I just get the 401 all the time... despite taking your advice to
> > > just sign with the HTTPmethod & URL.... My post data is laid out
> much
> > > like yours... though I never got that 500 error...
> >
> > > I've tried all sorts... dropping the & off the end.... different
> > > encodings...
> >
> > > What encoding did you use to encode your image, and then to post the
> > > request?
> >
> > > Does it still work for you... or did this get broken when Twitter
> > > 'fixed' their Oauth implementation?
> >
> > > Can anyone else advise if they have got this working and where I
> might
> > > be going wrong?
> >
> > > Thanks
> >
> > > Simon (Zaudio)
> >
> > > On Aug 19, 11:40 pm, David Carson <carson63...@gmail.com

signature.asc

Zaudio

unread,
Oct 20, 2009, 10:00:43 AM10/20/09
to Twitter Development Talk
Thanks Thomas... I did look at TwitterVB as a possible way to find the
answer to this particular function call... but the API says it doesn't
yet cover account/updateprofileimage...

Thanks

Simon

On Oct 19, 3:39 pm, Thomas Hübner <thueb...@gmx.de> wrote:
> You can use TwitterVB which covers nearly the complete API in .NET
> (OAuth included). U find it on codeplexhttp://twittervb.codeplex.com/
>
> Cheers,
> Thomas
>
> Nicholas Granado schrieb:
>
> > Simon,
>
> > You would sign the request with all of the usual "oauth param"
> > suspects. If I recall correctly this endpoint has no other params other
> > than the 'image' param in the multi-part post body whose value would be
> > the bytes of the image file. Typically I've only seen the post params
> > passed into the oauth signing rigmarole when the post body is urlencoded.
>
> > I hope this helps, this whole OAuth thing can be very confusing at first
> > glance. If you are in C# I have my own lib for twitter basic auth/oauth
> > that I've baked up, if you like I could pass you the bits.
>
> > Nicholas
> > ---
> > Nicholas Granado
> signature.asc
> < 1KViewDownload

Zaudio

unread,
Oct 20, 2009, 10:05:03 AM10/20/09
to Twitter Development Talk
Hi Nicholas,

Sounds like you have this particular method cracked (account/
updateprofileimage) in Oauth....

Our code does use C# for all twitter layers... And thanks for your
offer.. all I'm really after is the logic to get the correctly signed
POST for this method... You seem to suggest I don't need to sign the
image data as it is not urlencoded... So I'll try from there.
If you can send me snippets that show the logic to make this work...
that might help.

Thanks again

Simon

On Oct 19, 8:32 am, Nicholas Granado <ngran...@gmail.com> wrote:
> Simon,
>
> You would sign the request with all of the usual "oauth param" suspects. If
> I recall correctly this endpoint has no other params other than the 'image'
> param in the multi-part post body whose value would be the bytes of the
> image file. Typically I've only seen the post params passed into the oauth
> signing rigmarole when the post body is urlencoded.
>
> I hope this helps, this whole OAuth thing can be very confusing at first
> glance. If you are in C# I have my own lib for twitter basic auth/oauth
> that I've baked up, if you like I could pass you the bits.
>
> Nicholas
> ---
> Nicholas Granado
Reply all
Reply to author
Forward
0 new messages