Skip to content

Instantly share code, notes, and snippets.

@linuskmr
Last active July 22, 2021 09:11
Show Gist options
  • Save linuskmr/ccaed0b05bd7093a5cdf77ed85c8532c to your computer and use it in GitHub Desktop.
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.
# 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]
# 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
<?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