1: <?php
2:
3: 4: 5:
6:
7: namespace Mapbender\CoreBundle\Component;
8:
9: use Symfony\Component\HttpFoundation\Request;
10: use Symfony\Component\HttpFoundation\Response;
11: use Symfony\Component\HttpKernel\Exception\HttpException;
12:
13: 14: 15: 16: 17: 18: 19:
20: class ProxyService
21: {
22:
23: protected $proxy_conf;
24: protected $noproxy;
25:
26: public function __construct($proxy_conf)
27: {
28: if($proxy_conf['host'] !== null)
29: {
30: $this->proxy_conf[CURLOPT_PROXY] = $proxy_conf['host'];
31: $this->proxy_conf[CURLOPT_PROXYPORT] = $proxy_conf['port'];
32:
33: $user = $proxy_conf['user'];
34: if($user && $proxy_conf['password'])
35: {
36: $user .= ':' . $proxy_conf['password'];
37: }
38: $this->proxy_conf[CURLOPT_PROXYUSERPWD] = $user;
39:
40: $this->noproxy = $proxy_conf['noproxy'];
41: } else
42: {
43: $this->proxy_conf = array();
44: $this->noproxy = array();
45: }
46: }
47:
48: 49: 50: 51: 52: 53:
54: public function proxy(Request $request)
55: {
56: $url = parse_url($request->get('url'));
57:
58: if(!$url)
59: {
60: throw new \RuntimeException('No URL passed in proxy request.');
61: }
62:
63: $baseUrl = $request->get('url');
64:
65: foreach($request->query->all() as $key => $value)
66: {
67: if($key === "url")
68: continue;
69: $baseUrl .= "&$key=" . urlencode($value);
70: }
71:
72:
73: if(!isset($url['scheme']))
74: {
75: throw new HttpException(500, 'This proxy only allow HTTP and '
76: . 'HTTPS urls.');
77: }
78: if(!$url['scheme'] == 'http' && !$url['scheme'] == 'https')
79: {
80: throw new HttpException(500, 'This proxy only allow HTTP and '
81: . 'HTTPS urls.');
82: }
83:
84:
85: $ch = curl_init($baseUrl);
86:
87:
88: if($request->getMethod() == 'POST')
89: {
90: curl_setopt($ch, CURLOPT_POST, true);
91: $contentType = explode(';', $request->headers->get('Content-Type'));
92:
93: if($contentType[0] == 'application/xml')
94: {
95:
96:
97: $content = $request->getContent();
98: curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: ' . $contentType[0]));
99: curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getContent());
100: 101: 102: 103: 104: 105:
106: } else
107: {
108: curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getParameters());
109:
110: }
111: }
112:
113: $user_agent = array_key_exists('HTTP_USER_AGENT', $_SERVER) ?
114: $_SERVER['HTTP_USER_AGENT'] : 'Mapbender3';
115:
116: $curl_config = array(
117: CURLOPT_FOLLOWLOCATION => true,
118: CURLOPT_HEADER => false,
119: CURLOPT_RETURNTRANSFER => true,
120: CURLOPT_USERAGENT => $user_agent);
121:
122:
123: if(!in_array($url['host'], $this->noproxy))
124: {
125: $curl_config += $this->proxy_conf;
126: }
127:
128: curl_setopt_array($ch, $curl_config);
129:
130:
131: $content = curl_exec($ch);
132:
133: $status = curl_getinfo($ch);
134:
135: if($content === false)
136: {
137: throw new \RuntimeException('Proxying failed: ' . curl_error($ch)
138: . ' [' . curl_errno($ch) . ']', curl_errno($ch));
139: }
140: curl_close($ch);
141:
142: try
143: {
144: $contentType = $request->headers->get("content-type");
145: if($contentType !== null && strlen($contentType) > 0)
146: {
147: $tmp = explode(";", $contentType);
148: foreach($tmp as $value)
149: {
150: if(stripos($value, "charset") !== false
151: && stripos($value, "charset") == 0)
152: {
153: $charset = explode("=", $value);
154: }
155: }
156: if(isset($charset) && isset($charset[1])
157: && !mb_check_encoding($content, $charset[1]))
158: {
159: $content = mb_convert_encoding($content, $charset[1]);
160: }
161: }
162: } catch(\Exception $e)
163: {
164:
165: }
166:
167: return new Response($content, $status['http_code'], array(
168: 'Content-Type' => $status['content_type']));
169: }
170:
171: }
172:
173: