getting 400 bad request when requesting token

39 views
Skip to first unread message

moonlightcheese

unread,
Jul 8, 2010, 1:45:58 PM7/8/10
to Friends of the Unofficial Google Reader API
this code worked fine before, but i'm having problems for some
reason. here is the request i'm trying to make:

https://www.google.com/reader/api/0/token

i'm getting 400:Bad Request as a response, and i'm not sure why.
isn't this the correct URL for requesting a token? the auth token is
being passed as a header in all requests now, and i can request feed
list, and it works just fine, so there's nothing wrong with the auth
code. what gives?

moonlightcheese

unread,
Jul 8, 2010, 2:11:10 PM7/8/10
to Friends of the Unofficial Google Reader API
in addition, i can request this token in a normal browser window and
get a token as a response body. i can't figure out what in my request
code is mucking things up. it's terribly frustrating, since this code
worked perfectly before the ClientLogin changes. i've also tried
removing the authorization header from the token request, but still
get no token and a 400 error.

moonlightcheese

unread,
Jul 8, 2010, 3:09:22 PM7/8/10
to Friends of the Unofficial Google Reader API
just tried to request a token as a POST rather than a GET request.
still not working. also tried clearing cookies before sending request
(just to make sure the saved SID in the cookie store wasn't causing
some problem) and nothing. shooting in the dark here... is no one
else having this issue?

Mihai Parparita

unread,
Jul 8, 2010, 3:11:32 PM7/8/10
to foug...@googlegroups.com
What authentication method are you using? Have you tried using http instead of https for requesting the token?

Mihai

Sven Walther

unread,
Jul 8, 2010, 3:13:03 PM7/8/10
to foug...@googlegroups.com
Could you maybe give us some code snippets of your request? Switched
my Desktop Google Reader to ClientLogin recently and did have no
problems with getting the token.

Gesendet mit meinem iPhone

Am 08.07.2010 um 21:09 schrieb moonlightcheese <moonlig...@gmail.com
>:

moonlightcheese

unread,
Jul 8, 2010, 3:37:43 PM7/8/10
to Friends of the Unofficial Google Reader API
switched from https to http and this solved the problem. i'm able to
get tokens now, but now i have another bad request error, and
switching from https to http didn't help this time:

http://www.google.com/reader/api/0/stream/items/contents

i've tried to submit this as a post and get, using both http and https
requests. any ideas?

On Jul 8, 2:11 pm, Mihai Parparita <mih...@google.com> wrote:
> What authentication method are you using? Have you tried using http instead
> of https for requesting the token?
>
> Mihai
>
> On Thu, Jul 8, 2010 at 3:09 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:

Mihai Parparita

unread,
Jul 8, 2010, 3:49:57 PM7/8/10
to foug...@googlegroups.com
That servlet only accepts POST, because its parameter list can get very long, and we didn't want to run into URL length issues (the accepts i=<item ID> parameters).

Mihai

moonlightcheese

unread,
Jul 8, 2010, 3:59:22 PM7/8/10
to Friends of the Unofficial Google Reader API
after removing the token and using only the i=<item id> parameter i
was able to get a bit further, but now i get a 411:Length Required
error instead of a 400. the ammended URL that gets this response
(sent as POST) is:

http://www.google.com/reader/api/0/stream/items/contents

any idea about the 411 issue?

On Jul 8, 2:49 pm, Mihai Parparita <mih...@google.com> wrote:
> That servlet only accepts POST, because its parameter list can get very
> long, and we didn't want to run into URL length issues (the accepts i=<item
> ID> parameters).
>
> Mihai
>
> On Thu, Jul 8, 2010 at 3:37 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:

Mihai Parparita

unread,
Jul 8, 2010, 4:03:32 PM7/8/10
to foug...@googlegroups.com
You need to also specify a Content-Length HTTP header (see item 5 of http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4).

Mihai

