Skip to content

Instantly share code, notes, and snippets.

@codedokode
Created December 23, 2016 22:22
Show Gist options
  • Save codedokode/ea0503ecb0efbc385b24f3972b774976 to your computer and use it in GitHub Desktop.
Save codedokode/ea0503ecb0efbc385b24f3972b774976 to your computer and use it in GitHub Desktop.
Простой прокси-сервер на PHP для изучения и модификации данных, передаваемых между браузером и сторонним сервером
<?php
/**
* Простой прокси-сервер на PHP для изучения и модификации данных,
* передаваемых между браузером и сторонним сервером.
*
* Запуск:
*
* указать URL сайта в $base
* php -S 127.0.0.1:9001 proxy.php
*
* После этого в браузере можно открывать http://127.0.0.1:9001/
* и все запросы пойдут через прокси на указанный в $base адрес.
*/
// Для вывода данных в консоль
$stderr = fopen('php://stderr', 'w');
$url = $_SERVER['REQUEST_URI'];
$path = parse_url($url, PHP_URL_PATH);
$query = parse_url($url, PHP_URL_QUERY);
$newPath = ltrim($path, '/');
if ($query) {
$newPath .= '?' . $query;
}
$base = 'https://someapprentice.github.io/maintaskforlayout/';
$proxyUrl = $base . $newPath;
// $context = stream_context_create();
$contents = @file_get_contents($proxyUrl /* , false, $context */);
// Получаем заголовки ответа из глобальной переменной (PHP!)
$headers = $http_response_header;
$firstLine = $headers[0];
if ($contents === false) {
fwrite($stderr, "Request failed: $proxyUrl - $firstLine\n");
header("HTTP/1.1 503 Proxy error");
die("Proxy failed to get contents at $proxyUrl");
}
fwrite($stderr, "$proxyUrl - OK: $firstLine\n");
$allowedHeaders = "!^(http/1.1|server:|content-type:|last-modified|access-control-allow-origin|Content-Length:|Accept-Ranges:|Date:|Via:|Connection:|X-|age|cache-control|vary)!i";
// Прокидываем разрешенные заголовки
foreach ($headers as $header) {
if (preg_match($allowedHeaders, $header)) {
fwrite($stderr, "+ $header\n");
header($header);
} else {
fwrite($stderr, "- $header\n");
}
}
echo $contents;
@krumkkkk
Copy link

Прекрасно "берет" и "отдает" указанную в $base страницу :) ...
Вот если бы и все ссылки тоже так-же продолжали выполняться после клика...

@Delimer
Copy link

Delimer commented Jan 17, 2020

Будет тупить, так как сначала скрипт получает весь контент, и только потом начинает его отдавать.

@codedokode
Copy link
Author

codedokode commented Feb 19, 2020

@krumkkkk

Вот если бы и все ссылки тоже так-же продолжали выполняться после клика...

Для этого придется анализировать текст передаваемой страницы и заменять в ней ссылки. Либо регулярками в простейшем случае, либо разбирать HTML код в дерево DOM и в этом дереве менять ссылки в атрибутах, а потом генерировать из него HTML.

@Delimer

Будет тупить, так как сначала скрипт получает весь контент, и только потом начинает его отдавать.

Совершенно верно. Это очень простой скрипт, не использующий асинхронность ради краткости и не умеющий параллельно обрабатывать несколько запросов. По идее, можно сделать (или найти готовое) что-то более сложное на библиотеке вроде ReactPHP.

@Delimer
Copy link

Delimer commented Feb 19, 2020

По идее, можно сделать (или найти готовое) что-то более сложное на библиотеке вроде ReactPHP.

Вот простое решение для асинхронных серверов https://github.com/walkor/Workerman
И прокси сделанный на нём https://github.com/walkor/php-http-proxy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment