PHP proxy script with streaming and header support

raw

proxy.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
/**
 * PHP proxy script that proxies the URL given in the "url" parameter.
 *
 * Sends all incoming headers, and also returns all remote headers.
 * Streams the response, so that large responses should work fine.
 *
 * @author Christian Weiske <cweiske@cweiske.de>
 */
if (!isset($_GET['url']) || $_GET['url'] == '') {
    header('HTTP/1.0 400 Bad Request');
    echo "url parameter missing\n";
    exit(1);
}
if (substr($_GET['url'], 0, 7) != 'http://'
    && substr($_GET['url'], 0, 8) != 'https://'
) {
    header('HTTP/1.0 400 Bad Request');
    echo "Only http and https URLs supported\n";
    exit(1);
}
 
$url = $_GET['url'];
 
//send original http headers
$headers = [];
foreach (apache_request_headers() as $name => $value) {
    if (strtolower($name) == 'host') {
        continue;
    }
    $headers[] = $name . ': ' . $value;
}
$context = stream_context_create(
    ['http' => ['header' => $headers, 'ignore_errors' => true]]
);
 
$fp = fopen($url, 'r', false, $context);
if (!$fp) {
    header('HTTP/1.0 400 Bad Request');
    echo "Error fetching URL\n";
    exit(1);
}
 
//send original headers
if (is_array($http_response_header)) {
    foreach ($http_response_header as $header) {
        header($header);
    }
}
 
//stream the data in 1kiB blocks
while (!feof($fp)) {
    echo fread($fp, 1024);
    ob_flush();
    flush();
}
fclose($fp);
?>
 
Christian Weiske Christian Weiske
owner

History