1 Star 0 Fork 0

xiaoluoji/dns-ui

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Pest.php 15.95 KB
一键复制 编辑 原始数据 按行查看 历史
Thomas Pike 提交于 2017-01-21 00:13 +08:00 . Initial public commit
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
<?php
/**
* Pest is a REST client for PHP.
*
* See http://github.com/educoder/pest for details.
*
* This code is licensed for use, modification, and distribution
* under the terms of the MIT License (see http://en.wikipedia.org/wiki/MIT_License)
*/
class Pest
{
/**
* @var array Default CURL options
*/
public $curl_opts = array(
CURLOPT_RETURNTRANSFER => true, // return result instead of echoing
CURLOPT_SSL_VERIFYPEER => false, // stop cURL from verifying the peer's certificate
CURLOPT_FOLLOWLOCATION => false, // follow redirects, Location: headers
CURLOPT_MAXREDIRS => 10, // but dont redirect more than 10 times
CURLOPT_HTTPHEADER => array()
);
/**
* @var string Base URL
*/
public $base_url;
/**
* @var array Last response
*/
public $last_response;
/**
* @var array Last request
*/
public $last_request;
/**
* @var array Last headers
*/
public $last_headers;
/**
* @var bool Throw exceptions on HTTP error codes
*/
public $throw_exceptions = true;
/**
* Class constructor
* @param string $base_url
* @throws Exception
*/
public function __construct($base_url)
{
if (!function_exists('curl_init')) {
throw new Exception('CURL module not available! Pest requires CURL. See http://php.net/manual/en/book.curl.php');
}
/*
* Only enable CURLOPT_FOLLOWLOCATION if safe_mode and open_base_dir are
* not in use
*/
if (ini_get('open_basedir') == '' && strtolower(ini_get('safe_mode')) == 'off') {
$this->curl_opts['CURLOPT_FOLLOWLOCATION'] = true;
}
$this->base_url = $base_url;
// The callback to handle return headers
// Using PHP 5.2, it cannot be initialised in the static context
$this->curl_opts[CURLOPT_HEADERFUNCTION] = array($this, 'handle_header');
}
/**
* Setup authentication
*
* @param string $user
* @param string $pass
* @param string $auth Can be 'basic' or 'digest'
*/
public function setupAuth($user, $pass, $auth = 'basic')
{
$this->curl_opts[CURLOPT_HTTPAUTH] = constant('CURLAUTH_' . strtoupper($auth));
$this->curl_opts[CURLOPT_USERPWD] = $user . ":" . $pass;
}
/**
* Set cookies for this session
* @param array $cookies
*
* @see http://curl.haxx.se/docs/manpage.html
* @see http://www.nczonline.net/blog/2009/05/05/http-cookies-explained/
*/
public function setupCookies($cookies)
{
if (empty($cookies)) {
return;
}
$cookie_list = array();
foreach ($cookies as $cookie_name => $cookie_value)
{
$cookie = urlencode($cookie_name);
if (isset($cookie_value))
{
$cookie .= '=';
$cookie .= urlencode($cookie_value);
}
$cookie_list[] = $cookie;
}
$this->curl_opts[CURLOPT_COOKIE] = implode(';', $cookie_list);
}
/**
* Setup proxy
* @param string $host
* @param int $port
* @param string $user Optional.
* @param string $pass Optional.
*/
public function setupProxy($host, $port, $user = NULL, $pass = NULL)
{
$this->curl_opts[CURLOPT_PROXYTYPE] = 'HTTP';
$this->curl_opts[CURLOPT_PROXY] = $host;
$this->curl_opts[CURLOPT_PROXYPORT] = $port;
if ($user && $pass) {
$this->curl_opts[CURLOPT_PROXYUSERPWD] = $user . ":" . $pass;
}
}
/**
* Perform HTTP GET request
*
* @param string $url
* @param array $data
* @param array $headers
* @return string
*/
public function get($url, $data = array(), $headers=array())
{
if (!empty($data)) {
$pos = strpos($url, '?');
if ($pos !== false) {
$url = substr($url, 0, $pos);
}
$url .= '?' . http_build_query($data);
}
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl = $this->prepRequest($curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Prepare request
*
* @param array $opts
* @param string $url
* @return resource
* @throws Pest_Curl_Init
*/
protected function prepRequest($opts, $url)
{
if (strncmp($url, $this->base_url, strlen($this->base_url)) != 0) {
$url = rtrim($this->base_url, '/') . '/' . ltrim($url, '/');
}
$curl = curl_init($url);
if ($curl === false) {
throw new Pest_Curl_Init($this->processError(curl_error($curl), 'curl'), curl_errno($curl));
}
foreach ($opts as $opt => $val)
curl_setopt($curl, $opt, $val);
$this->last_request = array(
'url' => $url
);
if (isset($opts[CURLOPT_CUSTOMREQUEST]))
$this->last_request['method'] = $opts[CURLOPT_CUSTOMREQUEST];
else
$this->last_request['method'] = 'GET';
if (isset($opts[CURLOPT_POSTFIELDS]))
$this->last_request['data'] = $opts[CURLOPT_POSTFIELDS];
return $curl;
}
/**
* Determines if a given array is numerically indexed or not
*
* @param array $array
* @return boolean
*/
protected function _isNumericallyIndexedArray($array)
{
return !(bool)count(array_filter(array_keys($array), 'is_string'));
}
/**
* Flatten headers from an associative array to a numerically indexed array of "Name: Value"
* style entries like CURLOPT_HTTPHEADER expects. Numerically indexed arrays are not modified.
*
* @param array $headers
* @return array
*/
protected function prepHeaders($headers)
{
if ($this->_isNumericallyIndexedArray($headers)) {
return $headers;
}
$flattened = array();
foreach ($headers as $name => $value) {
$flattened[] = $name . ': ' . $value;
}
return $flattened;
}
/**
* Process error
* @param string $body
* @return string
*/
protected function processError($body)
{
// Override this in classes that extend Pest.
// The body of every erroneous (non-2xx/3xx) GET/POST/PUT/DELETE
// response goes through here prior to being used as the 'message'
// of the resulting Pest_Exception
return $body;
}
/**
* Do CURL request
* @param resource $curl
* @return mixed
* @throws Pest_Curl_Exec
* @throws Pest_Curl_Meta
*/
private function doRequest($curl)
{
$this->last_headers = array();
$this->last_response = array();
// curl_error() needs to be tested right after function failure
$this->last_response["body"] = curl_exec($curl);
if ($this->last_response["body"] === false && $this->throw_exceptions) {
throw new Pest_Curl_Exec(curl_error($curl), curl_errno($curl));
}
$this->last_response["meta"] = curl_getinfo($curl);
if ($this->last_response["meta"] === false && $this->throw_exceptions) {
throw new Pest_Curl_Meta(curl_error($curl), curl_errno($curl));
}
curl_close($curl);
$this->checkLastResponseForError();
return $this->last_response["body"];
}
/**
* Check last response for error
*
* @throws Pest_Conflict
* @throws Pest_Gone
* @throws Pest_Unauthorized
* @throws Pest_ClientError
* @throws Pest_MethodNotAllowed
* @throws Pest_NotFound
* @throws Pest_BadRequest
* @throws Pest_UnknownResponse
* @throws Pest_InvalidRecord
* @throws Pest_ServerError
* @throws Pest_Forbidden
*/
protected function checkLastResponseForError()
{
if (!$this->throw_exceptions)
return;
$meta = $this->last_response['meta'];
$body = $this->last_response['body'];
if ($meta === false)
return;
$err = null;
switch ($meta['http_code']) {
case 400:
throw new Pest_BadRequest($this->processError($body));
break;
case 401:
throw new Pest_Unauthorized($this->processError($body));
break;
case 403:
throw new Pest_Forbidden($this->processError($body));
break;
case 404:
throw new Pest_NotFound($this->processError($body));
break;
case 405:
throw new Pest_MethodNotAllowed($this->processError($body));
break;
case 409:
throw new Pest_Conflict($this->processError($body));
break;
case 410:
throw new Pest_Gone($this->processError($body));
break;
case 422:
// Unprocessable Entity -- see http://www.iana.org/assignments/http-status-codes
// This is now commonly used (in Rails, at least) to indicate
// a response to a request that is syntactically correct,
// but semantically invalid (for example, when trying to
// create a resource with some required fields missing)
throw new Pest_InvalidRecord($this->processError($body));
break;
default:
if ($meta['http_code'] >= 400 && $meta['http_code'] <= 499)
throw new Pest_ClientError($this->processError($body));
elseif ($meta['http_code'] >= 500 && $meta['http_code'] <= 599)
throw new Pest_ServerError($this->processError($body)); elseif (!isset($meta['http_code']) || $meta['http_code'] >= 600) {
throw new Pest_UnknownResponse($this->processError($body));
}
}
}
/**
* Process body
* @param string $body
* @return string
*/
protected function processBody($body)
{
// Override this in classes that extend Pest.
// The body of every GET/POST/PUT/DELETE response goes through
// here prior to being returned.
return $body;
}
/**
* Perform HTTP HEAD request
* @param string $url
* @return string
*/
public function head($url, $headers = array())
{
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_NOBODY] = true;
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl = $this->prepRequest($this->curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Perform HTTP POST request
*
* @param string $url
* @param array $data
* @param array $headers
* @return string
*/
public function post($url, $data, $headers = array())
{
$data = $this->prepData($data);
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_CUSTOMREQUEST] = 'POST';
if (!is_array($data)) $headers[] = 'Content-Length: ' . strlen($data);
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl_opts[CURLOPT_POSTFIELDS] = $data;
$curl = $this->prepRequest($curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Prepare data
* @param array $data
* @return array|string
*/
public function prepData($data)
{
if (is_array($data)) {
$multipart = false;
foreach ($data as $item) {
if (is_string($item) && strncmp($item, "@", 1) == 0 && is_file(substr($item, 1))) {
$multipart = true;
break;
}
}
return ($multipart) ? $data : http_build_query($data);
} else {
return $data;
}
}
/**
* Perform HTTP PUT request
*
* @param string $url
* @param array $data
* @param array $headers
* @return string
*/
public function put($url, $data, $headers = array())
{
$data = $this->prepData($data);
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_CUSTOMREQUEST] = 'PUT';
if (!is_array($data)) $headers[] = 'Content-Length: ' . strlen($data);
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl_opts[CURLOPT_POSTFIELDS] = $data;
$curl = $this->prepRequest($curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Perform HTTP PATCH request
*
* @param string $url
* @param array $data
* @param array $headers
* @return string
*/
public function patch($url, $data, $headers = array())
{
$data = (is_array($data)) ? http_build_query($data) : $data;
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_CUSTOMREQUEST] = 'PATCH';
$headers[] = 'Content-Length: ' . strlen($data);
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl_opts[CURLOPT_POSTFIELDS] = $data;
$curl = $this->prepRequest($curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Perform HTTP DELETE request
*
* @param string $url
* @param array $headers
* @return string
*/
public function delete($url, $headers=array())
{
$curl_opts = $this->curl_opts;
$curl_opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
$curl_opts[CURLOPT_HTTPHEADER] = $this->prepHeaders($headers);
$curl = $this->prepRequest($curl_opts, $url);
$body = $this->doRequest($curl);
$body = $this->processBody($body);
return $body;
}
/**
* Get last response body
*
* @return string
*/
public function lastBody()
{
return $this->last_response['body'];
}
/**
* Get last response status
*
* @return int
*/
public function lastStatus()
{
return $this->last_response['meta']['http_code'];
}
/**
* Return the last response header (case insensitive) or NULL if not present.
* HTTP allows empty headers (e.g. RFC 2616, Section 14.23), thus is_null()
* and not negation or empty() should be used.
*
* @param string $header
* @return string
*/
public function lastHeader($header)
{
if (empty($this->last_headers[strtolower($header)])) {
return NULL;
}
return $this->last_headers[strtolower($header)];
}
/**
* Handle header
* @param $ch
* @param $str
* @return int
*/
private function handle_header($ch, $str)
{
if (preg_match('/([^:]+):\s(.+)/m', $str, $match)) {
$this->last_headers[strtolower($match[1])] = trim($match[2]);
}
return strlen($str);
}
}
class Pest_Exception extends Exception
{}
class Pest_UnknownResponse extends Pest_Exception
{}
// HTTP Errors
/* 401-499 */
class Pest_ClientError extends Pest_Exception
{}
/* 400 */
class Pest_BadRequest extends Pest_ClientError
{}
/* 401 */
class Pest_Unauthorized extends Pest_ClientError
{}
/* 403 */
class Pest_Forbidden extends Pest_ClientError
{}
/* 404 */
class Pest_NotFound extends Pest_ClientError
{}
/* 405 */
class Pest_MethodNotAllowed extends Pest_ClientError
{}
/* 409 */
class Pest_Conflict extends Pest_ClientError
{}
/* 410 */
class Pest_Gone extends Pest_ClientError
{}
/* 422 */
class Pest_InvalidRecord extends Pest_ClientError
{}
/* 500-599 */
class Pest_ServerError extends Pest_ClientError
{}
// CURL Errors
/* init */
class Pest_Curl_Init extends Pest_Exception
{}
/* meta */
class Pest_Curl_Meta extends Pest_Exception
{}
/* exec */
class Pest_Curl_Exec extends Pest_Exception
{}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
PHP
1
https://gitee.com/xiaoluoji/dns-ui.git
git@gitee.com:xiaoluoji/dns-ui.git
xiaoluoji
dns-ui
dns-ui
master

搜索帮助