Tập lệnh này nghe trên IP/cổng và dự định hoạt động như một proxy HTTP (S).cURL làm proxy, xử lý phương thức HTTPS/CONNECT
Yêu cầu đối với URL HTTP hoạt động tốt, nhưng tôi đang lo ngại về cách xử lý các yêu cầu HTTPS và cụ thể hơn, bắt tay SSLv3 sau khi máy khách gửi yêu cầu CONNECT đến proxy.
Gần nhất tôi đã đến những gì trông giống như một câu trả lời là: libcurl tùy chọn
- CURLOPT_HTTPPROXYTUNNEL để dữ liệu đường hầm giữa máy khách và máy chủ mục tiêu
- stream_socket_enable_crypto() để có thể "làm công cụ" với dữ liệu được mã hóa
Tôi thực sự không chắc chắn, vì vậy một con trỏ về cách xử lý vấn đề này sẽ được đánh giá cao.
Đây là một yêu cầu mẫu: http://pastebin.com/xkWhGyjW
<?php
class proxy {
static $server;
static $client;
static function headers($str) { // Parses HTTP headers into an array
$tmp = preg_split("'\r?\n'",$str);
$output = array();
$output[] = explode(' ',array_shift($tmp));
$post = ($output[0][0] == 'POST' ? true : false);
foreach($tmp as $i => $header) {
if($post && !trim($header)) {
$output['POST'] = $tmp[$i+1];
break;
}
else {
$l = explode(':',$header,2);
$output[$l[0]] = $l[0].': '.ltrim($l[1]);
}
}
return $output;
}
public function output($curl,$data) {
socket_write(proxy::$client,$data);
return strlen($data);
}
}
$ip = "127.0.0.1";
$port = 50000;
proxy::$server = socket_create(AF_INET,SOCK_STREAM, SOL_TCP);
socket_set_option(proxy::$server,SOL_SOCKET,SO_REUSEADDR,1);
socket_bind(proxy::$server,$ip,50000);
socket_getsockname(proxy::$server,$ip,$port);
socket_listen(proxy::$server);
while(proxy::$client = socket_accept(proxy::$server)) {
$input = socket_read(proxy::$client,4096);
preg_match("'^([^\s]+)\s([^\s]+)\s([^\r\n]+)'ims",$input,$request);
$headers = proxy::headers($input);
echo $input,"\n\n";
if(preg_match("'^CONNECT '",$input)) { // HTTPS
// Tell the client we can deal with this
socket_write(proxy::$client,"HTTP/1.1 200 Connection Established\r\n\r\n");
// Client sends binary data here (SSLv3, TLS handshake, Client hello?)
// socket_read(proxy::$client,4096);
// ?
}
else { // HTTP
$input = preg_replace("'^([^\s]+)\s([a-z]+://)?[a-z0-9\.\-]+'","\\1 ",$input);
$curl = curl_init($request[2]);
curl_setopt($curl,CURLOPT_HEADER,1);
curl_setopt($curl,CURLOPT_HTTPHEADER,$headers);
curl_setopt($curl,CURLOPT_TIMEOUT,15);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl,CURLOPT_NOPROGRESS,1);
curl_setopt($curl,CURLOPT_VERBOSE,1);
curl_setopt($curl,CURLOPT_AUTOREFERER,true);
curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($curl,CURLOPT_WRITEFUNCTION, array("proxy","output"));
curl_exec($curl);
curl_close($curl);
}
socket_close(proxy::$client);
}
socket_close(proxy::$server);
?>
Bạn có thể đăng trên Pastebin mã của bạn cho các yêu cầu HTTP URL? –
Tất nhiên ... Tôi đang sử dụng dòng lệnh cURL để kiểm tra. http://pastebin.com/xkWhGyjW – innvo
Bạn đã thử các trang web khác ngoài google.com (theo pastebin của bạn) chưa? (xem tại đây http://superuser.com/questions/404116/cannot-connect-to-website-ssl-handshaking-fails) Và bạn đã thử kết nối mà không có proxy, tức là 'curl -L -i -v' https://www.google.com/ "'? Đầu ra là gì nếu bạn thêm '--trace tracetxt.tmp' vào cuộc gọi curl, khi sử dụng proxy và khi kết nối trực tiếp? Có lẽ sự khác biệt của các dấu vết có thể giúp đỡ? – stef77