Simple HTTP proxy written in PHP for uncooperative servers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
3.3KB

  1. <?php
  2. class Proxy {
  3. public function __construct($serv, $port = 80, $root = '', $localRoot = '') {
  4. // Functions
  5. function str_replace_once($search, $replace, $subject) { // TODO Credit
  6. $pos = strpos($subject, $search);
  7. if ($pos === false) {
  8. return $subject;
  9. }
  10. return substr($subject, 0, $pos) . $replace . substr($subject, $pos + strlen($search));
  11. }
  12. if (!function_exists('getallheaders')) { // TODO Credit
  13. function getallheaders() {
  14. if (!is_array($_SERVER)) {
  15. return array();
  16. }
  17. $headers = array();
  18. foreach ($_SERVER as $name => $value) {
  19. if (substr($name, 0, 5) == 'HTTP_') {
  20. $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
  21. } else if (substr($name, 0, 8) == 'CONTENT_') {
  22. $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $name))))] = $value;
  23. }
  24. }
  25. return $headers;
  26. }
  27. }
  28. // Target determination
  29. $metd = $_SERVER['REQUEST_METHOD'];
  30. $reqp = $_SERVER['REQUEST_URI'];
  31. if ($localRoot != '') {
  32. $reqp = str_replace_once($localRoot, '', $reqp); // TODO Reliable method
  33. }
  34. // Preparing request headers
  35. $reqHeds = "$metd $root$reqp HTTP/1.1\r\n";
  36. $reqHeds .= "Host: $serv:$port\r\n";
  37. // Converting client request headers to server request headers
  38. $reqsHedsC = getallheaders();
  39. foreach ($reqsHedsC as $name => $content) {
  40. switch ($name) {
  41. case 'Host':
  42. case 'Connection':
  43. break;
  44. default:
  45. $reqHeds .= "$name: $content\r\n";
  46. }
  47. }
  48. $reqHeds .= "Connection: Close\r\n\r\n".file_get_contents('php://input');
  49. $fp = fsockopen($serv, $port, $errno, $errstr, 30);
  50. if (!$fp) { // TODO ErrorCode, ErrorDocument
  51. echo "Couldn't connect to server.\n<br/>$errstr ($errno)<br />\n";
  52. } else {
  53. // Sending request
  54. fwrite($fp, $reqHeds);
  55. $resBuf = '';
  56. while ($get = fgets($fp, 128)) {
  57. // Getting response
  58. if ($resBuf === True) { // If headers sent
  59. echo $get;
  60. } else {
  61. $resBuf .= $get;
  62. if ($sepPos = strrpos($resBuf, "\r\n\r\n")) { // Headers have been retrieved
  63. $resHeds = explode("\r\n", substr($resBuf, 0, $sepPos));
  64. foreach ($resHeds as $resHed) { // Setting headers
  65. header($resHed);
  66. if (substr($resHed, 0, 4) == 'HTTP') { // FastCGI fix when using ErrorDocument
  67. header('Status: ' . substr($resHed, 9));
  68. }
  69. }
  70. echo substr($resBuf, $sepPos + 4); // Sending the rest (usually empty)
  71. $resBuf = True; // Setting mode to automatically redirect
  72. }
  73. }
  74. }
  75. fclose($fp);
  76. }
  77. }
  78. }
  79. ?>