Subversion Repositories munaweb

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 - 1
<?php
2
/**
3
 * AJAX Cross Domain (PHP) Proxy 0.8
4
 * Copyright (C) 2016 Iacovos Constantinou (https://github.com/softius)
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
/**
18
 * Enables or disables filtering for cross domain requests.
19
 * Recommended value: true
20
 */
21
define('CSAJAX_FILTERS', true);
22
/**
23
 * If set to true, $valid_requests should hold only domains i.e. a.example.com, b.example.com, usethisdomain.com
24
 * If set to false, $valid_requests should hold the whole URL ( without the parameters ) i.e. http://example.com/this/is/long/url/
25
 * Recommended value: false (for security reasons - do not forget that anyone can access your proxy)
26
 */
27
define('CSAJAX_FILTER_DOMAIN', true);
28
/**
29
 * Enables or disables Expect: 100-continue header. Some webservers don't
30
 * handle this header correctly.
31
 * Recommended value: false
32
 */
33
define('CSAJAX_SUPPRESS_EXPECT', false);
34
/**
35
 * Set debugging to true to receive additional messages - really helpful on development
36
 */
37
define('CSAJAX_DEBUG', false);
38
/**
39
 * A set of valid cross domain requests
40
 */
41
$valid_requests = array(
42
		'api.ebay.com',
43
		'open.api.ebay.com',
44
		'secure.shippingapis.com',
45
		'muna-trading.myshopify.com',
46
		'svcs.ebay.com',
47
		'api.discogs.com',
48
		'onlinetools.ups.com'
49
);
50
/**
51
 * Set extra multiple options for cURL
52
 * Could be used to define CURLOPT_SSL_VERIFYPEER & CURLOPT_SSL_VERIFYHOST for HTTPS
53
 * Also to overwrite any other options without changing the code
54
 * See http://php.net/manual/en/function.curl-setopt-array.php
55
 */
