模拟get和post请求(支持自定义header和测试CDN节点)

简介:
下面是一个模拟get或者post请求的方法支持
1.get,post方法
2.自定义参数
3.自定义header
4.返回服务器的返回内容和header
5.支持相特定的服务器请求url,适合测试cdn节点
代码如下

 

 
  1. <?php  
  2. error_reporting(0);  
  3. $user_agent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10)";  
  4.  
  5. list($rheaders,$conntent)=request_url("60.28.14.148","80","get","http://mat1.gtimg.com/www/iskin960/qqcomlogo.png",array("User-Agent"=> $user_agent),array());  
  6.  
  7. //list($rheaders,$conntent)=request_url("","","get","http://www.baidu.com/s",array("User-Agent"=>$user_agent),array("wd"=>"test"));  
  8. if($rheaders["httpstatus"]>=200&&$rheaders["httpstatus"]<=300)  
  9. {  
  10.  
  11.   //根据返回的类型,修改header  
  12.   if($rheaders['Content-Type']!="")  
  13.     header('Content-Type: '.$rheaders['Content-Type']);  
  14.     echo     $conntent;  
  15. //    foreach($rheaders as $k => $v)echo "$k: $v<br/>";  
  16. }else 
  17. {  
  18.     //若是是302,301之类跳转的话,继续取跳转的  
  19.     if($rheaders["httpstatus"]>=300&&$rheaders["httpstatus"]<=400){  
  20.             list($rheaders,$conntent)=request_url("","","get",$rheaders["Location"],array("User-Agent"=> $user_agent),array());          
  21.             if($rheaders["httpstatus"]>=200&&$rheaders["httpstatus"]<=300)  
  22.             {  
  23.              //根据返回的类型,修改header  
  24.              if($rheaders['Content-Type'])  
  25.                     header('Content-Type: '.$rheaders['Content-Type']);  
  26.                 echo     $conntent;  
  27.             }  
  28.     }  
  29.     //    foreach($rheaders as $k => $v)echo "$k: $v<br/>";  
  30. }  
  31.  
  32.  
  33.  
  34. /*  
  35.  * 模拟get,post方法向服务器请求某url的内容,返回内容和状态码  
  36.  * 参数: $ip:url所在的服务器ip或者域名,当传入为空时,ip的默认值就是$aURL里包含host(ip或者域名)  
  37.          $port:int,url所在的服务器的端口,当传入为空时,ip的默认值就是$aURL里包含端口,若是没有的话为80  
  38.          $method:get还是post,缺省为post  
  39.          $aURL:请求的url,格式为http://username:password@hostname:port/path?arg=value#anchor  
  40.          $headers:数组,需要模拟的http头部(Referer,Content-Disposition,Expires,Cookie,Pragma,User-Agent,Accept-Language等等)  
  41.                        $headers=array("Referer"=>"http://123.com","User-Agent"=>"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10)");  
  42.          $aParamsArray:数组,需要post或者get的参数  
  43.                        $aParamsArray=array("id"=>123,"name"=>"abc");  
  44.  * 返回值:数组:第一个元素为返回的http头部数组(http状态(默认为0,连接错误为-1)),第二个为返回的内容  
  45.            
  46. */ 
  47. function request_url($ip,$port,$method,$aURL,$headers,$aParamsArray)  
  48. {  
  49.     $rheaders=array();  
  50.      $rheaders["httpstatus"]=0;  
  51.     //分解URL为host,端口,和路径  
  52.     $URL=parse_url($aURL);  
  53.     if(!$port)  
  54.     {  
  55.         //缺省端口为80  
  56.         $port=($URL["port"]? $URL["port"]:80);      
  57.     }  
  58.     if(strcasecmp($method,"get")==0){  
  59.         $method="GET";  
  60.     }else{  
  61.         $method="POST";  
  62.     }  
  63.     //把post的数据放到数据段里  
  64.     foreach($aParamsArray as $key=> $value)  
  65.     {  
  66.      if($flag!=0)  
  67.      {  
  68.      $params.="&";  
  69.      $flag=1;  
  70.      }  
  71.      $params.=$key."=";  
  72.      $params.=urlencode($value);  
  73.      $flag=1;  
  74.     }  
  75.         if($method=="POST")  
  76.         {  
  77.      //获得数据段长度,放入Content-Length  
  78.      $length=strlen($params);  
  79.  
  80.          }else 
  81.          {  
  82.           $length=0;  
  83.           //把数据放到url的参数后面  
  84.           $URL["query"]=$URL["query"]."&".$params;  
  85.          }  
  86.          if($URL["query"]){  
  87.              //添加参数  
  88.              $URL["path"].="?".$URL["query"].($URL["fragment"]?"#".$URL["fragment"]:"");  
  89.          }  
  90.      //创建socket连接  
  91.      $fp=fsockopen($ip==""$URL["host"]:$ip,$port,$errno,$errstr,10);  
  92.      if(!$fp)  
  93.      {  
  94.           $rheaders["httpstatus"]=-1;  
  95.              return array($rheaders,$errstr."--->".$errno);  
  96.      }  
  97.      //去掉不多余的头部  
  98.      unset($headers['Host']);  
  99.      unset($headers['Content-Length']);  
  100.      unset($headers['Content-Type']);  
  101.      //构造post请求的头  
  102.      $header="$method ".$URL["path"]." HTTP/1.1\r\n";  
  103.      $header.="Host:".$URL["host"]."\r\n";  
  104.      foreach($headers as $k=> $v){  
  105.          $header.="$k:$v\r\n";  
  106.      }  
  107.      if(!$header["Content-Type"]){  
  108.      $header.="Content-Type:application/x-www-form-urlencoded\r\n";  
  109.           }  
  110.      $header.="Content-Length:".$length."\r\n";  
  111.      $header.="Connection:Close\r\n\r\n";  
  112.      if($method=="POST")  
  113.          {  
  114.          //添加post的字符串  
  115.          $header.=$params."\r\n";  
  116.      }  
  117. //     echo $header;  
  118.      //发送post的数据  
  119.      fputs($fp,$header);  
  120.      $inheader=1;  
  121.      $lineno=0;  
  122.      $conntent="";  
  123.  
  124.      while(!feof($fp))  
  125.      {  
  126.           if($inheader){  
  127.          $line=fgets($fp,1024);//读取header  
  128.          }else{  
  129.              if($rheaders["Content-Length"]>=0){  
  130.                  $line=fread($fp,$rheaders["Content-Length"]);//读取返回内容  
  131.              }else{  
  132.                  $line=fread($fp,1024);//读取返回内容      
  133.              }  
  134.          }  
  135.      $lineno++;  
  136.      if($inheader){  
  137.          if($lineno==1)  
  138.          {  
  139.                  //从第一行,获取返回的状态码  
  140.                  if(preg_match("/^HTTP\/1\.[1|0] (\d{3})/i",$line,$match)){  
  141.                      $rheaders["httpstatus"]=$match[1];  
  142.                  }  
  143.          }  
  144.      //解析http头部,把所有字段  
  145.          if(preg_match("/^(.*): (.*)$/i",$line,$matches)){  
  146.                         $rheaders[$matches[1]]=$matches[2];  
  147.          }  
  148.      }  
  149.      if($inheader&&($line=="\n"||$line=="\r\n")){  
  150.      $inheader=0;  
  151.      continue;  
  152.      }  
  153.      if($inheader==0)  
  154.      {  
  155.          //获得返回内容  
  156.      $conntent.=$line;  
  157.      }  
  158.      }  
  159.     fclose($fp);  
  160.     return array($rheaders,$conntent);  
  161. }  
  162. ?> 

      本文转自yifangyou 51CTO博客,原文链接:http://blog.51cto.com/yifangyou/604613,如需转载请自行联系原作者


