好吧,matzahboy 和 VBart 已经提供了 nginx 配置摘录,它们正确地向您展示了如何将 URL 重写为 GET 变量。但为了使用它,您必须解释$_GET['q']
. 您还没有指定要遵循的规则,所以这里有一个建议。
要按此顺序进行测试:
- 根据RFC2396使用 PHP 的 Validate Filter 的有效 URL:使用 cURL 进行测试,对 HTTP 响应代码 < 400 响应 TRUE,对其他任何内容响应 FALSE。
- (host.)example.com/path (missing protocol):假设 HTTP 协议,按照 #1 进行测试。
- host.example.com(仅限主机名):与 #2 相同
- example.com(仅限域):测试为 #2,然后测试为www.example.com。
- 其他任何事情:失败。
如果这对您有意义,那么以下 index.php 可能会帮助您入门:
<?php
function http_response($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$head = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (!$head) {
return FALSE;
}
if ($httpCode < 400) {
return $url;
} else {
return FALSE;
}
}
function test_string($q) {
if (filter_var($q, FILTER_VALIDATE_URL)) {
// Matches RFC2396, so let's generate a hit.
return http_response($q);
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.)+[a-z]{2,}(:[0-9]+)?\/.+$/', $q)) {
// Matches: (host.)example.com/path
return http_response("http://" . $q);
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.){2,}[a-z]{2,}$/', $q)) {
// Matches: host.example.com
return http_response("http://" . $q . "/");
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.)+[a-z]{2,}$/', $q)) {
// Matches: example.com
$ret=http_response("http://" . $q . "/");
if ($ret === FALSE) {
return http_response("http://www." . $q . "/");
} else {
return $ret;
}
}
else {
return FALSE;
}
}
$q = $_GET['q'];
//$q = $argv[1]; // for command-line testing
$url = test_string($q);
if ($url === FALSE) {
printf("<p>The URL <strong>%s</strong> is invalid.</p>\n", $q);
} else {
printf("<p>The URL is <strong>%s</strong>.</p>\n", $url);
}
我并没有声称这是最漂亮或最安全的代码,但至少它为提供的 URL 实现了分析策略,例如:
http://example.com/https://www.example.net/foo/bar
,
http://example.com/example.org/foo/bar
或者
http://example.com/example.org
请注意,cURL 的 gopher 支持可能会被破坏,并且上面的代码不支持其他协议(不返回 HTTP 响应代码)。如果您需要支持 HTTP 和 HTTPS 以外的协议,请在您的问题中说明,我会相应地调整 PHP。
具体来说,如果您希望能够检查http://example.com/ping://host.example.net
它并不难,但它必须与 cURL 处理的位分开编码。