XF 2.1 Check for XF-Forwarded-For for api calls or let XF\Http\Request run through the class proxy

Zambfd

Member
Hi,

we implemented the xenforo threads as a comment section in our frontend and create new posts and threads through the api ( Super User Key ).

But because of that every user interaction with the frontend is now stored with the server ip address in xenforo because the api retreives the current ip with ->getIp() not ->getIp(true) for the proxy check.

I tried to extend the Request class to override the getIp() method but this class is not pushed through the class proxy ...

Any solutions except for that the developers should change the core code? ^^

Regards
 
If it's for an internal website, and you're not planning on releasing it as an add-on, you can override your site's Request object manually through the config.php file (by setting $config['container']['request'] to a function that instantiates and returns a request instance, see the App class for details).

You might be able to accomplish the same thing using the app_pub_setup event, but it isn't recommended and shouldn't be used on a released add-on.
 
You might be able to accomplish the same thing using the app_pub_setup event, but it isn't recommended and shouldn't be used on a released add-on.
It uses an API. It is necessary to use the event then app_api_setup
 
Note:
Do not do this if you plan to release your addon

Create:
\XF\Http\Request.php inside your addon path

Code:

PHP:
namespace YOUR\ADDON\XF\Http;

/**
* Class Request
* @package CTEC\General\XF\Http
*/
class Request extends \XF\Http\Request {

   /**
    * @param bool $allowProxied
    * @return mixed
    */
   public function getIp($allowProxied = false) {

      if ( preg_match('#^/?api/#i', $_SERVER['REQUEST_URI']) ) {
         $allowProxied = true;
      }

      return parrent::getIp($allowedProxied);
   }
}

Add to config.php:
PHP:
$config['container']['request'] = function(XF\Container $c) {
        $request = new YOUR\ADDON\NAMESPACE\XF\Http\Request($c['inputFilterer']);
        $request->setCookiePrefix($c['config']['cookie']['prefix']);
        return $request;
};
 
Last edited:
@Zambfd, you can just change it. Use app_api_setup. And replace in Request.php:
PHP:
namespace YOUR\ADDON\XF\Http;

/**
* Class Request
* @package CTEC\General\XF\Http
*/
class Request extends \XF\Http\Request {

   /**
    * @param bool $allowProxied
    * @return mixed
    */
   public function getIp($allowProxied = false) {

      if ( preg_match('#^/?api/#i', $_SERVER['REQUEST_URI']) ) {
         $allowProxied = true;
      }

if ($allowProxied && $ip = $this->getServer('HTTP_CLIENT_IP'))
      {
         list($ip) = explode(',', $ip);
         return $this->getFilteredIp($ip);
      }
      else if ($allowProxied && $ip = $this->getServer('HTTP_X_FORWARDED_FOR'))
      {
         list($ip) = explode(',', $ip);
         return $this->getFilteredIp($ip);
      }


      return parent::getIp($allowProxied);
   }
}
 
Do you mean the code event listener?
What's the callback::method entry?

Shorter version of the method
PHP:
public function getIp($allowProxied = false) {

      if ( preg_match('#^/?api/#i', $_SERVER['REQUEST_URI']) ) {
         $allowProxied = true;
      }

      return parent::getIp($allowProxied);
}
 
Last edited:
Do you mean the code event listener?
What's the callback::method entry?

Shorter version of the method
PHP:
public function getIp($allowProxied = false) {

      if ( preg_match('#^/?api/#i', $_SERVER['REQUEST_URI']) ) {
         $allowProxied = true;
      }

      return parent::getIp($allowProxied);
}
I wrote it considering if it doesn’t apply. But the first version of the message was just that. About the event handler:
/admin.php?code-events/listeners/
Execute callback YOUR\ADDON\Listener::appApiSetup
Listener.php:
PHP:
namespace YOUR\ADDON;

class Listener {
public static function appApiSetup(\XF\App $app)
{
  $container = $app->container();
  $container['request'] = function(XF\Container $c) use ($app) {
        $class = $app->extendClass('XF\Http\Request');
        $request = new $class($c['inputFilterer']);
        $request->setCookiePrefix($c['config']['cookie']['prefix']);
        return $request;
  };
}
}
 
Top Bottom