[wp-trac] [WordPress Trac] #3082: Wordpress can't make outbound POST and GET requests when its behind a proxy

WordPress Trac wp-trac at lists.automattic.com
Wed Aug 30 09:55:49 GMT 2006


#3082: Wordpress can't make outbound POST and GET requests when its behind a proxy
--------------------------+-------------------------------------------------
 Reporter:  the_dead_one  |       Owner:  anonymous                  
     Type:  defect        |      Status:  new                        
 Priority:  normal        |   Milestone:                             
Component:  General       |     Version:  2.0.3                      
 Severity:  normal        |    Keywords:  proxy Dashboard Akismet IXR
--------------------------+-------------------------------------------------
 I have wordpress installed on a server that is behind a proxy. Both the
 server and the proxy allow outbound HTTP requests. However there is no
 support or options for using a proxy. This affects outbound pings,
 dashboard feeds, akismet plugin and several functions used by other
 plugins.

 The reason it doesn't work is that PHP's fopen and fsockopen do not
 support requests via proxies and must be modified to handle proxies. All
 requests to fopen and/or fsockopen would have to be updated to support the
 use of a proxy if one exists.

 I've applied several hacks to the wordpress core to get it to work,
 however they would need to be scaled up to become a patch as they are not
 compatible when there is no proxy and they do no support proxy
 authentication. (Originally I documented them
 [http://wiki.redbrick.dcu.ie/mw/Installing_Wordpress_on_Redbrick#Getting_it_to_work_through_the_Redbrick.2FDCU_Proxy
 here]).

 These hacks do not cover all instances of fopen and fsockopen in the
 codebase, so more extensive testing may need to be done.

 '''The Dashboard feeds''' are not updated through a proxy. This is the
 most trivial to fix as class-snoopy.php is the only file to support proxy.
 In 'wp-include/class-snoopy.php', set the 'proxy_host' variable to your
 proxy host and 'proxy_port' variable to your proxy port. Set '_isproxy' to
 "true".

 To get '''Akismet''' to work, in 'wp-content/plugins/akismet.php', modify
 the function ksd_http_post like this but replacing your_proxy_host with
 the proxy address and  your_proxy_port with the port of the proxy.

 {{{
 // Returns array with headers in $response[0] and entity in $response[1]
 function ksd_http_post($request, $host, $path, $port = 80) {
         global $ksd_user_agent;

         //$http_request  = "POST $path HTTP/1.0\r\n";
         //$http_request .= "Host: $host\r\n";
         $http_request  = "POST http://$host$path HTTP/1.0\r\n";
         $http_request .= "Host: http://$host\r\n";
         $http_request .= "Content-Type: application/x-www-form-urlencoded;
 charset=" . get_settings('blog_charset') . "\r\n";
         $http_request .= "Content-Length: " . strlen($request) . "\r\n";
         $http_request .= "User-Agent: $ksd_user_agent\r\n";
         $http_request .= "\r\n";
         $http_request .= $request;
         $response = '';

         //if( false !== ( $fs = @fsockopen($host, $port, $errno, $errstr,
 10) ) ) {
         if( false !== ( $fs = @fsockopen('your_proxy_host',
 your_proxy_port, $errno, $errstr, 10) ) ) {
                 fwrite($fs, $http_request);

                 while ( !feof($fs) )
                         $response .= fgets($fs, 1160); // One TCP-IP
 packet
                 fclose($fs);
                 $response = explode("\r\n\r\n", $response, 2);
         }
         return $response;
 }
 }}}

 I've found '''class-IXR.php''' must also be updated. I discovered this
 while trying to get a plugin to work. In 'class-IXR.php', search for
 'fsockopen'. Just above the first refernce to it, modify the '$request'
 string like this, but replacing your_proxy_host with the proxy address and
 your_proxy_port with the port of the proxy:

 {{{
  $request  = "POST http://{$this->server}{$this->path} HTTP/1.0$r";
  $request .= "Host: http://{$this->server}$r";
  $request .= "Content-Type: text/xml$r";
  $request .= "User-Agent: {$this->useragent}$r";
  $request .= "Content-length: {$length}$r$r";
  $request .= $xml;
 }}}

 Then below that, modify the 'fsockopen' call like this:

 {{{
  if ($this->timeout) {
   //$fp = @fsockopen($this->server, $this->port, $errno, $errstr,
 $this->timeout);
   $fp = @fsockopen('your_proxy_host', your_proxy_port, $errno, $errstr,
 $this->timeout);
  } else {
   //$fp = @fsockopen($this->server, $this->port, $errno, $errstr);
   $fp = @fsockopen('your_proxy_host', your_proxy_port, $errno, $errstr);
  }
 }}}

 Also I've found '''functions.php''' must also be updated. I discovered
 this while trying to get another plugin to work. In 'wp-
 includes/functions.php', modify thefunction 'wp_remote_fopen' as below,
 but replacing your_proxy_host with the proxy address and  your_proxy_port
 with the port of the proxy.

 {{{
   function wp_remote_fopen( $uri ) {
         if ( ini_get('allow_url_fopen') ) {
                 /*$fp = fopen( $uri, 'r' );
                 if ( !$fp )
                         return false;
                 $linea = '';
                 while( $remote_read = fread($fp, 4096) )
                         $linea .= $remote_read;
                 fclose($fp);
                 return $linea;*/

                 $proxy_fp =
 fsockopen('your_proxy_host','your_proxy_port');
                 if ( !$proxy_fp )
                         return false;
                 fputs($proxy_fp, "GET $uri HTTP/1.0\r\nHost:
 your_proxy_host\r\n\r$
                 while(!feof($proxy_fp))
                         $proxy_cont .= fread($proxy_fp,4096);
                 fclose($proxy_fp);
                $proxy_cont = substr($proxy_cont,
 strpos($proxy_cont,"\r\n\r\n")$
         } else if ( function_exists('curl_init') ) {
 }}}

-- 
Ticket URL: <http://trac.wordpress.org/ticket/3082>
WordPress Trac <http://wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list