相同的Http请求适用于一台主机但不适用于另一台主机

时间:2017-04-28 09:45:57

标签: php apache sockets http curl

我有以下代码:

function posturl($URL, $post_data, $referrer = "") {  
        $URL_Info = parse_url ( $URL );
        // Building referrer
        if ($referrer == "")
                $referrer = $_SERVER["SCRIPT_URI"];

        // making string from $data
        foreach ( $post_data as $key => $value )
                $values [] = "$key=" . urlencode ( $value );

        $data_string = implode ( "&", $values );

        if (! isset ( $URL_Info ["port"] ))
                $URL_Info ["port"] = 80;

        $request .= "POST " . $URL_Info ["path"] . " HTTP/1.1\n";
        $request .= "Host: " . $URL_Info ["host"] . "\n";
        $request .= "Referer: $referrer\n";
        $request .= "Content-type: application/x-www-form-urlencoded\n";
        $request .= "Content-length: " . strlen ( $data_string ) . "\n";
        $request .= "Connection: close\n";
        $request .= "\n";
        $request .= $data_string . "\n";

        echo ">>>> Request:\n";
        echo($request);
        var_dump($URL_Info);

        $fp = fsockopen ( $URL_Info ["host"], $URL_Info ["port"] );
        fputs ( $fp, $request );
        while ( ! feof ( $fp ) ) {
                $result .= fgets ( $fp, 128 );
        }
        fclose ( $fp );
        $result=substr($result, strpos($result, "\r\n\r\n"));
        return $result;
}

以下请求:

POST /fia/interface/product_use_action.php HTTP/1.1
Host: orlof.is
Referer: 
Content-type: application/x-www-form-urlencoded
Content-length: 111
Connection: close

task=check&ticket_number=EDDAFIA073&secret_code=htl440&seller_number=104&ternimal_number=Edda&global_language=8

我收到以下回复:

https://pastebin.com/5sf4fUiY

我的问题:

请求有问题吗?

我也有相同的代码和相同的请求,但Host不同,我不会在那里得到错误。

POST /fia/interface/product_use_action.php HTTP/1.1
Host: test.orlof.is
Referer: 
Content-type: application/x-www-form-urlencoded
Content-length: 111
Connection: close

task=check&ticket_number=EDDAFIA073&secret_code=htl440&seller_number=104&ternimal_number=Edda&global_language=8

我们可以看到唯一的区别是test.orlof.is而不是orlof.is

感谢。

1 个答案:

答案 0 :(得分:0)

我不确定这是否真的是问题,但您的请求有两个明显错误的事情:

    $request .= "POST " . $URL_Info ["path"] . " HTTP/1.1\n";

HTTP的结尾应该是\r\n,而不是\n。这适用于所有行结尾,包括HTTP标头和正文之间的分隔符。

   $request .= "Content-length: " . strlen ( $data_string ) . "\n";
   ...
   $request .= $data_string . "\n";

您可以使用strlen ( $data_string )指定正文的长度,但实际上您还要发送一个字节。无需在正文结尾处发送\n,但是当您这样做时,您也应该在content-length标题中对此进行说明。

除此之外,您正在执行HTTP / 1.1请求,但希望您可以简单地将HTTP响应主体视为最终数据。但是,对于HTTP / 1.1,服务器只能使用分块传输编码,即响应将是块,每个块具有大小前缀。如果您不想更好地使用HTTP / 1.0。

至于为什么它适用于一个服务器而不是另一个服务器:可能是因为一个服务器可能具有更宽容的HTTP标准实现,另一个服务器更严格。在任何情况下,使用HTTP的最终来源是the standard而不是你在某处看过的一些例子。