Created
February 11, 2013 13:42
-
-
Save seebz/4754475 to your computer and use it in GitHub Desktop.
PHP mod_proxy
This file contains hidden or 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 | |
| // .Htacesss | |
| // --------- | |
| /* | |
| <IfModule mod_rewrite.c> | |
| RewriteEngine on | |
| RewriteRule .* proxy.php [L] | |
| </IfModule> | |
| */ | |
| // Settings (require php5.3) | |
| // ---------------------------------------------------------------------------- | |
| $target_ip = '123.123.123.123'; | |
| $target_domain = false; // Si différent de la requête | |
| $target_path = false; // Si différent de la requête | |
| // ---------------------------------------------------------------------------- | |
| // Analyse de la requête client | |
| // ---------------------------------------------------------------------------- | |
| $request_headers = request_headers(); | |
| $request_method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET'; | |
| $request_protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); | |
| $request_domain = $_SERVER['HTTP_HOST']; | |
| $request_path = $_SERVER['REQUEST_URI']; | |
| $target_url = $request_protocol . '://' | |
| . ($target_ip ?: ($target_domain ?: $request_domain)) | |
| . ($target_path ?: $request_path); | |
| if ($target_domain) | |
| { | |
| $request_headers['Host'] = $target_domain; | |
| } | |
| if (isset($request_headers['Accept-Encoding'])) unset($request_headers['Accept-Encoding']); | |
| if (isset($request_headers['Content-Length'])) unset($request_headers['Content-Length']); | |
| // Post data | |
| $request_post_fields = $_POST; | |
| // Uploads | |
| if ($_FILES) | |
| { | |
| $UPLOADS = convert_files_var($_FILES); | |
| $request_post_fields += $UPLOADS; | |
| $request_headers['Content-Type'] = 'multipart/form-data'; | |
| } | |
| // Requête distante | |
| // ---------------------------------------------------------------------------- | |
| $params = array( | |
| 'url' => $target_url, | |
| 'headers' => $request_headers, | |
| 'method' => $request_method, | |
| 'post_fields' => http_build_query_for_curl($request_post_fields), | |
| ); | |
| $cr = new CurlRequest($params); | |
| $response = $cr->exec(); | |
| // Curl error | |
| if ($response['curl_error']) | |
| { | |
| header('Status: 500'); | |
| die ($response['curl_error']); | |
| } | |
| // Traitement de la réponse | |
| $response_http_code = $response['http_code']; | |
| $response_headers = $response['headers']; | |
| $response_body = $response['body']; | |
| // Réponse (headers) | |
| $ignore = array('Transfer-Encoding', 'Content-Length'); | |
| $pattern = sprintf('`^(%s)`i', implode('|', $ignore)); | |
| foreach($response_headers as $i => $h) { | |
| if ( ! preg_match($pattern, $h)) | |
| header($h); | |
| } | |
| header("Status: {$response_http_code}", true, $response_http_code); | |
| header("X-Forwarded-For: {$_SERVER['REMOTE_ADDR']}"); | |
| header('X-Forwarded-Host: '. ($target_domain ?: $_SERVER['HTTP_HOST'])); | |
| header("X-Forwarded-Server: {$_SERVER['HTTP_HOST']}"); | |
| // Réponse (body) | |
| echo $response_body; | |
| // Fonctions utiles | |
| // ---------------------------------------------------------------------------- | |
| /** | |
| * Fetch all HTTP request headers | |
| * @link http://php.net/manual/en/function.apache-request-headers.php | |
| * @return array An associative array of all the HTTP headers in the current request, or FALSE on failure. | |
| */ | |
| function request_headers() | |
| { | |
| if (function_exists('apache_request_headers')) { | |
| return apache_request_headers(); | |
| } | |
| foreach($_SERVER as $k => $v) | |
| { | |
| if (substr($k, 0, 5) == 'HTTP_') | |
| { | |
| $k = str_replace('_', ' ', substr($k, 5)); | |
| $k = ucwords(strtolower($k)); | |
| $k = str_replace(' ', '-', $k); | |
| $out[$k] = $v; | |
| } | |
| } | |
| if (isset($_SERVER['CONTENT_TYPE'])) | |
| $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; | |
| if (isset($_SERVER['CONTENT_LENGTH'])) | |
| $out['Content-Length'] = $_SERVER['CONTENT_LENGTH']; | |
| if (isset($out['Remote-Ip'])) | |
| unset($out['Remote-Ip']); | |
| return $out; | |
| } | |
| /** | |
| * Converts $_FILES var to logical array | |
| * | |
| * $UPLOADS = convert_files_var($_FILES); | |
| */ | |
| function convert_files_var(array $in) | |
| { | |
| $out = $in; | |
| foreach ($out as $key => $v) | |
| { | |
| if (is_array($v['name'])) | |
| { | |
| $v_convert = array(); | |
| $v_keys = array_keys($v['name']); | |
| foreach($v_keys as $v_k) | |
| { | |
| $v_convert[$v_k] = array( | |
| 'name' => $v['name'][$v_k], | |
| 'type' => $v['type'][$v_k], | |
| 'tmp_name' => $v['tmp_name'][$v_k], | |
| 'error' => $v['error'][$v_k], | |
| 'size' => $v['size'][$v_k], | |
| ); | |
| } | |
| $out[$key] = call_user_func(__FUNCTION__, $v_convert); | |
| } | |
| } | |
| return $out; | |
| } | |
| // http://stackoverflow.com/a/8224117 | |
| function http_build_query_for_curl($query_data, &$new = array(), $prefix = null ) | |
| { | |
| if (is_object($query_data)) | |
| { | |
| $query_data = get_object_vars($query_data); | |
| } | |
| foreach ($query_data AS $key => $value) | |
| { | |
| $k = isset($prefix) ? $prefix . '[' . $key . ']' : $key; | |
| if (is_array($value) OR is_object($value)) | |
| { | |
| //http_build_query_for_curl( $value, $new, $k ); | |
| $func = __FUNCTION__; | |
| $func($value, $new, $k); | |
| } | |
| else | |
| { | |
| $new[$k] = $value; | |
| } | |
| } | |
| return $new; | |
| } | |
| class CurlRequest { | |
| private $ch; | |
| private $options = array( | |
| 'RETURNTRANSFER' => true, | |
| 'HEADER' => true, | |
| 'FOLLOWLOCATION' => false, | |
| 'SSL_VERIFYPEER' => false, | |
| 'SSL_VERIFYHOST' => false, | |
| 'TIMEOUT' => 5, | |
| ); | |
| /** | |
| * Init curl session | |
| * | |
| * $params = array('url' => '', | |
| * 'host' => '', | |
| * 'header' => '', | |
| * 'method' => '', | |
| * 'referer' => '', | |
| * 'cookie' => '', | |
| * 'post_fields' => '', | |
| * ['login' => '',] | |
| * ['password' => '',] | |
| * 'timeout' => 0 | |
| * ); | |
| */ | |
| public function __construct($params) { | |
| $this->ch = curl_init(); | |
| // Options | |
| foreach ($this->options as $key => $value) { | |
| $constant = 'CURLOPT_' . $key; | |
| if (defined($constant)) { | |
| @curl_setopt($this->ch, constant($constant), $value); | |
| } | |
| } | |
| // Url | |
| @curl_setopt($this->ch, CURLOPT_URL, $params['url']); | |
| // Headers | |
| $headers = array(); | |
| foreach($params['headers'] as $k => $v) { | |
| $headers[] = $k . ': ' . $v; | |
| } | |
| @curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); | |
| switch(strtoupper($params['method'])) { | |
| case 'HEAD': | |
| @curl_setopt($this -> ch,CURLOPT_NOBODY, true); | |
| break; | |
| case 'POST': | |
| curl_setopt($this->ch, CURLOPT_POST, true); | |
| //curl_setopt($this->ch, CURLOPT_POSTFIELDS, http_build_query($_POST)); | |
| $post_fields = ($params['post_fields'] ?: array()); | |
| curl_setopt($this->ch, CURLOPT_POSTFIELDS, $post_fields); | |
| break; | |
| } | |
| // Ne fonctionne plus depuis PHP 4.3.0 | |
| if (isset($_SERVER['PHP_AUTH_USER']) & isset($_SERVER['PHP_AUTH_PW'])) { | |
| @curl_setopt($this->ch, CURLOPT_USERPWD, $_SERVER['PHP_AUTH_USER'].':'.$_SERVER['PHP_AUTH_PW']); | |
| } | |
| } | |
| /** | |
| * Make curl request | |
| * | |
| * @return array 'header','body','curl_error','http_code','last_url' | |
| */ | |
| public function exec() { | |
| $response = curl_exec($this->ch); | |
| $error = curl_error($this->ch); | |
| $result = array( | |
| 'header' => '', | |
| 'body' => '', | |
| 'curl_error' => '', | |
| 'http_code' => '', | |
| 'last_url' => '', | |
| ); | |
| if ( $error ) { | |
| $result['curl_error'] = $error; | |
| return $result; | |
| } | |
| $header_size = curl_getinfo($this->ch,CURLINFO_HEADER_SIZE); | |
| $headers = trim(substr($response, 0, $header_size)); | |
| $headers = explode("\n", $headers); | |
| if (stripos($headers[0], 'HTTP/1')===0) { | |
| unset($headers[0]); | |
| } | |
| $result = array( | |
| 'headers' => $headers, | |
| 'body' => substr( $response, $header_size ), | |
| 'curl_error' => '', | |
| 'http_code' => curl_getinfo($this -> ch,CURLINFO_HTTP_CODE), | |
| 'last_url' => curl_getinfo($this -> ch,CURLINFO_EFFECTIVE_URL), | |
| ); | |
| return $result; | |
| } | |
| } | |
| ?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment