http基础和php里file_get_contents,fsockopen,fopen发送post
报文:用于http协议交互的信息
请求行:包括请求的方法,url和http协议版本
状态行:包括响应结果的状态码,状态描述和http版本
首部字段:包括请求和响应的各种条件和属性值(键值对)
telnet模拟http请求
- cmd下->telnet 主机地址 80,回车
- 按下快捷键:Ctrl+] ,再按下回车,打开回显功能
- 发送请求报文
模拟get
telnet 127.0.0.1 80 回车
ctrl+]再回车
get /web/t.php?a=1&b=2&c=3 http/1.1 //---->请求行
host:localhost //请求首部
(空行)
响应内容
HTTP/1.1 200 OK
Date: Wed, 21 Mar 2018 14:22:38 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
X-Powered-By: PHP/5.6.25
Content-Length: 29
Content-Type: text/html; charset=UTF-8
2018-03-21 22:22:46
1,2,3end
模拟post
post /web/t.php http/1.1
host:localhost
Content-type:application/x-www-form-urlencoded
content-length:20
(空行)
a=1&b=2&c=3 (报文主体,到长度后直接返回结果)
Php获取
print_r(file_get_contents("php://input"));
$_POST获取不到数据(menthod小写导致)
根据RFC2616,HTTP Method是区分大小写的,而Header是不区分的。
所以 GET/POST/PUT等需要大写,而content-encoding/user-agent则不用
file_get_contents和fopen模拟post请求
rev.php(接受请求的)
<?php echo "<pre>"; print_r($_POST); print_r($_SERVER['HTTP_TEST']);
send.php (发送)
<?php $rev='http://localhost/web/http/rev.php'; $data=['a'=>'ajax','b'=>22]; $post_data=http_build_query($data); $opt=[ 'http'=>[ 'method'=>'POST', 'header'=> "host:localhost\r\n". "Content-type:application/x-www-form-urlencoded\r\n". 'Content-length:'.strlen($post_data)."\r\n". "test:tt\r\n", 'content'=>$post_data ] ]; $context=stream_context_create($opt); $file_get=false; if($file_get){ $r=file_get_contents($rev,false,$context); echo $r; }else{ $r=fopen($rev,'r',false,$context); while(!feof($r)){ echo fread($r,1024); } fclose($r); }
结果
Array ( [a] => ajax [b] => 22 ) tt
要特别注意\r\n必须用双引号
fsockopen模拟
<?php $rev='http://localhost/web/http/rev.php'; $data=['a'=>'ajax','b'=>22]; $post_data=http_build_query($data); $fp=fsockopen("localhost",80,$errno,$errStr,5); if($errno){ echo $errStr; }else{ $request="POST {$rev} HTTP/1.1\r\n"; $request.="host:localhost\r\n"; $request.="test:tt\r\n"; $request.="content-type:application/x-www-form-urlencoded\r\n"; $request.="content-length:".strlen($post_data)."\r\n\r\n"; $request.=$post_data; if(false!==fwrite($fp,$request)){ while(!feof($fp)){ echo fgets($fp,1024); } fclose($fp); }else{ echo 'fwrite error'; } }
结果
HTTP/1.1 200 OK Date: Thu, 22 Mar 2018 14:44:17 GMT Server: Apache/2.4.23 (Win64) PHP/5.6.25 X-Powered-By: PHP/5.6.25 Content-Length: 47 Content-Type: text/html; charset=UTF-8 Array ( [a] => ajax [b] => 22 ) tt