/** * @test */ public function Can_invoke_get() { // arrange $uri = 'http://example.com/foo/bar?baz=qux'; MockPlug::register(MockRequest::newMockRequest(HttpPlug::VERB_GET, $uri, []), MockResponse::newMockResponse(HttpPlug::HTTPSUCCESS, [], ['page'])); $Plug = HttpPlug::newPlug($uri); // act $Result = new XArray($Plug->get()); // assert $this->assertEquals(200, $Result->getVal('status')); $this->assertEquals('page', $Result->getVal('body')); }
/** * @test */ public function Can_invoke_get() { // arrange $uri = 'http://example.com/@api/deki/pages/=foo'; MockPlug::register(MockRequest::newMockRequest(ApiPlug::VERB_GET, $uri, []), MockResponse::newMockResponse(ApiPlug::HTTPSUCCESS, [], ['page'])); $Plug = ApiPlug::newPlug($uri); // act $Result = $Plug->get(); // assert $this->assertEquals(200, $Result->getStatus()); $this->assertEquals('page', $Result->getVal('body')); }
/** * @param string $verb * @param string $content * @param string $contentType * @param bool $contentFromFile - if true, then $content is assumed to be a file path * @return array - request response */ protected function invoke($verb, $content = null, $contentType = null, $contentFromFile = false) { // create the request info $request = ['verb' => $verb, 'uri' => $this->getUri(), 'start' => 0, 'end' => 0, 'headers' => $this->headers]; // explicitly set content length for empty bodies if (is_null($content) || $content === false || is_string($content) && strlen($content) == 0) { self::setMultiValueArray($request['headers'], self::HEADER_CONTENT_LENGTH, 0); } // set the content type if provided if (!is_null($contentType)) { self::setMultiValueArray($request['headers'], self::HEADER_CONTENT_TYPE, $contentType); } $this->invokeApplyCredentials($request['headers']); // if MockPlug returns a response, curl is not needed if (MockPlug::$registered) { $Response = MockPlug::getResponse(MockRequest::newMockRequest($verb, $request['uri'], $request['headers'], $content)); if ($Response !== null) { $response = ['verb' => $verb, 'body' => $Response->body, 'headers' => $Response->headers, 'status' => $Response->status, 'errno' => '', 'error' => '']; if (isset($Response->headers[self::HEADER_CONTENT_TYPE])) { $response['type'] = $Response->headers[self::HEADER_CONTENT_TYPE]; } $request['headers'] = self::flattenPlugHeaders($request['headers']); return $this->invokeComplete($request, $response); } } // normal plug request $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $request['uri']); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_MAXREDIRS, 10); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $verb); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // custom behavior based on the request type switch ($verb) { case self::VERB_PUT: if ($contentFromFile && is_file($content)) { // read in content from file curl_setopt($curl, CURLOPT_PUT, true); curl_setopt($curl, CURLOPT_INFILE, fopen($content, 'r')); curl_setopt($curl, CURLOPT_INFILESIZE, filesize($content)); } break; case self::VERB_POST: /** * The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with @ and use the full path. * This can either be passed as a urlencoded string like 'para1=val1¶2=val2&...' or as an array with the field name as * key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. */ if ($contentFromFile && is_file($content)) { curl_setopt($curl, CURLOPT_POST, true); $postFields = ['file' => '@' . $content]; curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields); } else { curl_setopt($curl, CURLOPT_POSTFIELDS, $content); } break; default: } // add the request headers if (!empty($request['headers'])) { // flatten headers $request['headers'] = self::flattenPlugHeaders($request['headers']); curl_setopt($curl, CURLOPT_HTTPHEADER, $request['headers']); } // retrieve the response headers curl_setopt($curl, CURLOPT_HEADER, true); // execute request $request['start'] = $this->getTime(); $httpMessage = curl_exec($curl); $request['end'] = $this->getTime(); // create the response info $response = ['headers' => [], 'status' => curl_getinfo($curl, CURLINFO_HTTP_CODE), 'type' => curl_getinfo($curl, CURLINFO_CONTENT_TYPE), 'errno' => curl_errno($curl), 'error' => curl_error($curl)]; curl_close($curl); // header parsing // make sure ther response is not empty before trying to parse // also make sure there isn't a curl error if ($response['status'] != 0 && $response['errno'] == 0) { // split response into header and response body do { list($headers, $httpMessage) = explode("\r\n\r\n", $httpMessage, 2); $headers = explode("\r\n", $headers); // First line of headers is the HTTP response code, remove it $httpStatus = array_shift($headers); // check if there is another header chunk to parse } while ($httpStatus == 'HTTP/1.1 100 Continue'); // set the response body $response['body'] =& $httpMessage; // put the rest of the headers in an array foreach ($headers as $headerLine) { list($header, $value) = explode(': ', $headerLine, 2); // allow for multiple header values self::setMultiValueArray($response['headers'], $header, trim($value), true); } } return $this->invokeComplete($request, $response); }