moonlightcheese

unread,
Jul 8, 2010, 5:40:35 PM7/8/10
to Friends of the Unofficial Google Reader API
so let me get this straight... basically i'm making requests to an
HTTP1.0 server...?

i'm having a terrible time getting the Content-Length header value in
Android, as there's no easy-to-find documentation on the
implementation. additionally, this code worked fine not even two
weeks ago. what changed on Google's end that caused the problems? is
there some documentation somewhere that i haven't seen? finding
information on the google API has proved very frustrating and this is
pretty much the only well-kept source of info i've found so far.

On Jul 8, 3:03 pm, Mihai Parparita <mih...@google.com> wrote:
> You need to also specify a Content-Length HTTP header (see item 5 ofhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4).
>
> Mihai
>
> On Thu, Jul 8, 2010 at 3:59 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:

Mihai Parparita

unread,
Jul 8, 2010, 6:09:00 PM7/8/10
to foug...@googlegroups.com
Reader itself hasn't changed in the past couple of weeks, but other servers at Google that sit between Reader and the outside world may have (sorry I can't provide more details, I don't know them myself). That being said, there are other Android developers on this list (e.g. Mariano Kamp) who haven't complained of this issue, so I assume that setting the Content-Length header on Android is feasible.

Mihai

moonlightcheese

unread,
Jul 8, 2010, 7:30:41 PM7/8/10
to Friends of the Unofficial Google Reader API
it would appear that the Content-Length header is supposed to be the
size of the message body, in octets. there is no message body in this
request. it's just a single header containing the auth code, and the
URL itself. so how could a content-length be necessary? even when
trying to set the Content-Length header to "0" or "-1", it doesn't fix
the problem. whenever i set the Content-Length the program crashes
with a ClientProtocolException. something's not right here... i just
don't understand why code that worked two weeks ago suddenly stopped
working. i could perform text searches through items before using the
above URL. now i cannot... something had to have changed...

On Jul 8, 5:09 pm, Mihai Parparita <mih...@google.com> wrote:
> Reader itself hasn't changed in the past couple of weeks, but other servers
> at Google that sit between Reader and the outside world may have (sorry I
> can't provide more details, I don't know them myself). That being said,
> there are other Android developers on this list (e.g. Mariano Kamp) who
> haven't complained of this issue, so I assume that setting the
> Content-Length header on Android is feasible.
>
> Mihai
>
> On Thu, Jul 8, 2010 at 5:40 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:

Mariano Kamp

unread,
Jul 9, 2010, 1:25:49 AM7/9/10
to foug...@googlegroups.com
I don't do the HTTP access on this low level so that I would have to calculate content-length myself. I use the Apache http client library that comes bundled with the platform.

Jayesh Salvi

unread,
Jul 9, 2010, 3:36:47 AM7/9/10
to foug...@googlegroups.com
I remember I was getting "411 Length required" once. I just went
through my git log and indeed found what I did. I was getting it with
OAuth and I was using signpost library (which in turn uses Android's
apache commons libraries). The change I did to get rid of the error
was in signpost library. And I believe that change was to change a
POST to GET:

diff --git a/signpost-core/src/main/java/oauth/signpost/basic/DefaultOAuthProvid
index a065d15..a02d2ef 100644
--- a/signpost-core/src/main/java/oauth/signpost/basic/DefaultOAuthProvider.java
+++ b/signpost-core/src/main/java/oauth/signpost/basic/DefaultOAuthProvider.java
@@ -37,7 +37,7 @@ public class DefaultOAuthProvider extends AbstractOAuthProvide
protected HttpRequest createRequest(String endpointUrl) throws MalformedURL
IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(endpointUrl)
- connection.setRequestMethod("POST");
+ connection.setRequestMethod("GET");
connection.setAllowUserInteraction(false);
connection.setRequestProperty("Content-Length", "0");

See if that helps.

