/** * @param Request $request * @param bool $postponedResponseId * @param null $postponedOutput * @throws RequestFailed * @return Response */ public function sendRequest(Request $request, $postponedResponseId = null, $postponedOutput = null) { $clientData = $request->getClientData(); if ($clientData) { $request->cookies[\PhpConsole\Connector::CLIENT_INFO_COOKIE] = base64_encode(json_encode($clientData)); } if ($postponedResponseId) { $request->postData[\PhpConsole\Connector::POST_VAR_NAME] = array('getPostponedResponse' => $postponedResponseId); } $request->postData[static::POST_VAR_NAME] = array('scripts' => $request->getScripts()); $postData = $request->postData; array_walk_recursive($postData, function (&$item) { if (!is_object($item)) { $item = base64_encode($item); } }); $rawPostData = serialize($postData); $url = $request->isSsl ? str_replace('http://', 'https://', $this->serverWrapperUrl) : $this->serverWrapperUrl; $curlOptions = array(CURLOPT_URL => $url . '?signature=' . $this->getPostDataSignature($rawPostData), CURLOPT_CONNECTTIMEOUT => 100, CURLOPT_TIMEOUT => 100, CURLOPT_HEADER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $rawPostData, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 3, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false); if ($request->cookies) { $cookiesData = array(); foreach ($request->cookies as $name => $value) { $cookiesData[] = rawurlencode($name) . '=' . rawurlencode($value); } $curlOptions[CURLOPT_COOKIE] = implode('; ', $cookiesData); } $curlHandle = curl_init(); curl_setopt_array($curlHandle, $curlOptions); $responseData = curl_exec($curlHandle); $code = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE); $error = curl_error($curlHandle); $responseHeaders = substr($responseData, 0, curl_getinfo($curlHandle, CURLINFO_HEADER_SIZE)); if (substr($responseHeaders, -1) !== "\n") { // because curl_getinfo($curlHandle, CURLINFO_HEADER_SIZE) is bugged on some PHP versions $responseHeaders = substr($responseData, 0, strpos($responseData, PHP_EOL . PHP_EOL)); } $responseOutput = substr($responseData, strlen($responseHeaders)); curl_close($curlHandle); $response = new Response(); $response->code = $code; $response->output = (string) ($postponedResponseId ? $postponedOutput : $responseOutput); $response->headerData = $this->parseHeaderData($responseHeaders); $response->cookies = $this->parseCookies($responseHeaders); try { if ($error || $code != 200 && $code != 204 && $code != 500) { throw new \Exception('Connection to "' . $this->serverWrapperUrl . '" failed with code "' . $code . '" and error: ' . $error . '" and response: "' . $responseOutput, $code); } $packageEncodedData = $postponedResponseId ? $responseOutput : $response->headerData; if ($packageEncodedData) { $packageData = $this->jsonDecode($packageEncodedData); if (!empty($packageData['isPostponed'])) { $request->cookies = $response->cookies; $response = $this->sendRequest($request, $packageData['id'], $responseOutput); $response->isPostponed = true; return $response; } $response->package = $this->initResponsePackage($packageData); } } catch (\Exception $exception) { throw new RequestFailed($exception, $request, $response); } return $response; }