【问题标题】:Ubuntu Lamp - Proxy - Firewall - Joomla curl and fsockopen wont workUbuntu Lamp - 代理 - 防火墙 - Joomla curl 和 fsockopen 不起作用
【发布时间】:2015-08-01 07:51:33
【问题描述】:

好吧,我已经为此苦苦挣扎了几天。

我在我们网络上的本地计算机上安装了 Joomla,用于我们的 Intranet,还安装了 Jomsocial。

问题是,当我去站点配置或编辑事件或导航到任何调用外部 api 的 joomla 模块时,我得到任何一个

CURL error : 7 Failed to connect to maps.google.com port 80: Connection timed out 

Connection timed out (110) 

问题绝对不是 Joomla 或 Jomsocial,因为我在同一台服务器上运行的其他 php 应用程序也无法联系外部 api

服务器设置是

Ubuntu 14Lts PHP 5.5 阿帕奇 2.4.7 玛丽亚数据库

服务器位于代理之后,但可以通过 CLI 完全访问 Internet。启用所有必要的 php 扩展。我已经在 /etc/environment 中设置了全局代理变量,也在 apt config 中设置了代理变量,并在 Joomla 中设置了代理变量。我的 Joomla 更新和组件更新工作正常,但 fsockopen 函数的 curl 不工作。

我不知道在哪里寻找错误。我的想法是 www-data 用户可能没有足够的权限从浏览器执行 fsockopen 和 curl。

有什么建议吗?

更新,我已经在另一台不在公司网络(直接连接到互联网)上的机器上测试了该站点,并且一切正常。所以我很确定我的问题出在我的机器和网络权限上,特别是我的 www-data 用户。我该如何解决这个问题?

【问题讨论】:

  • 如果可能,尝试在 Joomla 的 index.php 文件中使用 putenv('http_proxy=http://proxy.example.com:8080/'); 设置您的代理,看看它是否可以这样工作。
  • 谢谢!那解决了它。虽然我必须在 index.php 和 /administrator/index.php 中设置变量。请发表您的评论作为索取赏金的答案

标签: php apache ubuntu curl joomla


【解决方案1】:

我刚刚在非常接近的设置下遇到了同样的问题(唯一的区别是 mysql 而不是 MariaDb 和 Joomla 3.4.1),我花了很长时间才把所有东西放在一起,所以我将列出这里可能的绊脚石:

  1. 确保 php5-curl 已安装。 Joomla 只能使用 CURL 作为传输层的代理。

    sudo apt-get install php5-curl
    
  2. 我发现在 Joomla 配置中输入代理没有用。它唯一的好处是更新连接不会超时而是立即返回。

  3. 环境变量放在/etc/apache2/envvars是不够的,还需要在/etc/apache2/apache2.conf中使用“PassEnv”, 即(取自https://stackoverflow.com/a/21571588/1967646

    PassEnv http_proxy
    
  4. 另外,我需要同时传递 HTTP_PROXYHTTPS_PROXY,因为 xml 列表是通过 http 获取的,而文件稍后是通过 https 获取的(可能从 github 更新文件) .可能,您需要将这些变量以小写形式显示,但在 joomla 配置页面“PHP 信息”中,类似名称的变量以大写形式显示。

  5. 我不知道这真的有什么不同,但是如下重启 apache2 似乎是正确的方法(而不是 apache2ctl)。

     sudo service apache2 restart
    

我整理了一些杂乱无章的代码来测试 curl 和 php 是否可以一起工作,其中大部分来自https://stackoverflow.com/a/1477710/1967646。我只添加了大量的错误报告。将文件 test.php 放入 web 文件夹的根目录中,然后使用您喜欢的浏览器查看。

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);

$url = 'http://update.joomla.org/core/list.xml';

function get_page($url, $proxy=true) {
    if ($url!='') {
        $ch = curl_init ();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        if ($proxy) {
            curl_setopt($ch, CURLOPT_PROXY, '<enter your proxy host here>');
            curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
            curl_setopt($ch, CURLOPT_PROXYPORT, <enter your proxy port here>);
        }
        if (! $html = curl_exec($ch)) {
            echo '<br>Last CURL error is '.curl_error($ch).'<br>';
    } else {
            echo '<br>CURL without error.<br>';
    }
        curl_close($ch);
        return $html;
    } else {
    echo 'Empty URL.';
    }
}

echo 'Hello, getting pages via curl:';
$html=get_page($url);
var_dump($html);
echo bin2hex($html);
echo '<br>';
var_dump(get_page($url, false));
echo '<br>done.<br>';
?>

【讨论】:

    【解决方案2】:

    似乎http_proxy 变量没有被PHP (mod_php) 使用,即使PassEnv 用于传递它,或者直接使用SetEnv 设置。另外,在PHP脚本中调用getenv('http_proxy')时也能正确显示。

    但是,有两种方法可以让它工作:

    • 在 Apache envvars (/etc/apache2/envvars) 中设置如下:

      export http_proxy=http://proxy.example.com:8080/
      

      并重新启动 Apache。

    • 放入加载应用程序的 PHP 文件(例如 index.php、bootstrap.php 等):

      putenv('http_proxy=http://proxy.example.com:8080/');
      

    同样,如果您使用 getenv('http_proxy') 进行测试,您将看到它们设置正确。

    【讨论】:

      【解决方案3】:

      使用这个:

      export http_proxy=http://your.proxy.server:port/
      

      或者这个:

      来自man curl:

      -x, --proxy <[protocol://][user:password@]proxyhost[:port]>
      
       Use the specified HTTP proxy. 
       If the port number is not specified, it is assumed at port 1080.
      

      【讨论】:

        猜你喜欢
        • 2014-02-23
        • 2014-10-21
        • 2013-10-06
        • 1970-01-01
        • 2012-07-24
        • 2011-05-05
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多