Besides, as Mariano suggested using standard http library like apache
commons (that ships with android) is a good idea.

I am also hit by this 400 bad request problem. I posted it earlier
last week. However I hit it during requestToken call of OAuth
authentication. I get it from one computer, while it works from
another computer. I haven't found any reasonable explanation for that
yet. Something somewhere is wrong for sure.

--
Jayesh

moonlightcheese

unread,
Jul 9, 2010, 10:37:41 AM7/9/10
to Friends of the Unofficial Google Reader API
@Jayesh
as Mihai states above, a POST method must be made for this
transaction. tried changing to a GET before, but nothing changed
(also tried http and https protocols with both methods).

@Mariano
I am using the 4.0.1 client packaged with Android.

I suppose there's no way around showing some code:

<code>
private String execute(HttpUriRequest request, List<Parameter>
parameters, boolean useCookies) {
try {
response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode != HttpStatus.SC_OK) {
String error = String.format("(ex)Expected 200 OK. Received %d %s
\n", statusCode, response.getStatusLine().toString());
error += request.getURI().toString();
Log.e(TAG, "http request failed " + error);
return new Integer(statusCode).toString();
}
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
if (stream == null) {
Log.e(TAG, "entity had null content");
}
return getContent(stream);
} catch (Throwable err) {
Log.e(TAG, request.getURI().toString());
} finally {
//release connection
request.abort();
}
}
</code>
here's my post method request building method
<code>
public String post(String url, List<Parameter> parameters, boolean
useCookies, String auth) {
HttpPost postMethod = new HttpPost(url);
List<NameValuePair> params = null;
if(!(parameters == null)) {
params = toNameValuePairArray(parameters);
try {
postMethod.setEntity(new UrlEncodedFormEntity(params,
HTTP.UTF_8));
} catch(UnsupportedEncodingException e) {
Log.i(TAG, "UnsupportedEncodingException when building post
request");
}
}

if(!(auth == null)){
postMethod.addHeader("Authorization", "GoogleLogin auth="+auth);
}

return execute(postMethod, parameters, useCookies);
}
</code>
and here's the method that i'm having trouble with, which is making
the POST request. i can request the subscription list, and it works
fine as a GET request, using the https protocol. but this POST method
doesn't work. the code is largely the same except for the method:
<code>
public String post(String url, List<Parameter> parameters, boolean
useCookies, String auth) {
HttpPost postMethod = new HttpPost(url);
List<NameValuePair> params = null;
if(!(parameters == null)) {
params = toNameValuePairArray(parameters);
try {
postMethod.setEntity(new UrlEncodedFormEntity(params,
HTTP.UTF_8));
} catch(UnsupportedEncodingException e) {
Log.i("error", "UnsupportedEncodingException when building post
request");
}
}

if(!(auth == null)){
postMethod.addHeader("Authorization", "GoogleLogin auth="+auth);
}

return execute(postMethod, parameters, useCookies);
}
</code>

i don't know where the error is...
> On Fri, Jul 9, 2010 at 10:55 AM, Mariano Kamp <mariano.k...@gmail.com> wrote:
> > I don't do the HTTP access on this low level so that I would have to
> > calculate content-length myself. I use the Apache http client library that
> > comes bundled with the platform.
> >http://developer.android.com/intl/zh-TW/reference/org/apache/http/pac...
>
> > Meanwhile there is even a convenience wrapper since Android
> > 2.2: http://developer.android.com/intl/zh-TW/reference/android/net/http/An...
>
> > On Fri, Jul 9, 2010 at 1:30 AM, moonlightcheese <moonlightche...@gmail.com>

Mariano Kamp

unread,
Jul 12, 2010, 6:48:47 AM7/12/10
to foug...@googlegroups.com
I don't know what your toNameValuePairArray() method exactly does, but if it produces BasicNameValuePairs then your code looks pretty much like mine, except that I use the one argument version of execute().

moonlightcheese

unread,
Jul 12, 2010, 2:41:40 PM7/12/10
to Friends of the Unofficial Google Reader API
@Mariano:
I am using the single argument version of execute as well. I posted
my execute method in the above post. The extraneous arguments were
for testing purposes. Additionally, i tried calling the single
argument execute from within the post method i built, and still get a
411 error. I thought maybe the cast to a HttpUriRequest was the
problem, but that's apparently not the case.

I'm really scratching my head over this one... What I don't get is why
I'm the only one affected by this... especially if my code is nearly
identical to everyone else's...

On Jul 12, 5:48 am, Mariano Kamp <mariano.k...@gmail.com> wrote:
> I don't know what your toNameValuePairArray() method exactly does, but if it
> produces BasicNameValuePairs then your code looks pretty much like mine,
> except that I use the one argument version of execute().
>
> On Fri, Jul 9, 2010 at 4:37 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:
> ...
>
> read more »

Mariano Kamp

unread,
Jul 12, 2010, 2:57:13 PM7/12/10
to foug...@googlegroups.com
No idea, really.

Maybe you could post your toNameValuePairArray method ... not sure if that would help though.

moonlightcheese

unread,
Jul 12, 2010, 3:01:16 PM7/12/10
to Friends of the Unofficial Google Reader API
it's pretty basic, just changes a parameter list to a namevaluepair
list. i don't see why it would matter though. the content-length is
supposed to be set automagically. when i try to set it manually, the
program simply exits with no trace dump in adb logcat.

private List<NameValuePair> toNameValuePairArray(List<Parameter> in) {
if (in == null) {
return null;
}
List<NameValuePair> out = new ArrayList<NameValuePair>();
for (Parameter parameter : in) {
if (parameter.hasName() && parameter.hasValue()) {
out.add(new NameValuePair(parameter.getName(),
parameter.getValue().toString()));
}
}
return out;
}

On Jul 12, 5:48 am, Mariano Kamp <mariano.k...@gmail.com> wrote:
> I don't know what your toNameValuePairArray() method exactly does, but if it
> produces BasicNameValuePairs then your code looks pretty much like mine,
> except that I use the one argument version of execute().
>
> On Fri, Jul 9, 2010 at 4:37 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:
> ...
>
> read more »

Mariano Kamp

unread,
Jul 12, 2010, 3:08:01 PM7/12/10
to foug...@googlegroups.com
My thinking was that the client library somehow fails to calculate properly and so I wanted to see the input, which are the parameters.

Maybe I am not seeing the forrest, but how does that code run? NameValuePair is an interface: http://developer.android.com/reference/org/apache/http/NameValuePair.html

Please humor me and change it to BasicNameValuePair.

moonlightcheese

unread,
Jul 12, 2010, 3:16:28 PM7/12/10
to Friends of the Unofficial Google Reader API
I did actually try changing to BasicNameValuePair just before that
last post to see if there were some default values or something
missing. Nothing changed. I'm able to read the content length using
UrlEncodedFormEntity.getContentLength method, it's just not getting
set for some reason...

It's so strange because this code worked fine in the past. I don't
know what changed on the other end and I can't find the flaw in my
code...

On Jul 12, 2:08 pm, Mariano Kamp <mariano.k...@gmail.com> wrote:
> My thinking was that the client library somehow fails to calculate properly
> and so I wanted to see the input, which are the parameters.
>
> Maybe I am not seeing the forrest, but how does that code run? NameValuePair
> is an interface:http://developer.android.com/reference/org/apache/http/NameValuePair....
>
> Please humor me and change it to BasicNameValuePair.
>
> On Mon, Jul 12, 2010 at 9:01 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:
> ...
>
> read more »

moonlightcheese

unread,
Jul 12, 2010, 3:23:07 PM7/12/10
to Friends of the Unofficial Google Reader API
Additionally, I know the post method works for other transactions
because a POST is required for logging in, and I'm able to log in just
fine and get the auth code. For some reason, the 411 Length required
error only pops up when requesting items by item id. Here's some
output from adb logcat that may help...

E/SimpleHttpManager(28150): https://www.google.com/accounts/ClientLogin
I/NVP (28150): Email : moonlightcheese
I/NVP (28150): Passwd : ********
I/NVP (28150): service : reader
I/NVP (28150): accountType : GOOGLE
I/NVP (28150): source : moonlightcheese-srss-1.0
I/length (28150): 103
D/dalvikvm(28150): GC freed 5593 objects / 347216 bytes in 50ms
D/dalvikvm(28150): GC freed 110 objects / 3824 bytes in 44ms
I/login (28150):
SID=DQAAAJMAAAC3ylpc8eigRmVAmh8zGaOP7GOHEQRnP2HsNUj2c5D2MLhCl
wZv_URAWxyfYldT3tKd0qb...
I/login (28150):
LSID=DQAAAJUAAADEY7Ub55kWAfok426ugBnrvF5Ip4C9tkneymsRpeFAkFs6
AvE05dIbq1Mhi9Ea6Qc3YQ...
I/login (28150):
Auth=DQAAAJMAAADEY7Ub55kWAfok426ugBnrvF5Ip4C9tkneymsRpeFAkFs6
AvE05dIbq1Mhi...
I/NVP (28150): q : c
I/NVP (28150): output : json
I/NVP (28150): i : -7970186577665357408
I/length (28150): 22
D/dalvikvm(28150): GC freed 2831 objects / 132128 bytes in 77ms
E/SimpleHttpManager
(28150): http request failed (ex)Expected 200 OK. Received 411 HTTP/
1.0 411 Len
gth Required
E/SimpleHttpManager
(28150): http://www.google.com/reader/api/0/stream/items/contents :
POST
I/ActivityManager( 1026): Displayed activity
com.moonlightcheese.httptest/.mainH

I've also tried to change the search query around until i got a
positive number for an item id, just in case. It doesn't seem to
matter whether it's negative or positive (which it shouldn't). I'm
just running out of ideas. I'm compiling for old targets though (1.5+
i think).... perhaps something changed in the later Android releases
that fixes this?
> ...
>
> read more »

