Hi David, I am trying to create new contact in a user's personal contact using your POST call script. But I am getting "Unknown authorization header" when I tried. It could be probably because of the gsessionid part that you explained. Can you please have a look at the below code and suggest a solution?
--------------------------------------------------------- #!/usr/bin/perl -w use Net::OAuth; use LWP::UserAgent; use Data::Dumper; use HTTP::Request qw(:strict); my $key = 'example.com'; my $secret = 'yewuiyrwejhwryewhuh'; my $username = 'abcd.zxy'; my $req_url = 'http://www.google.com/m8/feeds/contacts/'; my $email = $username.'@'.$key; my $xoauth = 'xoauth_requestor_id'; my $extra_arg = 'max-results'; my $extra_val = '50'; my $req_method = 'POST'; my $sig_method = 'HMAC-SHA1'; my $timestamp = time; my $nonce = int(rand(99999999)); my $geturl = $req_url.$username.'/full?'.$xoauth.'='.$email; my $request = Net::OAuth->request('consumer')->new( consumer_key => $key, consumer_secret => $secret, request_url => $req_url, request_method => $req_method, signature_method => $sig_method, timestamp => $timestamp, nonce => $nonce, extra_params => { $xoauth => $email } ); my $content = '<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005"> <atom:category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact" /> <atom:title type="text">Sample Contact 1</atom:title> <atom:content type="text">New Contact</atom:content> <gd:email rel="http://schemas.google.com/g/2005#work" primary="true" address="[email protected]" /> <gd:phoneNumber rel="http://schemas.google.com/g/2005#work" primary="true">123456789</gd:phoneNumber> <gd:phoneNumber rel="http://schemas.google.com/g/ 2005#mobile">987654321</gd:phoneNumber> <gd:phoneNumber rel="http://schemas.google.com/g/ 2005#work_fax">5555555</gd:phoneNumber> <gd:postalAddress rel="http://schemas.google.com/g/2005#work" primary="true"> 1 qwerty Newyork City NY USA </gd:postalAddress> </atom:entry>'; $request->sign; my $lwp_object = LWP::UserAgent->new; my $req = HTTP::Request->new(POST => $geturl); $req->header('Content-Type' => 'application/atom+xml'); $req->header('Authorization' => $request->to_authorization_header); $req->header('Accept-Encoding' => 'identity'); $req->content($content); my $response = $lwp_object->request($req); print Dumper($response); ----------------------------------------- Part of the output is, <HEAD> <TITLE>Unknown authorization header</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Unknown authorization header</H1> <H2>Error 401</H2> </BODY> </HTML> ', '_rc' => '401', '_headers' => bless( { 'connection' => 'Close', 'client-response-num' => 1, 'cache-control' => 'private, max-age=0', 'date' => 'Thu, 26 Feb 2009 20:51:02 GMT', 'client-peer' => 'x.xx.xx.xxx: 80', 'content-length' => '179', 'client-warning' => 'Missing Authenticate header', 'client-date' => 'Thu, 26 Feb 2009 20:51:03 GMT', 'content-type' => 'text/html; charset=UTF-8', 'x-content-type-options' => 'nosniff', 'title' => 'Unknown authorization header', 'server' => 'GFE/1.3', 'expires' => 'Thu, 26 Feb 2009 20:51:02 GMT' }, 'HTTP::Headers' ), ---------------------------------------------------------------------- Regards, Parri On Feb 4, 6:29 pm, DavidMurrell <[email protected]> wrote: > No problem. > > Because I'm feeling nice, I'll add some more :) > > Heres a POST call - slightly different - make a document in google > docs: > > #!/usr/bin/perl -w > > use Net::OAuth; > use LWP::UserAgent; > use Data::Dumper; > use HTTP::Request qw(:strict); > > my $key = 'replace with oauth consumer key'; > my $secret = 'replace with oauth consumer secret'; > my $username = 'replace with valid username on hosted domain'; > > my $req_url = 'http://docs.google.com/feeds/documents/private/ > full'; > my $email = $username.'@'.$key; > my $xoauth = 'xoauth_requestor_id'; > my $extra_arg = 'max-results'; > my $extra_val = '50'; > my $req_method = 'POST'; > my $sig_method = 'HMAC-SHA1'; > my $timestamp = time; > my $nonce = int(rand(99999999)); > > my $geturl = $req_url.'?'.$xoauth.'='.$email; > my $request = Net::OAuth->request('consumer')->new( > consumer_key => $key, > consumer_secret => $secret, > request_url => $req_url, > request_method => $req_method, > signature_method => $sig_method, > timestamp => $timestamp, > nonce => $nonce, > extra_params => { > $xoauth => $email, > } > ); > > my $content = '<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"> > <atom:category scheme="http://schemas.google.com/g/2005#kind" > term="http://schemas.google.com/docs/2007#document" / > > <atom:title>Company Perks</atom:title> > </atom:entry>'; > > $request->sign; > > my $lwp_object = LWP::UserAgent->new; > my $req = HTTP::Request->new(POST => $geturl); > $req->header('Content-Type' => 'application/atom+xml'); > $req->header('Authorization' => $request->to_authorization_header); > $req->header('Accept-Encoding' => 'identity'); > $req->content($content); > > my $response = $lwp_object->request($req); > print Dumper($response); > > Something else I've figured out (this may be terribly obvious, but > again, I hope it helps someone) - following a redirect when > interacting with something like, > sayhttp://www.google.com/calendar/feeds/default/allcalendars/full > isn't as simple as directly resubmitting the request at the new url. > > Resubmitting the existing signed authorization header to the new url > doesn't work because the new url has a gsessionid value appended to > it, and a different base url value, meaning that the signature won't > match what the server is expecting on its side. > > Update the request_url in the hash with its new value, and add the > gsessionid and its value to the extra_params hash. > > Heres an ugly snippet that does this: (Yes, I'm aware that one can do > the split and foreach bit with a library, but obvious is good, right.. > right? :) ) > > my $redirect = $response->header('location'); > my ($dom,$query_string) = split (/\?/,$redirect); > > foreach my $pair (split(/&/, $query_string)) { > my ($_n, $_v) = split(/=/, $pair); > $qs{$_n} = $_v; > > } > > $request->{extra_params}->{gsessionid} = $qs{'gsessionid'}; > $request->{request_url} = $dom; > $request->sign; > > $req_url = $dom; > $geturl = $req_url.'?'.$xoauth.'='.$email.'&.'gsessionid'.'='.$qs > {'gsessionid'}; > > Resubmit that, and it should auth with the calendaring service > properly, and any others that have redirects in them. I do remember > reading somewhere that redirects are part of the OAuth spec (might > have been the actual spec...), so one probably should be defensively > coding against them, rather than on a case by case basis. > > Cheers, > David --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google Apps APIs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-apps-apis?hl=en -~----------~----~----~----~------~----~------~--~---
