Last active
July 22, 2021 09:11
-
-
Save linuskmr/ccaed0b05bd7093a5cdf77ed85c8532c to your computer and use it in GitHub Desktop.
Reverse proxy in PHP for HTTP/HTTPS. This is especially useful for hobby projects where you have a simple HTTP server and it should/must be reachable via HTTPS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://stackoverflow.com/questions/39712599/redirect-all-requests-to-single-page | |
# Redirect all requests to reverse_proxy.php and append the requested path. | |
# Note: You need to activate the RewriteEngine with `a2enmod rewrite`. | |
RewriteEngine on | |
RewriteCond %{REQUEST_FILENAME} !-f | |
RewriteCond %{REQUEST_FILENAME} !-d | |
RewriteRule ^(.*)$ /reverse_proxy.php?path=$1 [NC,L,QSA] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# docker build -t php_reverse_proxy | |
# docker run -p 9999:80 -v "$PWD":/var/www/html:ro php_reverse_proxy | |
FROM php:7.2-apache | |
RUN a2enmod rewrite | |
RUN service apache2 restart |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This PHP script is a reverse proxy. This can be used, for example, to host an HTTP server accessible on the | |
// Internet on the local domain. If the local domain then has HTTPS, then one has a HTTPS version to the HTTP website | |
// now. This is especially useful for hobby projects where you have a simple HTTP server and it should/must be | |
// reachable via HTTPS. | |
// All incoming requests are directed to the index.php and this loads the corresponding URL in $base_url together with | |
// the specified path from the request and delivers this. | |
// The url with leading `/` you want to be accessible via this reverse proxy. | |
$base_url = 'https://gist.github.com/linuskmr/ccaed0b05bd7093a5cdf77ed85c8532c/'; | |
// Extract path from get parameters | |
$path = $_GET['path']; | |
// Remove path because it is only used internally | |
unset($_GET['path']); | |
$path = $base_url . $path . '?' . http_build_query($_GET); | |
// Initialize cURL | |
$ch = curl_init(); | |
// Set the URL we want to GET by using the CURLOPT_URL option | |
curl_setopt($ch, CURLOPT_URL, $path); | |
// Set CURLOPT_RETURNTRANSFER so that the content is returned as a variable | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
// Load local request headers | |
$request_headers = getallheaders(); | |
// Delete host, because this is not correct for base_url | |
unset($request_headers["Host"]); | |
// Convert headers to an array | |
$request_headers_url = array(); | |
foreach ($request_headers as $name => $value) { | |
array_push($request_headers_url, "$name: $value"); | |
} | |
// Forward local request headers to the remote server | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers_url); | |
// Set CURLOPT_HEADER to get response headers | |
curl_setopt($ch, CURLOPT_HEADER, true); | |
// Set CURLOPT_FOLLOWLOCATION to true to follow redirects | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
// Execute the request | |
$response = curl_exec($ch); | |
// Get size of response header | |
$response_header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); | |
// Extract header | |
$response_headers = substr($response, 0, $response_header_size); | |
// Split headers on newline | |
$response_headers = explode("\n", $response_headers); | |
// Set each header, i.e. copy all headers from the request url to this response | |
foreach ($response_headers as $header) { | |
header($header); | |
} | |
// Extract body | |
$body = substr($response, $response_header_size); | |
// Close the cURL handle | |
curl_close($ch); | |
//Print the body out onto the page | |
echo $body; | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment