1 Star 0 Fork 2

whale/cnblogs-sdk

forked from hydrid/cnblogs-sdk 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
httpclient.php 19.26 KB
一键复制 编辑 原始数据 按行查看 历史
dlj 提交于 2017-02-25 20:39 +08:00 . cnblogs登陆授权SDK封装
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
<?php
/**
* HttpClient
*
* Http client for HTTP protocol v 1.0 & 1.1
* ---
* @author Ricardo Gamba <rgamba@gmail.com>
* @license GNU MIT
* @version 1.0
*/
class HttpClient{
const CRLF = "\r\n";
private $request_std_headers=array(
'Accept',
'Accept-Charset',
'Accept-Encoding',
'Accept-Language',
'Authorization',
'Expect',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Max-Forwards',
'Proxy-Authorization',
'Range',
'Referer',
'TE',
'User-Agent'
);
private $response_std_headers=array(
'Accept-Ranges',
'Age',
'Cache-Control',
'Connection',
'Date',
'ETag',
'Location',
'Proxy-Authenticate',
'Retry-After',
'Server',
'Transfer-Encoding',
'Vary',
'WWW-Authenticate'
);
private $entity_headers=array(
'Allow',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-MD5',
'Content-Range',
'Content-Type',
'Expires',
'Last-Modified'
);
private $protocol_version="1.1";
private $socket;
private $method;
private $status_code;
private $status_msg;
private $request_headers=array();
private $response_headers=array();
private $raw_request;
private $raw_response;
private $request_body;
private $response_body;
private $sys_err=array('no'=>NULL,'msg'=>NULL);
private $follow_redirects=false;
private $max_redirects=5;
private $cur_redirects=0;
private $auth_user;
private $auth_pass;
private $auth_login=false;
private $auth_type="basic";
private $auth_nonce_count=1;
private $www_auth=array();
private $cookies=array();
private $accept_cookies=true;
private $log="";
public $scheme;
public $url;
public $uri;
public $query;
public $host;
public $port=80;
public $user_agent="PHPHttpClient/1.0";
/**
* Constructor
*
* @param mixed $url "http://www.example.com[:80][/path/[index.php[?var=val&var2=val2]]]"
*/
public function __construct($url=NULL){
if($url==NULL)
return;
$this->parseUrl($url);
}
/**
* Add header to the request
*
* @param mixed $name
* @param mixed $val
*/
public function setHeader($name=NULL,$val=NULL){
if(empty($name))
return false;
$this->request_headers[str_replace(' ','-',ucwords(str_replace('-',' ',$name)))]=$val;
}
/**
* Set the body of the request
*
* @param mixed $content
*/
public function setBody($content=NULL){
if($content==NULL)
return false;
$this->request_body=$content;
}
/**
* Send HTTP Head command
*
* @param mixed $uri
* @param string $vars status number
*/
public function head($uri=NULL,$vars=NULL){
if(!empty($uri)) $this->uri=$uri;
if(!empty($vars) && is_array($vars))
$vars=http_build_query($vars);
if(empty($this->query))
$this->query=$vars;
else
if(!empty($vars))
$this->query.="&".$vars;
if(!empty($this->query))
$this->uri.="?".$this->query;
$this->method="HEAD";
$this->request_body=NULL;
$this->send();
}
/**
* Send HTTP Delete command
*
* @param mixed $uri
* @param string $vars
* @return string Status number
*/
public function delete($uri=NULL,$vars=NULL){
if(!empty($uri)) $this->uri=$uri;
if(!empty($vars) && is_array($vars))
$vars=http_build_query($vars);
if(empty($this->query))
$this->query=$vars;
else
if(!empty($vars))
$this->query.="&".$vars;
if(!empty($this->query))
$this->uri.="?".$this->query;
$this->method="DELETE";
$this->request_body=NULL;
$this->send();
return $this->status_code;
}
/**
* Send HTTP Trace command
*
* @param mixed $uri
* @param string $vars
* @return string status number
*/
public function trace($uri=NULL,$vars=NULL){
if(!empty($uri)) $this->uri=$uri;
if(!empty($vars) && is_array($vars))
$vars=http_build_query($vars);
if(empty($this->query))
$this->query=$vars;
else
if(!empty($vars))
$this->query.="&".$vars;
if(!empty($this->query))
$this->uri.="?".$this->query;
$this->method="TRACE";
$this->request_body=NULL;
foreach($this->request_headers as $k => $v){
if(in_array($k,$this->entity_headers))
unset($this->request_headers[$k]);
}
$this->send();
return $this->status_code;
}
/**
* Execute HTTP Get command
*
* @param mixed $uri
* @param string $vars
* @return string status
*/
public function get($uri=NULL,$vars=NULL){
if(!empty($uri)) $this->uri=$uri;
if(!empty($vars) && is_array($vars))
$vars=http_build_query($vars);
if(empty($this->query))
$this->query=$vars;
else
if(!empty($vars))
$this->query.="&".$vars;
if(!empty($this->query))
$this->uri.="?".$this->query;
$this->method="GET";
$this->request_body=NULL;
$this->send();
return $this->status_code;
}
/**
* Send HTTP Post command
*
* @param mixed $uri
* @param string $content
* @return string status code
*/
public function post($uri=NULL,$content=NULL,$files=NULL){
if(!empty($uri)) $this->uri=$uri;
if(is_array($content) && empty($files)){
$content=http_build_query($content,"","&");
$this->setHeader('Content-Type','application/x-www-form-urlencoded');
}
if(!empty($files) && is_array($files)){
$boundary=uniqid('---------------------------');
$this->setHeader('Content-Type','multipart/form-data; boundary='.$boundary);
if(!empty($this->content) && is_array($this->content)){
foreach($this->content as $k => $v){
$cont.=$boundary.self::CRLF.'Content-Disposition: form-data; name="'.$k.'"'.self::CRLF.self::CRLF.$v.self::CRLF;
}
}
foreach($files as $i => $file){
$cont.=$boundary.self::CRLF.'Content-Disposition: form-data; name="'.$file['name'].'"; filename="'.$file['filename'].'"'.self::CRLF;
$cont.="Content-Type: ".(empty($file['content-type']) ? 'application/octet-stream' : $file['content-type']).self::CRLF.self::CRLF;
$cont.=$file['data'].self::CRLF;
}
$content=$cont;
}
$this->request_body=$content;
$this->method="POST";
$this->send();
return $this->status_code;
}
/**
* Send HTTP Put command
*
* @param string $content
* @return string
*/
public function put($content=NULL){
if(is_array($content)){
$content=http_build_query($content);
$this->setHeader('Content-Type','application/x-www-form-urlencoded');
}
$this->request_body=$content.self::CRLF.self::CRLF;
$this->method="PUT";
$this->send();
return $this->status_code;
}
/**
* Get a specific response header
*
* @param mixed $key
* @return mixed
*/
public function getHeader($key){
return $this->response_headers[$key];
}
/**
* Get the response body
*
*/
public function getBody(){
return $this->response_body;
}
/**
* Get the response headers, associative array
*
* @return array
*/
public function getHeaders(){
return $this->response_headers;
}
/**
* Retrieve the HTTP raw request command
*
* @return string
*/
public function rawRequest(){
return $this->raw_request;
}
/**
* Retrieve the HTTP raw response command
*
* @return string
*/
public function rawResponse(){
return $this->raw_response;
}
/**
* Get the request status
*
* @return object ('number' => 'status number', 'msg' => 'status message')
*/
public function status(){
$obj->number=$this->status_code;
$obj->msg=$this->status_msg;
return $obj;
}
public function statusOk(){
return $this->status()->number=="200";
}
/**
* Set wether the client should follow the server redirects or not
*
* @param boolean $b
* @param integer $n max number of redirects allowed
*/
public function followRedirects($b,$n=NULL){
$this->follow_redirects=$b==true;
if(!is_null($n) && is_numeric($n))
$this->max_redirects=(integer)$n;
}
/**
* Set the maximum number of redirects allowed
*
* @param integer $n
*/
public function maxRedirects($n){
$this->max_redirects=$n;
}
/**
* Set credentials for BASIC authentication
*
* @param mixed $usr
* @param mixed $pass
*/
public function basicAuth($usr,$pass){
$this->auth_type="basic";
$this->auth_login=true;
$this->auth_user=$usr;
$this->auth_pass=$pass;
}
/**
* Set credentials for DIGEST authentication
*
* @param mixed $usr
* @param mixed $pass
*/
public function digestAuth($usr,$pass=NULL){
$this->auth_type="digest";
$this->auth_login=true;
$this->auth_user=$usr;
$this->auth_pass=$pass;
}
/**
* Close the socket connection
*
*/
public function disconnect(){
@fclose($this->socket);
}
/**
* Delete all cookies from specified host
*
* @param mixed $host
*/
public function eraseCookies($host=NULL){
if(empty($host))
$host=$this->host;
unset($this->cookies[$host]);
}
/**
* Accept or deny cookies
*
* @param mixed $allow
*/
public function acceptCookies($allow=true){
$this->accept_cookies=($allow==true);
}
/**
* Obtain the complete log of communication, requests,
* responses and all redirects
*
*/
public function getLogHistory(){
return $this->log;
}
private function parseUrl($url){
$this->url=$url;
$u=@parse_url($url);
$this->scheme=$u['scheme'];
$this->host=$u['host'];
$this->uri=$u['path'];
if(!empty($u['port']))
$this->port=$u['port'];
$this->query=$u['query'];
}
private function connect(){
if(empty($this->url)){
throw new Exception("Empty URL");
return false;
}
$this->socket=fsockopen(($this->scheme=="https" ? 'ssl://' : '').$this->host,($this->scheme=="https" ? 443 : $this->port),$this->sys_err['no'],$this->sys_err['msg'],10);
if(!$this->socket){
throw new Exception("Error while trying to connect to the host: ".$this->sys_err['msg']);
return false;
}
return true;
}
private function send(){
$this->clearBuffer();
$this->raw_request=$this->method." ".(empty($this->uri) ? "/" : $this->uri)." HTTP/".$this->protocol_version.self::CRLF;
$this->raw_request.="Host: ".$this->host.self::CRLF;
if(!empty($this->request_body))
$this->raw_request.="Content-Length: ".strlen($this->request_body).self::CRLF;
else
unset($this->request_headers['Content-Length']);
unset($this->request_headers['User-Agent']);
$this->setHeader('User-Agent',$this->user_agent);
if(empty($this->request_headers['Accept']))
$this->setHeader('Accept','*/*');
if($this->auth_login!=false){
$this->setCredentials();
}
if(empty($this->request_headers['Connection']))
$this->setHeader('Connection','close');
$this->addCookieHeaders();
if(!empty($this->request_headers)){
foreach($this->request_headers as $name => $val)
$this->raw_request.=$name.": ".$val.self::CRLF;
}
$this->raw_request.=self::CRLF;
if(!empty($this->request_body))
$this->raw_request.=$this->request_body.self::CRLF.self::CRLF;
$this->logHistory($this->raw_request);
if(!$this->socket){
try{
$this->connect();
}catch(Exception $e){
throw new Exception($e->getMessage());
}
}
fwrite($this->socket,$this->raw_request);
if(!$this->parseResponse())
throw new Exception("Unknown response protocol");
}
private function setCredentials(){
if($this->auth_type=="basic"){
$this->setHeader('Authorization','Basic '.base64_encode($this->auth_user.":".$this->auth_pass));
}else{
if(!empty($this->www_auth)){
$ha1=md5($this->auth_user.$this->www_auth['realm'].$this->auth_pass);
$ha2=md5($this->method.":".$this->uri);
$cnonce=uniqid('000');
if($this->www_auth['qop']=="auth,auth-int" || $this->www_auth['qop']=="auth" || $this->www_auth['qop']=="auth-int"){
$response=md5($ha1.":".sprintf("%08d",$this->auth_nonce_count).":".$cnonce.":".$this->www_auth['qop'].":".$ha2);
}else{
$response=md5($ha1.":".$this->www_auth['nonce'].$ha2);
}
$digest=array(
'username' => '"'.$this->auth_user.'"',
'realm' => '"'.$this->www_auth['realm'].'"',
'nonce' => '"'.$this->www_auth['nonce'].'"',
'uri' => '"'.$this->uri.'"',
'qop' => 'auth',
'nc' => sprintf("%08d",$this->auth_nonce_count),
'cnonce' => '"'.$cnonce.'"',
'response' => '"'.$response.'"',
'opaque' => '"'.$this->www_auth['opaque'].'"'
);
$digest="Digest ".implode(',',$digest);
$this->setHeader('Authorization',$digest);
$this->auth_nonce_count++;
}
}
}
private function parseResponse(){
if(!$this->socket)
return false;
$in_head=true;
$body="";
$body_i=0;
$i=0;
$chunk_size=0;
while(!feof($this->socket)){
$line=@fgets($this->socket,4096);
$this->raw_response.=$line;
if(empty($line) || $line==self::CRLF){
$in_head=false;
continue;
}
if($i==0){
if(!$this->parseStatus($line))
return false;
$i++;
continue;
}
$i++;
if($in_head)
$this->parseHeader($line);
else{
if(strtolower($this->response_headers['Transfer-Encoding'])=="chunked"){
if(preg_match('/^[0-9a-f]+$/',trim($line))==1){
continue;
}
}
$body.=$line;
}
}
$this->logHistory($this->raw_response);
$this->response_body=$body;
$this->processHeaders();
return true;
}
private function processHeaders(){
if(empty($this->response_headers['Location']))
$this->cur_redirects=0;
foreach($this->response_headers as $k => $v){
switch($k){
case 'Location':
if($this->follow_redirects && $this->cur_redirects<=$this->max_redirects){
$this->redirect($v);
$this->cur_redirects++;
}
break;
case 'Connection':
if(strtolower($v)=="close")
$this->disconnect();
break;
case 'WWW-Authenticate':
$this->www_auth=array();
$auth_resp=explode(' ',$v,2);
if($auth_resp[0]=="Digest"){
$tokens=explode(',',$auth_resp[1]);
foreach($tokens as $token){
$t=explode('=',$token);
$this->www_auth[$t[0]]=str_replace('"','',$t[1]);
}
if(!empty($this->auth_user))
$this->redirect($this->url);
}
break;
}
}
}
private function redirect($url){
$this->clearBuffer();
$this->disconnect();
$this->parseUrl($url);
$this->connect();
try{
$this->get();
}catch(Exception $e){
die($e->getMessage());
}
}
private function parseStatus($line){
if(preg_match('/^HTTP\/(.)+/',$line)<=0)
return false;
$line=explode(" ",$line);
$this->status_code=trim($line[1]);
$this->status_msg=trim($line[2]);
return true;
}
private function parseHeader($line){
if(empty($line)) return false;
$line=explode(":",trim($line),2);
$header=trim($line[0]);
if(strtolower($header)=="set-cookie"){
$this->saveCookie(trim($line[1]));
}
$this->response_headers[$header]=trim($line[1]);
}
private function saveCookie($cookie){
if(!$this->accept_cookies)
return false;
$cookie=explode(';',$cookie);
$_cookie=array();
foreach($cookie as $c){
$c=trim($c);
list($k,$v)=explode('=',$c);
if(strtolower($k)=="secure" || strtolower($k)=="path" || strtolower($k)=="domain" || strtolower($k)=="expires"){
$_cookie['info'][strtolower($k)]=$v;
}else{
$_cookie['data'][$k]=$v;
}
}
$this->cookies[$this->host][]=$_cookie;
}
private function addCookieHeaders(){
if(empty($this->cookies[$this->host]))
return false;
$cookies=array();
foreach($this->cookies[$this->host] as $cookie){
if(isset($cookie['info']['secure']) && $this->scheme!="https")
continue;
// Path validation pending...
// Expire validation pending...
foreach($cookie['data'] as $k => $v)
$cookies[]="$k=$v";
}
$this->setHeader('Cookie',implode('; ',$cookies));
}
private function clearBuffer(){
$this->status_code="";
$this->status_msg="";
$this->raw_request=NULL;
$this->raw_response=NULL;
$this->response_body=NULL;
$this->response_headers=array();
}
private function logHistory($l){
$l.="\n----------\n";
$this->log.=$l;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/isoe/cnblogs-sdk.git
git@gitee.com:isoe/cnblogs-sdk.git
isoe
cnblogs-sdk
cnblogs-sdk
master

搜索帮助