public function request(Request $request)
 {
     $context = stream_context_create(array('http' => array('method' => $request->getRequestMethod(), 'header' => $request->getHeadersAsString(), 'proxy' => $request->getProxy(), 'content' => $request->getContentBody(), 'request_fulluri' => $request->hasProxy(), 'ignore_errors' => true)));
     /* Note: stream_socket_client does not support http(s) protocol. we have to use fopen here. */
     $socket = fopen($request->getUrl(), 'r', false, $context);
     if (!is_resource($socket)) {
         throw new \Exception("can't create stream socket.");
     }
     $headers = array();
     $meta_data = stream_get_meta_data($socket);
     if (isset($meta_data['wrapper_data'])) {
         foreach ($meta_data['wrapper_data'] as $value) {
             if (strpos($value, "HTTP/") === 0) {
                 list($dummy, $status, $dummy) = explode(" ", $value, 3);
                 $headers['HTTP_CODE'] = $status;
             } else {
                 list($key, $value) = explode(":", $value, 2);
                 $headers[$key] = $value;
             }
         }
     }
     if ($headers['HTTP_CODE'][0] != 2) {
         throw new \Exception(sprintf("API Server returns %s code: %s", $headers['HTTP_STATUS'], fread($socket, 8192)));
     }
     $data = stream_get_contents($socket);
     fclose($socket);
     return array($headers, $data);
 }