views:

1473

answers:

2

I get this error when trying to get a feed from Google Analytics API. However, using the same token I get successful feeds from Google Calendar. The code between the two is exactly the same except for the feed url. So it must have something to do with Analytics being https and Calendar just http.

I have successfully created a non-secure, long-lived token. The scope parameter while requesting the initial token:

scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F%20https%3A%2F%2Fwww.google.com%2Fanalytics%2Ffeeds

My request for the long-lived token:

GET /accounts/AuthSubSessionToken HTTP/1.1
Authorization: AuthSub token="CP_AgsyLDxDCtpjg-f____8B"
Content-Type: application/x-www-form-urlencoded
Host: www.google.com:443
Accept: text/html, */*
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

Returns a long-lived token. Using it for Google Calendar:

GET /calendar/feeds/default/allcalendars/full HTTP/1.1
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="CP_AgsyLDxCh2tmj-P____8B"
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

returns a temporary redirect (302):

HTTP/1.1 302 Moved Temporarily
Expires: Sun, 01 Nov 2009 03:00:01 GMT
Date: Sun, 01 Nov 2009 03:00:01 GMT
Set-Cookie: S=calendar=mta4-_BxxANrylcSnzUatg;Expires=Mon, 01-Nov-2010 03:00:01 GMT
Location: http://www.google.com/calendar/feeds/default/allcalendars/full?gsessionid=mta4-_BxxANrylcSnzUatg

which results in a successful Get to this:

GET /calendar/feeds/default/allcalendars/full?gsessionid=mta4-_BxxANrylcSnzUatg HTTP/1.1
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="CP_AgsyLDxCh2tmj-P____8B"
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)
Cookie: S=calendar=mta4-_BxxANrylcSnzUatg

But I get the error 401 when attempting to get the Google Analytics feed:

GET /analytics/feeds/accounts/default HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="CP_AgsyLDxCh2tmj-P____8B"
Host: www.google.com:443
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

Do I need a valid SSL certificate for my domain? Been fighting with this for weeks!!!
using Indy10 with Delphi 2007 in Apache.

A request was made to provide some of the Delphi code. What I have provided here is the code for the GET to the feed. I don't provide code to get the tokens because I assume they are good (I am able to get calendar feeds).

var
  IdHTTP: TIdHTTP;
  IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocketOpenSSL;

begin
  IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
  IdHTTP := TIdHTTP.create(nil);
  with IdSSLIOHandlerSocket1 do begin
    SSLOptions.Method := sslvSSLv3;
    SSLOptions.Mode :=  sslmUnassigned;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 2;
  end;
  with IdHTTP do begin
    IOHandler := IdSSLIOHandlerSocket1;
    ProxyParams.BasicAuthentication := False;
    Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
    Request.ContentType := 'application/x-www-form-urlencoded';
    request.host := 'www.google.com/analytics';
    request.connection := 'keep-alive';
    Request.Accept := 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2';
  end;

  idhttp.Request.CustomHeaders.Add('Authorization: AuthSub token="'+mToken+'" ');

  IdHTTP.Get('https://www.google.com/analytics/feeds/accounts/default');  // results in the 401
+1  A: 

Took some time and required me to use Fiddler and the Curl php approach. Found this line:

Host: www.google.com:443

can't have the :443. Must be like this:

Host: www.google.com

The Indy TIdHTTP component was automatically appending this to the host when it saw https. The only way I could get around it was to publish my own "host" property.

M Schenkel
Another workaround would be to include the :443 in the token scope; it just has to match.
Jonathan
Thanks - I will give that a try.
M Schenkel
A: 

I have the exact same problem with another google app. How did you publish your own "host" property? When I use HTTP.Request.CustomHeaders.Add('Host: www.google.com');, it just gets overwritten anyway, and it appends the 443.

Which version of Indy are you using? This is terribly frustrating...I've spent the better part of two days hunting this down, and am not 100% convinced this is my problem....

Anonymous
I am using Indy 10. You will need the source code to do this. Make sure property Host: String read FHost write FHost; is in the published section of class TIdRequestHeaderInfo.
M Schenkel