相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
3月前
|
测试技术 Android开发 Python
探索软件测试的艺术:从基础到高级安卓应用开发中的自定义视图
【8月更文挑战第29天】在软件开发的世界中,测试是不可或缺的一环。它如同艺术一般,需要精细的技巧和深厚的知识。本文旨在通过浅显易懂的语言,引领读者从软件测试的基础出发,逐步深入到更复杂的测试策略和工具的使用,最终达到能够独立进行高效测试的水平。我们将一起探索如何通过不同的测试方法来确保软件的质量和性能,就像艺术家通过不同的色彩和笔触来完成一幅画作一样。
|
1月前
|
机器学习/深度学习 JSON 算法
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-Seg模型进行图像分割的完整流程,包括图像分割的基础知识、YOLOv5-Seg模型的特点、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。通过实例代码,指导读者从自定义数据集开始,直至模型的测试验证,适合深度学习领域的研究者和开发者参考。
327 2
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
|
1月前
|
机器学习/深度学习 JSON 算法
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
本文介绍了DeepLab V3在语义分割中的应用,包括数据集准备、模型训练、测试和评估,提供了代码和资源链接。
170 0
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
|
1月前
|
机器学习/深度学习 算法 PyTorch
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-7.0版本进行目标检测的完整流程,包括算法介绍、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。YOLOv5以其高精度、快速度和模型小尺寸在计算机视觉领域受到广泛应用。
357 0
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
|
1月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
69 4
|
1月前
|
分布式计算 Hadoop Unix
Hadoop-28 ZooKeeper集群 ZNode简介概念和测试 数据结构与监听机制 持久性节点 持久顺序节点 事务ID Watcher机制
Hadoop-28 ZooKeeper集群 ZNode简介概念和测试 数据结构与监听机制 持久性节点 持久顺序节点 事务ID Watcher机制
41 1
|
1月前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
18 0
|
4月前
|
存储 Web App开发 Java
《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)
【7月更文挑战第13天】这篇文章介绍了如何在Java中创建一个简单的自定义日志系统,以替代Log4j或logback。
294 5
|
4月前
|
XML 测试技术 数据格式
《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)
【7月更文挑战第3天】TestNG教程展示了如何自定义日志记录。首先创建一个名为`TestLog`的测试类,包含3个测试方法,其中一个故意失败以展示日志。使用`Assert.assertTrue`和`Reporter.log`来记录信息。接着创建`CustomReporter`类,继承`TestListenerAdapter`,覆盖`onTestFailure`, `onTestSkipped`, 和 `onTestSuccess`,在这些方法中自定义日志输出。
50 6
|
5月前
|
JavaScript Java 测试技术
《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)
【6月更文挑战第12天】本文介绍了如何创建一个自定义类库来解决自动化测试中的元素同步问题。作者指出,大部分错误源于元素因时间不同步而引发,为此提供了一种解决方案。在项目实践中,首先在`library`包下创建名为`MyWait`的类,包含一个方法`isElementPresent`,该方法通过循环尝试并等待指定元素出现,避免了直接使用时间等待可能导致的不准确性。之后,在测试类中调用此自定义方法,成功实现了元素同步。代码示例展示了如何在Java+Selenium自动化测试中应用这个自定义类。
58 2