/** * Parse\Client::_request, internal method for communicating with Parse. * * @param string $method HTTP Method for this request. * @param string $relativeUrl REST API Path. * @param null $sessionToken Session Token. * @param null $data Data to provide with the request. * @param bool $useMasterKey Whether to use the Master Key. * @param bool $appRequest App request to create or modify a application * @param bool $returnHeaders Returns response headers * * @throws \Exception * * @return mixed Result from Parse API Call. */ public static function _request( $method, $relativeUrl, $sessionToken = null, $data = null, $useMasterKey = false, $appRequest = false, $returnHeaders = false ) { if ($data === '[]') { $data = '{}'; } if ($appRequest) { self::assertAppInitialized(); $headers = self::_getAppRequestHeaders(); } else { self::assertParseInitialized(); $headers = self::_getRequestHeaders($sessionToken, $useMasterKey); } $url = self::$serverURL.'/'.self::$mountPath.ltrim($relativeUrl, '/'); if ($method === 'GET' && !empty($data)) { $url .= '?'.http_build_query($data); } $rest = curl_init(); curl_setopt($rest, CURLOPT_URL, $url); curl_setopt($rest, CURLOPT_RETURNTRANSFER, 1); if ($method === 'POST') { $headers[] = 'Content-Type: application/json'; curl_setopt($rest, CURLOPT_POST, 1); curl_setopt($rest, CURLOPT_POSTFIELDS, $data); } if ($method === 'PUT') { $headers[] = 'Content-Type: application/json'; curl_setopt($rest, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($rest, CURLOPT_POSTFIELDS, $data); } if ($method === 'DELETE') { curl_setopt($rest, CURLOPT_CUSTOMREQUEST, $method); } curl_setopt($rest, CURLOPT_HTTPHEADER, $headers); if (!is_null(self::$connectionTimeout)) { curl_setopt($rest, CURLOPT_CONNECTTIMEOUT, self::$connectionTimeout); } if (!is_null(self::$timeout)) { curl_setopt($rest, CURLOPT_TIMEOUT, self::$timeout); } if ($returnHeaders) { curl_setopt($rest, CURLOPT_HEADER, 1); } $response = curl_exec($rest); $status = curl_getinfo($rest, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($rest, CURLINFO_CONTENT_TYPE); if (curl_errno($rest)) { if (self::$enableCurlExceptions) { throw new ParseException(curl_error($rest), curl_errno($rest)); } else { return false; } } $headerData = []; if ($returnHeaders) { $headerSize = curl_getinfo($rest, CURLINFO_HEADER_SIZE); $headerContent = substr($response, 0, $headerSize); $headerData = self::parseCurlHeaders($headerContent); $response = substr($response, $headerSize); } curl_close($rest); if (strpos($contentType, 'text/html') !== false) { throw new ParseException('Bad Request', -1); } $decoded = json_decode($response, true); if (isset($decoded['error'])) { throw new ParseException( $decoded['error'], isset($decoded['code']) ? $decoded['code'] : 0 ); } $result = $decoded; if ($returnHeaders) { $result['_headers'] = $headerData; } return $result; } private static function parseCurlHeaders($headerContent) { $headers = []; $exploded = explode("\r\n", $headerContent); foreach ($exploded as $i => $line) { if (empty($line)) { continue; } elseif ($i === 0) { $headers['http_code'] = $line; } else { list ($headerName, $headerValue) = explode(': ', $line); $headers[$headerName] = $headerValue; } } return $headers; }