Mariano Kamp

unread,
Jul 12, 2010, 3:27:21 PM7/12/10
to foug...@googlegroups.com
I am still wondering how you were able to instantiate an interface with "new" ;)

Anyway, for what it's worth I am requesting items using the long id, but your's should work as well and be more efficient anyway.

moonlightcheese

unread,
Jul 12, 2010, 3:57:45 PM7/12/10
to Friends of the Unofficial Google Reader API
That was a mistake actually... it should have been BasicNameValuePair
above, but I had already changed it to BasicNameValuePair and reverted
hastily to paste the example.

Anyhow, it doesn't matter how efficient it is if it doesn't work.

I've just tried changing the USER_AGENT parameter of the client and
nothing changed. I just don't get it...

On Jul 12, 2:27 pm, Mariano Kamp <mariano.k...@gmail.com> wrote:
> I am still wondering how you were able to instantiate an interface with
> "new" ;)
>
> Anyway, for what it's worth I am requesting items using the long id, but
> your's should work as well and be more efficient anyway.
>
> On Mon, Jul 12, 2010 at 9:23 PM, moonlightcheese
> <moonlightche...@gmail.com>wrote:
> ...
>
> read more »

moonlightcheese

unread,
Jul 12, 2010, 4:17:47 PM7/12/10
to Friends of the Unofficial Google Reader API
aright i've sort of hit a dead end. for some reason, this request in
particular will not work with my code (http://www.google.com/reader/
api/0/stream/items/contents). is there another way of getting items?
and for that matter, is there a FULL GUIDE with all of the available
api URLs and the post variables that go along with them? i've found
various resources, but nothing complete or even halfway official...
> ...
>
> read more »

