Hi, After some investigation, it appears that the GoDaddy proxy servers handle HTTPS connections via tunneling.
Thus, the HTTP exchange looks like: ----- CONNECT www.google.com:443 HTTP/1.1 Host: www.google.com HTTP/1.1 200 Connection established (SSL-encrypted request to www.google.com) (SSL-encrypted response from www.google.com) ---- This is different from what Zend_Http_Client_Adapter_Proxy is currently doing, which is something like this: ---- POST https://www.google.com:443 HTTP/1.1 Host: www.google.com (clear-text request) --- The Zend Framework classes currently connect via fsockopen, which, as far as I can tell, doesn't permit connecting via HTTP, sending the CONNECT headers and then 'upgrading' to HTTPS. I don't want the GoDaddy users out there to have to live without Google data APIs!, so I looked at how this issue can be solved. Basically, it involves writing a Zend_Http_Client_Adapter which uses Curl rather than fsockopen. There is an adapter for curl in the incubator of zend framework, though it's not intended for use with proxies and doesn't support methods other than GET and POST currently. So, I rolled my own-- there's no guarantees with the following code, but I was able to get it to work-- with a godaddy account and with full CRUD operations-- including authentication over HTTPS via ClientLogin (which only should be used by web applications if the username/password is part of the application configuration-- you should not be prompting users for their credentials to use with ClientLogin). Procedure: 1) Make a copy of Zend_Http_Client_Adapter_Proxy and rename it something like Adapter_ProxyWithCurl 2) Replace the contents of the following methods in your newly created adapter: public function connect($host, $port = 80, $secure = false) { // If no proxy is set, fall back to Socket adapter if (! $this->config['proxy_host']) { return parent::connect($host, $port, $secure); } } public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { // If no proxy is set, fall back to default Socket adapter if (! $this->config['proxy_host']) { return parent::write($method, $uri, $http_ver, $headers, $body); } $host = $this->config['proxy_host']; $port = $this->config['proxy_port']; $ch = curl_init(); curl_setopt($ch, CURLOPT_VERBOSE, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt($ch, CURLOPT_PROXY,"http://" . $host . ':' . $port); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_URL, $uri->__toString()); curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Save request method for later $this->method = $method; curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // Add Proxy-Authorization header if ($this->config['proxy_user'] && ! isset($headers['proxy- authorization'])) { $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader( $this->config['proxy_user'], $this- >config['proxy_pass'], $this->config['proxy_auth'] ); } $curlHeaders = array(); // Add all headers to the curl header array foreach ($headers as $k => $v) { if (is_string($k)) $v = ucfirst($k) . ": $v"; $curlHeaders[] = $v; } curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders); if ($body != null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } $this->result = curl_exec($ch); // HACK- The server returns chunked transfer encoding at times, and it's indicated in the header // However, curl and ZF both attempt to decode, leading to exceptions being thrown // There has to be a way to avoid the following line (or something like it), but haven't figured it out yet $this->result = str_ireplace('Transfer-encoding:', 'Transfer- encoding-old:', $this->result); return $this->result; } public function read() { return $this->result; } 3) In your code which is using the Calendar data API, follow the suggestions of Erik above except pass the name of the adapter you just created instead of Zend_Http_Client_Adapter_Proxy. Also make sure that this newly-created adapter has a corresponding require or loadClass statement. 4) Make a quick patch to Zend_Gdata_ClientLogin to prevent the proxy configuration from being lost after authentication is performed. You'll want to comment out the creation of the new Zend_Http_Client object in the following lines (~ line 130 of ClientLogin.php): if ($response->getStatus() == 200) { $headers['authorization'] = 'GoogleLogin auth=' . $goog_resp['Auth']; //$client = new Zend_Http_Client(); 5) Done -- test away. So- this is a quick and dirty hack. However, I will be following up on this problem by: a) Fixing the two issues in Zend_Gdata_ClientLogin-- the issue where exceptions aren't thrown, and the issue above where the client proxy configuration is lost b) Trying to get the Curl HTTP adapter pushed into core with support for proxies and all HTTP methods Please let me know if you have any questions. Thanks, -Ryan On Jun 14, 7:01 pm, CrazyAtlantaGuy <[EMAIL PROTECTED]> wrote: > The latest development from the confused and distorted reality that is > GoDaddy support: > > They say the scripts will need to be modified to make all connections > using CURL. They have an example > here:http://help.godaddy.com/article.php?article_id=288 > > On Jun 14, 2:03 pm, CrazyAtlantaGuy <[EMAIL PROTECTED]> wrote: > > > Lane or Ryan, > > > Would you agree that this appears to be a GoDaddy problem? Are there > > any other reasons you can think of that would be causing this > > behavior? They are starting to say now that this is a coding issue > > and they can't help me, but I'm 99% that is not the case. Do you > > agree? > > > Thanks for your help! > > > On Jun 14, 9:24 am, CrazyAtlantaGuy <[EMAIL PROTECTED]> wrote: > > > > Once my previous change is made, I run the code below. It's a simple > > > example of connecting to the Google server using username/password > > > authentication and retrieving the list of calendars. > > > > require_once 'Zend/Loader.php'; > > > Zend_Loader::loadClass('Zend_Gdata'); > > > Zend_Loader::loadClass('Zend_Gdata_AuthSub'); > > > Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); > > > Zend_Loader::loadClass('Zend_Gdata_Calendar'); > > > Zend_Loader::loadClass('Zend_Http_Client'); > > > > $service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; > > > $user = '[EMAIL PROTECTED]'; > > > $pass = 'XXXXXXX'; > > > > $config = array( > > > 'adapter' => 'Zend_Http_Client_Adapter_Proxy', > > > 'proxy_host' => 'proxy.shr.secureserver.net', > > > 'proxy_port' => 3128 > > > ); > > > > try { > > > $http = new Zend_Http_Client(); > > > $http->setConfig($config); > > > $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, > > > $service, $http); > > > var_dump($client); > > > $http->setConfig($config); > > > > $gdataCal = new Zend_Gdata_Calendar($client); > > > $calFeed = $gdataCal->getCalendarListFeed(); > > > foreach ($calFeed as $calendar) { > > > echo '<li>' . $calendar->title() . '</li>'; > > > } > > > } catch (Zend_Exception $e) { > > > var_dump($e); > > > } > > > > When I run this it fails and dumps the error. I'll cut to the chase > > > and show you what I sent... > > > > POSThttps://www.google.com:443/accounts/ClientLoginHTTP/1.1 > > > Host:www.google.com > > > Connection: close > > > User-agent: Zend-ZendFramework Zend_Framework_Gdata/1.0.0RC2 > > > Content-type: application/x-www-form-urlencoded > > > Content-length: 115 > > > accountType=HOSTED_OR_GOOGLE&Email=crazyatlantaguy > > > %40gmail.com&Passwd=XXXXXX&service=cl&source=Zend-ZendFramework > > > > ...and the dump containing what I received in return... > > > > ["last_response:protected"]=> > > > object(Zend_Http_Response)#5 (5) { > > > ["version:protected"]=> > > > string(3) "1.0" > > > ["code:protected"]=> > > > int(501) > > > ["message:protected"]=> > > > string(15) "Not Implemented" > > > ["headers:protected"]=> > > > array(8) { > > > ["Server"]=> > > > string(18) "squid/2.6.STABLE12" > > > ["Date"]=> > > > string(29) "Thu, 14 Jun 2007 12:29:47 GMT" > > > ["Content-type"]=> > > > string(9) "text/html" > > > ["Content-length"]=> > > > string(4) "1093" > > > ["Expires"]=> > > > string(29) "Thu, 14 Jun 2007 12:29:47 GMT" > > > ["X-squid-error"]=> > > > string(15) "ERR_UNSUP_REQ 0" > > > ["X-cache"]=> > > > string(27) "MISS from wc02.shr.phx3.gdg" > > > ["Proxy-connection"]=> > > > string(5) "close" > > > } > > > ["body:protected"]=> > > > string(1093) " > > > > ERROR > > > The requested URL could not be retrieved > > > While trying to retrieve the > > > URL:https://www.google.com/accounts/ClientLogin > > > The following error was encountered: > > > * Unsupported Request Method and Protocol > > > Squid does not support all request methods for all access protocols. > > > For example, you can not POST a Gopher request. > > > Your cache administrator is webmaster. > > > Generated Thu, 14 Jun 2007 12:29:47 GMT by wc02.shr.phx3.gdg (squid/ > > > 2.6.STABLE12) > > > "}} > > > > This is this reason that I contacted GoDaddy and was told that their > > > proxy does not support POST over outgoing SSL. Which I agree does not > > > make any sense. How you can you just ban key parts of HTTP? I > > > attempted to modify the ClientLogin code further to make this > > > authentication request us GET instead of POST. Although I believe I > > > made the right change (it works as a URL the browser) I still receive > > > this message from the proxy. > > > > On Jun 14, 9:12 am, CrazyAtlantaGuy <[EMAIL PROTECTED]> wrote: > > > > > First - A suggested change for google's implementation of the > > > > framework in PHP. > > > > > Within the file \Zend\GData\ClientLogin.php there are conditions while > > > > creating the client HTTP object which can cause it to fail without > > > > throwing an exception. This is why people have discussed their > > > > $client variable being null. There is an error here, we just don't > > > > see it because of a bug which causes it to return null instead. > > > > > To fix this in the most recent release of Zend, RC2, modify line 142 > > > > so that instead of reading: > > > > } elseif ($response->getStatus() == 403) { > > > > it reads > > > > } else { > > > > > Now when an unexpected error code is returned an exception is thrown. > > > > Previously exceptions were only thrown for 403 errors - not too > > > > helpful in our case. > > > > > On Jun 14, 8:20 am, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote: > > > > > > My ultimate goal is quite simple, all I really want to do is read my > > > > > event data so I can generate an RSS feed that can be fed into tumblr. > > > > > > I called godaddy, just on the off chance they'd be able to tell me > > > > > problems I'd encounter, and got a lot of "We don't help with coding" > > > > > and then when I just asked to make sure if it was even possible on > > > > > their shared hosting they told me it was, but that it'd be difficult. > > > > > > Anyway using the help from this thread, along with the manual I > > > > > crafted: > > > > > > $config = array( > > > > > 'adapter' => 'Zend_Http_Client_Adapter_Proxy', > > > > > 'proxy_host' => 'proxy.shr.secureserver.net', > > > > > 'proxy_port' => 3128 > > > > > ); > > > > > // Instantiate a client object > > > > > $clientp = new Zend_Http_Client($myCalendar, $config); > > > > > $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, 'cl', > > > > > $clientp); > > > > > $service = new Zend_Gdata_Calendar($client); > > > > > > try { > > > > > $listFeed= $service->getCalendarListFeed();} catch > > > > > (Zend_Gdata_App_Exception $e) { > > > > > > echo "Error: " . $e->getResponse(); > > > > > > } > > > > > > I get the Error every time, and I did some other testing and the > > > > > $client variable is null. I also am not setting $myCalendar because I > > > > > wasn't entirely clear and what that should be. I tried putting names > > > > > of my calendars in there, which those caused invalid schema errors, I > > > > > also tried the addresses of my feeds, which didn't throw errors, but > > > > > didn't improve the situation. > > > > > > I also tried getting events instead of calendars with the same > > > > > results. At this point I'm not sure if it's an error with goDaddy, or > > > > > just my not understanding how to use the API. > > > > > On Jun 14, 1:08 am, "Ryan Boyd (Google)" <[EMAIL PROTECTED]> wrote: > > > > > > > Hi CrazyAtlantaGuy, > > > > > > > That seems a bit odd that POST would not be allowed, as it's a > > > > > > common > > > > > > method of HTTP communication-- used in many web sites for form data > > > > > > and also used by lots of different APIs. > > > > > > > What operations were you performing at the time you received the > > > > > > timeout errors? Was it adding new entries, or updating/deleting > > > > > > entries? If the latter, the PUT/DELETE methods are used by default. > > > > > > These methods are less common and much more likely to be blocked by > > > > > > a > > > > > > proxy server. Fortunately, there is an option in > > > > > > Zend_Gdata_Calendar > > > > > > (via way of Zend_Gdata_App) to indicate that you want POST requests > > > > > > to > > > > > > be used in place of PUTs/DELETEs. This is set by calling > > > > > > $calendarService->setHttpMethodOverride(true); Setting this > > > > > > property > > > > > > tells the library to sent HTTP POSTS but add a 'X-Http-Method- > > > > > > Override' header indicating that PUT or DELETE was the intentioned > > > > > > method. > > > > > > > If it really is POST being disallowed, then the only other major > > > > > > remaining methods are GET and HEAD. It is highly unlikely that any > > > > > > insert/update/delete operations will ever work with Google data APIs > > > > > > using these HTTP verbs as GET and HEAD requests should not have any > > > > > > side-effects based upon the HTTP spec. > > > > > > > Also, for future debugging-- any HTTP errors should throw an > > > > > > instance > > > > > > of Zend_Gdata_App_HttpException. This provides a method called > > > > > > getResponse() which returns the Zend_Http_Response object. Just > > > > > > var_dump this and you should have any information you want about the > > > > > > server error. > > > > > > > Good luck in getting this resolved! > > > > > > > Cheers, > > > > > > -Ryan > > > > > > > On Jun 13, 5:32 pm, CrazyAtlantaGuy <[EMAIL PROTECTED]> wrote: > > > > > > > > I've been working on this recently too and have run into the same > > > > > > > troubles. I was able to avoid the timeout error by using the > > > > > > > proxy - > > > > > > > however now that I can connect to the proxy the communications > > > > > > > with > > > > > > > google still fails. Adding lots of print lines to the Zend code I > > > > > > > have found that the proxy is sending back an HTTP error > > > > > > > message,"501 > > > > > > > Not Implemented." After several emails with GoDaddy support I've > > > > > > > been > > > > > > > told "it appears that our hosting does not support the 'POST' > > ... > > read more >> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google Calendar Data API" 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-calendar-help-dataapi?hl=en -~----------~----~----~----~------~----~------~--~---
