2012-05-25 30 views
5

Tôi gặp sự cố khi triển khai API hoạt động với Java nhưng không hoạt động với cURL. Chúng tôi đã đi qua tất cả mọi thứ cho đến nay và phải có một cái gì đó là khác nhau giữa các yêu cầu mà Java làm và những gì chúng tôi thực hiện.Làm thế nào để nắm bắt dữ liệu yêu cầu HTTP đầy đủ (tiêu đề và nội dung) bằng PHP?

Trong PHP, chúng tôi có thể lấy dữ liệu tiêu đề bằng cách xem số $_SERVER['HTTP_*'] và chúng tôi có thể lấy nội dung yêu cầu từ file_get_contents('php://input'); Nhưng chúng tôi không thể lấy dữ liệu chính xác được gửi từ tác nhân người dùng đến ứng dụng khách.

Có thể nhận được yêu cầu đầy đủ, mà tác nhân người dùng gửi, với PHP không? Tiêu đề và nội dung được bao gồm? Nếu có thì làm sao?

Ví dụ duy nhất tôi tìm thấy là here, nhưng ví dụ này được hiển thị bằng cách phân tích cú pháp qua $_SERVER, có vẻ như một hack vì nó không bao giờ là 100%.

Tất cả trợ giúp và mẹo được đánh giá cao!

Trả lời

9

cho tiêu đề bạn có thể thử apache_request_headers() và cho cơ thể tôi không biết phương pháp nào khác hơn file_get_contents('php://input');

+0

Vì vậy, tôi giả sử không có cách để nắm bắt toàn bộ luồng yêu cầu theo cách nó đến máy chủ? – kingmaple

+0

Bạn cần những gì? Có vấn đề gì với việc không hài lòng? – Vytautas

+0

Đây là tiền phạt, nhưng chúng tôi đang tìm kiếm thêm so sánh mức byte. Dù sao thì, đây là điều tốt nhất chúng tôi có. – kingmaple

2

Cũ câu hỏi, nhưng đối với bất cứ ai cần phải làm điều này trong tương lai ... Điều tốt nhất (có thể là duy nhất) cách sẽ được kiểm soát hoàn toàn máy chủ bằng cách máy chủ.

Thiết lập máy chủ socket nghe trên cổng 80 (nếu đây là tất cả những gì bạn cần máy chủ thực hiện) hoặc bất kỳ cổng nào khác nếu 80 không khả dụng.

Bằng cách đó bạn có thể nắm bắt yêu cầu hoàn toàn chưa được sửa đổi. Ví dụ về các máy chủ ổ cắm cơ bản phong phú, đây là một phiên bản đơn giản của một mới nhất tôi thực hiện, mà sẽ in đầy đủ các yêu cầu:

<?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; 

Để khởi động máy chủ trên cổng 8080 chỉ cần chạy php filename.php 8080 từ một vỏ.

Các vấn đề liên quan