title: Google Contacts API: Unauthorized 401 Unknown authorization header
body: <p>I have carefully read Google Contacts API documentation, but I can't get PUT requests (i.e. updates) right. I'm using Ruby on Rails 3.2 with OAuth gem (v0.4.5). I fetch tokens with Omniauth and the scope is defined as "<a href="https://www.google.com/m8/feeds" rel="noreferrer">https://www.google.com/m8/feeds</a>"</p>
  
  <p>Let me demonstrate:</p>
  
  <pre><code>ruby-1.9.2-p290 :001 &gt; @access_token.get("https://www.google.com/m8/feeds/contacts/default/full/c1f86b48b52548c", {"GData-Version" =&gt; "3.0"})
  =&gt; #&lt;Net::HTTPOK 200 OK readbody=true&gt;
  </code></pre>
  
  <p>As you can see, GET requests work nicely so my OAuth access token should be alright. DELETE requests work, too:</p>
  
  <pre><code>ruby-1.9.2-p290 :002 &gt; @access_token.delete('https://www.google.com/m8/feeds/contacts/default/full/c1f86b48b52548c', { 'GData-Version' =&gt; '3.0', 'If-Match' =&gt; '"RH46fTVSLyt7I2A9Wx9VFkgMQAU."' })
   =&gt; #&lt;Net::HTTPOK 200 OK readbody=true&gt;
  </code></pre>
  
  <p>So far, so good. Here I provided the contact entry's Etag in the request header as instructed in Google's documentation [1]. So it shouldn't be causing any trouble.</p>
  
  <p>According to the OAuth gem documentation [2] the syntax of a PUT request should be like following:</p>
  
  <pre><code>- (Object) put(path, body = '', headers = {})
  </code></pre>
  
  <p>And an example from the documentation: </p>
  
  <pre><code>@token.put('/people/123', @person.to_xml, { 'Accept' =&gt; 'application/xml', 'Content-Type' =&gt; 'application/xml' })
  </code></pre>
  
  <p>As far as I understand, I should be sending a simple XML string as the body of the PUT request. So let's fetch some example data first:</p>
  
  <pre><code>ruby-1.9.2-p290 :003 &gt; xmldata = @access_token.get("https://www.google.com/m8/feeds/contacts/default/full/5f74bf0d5c621a", {"GData-Version" =&gt; "3.0"}).body
  
  =&gt; "&lt;?xml version='1.0' encoding='UTF-8'?&gt;
        &lt;entry xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='&amp;quot;R3w4fzVSLit7I2A9WhRaGEQCQgc.&amp;quot;'&gt;
          &lt;id&gt;http://www.google.com/m8/feeds/contacts/my.email%40address.com/base/5f74bf0d5c621a&lt;/id&gt;
          &lt;updated&gt;2012-02-22T08:15:36.237Z&lt;/updated&gt;
          &lt;app:edited xmlns:app='http://www.w3.org/2007/app'&gt;2012-02-22T08:15:36.237Z&lt;/app:edited&gt;
          &lt;category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/&gt;
          &lt;title&gt;Joe Average&lt;/title&gt;
          &lt;link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/my.email%40address.com/5f74bf0d5c621a?v=3.0'/&gt;
          &lt;link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/my.email%40address.com/full/5f74bf0d5c621a?v=3.0'/&gt;
          &lt;link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/my.email%40address.com/full/5f74bf0d5c621a?v=3.0'/&gt;
          &lt;gd:name&gt;
            &lt;gd:fullName&gt;Joe Average&lt;/gd:fullName&gt;
            &lt;gd:givenName&gt;Joe&lt;/gd:givenName&gt;
            &lt;gd:familyName&gt;Average&lt;/gd:familyName&gt;
          &lt;/gd:name&gt;
          &lt;gd:email rel='http://schemas.google.com/g/2005#other' address='joe.average@isp.net' primary='true'/&gt;
        &lt;/entry&gt;"
  </code></pre>
  
  <p>... and try to update it back to Google:</p>
  
  <pre><code>ruby-1.9.2-p290 :004 &gt; @access_token.put("https://www.google.com/m8/feeds/contacts/default/full/5f74bf0d5c621a", xmldata, {"GData-Version" =&gt; "3.0", 'If-Match' =&gt; '"R3w4fzVSLit7I2A9WhRaGEQCQgc."'})
  
  =&gt; #&lt;Net::HTTPUnauthorized 401 Unknown authorization header readbody=true&gt;
  </code></pre>
  
  <p>So this doesn't work. Let's try to strip down the XML a little so it'll look just like in documentation [1]:</p>
  
  <pre><code>xmldata = "&lt;entry gd:etag='&amp;quot;R3w4fzVSLit7I2A9WhRaGEQCQgc.&amp;quot;'&gt;
               &lt;id&gt;http://www.google.com/m8/feeds/contacts/my.email%40address.com/base/5f74bf0d5c621a&lt;/id&gt;
               &lt;updated&gt;2012-02-22T08:15:36.237Z&lt;/updated&gt;
               &lt;category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/&gt;
               &lt;link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/my.email%40address.com/5f74bf0d5c621a?v=3.0'/&gt;
               &lt;link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/my.email%40address.com/full/5f74bf0d5c621a?v=3.0'/&gt;
               &lt;link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/my.email%40address.com/full/5f74bf0d5c621a?v=3.0'/&gt;
               &lt;gd:name&gt;
                 &lt;gd:fullName&gt;Joe Average&lt;/gd:fullName&gt;
                 &lt;gd:givenName&gt;Joe&lt;/gd:givenName&gt;
                 &lt;gd:familyName&gt;Average&lt;/gd:familyName&gt;
               &lt;/gd:name&gt;
               &lt;gd:email rel='http://schemas.google.com/g/2005#other' address='joe.average@isp.net' primary='true'/&gt;
             &lt;/entry&gt;"
  </code></pre>
  
  <p>But no luck, exactly the same error as before.</p>
  
  <p>This is where I'm totally stuck now. I would greatly appreciate any hints to right direction.</p>
  
  <p>[1] <a href="https://developers.google.com/google-apps/contacts/v3/#updating_contacts" rel="noreferrer">https://developers.google.com/google-apps/contacts/v3/#updating_contacts</a></p>
  
  <p>[2] <a href="http://rubydoc.info/gems/oauth/0.4.5/OAuth/AccessToken" rel="noreferrer">http://rubydoc.info/gems/oauth/0.4.5/OAuth/AccessToken</a></p>