harryrobbins / gdata-samples

Automatically exported from code.google.com/p/gdata-samples
0 stars 1 forks source link

No support for redirects (used by Google Calendar for example) #3

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Several Data APIs, like the Google Calendar API will produce redirects
which are handled properly by the Zend classes but not by the hybrid
example provided here at googlecodesamples.com.

An example redirect would be
http://docs.google.com/feeds/documents/private/full
=>
http://docs.google.com/feeds/documents/private/full?gsessid=xxxxxxxx
(variable name may be inaccurate, sorry).

The problem is that within the hybrid example requests are signed outside
the Zend classes thus the Zend classes have no clue that each request needs
to be signed, only that a specific Authentication header has to be sent.
When a redirect happens, which is handled properly inside
Zend_Gdata_App::performHttpRequest(), this function will call itself to
make the request where the redirect is pointing to. The problem is that the
same Authentication header will be sent again, which will result in a 401
Unauthorized response.

Although I have no time right now to provide a patch, I can attach a sample
replacement inside index.php to make the hybrid example work with Google
Calendar (and possibly other Google Data APIs making redirects):

// [...]

if (isset($_SESSION['redirect_to'])) {
  $redirect = $_SESSION['redirect_to'];
  unset($_SESSION['redirect_to']);
  header('Location: ' .$redirect);
}

// WORKS ONLY WITH GET
class Zend_Oauth_HttpClient extends Zend_Gdata_HttpClient {
    public function filterHttpRequest($method, $url, $headers = array(),
$body = null, $contentType = null) {
        $urlPart = $url;
        if (strpos($url, '?') > 0) {
            list($urlPart, $paramPart) = explode('?', $url, 2);
            parse_str($paramPart, $paramPart);
        }

        $req = OAuthRequest::from_consumer_and_token($GLOBALS['consumer'],
$GLOBALS['access_token'],
                                                   $method, $urlPart,
$paramPart);
        $req->sign_request($GLOBALS['sig_method'], $GLOBALS['consumer'],
$GLOBALS['access_token']);

        $this->setHeaders($req->to_header());

        return array('method' => $method, 'url' => $url, 'body' => $body,
'headers' => $headers, 'contentType' => $contentType);
    }
}

$request_token = @$_REQUEST['openid_ext2_request_token'];
if ($request_token) {
  $data = array();
  $httpClient = new Zend_Oauth_HttpClient();
  $access_token = getAccessToken($request_token);

  // Query the Calendar API ===================================================
  $calendarService = new Zend_Gdata_Calendar($httpClient);

  $feed = $calendarService->getCalendarListFeed();
  $data['calendars']['html'] = listEntries($feed);
  $data['calendars']['xml'] = $feed->saveXML();
  //
===========================================================================

// [...]

Providing a custom HTTP client will sign each and every outgoing request
implicitly. This also makes it unnecessary to pass parameters twice (once
to oauth and one more time to Zend_Gdata_*) because it extracts parameters
internally and uses them for generating the signature. This enables you to
avoid figuring out what parameters each feed actually handles.

Warning: Zend_Oauth_HttpClient is not contained within the Zend Framework
yet; if you see one in there, which is a work in progress right now, use
that one and skip this example! At the time of this writing no Oauth HTTP
client was available within the Zend Framework).

I know this is kinda messy but it may save several weeks for some people.
Hope it makes sense!

Best Regards,
Norbert Mocsnik
http://sethigherstandards.net

Original issue reported on code.google.com by norb...@mocsnik.hu on 6 Nov 2009 at 12:13

GoogleCodeExporter commented 9 years ago
This is of course just a proof of concept. Other methods than GET should be
implemented as well and the use of global variables should be avoided. It is a
working example though.

Original comment by norb...@mocsnik.hu on 6 Nov 2009 at 12:21