Php HTML净化器拦截请求
HTML净化器或CSRF Magic之类的东西实际上是如何拦截HTTP请求的?它的文档说它基于Python的Django中间件框架的思想,但我还没有找到一些关于它如何拦截HTTP请求的文档。它不需要安装任何PHP扩展就可以工作 有人能解释一下这个问题吗 关于如果没有笑话,“拦截”http请求并发送响应是任何web应用程序都应该做的事情。Php HTML净化器拦截请求,php,Php,HTML净化器或CSRF Magic之类的东西实际上是如何拦截HTTP请求的?它的文档说它基于Python的Django中间件框架的思想,但我还没有找到一些关于它如何拦截HTTP请求的文档。它不需要安装任何PHP扩展就可以工作 有人能解释一下这个问题吗 关于如果没有笑话,“拦截”http请求并发送响应是任何web应用程序都应该做的事情。 而且您不需要任何扩展,因为PHP完全是为创建web应用程序而设计的工具。 要读取HTTP请求的数据,请使用数组$\u GET、$\u POST、$\u SERV
而且您不需要任何扩展,因为PHP完全是为创建web应用程序而设计的工具。
要读取HTTP请求的数据,请使用数组$\u GET、$\u POST、$\u SERVER(和
php://input
有时),要发送响应,您只需回显“那是我的响应!”代码>
我甚至可以给你们两个我的类来处理请求和响应,希望它会有用(或者只是有趣,至少):
csrfmagic使用PHP函数。它捕获脚本的输出,对其进行修改,并使用一个特殊的处理函数来修改打印前捕获的输出。因此,真正的魔力在于ob\u start
。如果你感兴趣,请仔细阅读。另外,由于CSRF Magic是一个开源项目,您可以
这最终归结为:
这一行表示,如果条件为真(通常为真),则启动输出缓冲区(
ob\u start
),并在输出完成时对该输出运行csrf\u ob\u handler
)csrf\u ob\u handler
修改脚本的原始输出以添加隐藏的输入,然后打印结果。这可能是一个以标准方式处理请求的框架,但问题似乎是,如何简单地require
在发送前自动重写脚本顶部的CSRF魔术脚本的输出。@Matchu您所说的是响应,而不是请求。您所说的是与问题完全无关的内容o.o让我看看是否可以简化它:“像CSRF Magic这样的脚本如何拦截我的请求,而我所做的只是将其包含在顶部?”这些类的有用性似乎与我们正在讨论的更具体的案例无关。不是“我应该如何拦截请求?”而是“它们如何拦截请求?”?“@Matchu他们读了$\u GET和$\u POST。在你的回答中,你指的是回应,而不是请求。如果这是OP的要求-好。@OZ_uu您能详细说明如何使用您提供的请求和响应的2个代码吗?它们看起来很有趣,但我中途迷路了。$GLOBALS['csrf']['rewrite']
不管怎样,这是xP行
<?php
namespace Jamm\HTTP;
class Request
{
protected $method;
protected $headers;
protected $data;
protected $accept;
const method_GET = 'GET';
const method_POST = 'POST';
const method_PUT = 'PUT';
const method_DELETE = 'DELETE';
/**
* @param bool $parse - parse current input to object's variables (input request)
* @return \Jamm\HTTP\Request
*
*/
public function __construct($parse = false)
{
$this->method = self::method_GET;
if ($parse) $this->BuildFromInput();
$this->setHeader('Content-type', 'text/plain');
}
public function BuildFromInput()
{
$this->headers = $_SERVER;
$this->accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '';
$this->method = $_SERVER['REQUEST_METHOD'];
switch ($this->method)
{
case 'HEAD':
case 'GET':
$this->data = $_GET;
break;
case 'POST':
$this->data = $_POST;
break;
default:
parse_str(file_get_contents('php://input'), $this->data);
}
}
/**
* Return header from array by key, or all keys
* @param string $key
* @return null|array|mixed
*/
public function getHeaders($key = null)
{
if (!empty($key))
{
return isset($this->headers[$key]) ? $this->headers[$key] : NULL;
}
else return $this->headers;
}
/**
* Get type of request method
* @return string
*/
public function getMethod()
{
return $this->method;
}
/**
* Return key or all the keys of request
* @param string $key
* @return null|array|string|numeric
*/
public function getData($key = null)
{
if (empty($key)) return $this->data;
else
{
return isset($this->data[$key]) ? $this->data[$key] : NULL;
}
}
/**
* Return HTTP_ACCEPT header
* @return string
*/
public function getAccept()
{
return $this->accept;
}
/**
* Check, if this type is acceptable
* @param string $type
* @return bool
*/
public function isAcceptable($type)
{
if (empty($type) || (stripos($this->getAccept(), $type)!==false)) return true;
return false;
}
public function setHeader($header, $value)
{
$this->headers[$header] = $value;
}
/**
* Set the request method
* @param $method
* @return void
*/
public function setMethod($method)
{
$this->method = strtoupper($method);
if ($this->method!=self::method_GET) $this->setHeader('Content-type', 'application/x-www-form-urlencoded');
}
public function setDataKey($key, $value)
{
$this->data[$key] = $value;
}
public function SetAccept($accept)
{
$this->accept = $accept;
}
/**
* Send request by URL. Pass $Response argument, if you need response
* @param $URL
* @param IResponse|null $Response
* @return bool|IResponse
*/
public function Send($URL, IResponse $Response = NULL)
{
$url_data = parse_url($URL);
$fp = fsockopen($url_data['host'], 80);
if (!$fp) return false;
$path = (isset($url_data['path']) ? $url_data['path'] : '/').
(isset($url_data['query']) ? '?'.$url_data['query'] : '');
$data = $this->getData();
if (!empty($data) && is_array($data)) $data = http_build_query($data);
if ($this->method==self::method_GET)
{
fwrite($fp, $this->method." $path?$data HTTP/1.0\r\n");
}
else
{
fwrite($fp, $this->method." $path HTTP/1.0\r\n");
fwrite($fp, "Content-Length: ".strlen($data)."\r\n");
}
fwrite($fp, "Host: {$url_data['host']}\r\n");
foreach ($this->getHeaders() as $header_name => $header_value)
{
fwrite($fp, "$header_name: $header_value\r\n");
}
fwrite($fp, "Connection: Close\r\n\r\n");
if ($this->method!=self::method_GET)
{
fwrite($fp, $data);
}
if (!empty($Response)) return $this->ReadResponse($fp, $Response);
else return true;
}
/**
* @param \resource $fresource
* @param IResponse $response
* @return IResponse
*/
protected function ReadResponse($fresource, IResponse $response)
{
//read headers
$status_header = '';
$headers = array();
while (!feof($fresource))
{
$header = trim(fgets($fresource));
if (!empty($header))
{
if (empty($status_header)) $status_header = $header;
if (strpos($header, ':')!==false)
{
$header = explode(':', $header);
$headers[trim($header[0])] = trim($header[1]);
}
else $headers[] = $header;
}
else break;
}
$response->setHeaders($headers);
if (!empty($status_header))
{
$status_header = explode(' ', $status_header);
$response->setStatusCode(intval(trim($status_header[1])));
}
//read body
$body = '';
while (!feof($fresource)) $body .= fread($fresource, 4096);
fclose($fresource);
if (!empty($body)) $response->setBody($body);
return $response;
}
/**
* Set array of data
* @param array $values
*/
public function setData(array $values)
{
$this->data = $values;
}
}
<?php
namespace Jamm\HTTP;
class Response implements IResponse
{
protected $status_code;
protected $body;
protected $headers;
protected $serialize_method;
const serialize_JSON = 'JSON';
const serialize_XML = 'XML';
const serialize_PHP = 'PHP';
const header_Serialized = 'API-Serialized';
public function __construct($body = '', $status_code = 200)
{
$this->body = $body;
$this->status_code = $status_code;
$this->serialize_method = self::serialize_JSON;
}
public function getStatusCode()
{
return $this->status_code;
}
/** @param int $status_code */
public function setStatusCode($status_code)
{
$this->status_code = (int)$status_code;
}
/**
* Set header for the response
* @param string $header
* @param string|numeric $value
*/
public function setHeader($header, $value)
{
$this->headers[$header] = $value;
if ($header==='Location' && $this->status_code==200) $this->setStatusCode(301);
}
public function getHeader($header)
{
return isset($this->headers[$header]) ? $this->headers[$header] : NULL;
}
/**
* Get body of the response
* @return string
*/
public function getBody()
{
return $this->body;
}
/**
* Get Result of response - unpack value of body and headers
* @return bool|mixed
*/
public function getResult()
{
if ($this->getStatusCode() >= 400) return false;
if (($serialization_method = $this->getHeader(self::header_Serialized)))
{
$this->serialize_method = $serialization_method;
return $this->unserialize($this->body);
}
else return $this->body;
}
/**
* Set body of the response
* @param $body
*/
public function setBody($body)
{
if (!is_scalar($body))
{
$this->body = $this->serialize($body);
$this->setHeader(self::header_Serialized, $this->serialize_method);
}
else $this->body = $body;
}
public function getHeaders()
{
return $this->headers;
}
public function setHeaders(array $headers)
{
$this->headers = $headers;
}
public function serialize($content)
{
switch ($this->serialize_method)
{
case self::serialize_JSON:
return json_encode($content);
default:
return serialize($content);
}
}
public function unserialize($content)
{
switch ($this->serialize_method)
{
case self::serialize_JSON:
return json_decode($content, true);
default:
return unserialize($content);
}
}
/**
* Send headers and body to output
*/
public function Send()
{
$headers = $this->getHeaders();
if (!empty($headers))
{
foreach ($headers as $header_key => $header_value)
{
header($header_key.': '.$header_value, true, $this->status_code);
}
}
print $this->body;
}
}
if ($GLOBALS['csrf']['rewrite']) ob_start('csrf_ob_handler');