2012-05-25 31 views
5

我在執行與Java協同工作的API時遇到問題,但無法使用cURL。到目前爲止,我們已經完成了所有的工作,並且在Java所做的請求和我們所做的所有請求之間必定會有所不同。如何使用PHP捕獲完整的HTTP請求數據(標題和正文)?

在PHP中,我們可以通過查看$_SERVER['HTTP_*']變量來獲取標題數據,我們可以從file_get_contents('php://input');獲得請求正文但我們無法獲得從用戶代理髮送到客戶端的確切數據。

是否可以通過PHP獲取用戶代理髮送的完整請求?頭部和身體包括在內?如果是這樣,那麼怎麼樣?

我發現的唯一的例子是here,但是這一次得到的身體我提到的方式,同時通過解析通過$_SERVER獲得頭,這似乎是一個黑客,因爲它是一個什麼樣實際發送從來沒有100%。

所有的幫助和提示,感謝!

回答

9

頁眉,你可以嘗試apache_request_headers()和身體,我不知道比file_get_contents('php://input');

+0

所以我想有沒有方式捕獲整個請求流的方式,它到達服務器? – kingmaple

+0

你需要什麼?該酶有什麼問題? – Vytautas

+0

這些都很好,但我們正在尋找更多的字節級比較。無論如何,這是我們所想的最好的。 – kingmaple

2

老問題的其他方法,但任何人都需要做到這一點在未來...最好的(可能只)的方法是通過作爲服務器完全控制服務器。

設置偵聽端口80的套接字服務器(如果這是所有您需要的服務器執行的操作)或任何其他端口(如果80不可用)。

這樣你就可以完全不修改地捕獲請求。基本插槽服務器的例子很豐富,這裏是最新的一個,我實現,這將打印出完整的請求的簡化版本:

<?php 
//Read the port number from first parameter on the command line if set 
$port = (isset($argv[1])) ? intval($argv[1]) : 80; 

//Just a helper 
function dlog($string) { 
    echo '[' . date('Y-m-d H:i:s') . '] ' . $string . "\n"; 
} 

//Create socket 
while (($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { 
    dlog("socket_create() failed: reason: " . socket_strerror(socket_last_error())); 
    sleep(1); 
} 

//Reduce blocking if previous connections weren't ended correctly 
if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { 
    dlog("socket_set_option() failed: reason: " . socket_strerror(socket_last_error($sock))); 
    exit; 
} 

//Bind to port 
$tries = 0; 
while (@socket_bind($sock, 0, $port) === false) { 
    dlog("socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock))); 
    sleep(1); 
    $tries++; 
    if ($tries>30) { 
     dlog("socket_bind() failed 30 times giving up..."); 
     exit; 
    } 
} 

//Start listening 
while (@socket_listen($sock, 5) === false) { 
    dlog("socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock))); 
    sleep(1); 
} 

//Makes it possible to accept several simultaneous connections 
socket_set_nonblock($sock); 

//Keeps track of active connections 
$clients = array(); 

dlog("server started..."); 

while(true) { 
    //Accept new connections 
    while (($msgsock = @socket_accept($sock)) !== false) { 
     //Prevent blocking 
     socket_set_nonblock($msgsock); 

     //Get IP - just for logging 
     socket_getpeername($msgsock, $remote_address); 

     //Add new client to array 
     $clients[] = array('sock' => $msgsock, 'timeout' => time()+30, 'ip' => $remote_address); 

     dlog("$remote_address connected, client count: ".count($clients)); 
    } 
    //Loop existing clients and read input 
    foreach($clients as $key => $client) { 
     $rec = ''; 
     $buf = ''; 
     while (true) { 
      //Read 2 kb into buffer 
      $buf = socket_read($clients[$key]['sock'], 2048, PHP_BINARY_READ); 

      //Break if error reading 
      if ($buf === false) break; 

      //Append buffer to input 
      $rec .= $buf; 

      //If no more data is available socket read returns an empty string - break 
      if ($buf === '') break; 
     } 
     if ($rec=='') { 
      //If nothing was received from this client for 30 seconds then end the connection 
      if ($clients[$key]['timeout']<time()) { 
       dlog('No data from ' . $clients[$key]['ip'] . ' for 30 seconds. Ending connection'); 

       //Close socket 
       socket_close($client['sock']); 

       //Clean up clients array 
       unset($clients[$key]); 
      } 
     } else { 
      //If something was received increase the timeout 
      $clients[$key]['timeout']=time()+30; 

      //And.... DO SOMETHING 
      dlog('Raw data received from ' . $clients[$key]['ip'] . "\n------\n" . $rec . "\n------"); 
     } 
    } 

    //Allow the server to do other stuff by sleeping for 50 ms on each iteration 
    usleep(50000); 
} 

//We'll never reach here, but some logic should be implemented to correctly end the server 
foreach($clients as $key => $client) { 
    socket_close($client['sock']); 
} 
@socket_close($sock); 
exit; 

要啓動8080端口的服務器剛剛從shell中運行php filename.php 8080