2 |
- |
1 |
<?php
|
178 |
- |
2 |
error_reporting(-1);
|
|
|
3 |
|
2 |
- |
4 |
/**
|
|
|
5 |
* AJAX Cross Domain (PHP) Proxy 0.8
|
|
|
6 |
* Copyright (C) 2016 Iacovos Constantinou (https://github.com/softius)
|
|
|
7 |
*
|
|
|
8 |
* This program is free software: you can redistribute it and/or modify
|
|
|
9 |
* it under the terms of the GNU General Public License as published by
|
|
|
10 |
* the Free Software Foundation, either version 3 of the License, or
|
|
|
11 |
* (at your option) any later version.
|
|
|
12 |
* This program is distributed in the hope that it will be useful,
|
|
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
15 |
* GNU General Public License for more details.
|
|
|
16 |
* You should have received a copy of the GNU General Public License
|
|
|
17 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
18 |
*/
|
|
|
19 |
/**
|
|
|
20 |
* Enables or disables filtering for cross domain requests.
|
|
|
21 |
* Recommended value: true
|
|
|
22 |
*/
|
|
|
23 |
define('CSAJAX_FILTERS', true);
|
|
|
24 |
/**
|
|
|
25 |
* If set to true, $valid_requests should hold only domains i.e. a.example.com, b.example.com, usethisdomain.com
|
|
|
26 |
* If set to false, $valid_requests should hold the whole URL ( without the parameters ) i.e. http://example.com/this/is/long/url/
|
|
|
27 |
* Recommended value: false (for security reasons - do not forget that anyone can access your proxy)
|
|
|
28 |
*/
|
|
|
29 |
define('CSAJAX_FILTER_DOMAIN', true);
|
|
|
30 |
/**
|
|
|
31 |
* Enables or disables Expect: 100-continue header. Some webservers don't
|
|
|
32 |
* handle this header correctly.
|
|
|
33 |
* Recommended value: false
|
|
|
34 |
*/
|
|
|
35 |
define('CSAJAX_SUPPRESS_EXPECT', false);
|
|
|
36 |
/**
|
|
|
37 |
* Set debugging to true to receive additional messages - really helpful on development
|
|
|
38 |
*/
|
|
|
39 |
define('CSAJAX_DEBUG', false);
|
|
|
40 |
/**
|
|
|
41 |
* A set of valid cross domain requests
|
|
|
42 |
*/
|
|
|
43 |
$valid_requests = array(
|
|
|
44 |
'api.ebay.com',
|
|
|
45 |
'open.api.ebay.com',
|
|
|
46 |
'secure.shippingapis.com',
|
|
|
47 |
'muna-trading.myshopify.com',
|
|
|
48 |
'svcs.ebay.com',
|
|
|
49 |
'api.discogs.com',
|
|
|
50 |
'onlinetools.ups.com'
|
|
|
51 |
);
|
|
|
52 |
/**
|
|
|
53 |
* Set extra multiple options for cURL
|
|
|
54 |
* Could be used to define CURLOPT_SSL_VERIFYPEER & CURLOPT_SSL_VERIFYHOST for HTTPS
|
|
|
55 |
* Also to overwrite any other options without changing the code
|
|
|
56 |
* See http://php.net/manual/en/function.curl-setopt-array.php
|
|
|
57 |
*/
|
|
|
58 |
$curl_options = array(
|
|
|
59 |
// CURLOPT_SSL_VERIFYPEER => false,
|
|
|
60 |
// CURLOPT_SSL_VERIFYHOST => 2,
|
180 |
- |
61 |
CURLOPT_CONNECTTIMEOUT => 5,
|
|
|
62 |
CURLOPT_TIMEOUT => 30
|
2 |
- |
63 |
);
|
4 |
- |
64 |
/**
|
|
|
65 |
* Decode POST parameters after building the http array. Send Header X-DECODE-PARAMS
|
|
|
66 |
*/
|
19 |
- |
67 |
$decodeFlag = false;
|
32 |
- |
68 |
/**
|
|
|
69 |
* Do not decode X-Proxy-Url. Send Header X-LEAVE-ENCODED
|
|
|
70 |
*/
|
|
|
71 |
$leaveEncodedFlag = false;
|
|
|
72 |
|
2 |
- |
73 |
/* * * STOP EDITING HERE UNLESS YOU KNOW WHAT YOU ARE DOING * * */
|
|
|
74 |
// identify request headers
|
|
|
75 |
$request_headers = array( );
|
|
|
76 |
foreach ($_SERVER as $key => $value) {
|
|
|
77 |
if (strpos($key, 'HTTP_') === 0 || strpos($key, 'CONTENT_') === 0) {
|
|
|
78 |
$headername = str_replace('_', ' ', str_replace('HTTP_', '', $key));
|
|
|
79 |
$headername = str_replace(' ', '-', ucwords(strtolower($headername)));
|
|
|
80 |
if (!in_array($headername, array( 'Host', 'X-Proxy-Url' ))) {
|
|
|
81 |
if ($headername == "X-Authorization") {
|
|
|
82 |
$headername = "Authorization";
|
4 |
- |
83 |
} else if ($headername == "X-Decode-Params") {
|
|
|
84 |
$decodeFlag = true;
|
|
|
85 |
continue;
|
32 |
- |
86 |
} else if ($headername == "X-Leave-Encoded") {
|
|
|
87 |
$leaveEncodedFlag = true;
|
|
|
88 |
continue;
|
2 |
- |
89 |
}
|
83 |
- |
90 |
|
|
|
91 |
$value = authReplace($value);
|
|
|
92 |
|
2 |
- |
93 |
$request_headers[] = "$headername: $value";
|
|
|
94 |
}
|
|
|
95 |
}
|
|
|
96 |
}
|
|
|
97 |
// identify request method, url and params
|
|
|
98 |
$request_method = $_SERVER['REQUEST_METHOD'];
|
|
|
99 |
if ('GET' == $request_method) {
|
|
|
100 |
$request_params = $_GET;
|
|
|
101 |
} elseif ('POST' == $request_method) {
|
|
|
102 |
$request_params = $_POST;
|
|
|
103 |
if (empty($request_params)) {
|
|
|
104 |
$data = file_get_contents('php://input');
|
|
|
105 |
if (!empty($data)) {
|
|
|
106 |
$request_params = $data;
|
|
|
107 |
}
|
|
|
108 |
}
|
|
|
109 |
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) {
|
|
|
110 |
$request_params = file_get_contents('php://input');
|
|
|
111 |
} else {
|
|
|
112 |
$request_params = null;
|
|
|
113 |
}
|
|
|
114 |
// Get URL from `csurl` in GET or POST data, before falling back to X-Proxy-URL header.
|
|
|
115 |
if (isset($_REQUEST['csurl'])) {
|
|
|
116 |
$request_url = urldecode($_REQUEST['csurl']);
|
|
|
117 |
} elseif (isset($_SERVER['HTTP_X_PROXY_URL'])) {
|
32 |
- |
118 |
if ($leaveEncodedFlag) {
|
|
|
119 |
$request_url = $_SERVER['HTTP_X_PROXY_URL'];
|
|
|
120 |
} else {
|
|
|
121 |
$request_url = urldecode($_SERVER['HTTP_X_PROXY_URL']);
|
|
|
122 |
}
|
2 |
- |
123 |
} else {
|
|
|
124 |
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
|
|
|
125 |
header('Status: 404 Not Found');
|
|
|
126 |
$_SERVER['REDIRECT_STATUS'] = 404;
|
|
|
127 |
exit;
|
|
|
128 |
}
|
75 |
- |
129 |
|
83 |
- |
130 |
$request_url = authReplace($request_url);
|
75 |
- |
131 |
|
2 |
- |
132 |
$p_request_url = parse_url($request_url);
|
|
|
133 |
// csurl may exist in GET request methods
|
|
|
134 |
if (is_array($request_params) && array_key_exists('csurl', $request_params)) {
|
|
|
135 |
unset($request_params['csurl']);
|
|
|
136 |
}
|
|
|
137 |
// ignore requests for proxy :)
|
|
|
138 |
if (preg_match('!' . $_SERVER['SCRIPT_NAME'] . '!', $request_url) || empty($request_url) || count($p_request_url) == 1) {
|
|
|
139 |
csajax_debug_message('Invalid request - make sure that csurl variable is not empty');
|
|
|
140 |
exit;
|
|
|
141 |
}
|
|
|
142 |
// check against valid requests
|
|
|
143 |
if (CSAJAX_FILTERS) {
|
|
|
144 |
$parsed = $p_request_url;
|
|
|
145 |
if (CSAJAX_FILTER_DOMAIN) {
|
|
|
146 |
if (!in_array($parsed['host'], $valid_requests)) {
|
|
|
147 |
csajax_debug_message('Invalid domain - ' . $parsed['host'] . ' is not included in valid requests');
|
|
|
148 |
exit;
|
|
|
149 |
}
|
|
|
150 |
} else {
|
|
|
151 |
$check_url = isset($parsed['scheme']) ? $parsed['scheme'] . '://' : '';
|
|
|
152 |
$check_url .= isset($parsed['user']) ? $parsed['user'] . ($parsed['pass'] ? ':' . $parsed['pass'] : '') . '@' : '';
|
|
|
153 |
$check_url .= isset($parsed['host']) ? $parsed['host'] : '';
|
|
|
154 |
$check_url .= isset($parsed['port']) ? ':' . $parsed['port'] : '';
|
|
|
155 |
$check_url .= isset($parsed['path']) ? $parsed['path'] : '';
|
|
|
156 |
if (!in_array($check_url, $valid_requests)) {
|
|
|
157 |
csajax_debug_message('Invalid url - ' . $request_url . ' does not included in valid requests');
|
|
|
158 |
exit;
|
|
|
159 |
}
|
|
|
160 |
}
|
|
|
161 |
}
|
|
|
162 |
// append query string for GET requests
|
|
|
163 |
if ($request_method == 'GET' && count($request_params) > 0 && (!array_key_exists('query', $p_request_url) || empty($p_request_url['query']))) {
|
|
|
164 |
$request_url .= '?' . http_build_query($request_params);
|
|
|
165 |
}
|
178 |
- |
166 |
|
2 |
- |
167 |
// let the request begin
|
|
|
168 |
$ch = curl_init($request_url);
|
|
|
169 |
// Suppress Expect header
|
|
|
170 |
if (CSAJAX_SUPPRESS_EXPECT) {
|
|
|
171 |
array_push($request_headers, 'Expect:');
|
|
|
172 |
}
|
|
|
173 |
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers); // (re-)send headers
|
|
|
174 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return response
|
|
|
175 |
curl_setopt($ch, CURLOPT_HEADER, true); // enabled response headers
|
|
|
176 |
// add data for POST, PUT or DELETE requests
|
|
|
177 |
if ('POST' == $request_method) {
|
4 |
- |
178 |
$post_data = is_array($request_params) ? http_build_query($request_params) : $request_params;
|
87 |
- |
179 |
$post_data = authReplace($post_data);
|
2 |
- |
180 |
curl_setopt($ch, CURLOPT_POST, true);
|
4 |
- |
181 |
if ($decodeFlag) {
|
|
|
182 |
curl_setopt($ch, CURLOPT_POSTFIELDS, urldecode($post_data));
|
|
|
183 |
} else {
|
|
|
184 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
|
|
|
185 |
}
|
2 |
- |
186 |
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) {
|
|
|
187 |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method);
|
|
|
188 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_params);
|
|
|
189 |
}
|
|
|
190 |
// Set multiple options for curl according to configuration
|
|
|
191 |
if (is_array($curl_options) && 0 <= count($curl_options)) {
|
|
|
192 |
curl_setopt_array($ch, $curl_options);
|
|
|
193 |
}
|
178 |
- |
194 |
|
2 |
- |
195 |
// retrieve response (headers and content)
|
|
|
196 |
$response = curl_exec($ch);
|
180 |
- |
197 |
if (curl_errno($ch)) {
|
|
|
198 |
error_log("Curl error: " . curl_error($ch) . " (" . curl_error($ch) . ")");
|
|
|
199 |
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
|
|
|
200 |
header('Status: 404 Not Found');
|
|
|
201 |
$_SERVER['REDIRECT_STATUS'] = 404;
|
|
|
202 |
exit;
|
|
|
203 |
}
|
2 |
- |
204 |
curl_close($ch);
|
|
|
205 |
|
19 |
- |
206 |
// delete 100 Continue headers
|
|
|
207 |
$delimiter = "\r\n\r\n"; // HTTP header delimiter
|
|
|
208 |
// check if the 100 Continue header exists
|
|
|
209 |
while ( preg_match('#^HTTP/[0-9\\.]+\s+100\s+Continue#i',$response) ) {
|
|
|
210 |
$tmp = explode($delimiter,$response,2); // grab the 100 Continue header
|
|
|
211 |
$response = $tmp[1]; // update the response, purging the most recent 100 Continue header
|
2 |
- |
212 |
}
|
|
|
213 |
|
|
|
214 |
// split response to header and content
|
149 |
- |
215 |
list($response_headers, $response_content) = array_pad(preg_split('/(\r\n){2}/', $response, 2), 2, "");
|
2 |
- |
216 |
// (re-)send the headers
|
|
|
217 |
$response_headers = preg_split('/(\r\n){1}/', $response_headers);
|
|
|
218 |
foreach ($response_headers as $key => $response_header) {
|
|
|
219 |
// Rewrite the `Location` header, so clients will also use the proxy for redirects.
|
|
|
220 |
if (preg_match('/^Location:/', $response_header)) {
|
|
|
221 |
list($header, $value) = preg_split('/: /', $response_header, 2);
|
|
|
222 |
$response_header = 'Location: ' . $_SERVER['REQUEST_URI'] . '?csurl=' . $value;
|
|
|
223 |
}
|
180 |
- |
224 |
if (!preg_match('/^(Transfer-Encoding):/i', $response_header)) {
|
2 |
- |
225 |
header($response_header, false);
|
|
|
226 |
}
|
|
|
227 |
}
|
|
|
228 |
|
19 |
- |
229 |
// Debug File proxy.log
|
|
|
230 |
if (true == CSAJAX_DEBUG) {
|
|
|
231 |
$h = fopen("proxy.log", "a");
|
|
|
232 |
fwrite($h, "Request URL: " . $request_url . "\n");
|
178 |
- |
233 |
fwrite($h, "Request Headers: " . print_r($request_headers, true));
|
19 |
- |
234 |
fwrite($h, "Request Method: " . $request_method . "\n");
|
|
|
235 |
if ('POST' == $request_method) {
|
|
|
236 |
fwrite($h, "Post Params: " . $post_data . "\n");
|
|
|
237 |
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) {
|
|
|
238 |
fwrite($h, "Request Params: " . print_r($request_params, true) . "\n");
|
|
|
239 |
}
|
|
|
240 |
fwrite($h, "Return: " . $response . "\n");
|
178 |
- |
241 |
fwrite($h, "Response Headers: " . print_r($response_headers, true));
|
19 |
- |
242 |
fwrite($h, "Response Content: " . $response_content . "\n");
|
|
|
243 |
fwrite($h, "\n");
|
|
|
244 |
fclose($h);
|
|
|
245 |
}
|
2 |
- |
246 |
|
19 |
- |
247 |
// finally, output the content
|
178 |
- |
248 |
echo $response_content;
|
2 |
- |
249 |
|
83 |
- |
250 |
// insert authorization
|
|
|
251 |
function authReplace($str) {
|
87 |
- |
252 |
$str = str_replace('XxXRuNamexxxxxxxxxxxxxxxxxxxxxxx', 'Uwe_Jacobs-UweJacob-MUNATr-jwkrg', $str);
|
83 |
- |
253 |
$str = str_replace('XxXAppid', 'UweJacob-MUNATrad-PRD-d132041a0-85284729', $str);
|
|
|
254 |
$str = str_replace('XxXDevid', '00fd6fda-3751-4095-b733-3899b20431ad', $str);
|
|
|
255 |
$str = str_replace('XxXCertid', 'PRD-132041a078aa-1ee6-4300-9454-6c5b', $str);
|
85 |
- |
256 |
$str = str_replace('XxXDiscogsToken', 'zFvVdCdHTtQnDHCxEFTJiBhalyHFUsjdyFPCjbqP', $str);
|
83 |
- |
257 |
$str = str_replace('XxXUSPSUserId', '275MUNAT7574', $str);
|
|
|
258 |
$str = str_replace('XxXShopifyApiKey', '41f0d3bf0e8e114496b198938996d9d8', $str);
|
|
|
259 |
$str = str_replace('XxXShopifyPassword', 'f169694c488f45ccf187c92676765889', $str);
|
|
|
260 |
$str = str_replace('XxXUPSAccessKey', 'DD53C5F37DF74D28', $str);
|
|
|
261 |
$str = str_replace('XxXUPSUsername', 'muna_trading', $str);
|
|
|
262 |
$str = str_replace('XxXUPSPassword', 'ZX83tbf!w7', $str);
|
|
|
263 |
$str = str_replace('XxXAuthorization', base64_encode('UweJacob-MUNATrad-PRD-d132041a0-85284729' . ':' . 'PRD-132041a078aa-1ee6-4300-9454-6c5b'), $str);
|
|
|
264 |
|
|
|
265 |
return($str);
|
|
|
266 |
}
|
2 |
- |
267 |
function csajax_debug_message($message)
|
|
|
268 |
{
|
|
|
269 |
if (true == CSAJAX_DEBUG) {
|
|
|
270 |
print $message . PHP_EOL;
|
|
|
271 |
}
|
3 |
- |
272 |
}
|