56
$curl_options = array(
57
    // CURLOPT_SSL_VERIFYPEER => false,
58
    // CURLOPT_SSL_VERIFYHOST => 2,
59
//    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0 // avoid 'chunking'
60
);
61
/* * * STOP EDITING HERE UNLESS YOU KNOW WHAT YOU ARE DOING * * */
62
// identify request headers
63
$request_headers = array( );
64
foreach ($_SERVER as $key => $value) {
65
    if (strpos($key, 'HTTP_') === 0  ||  strpos($key, 'CONTENT_') === 0) {
66
        $headername = str_replace('_', ' ', str_replace('HTTP_', '', $key));
67
        $headername = str_replace(' ', '-', ucwords(strtolower($headername)));
68
        if (!in_array($headername, array( 'Host', 'X-Proxy-Url' ))) {
69
        	if ($headername == "X-Authorization") {
70
        		$headername = "Authorization";
71
        	}
72
            $request_headers[] = "$headername: $value";
73
        }
74
    }
75
}
76
// identify request method, url and params
77
$request_method = $_SERVER['REQUEST_METHOD'];
78
if ('GET' == $request_method) {
79
    $request_params = $_GET;
80
} elseif ('POST' == $request_method) {
81
    $request_params = $_POST;
82
    if (empty($request_params)) {
83
        $data = file_get_contents('php://input');
84
        if (!empty($data)) {
85
            $request_params = $data;
86
        }
87
    }
88
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) {
89
    $request_params = file_get_contents('php://input');
90
} else {
91
    $request_params = null;
92
}
93
// Get URL from `csurl` in GET or POST data, before falling back to X-Proxy-URL header.
94
if (isset($_REQUEST['csurl'])) {
95
    $request_url = urldecode($_REQUEST['csurl']);
96
} elseif (isset($_SERVER['HTTP_X_PROXY_URL'])) {
97
    $request_url = urldecode($_SERVER['HTTP_X_PROXY_URL']);
98
} else {
99
    header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
100
    header('Status: 404 Not Found');
101
    $_SERVER['REDIRECT_STATUS'] = 404;
102
    exit;
103
}
104
$p_request_url = parse_url($request_url);
105
// csurl may exist in GET request methods
106
if (is_array($request_params) && array_key_exists('csurl', $request_params)) {
107
    unset($request_params['csurl']);
108
}
109
// ignore requests for proxy :)
110
if (preg_match('!' . $_SERVER['SCRIPT_NAME'] . '!', $request_url) || empty($request_url) || count($p_request_url) == 1) {
111
    csajax_debug_message('Invalid request - make sure that csurl variable is not empty');
112
    exit;
113
}
114
// check against valid requests
115
if (CSAJAX_FILTERS) {
116
    $parsed = $p_request_url;
117
    if (CSAJAX_FILTER_DOMAIN) {
118
        if (!in_array($parsed['host'], $valid_requests)) {
119
            csajax_debug_message('Invalid domain - ' . $parsed['host'] . ' is not included in valid requests');
120
            exit;
121
        }
122
    } else {
123
        $check_url = isset($parsed['scheme']) ? $parsed['scheme'] . '://' : '';
124
        $check_url .= isset($parsed['user']) ? $parsed['user'] . ($parsed['pass'] ? ':' . $parsed['pass'] : '') . '@' : '';
125
        $check_url .= isset($parsed['host']) ? $parsed['host'] : '';
126
        $check_url .= isset($parsed['port']) ? ':' . $parsed['port'] : '';
127
        $check_url .= isset($parsed['path']) ? $parsed['path'] : '';
128
        if (!in_array($check_url, $valid_requests)) {
129
            csajax_debug_message('Invalid url - ' . $request_url . ' does not included in valid requests');
130
            exit;
131
        }
132
    }
133
}
134
// append query string for GET requests
135
if ($request_method == 'GET' && count($request_params) > 0 && (!array_key_exists('query', $p_request_url) || empty($p_request_url['query']))) {
136
    $request_url .= '?' . http_build_query($request_params);
137
}
138
// let the request begin
139
$ch = curl_init($request_url);
140
// Suppress Expect header
141
if (CSAJAX_SUPPRESS_EXPECT) {
142
    array_push($request_headers, 'Expect:');
143
}
144
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);   // (re-)send headers
145
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     // return response
146
curl_setopt($ch, CURLOPT_HEADER, true);       // enabled response headers
147
// add data for POST, PUT or DELETE requests
148
if ('POST' == $request_method) {
149
    $post_data = is_array($request_params) ? http_build_query($request_params) : $request_params;
150
    curl_setopt($ch, CURLOPT_POST, true);
151
    curl_setopt($ch, CURLOPT_POSTFIELDS,  $post_data);
152
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) {
153
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method);
154
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request_params);
155
}
156
// Set multiple options for curl according to configuration
157
if (is_array($curl_options) && 0 <= count($curl_options)) {
158
    curl_setopt_array($ch, $curl_options);
159
}
160
// retrieve response (headers and content)
161
$response = curl_exec($ch);
162
curl_close($ch);
163
 
164
// Debug File proxy.log
165
if (true == CSAJAX_DEBUG) {
166
$h = fopen("proxy.log", "a");
167
  fwrite($h, "Request URL: " . $request_url . "\n");
168
  fwrite($h, "Request Headers: " . print_r($request_headers, TRUE));
169
  fwrite($h, "Request Method: " . $request_method . "\n");
170
  fwrite($h, "Return: " . $response . "\n");
171
  fwrite($h, "\n");
172
  fclose($h);
173
}
174
 
175
// split response to header and content
176
list($response_headers, $response_content) = preg_split('/(\r\n){2}/', $response, 2);
177
// (re-)send the headers
178
$response_headers = preg_split('/(\r\n){1}/', $response_headers);
179
foreach ($response_headers as $key => $response_header) {
180
    // Rewrite the `Location` header, so clients will also use the proxy for redirects.
181
    if (preg_match('/^Location:/', $response_header)) {
182
        list($header, $value) = preg_split('/: /', $response_header, 2);
183
        $response_header = 'Location: ' . $_SERVER['REQUEST_URI'] . '?csurl=' . $value;
184
    }
185
    if (!preg_match('/^(Transfer-Encoding):/', $response_header)) {
186
        header($response_header, false);
187
    }
188
}
189
 
190
// flush headers
191
flush();
192
 
193
// finally, output the content and flush
194
print($response_content);
195
flush();
196
 
197
function csajax_debug_message($message)
198
{
199
    if (true == CSAJAX_DEBUG) {
200
        print $message . PHP_EOL;
201
    }
202
}