Mariano Kamp

unread,
Jul 19, 2010, 1:35:44 PM7/19/10
to foug...@googlegroups.com
Moonlightcheese ... I have the same issue now at least with one user. 

Did you check with the people from Apache?

curl --header "Authorization: GoogleLogin auth=REDACTED" "https://www.google.com/reader/api/0/edit-tag?client=newsrob" --data-ascii "client=newsrob&a=user%2F-%2Fstate%2Fcom.google%2Fread
&i=tag%3Agoogle.com%2C2005%3Areader%2Fitem%2REDACTED
... 19 more times with other ids ...
&T=REDACTED"

-> HTTP STATUS: 400 HTTP/1.1 400 Bad Request length=1334

<07 16 18:35> Status 400 for https://www.google.com/reader/api/0/edit-tag?client=newsrob:
<07 16 18:35>   headers=
<07 16 18:35>     Content-Type=text/html; charset=UTF-8
<07 16 18:35>     X-Reader-Google-Version=507-000
<07 16 18:35>     X-Reader-User=15214383818468752705
<07 16 18:35>     Date=Fri, 16 Jul 2010 17:35:07 GMT
<07 16 18:35>     Expires=Fri, 16 Jul 2010 17:35:07 GMT
<07 16 18:35>     Cache-Control=private, max-age=0
<07 16 18:35>     X-Content-Type-Options=nosniff
<07 16 18:35>     X-Frame-Options=SAMEORIGIN
<07 16 18:35>     X-XSS-Protection=1; mode=block
<07 16 18:35>     Content-Length=1334
<07 16 18:35>     Server=GSE

Mariano Kamp

unread,
Jul 19, 2010, 1:50:44 PM7/19/10
to Friends of the Unofficial Google Reader API
Sorry, that was me misreading the debug output that I implemented
months ago. It must me "Bad Request. Length=1334". Not bad request
length ;)

Still don't know what this is about, but I just got started.

On Jul 19, 7:35 pm, Mariano Kamp <mariano.k...@gmail.com> wrote:
> Moonlightcheese ... I have the same issue now at least with one user.
>
> Did you check with the people from Apache?
>
> curl --header "Authorization: GoogleLogin auth=REDACTED" "https://www.google.com/reader/api/0/edit-tag?client=newsrob" --data-ascii
> "client=newsrob&a=user%2F-%2Fstate%2Fcom.google%2Fread
> &i=tag%3Agoogle.com%2C2005%3Areader%2Fitem%2REDACTED
> ... 19 more times with other ids ...
> &T=REDACTED"
>
> -> HTTP STATUS: 400 HTTP/1.1 400 Bad Request length=1334
>
> <07 16 18:35> Status 400 forhttps://www.google.com/reader/api/0/edit-tag?client=newsrob:
> <07 16 18:35>   headers=
> <07 16 18:35>     Content-Type=text/html; charset=UTF-8
> <07 16 18:35>     X-Reader-Google-Version=507-000
> <07 16 18:35>     X-Reader-User=15214383818468752705
> <07 16 18:35>     Date=Fri, 16 Jul 2010 17:35:07 GMT
> <07 16 18:35>     Expires=Fri, 16 Jul 2010 17:35:07 GMT
> <07 16 18:35>     Cache-Control=private, max-age=0
> <07 16 18:35>     X-Content-Type-Options=nosniff
> <07 16 18:35>     X-Frame-Options=SAMEORIGIN
> <07 16 18:35>     X-XSS-Protection=1; mode=block
> <07 16 18:35>     Content-Length=1334
> <07 16 18:35>     Server=GSE
>
> On Mon, Jul 12, 2010 at 10:17 PM, moonlightcheese <moonlightche...@gmail.com
Reply all
Reply to author
Forward
0 new messages