【问题标题】:PHP use socks5 proxy with fsockopen sslPHP 使用带有 fsockopen ssl 的 socks5 代理
【发布时间】:2014-08-06 14:14:16
【问题描述】:

我正在尝试通过 socks5 代理使用 php 打开一个 HTTPS 页面,但我不能使用 curl,因为我必须能够读取响应的每一行。

为此,我使用了这个 PHP 类:http://www.phpkode.com/source/s/socksed/socksed.php,但如果我在端口 443 上启动一个连接,并发送一个带有参数的 HTTP POST 请求,nginx 会向我发回这条消息:

400 the plain http request was sent to https port

我试图将那部分代码@fsockopen("tcp:// 改为@fsockopen("ssl://),但是我无法打开页面。

【问题讨论】:

  • 您可以通过设置CURLOPT_PROXY 属性使用curl 连接到SOCKS5 代理。您在使用 curl 时遇到什么限制会阻止您阅读响应?
  • 我想逐行读取 os 下载的响应,并在特定点断开连接,我不想下载整个文件以找到我想要的内容跨度>
  • 您可以使用 curl 的 CURLOPT_WRITEFUNCTION 和 CURLOPT_BUFFERSIZE 选项来实现这一点。如果问题仍然存在,我将在明天发布答案。

标签: php curl ssl proxy socks


【解决方案1】:

试试这个:

$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
$curl_scraped_page = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);

【讨论】:

    【解决方案2】:

    如果您可以使用 curl,以下内容应该有助于实现您的目标:

    // create the curl buffered reader object with a connection to a socks5 proxy on localhost port 8888
    $cbr = new \CurlBufferedReader(array(
        CURLOPT_PROXY => 'socks5://127.0.0.1:8888',
        // disable ssl certificate verification, you probably don't need this so I've commented it out
        //CURLOPT_SSL_VERIFYPEER => false
    ));
    
    // gets the body at the url up until the point specified by the callback function
    $body = $cbr->get('https://stackoverflow.com/questions/24249029/php-use-socks5-proxy-with-fsockopen-ssl',
        /**
         * The callback function to determine whether to continue reading the body sent by the remote server
         * @param string $body
         */
        function (&$body) {
            if (($off = strpos($body, "\nTo do that,")) !== false) {
                // truncate body so that we have everything up until the newline before the string "To do that,"
                $body = substr($body, 0, $off + 1);
            }
    
            return $off === false; // continue reading while true
        });
    
    echo $body;
    

    以及相关的类:

    class CurlBufferedReader {
        private $body = false;
        private $callback;
        private $ch;
    
        public function __construct(array $curlopts = array()) {
            $this->ch = curl_init();
    
            curl_setopt_array($this->ch, $curlopts + array(
                // general curl options
                CURLOPT_CONNECTTIMEOUT   => 30,
                CURLOPT_FOLLOWLOCATION   => true,
                CURLOPT_MAXREDIRS        => 10,
                CURLOPT_RETURNTRANSFER   => true,
    
                // specific options to abort the connection early
                CURLOPT_BUFFERSIZE       => 8192,
                CURLOPT_WRITEFUNCTION    => array($this, 'writeFunction')
            ));
        }
    
        public function get($url, $callback = null) {
            curl_setopt($this->ch, CURLOPT_URL, $url);
            $this->callback = $callback;
    
            if (!($success = $this->exec())) {
                // errno 23 when aborted by the client
                if ($this->getErrno() !== 23) {
                    $this->body = false;
                }
            }
    
            return $this->body;
        }
    
        public function getBody() {
            return $this->body;
        }
    
        public function getError() {
            return curl_error($this->ch);
        }
    
        public function getErrno() {
            return curl_errno($this->ch);
        }
    
        private function exec() {
            $status = curl_exec($this->ch);
            $this->callback = null;
            return $status;
        }
    
        private function writeFunction($ch, $buffer) {
            $this->body .= $buffer;
    
            if ($this->callback && !call_user_func_array($this->callback, array(&$this->body))) {
                $written = -1; // user callback requested abort
            } else {
                $written = strlen($buffer);
            }
    
            return $written;
        }
    }
    

    它通过从远程服务器一次读取 8,192 个字节来工作。调用用户函数以读取在每个读取事件时接收到的整体。当它希望中止连接时,用户函数必须return false。同样重要的是要注意$body 是一个参考。因此,您对其所做的任何更改都会影响CurlBufferedReader::get 方法接收到的字符串。

    【讨论】:

      猜你喜欢
      • 2011-03-16
      • 2011-12-30
      • 1970-01-01
      • 2021-03-11
      • 2018-07-28
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多