{"id":39452898,"url":"https://github.com/stiction/http","last_synced_at":"2026-01-18T04:31:51.900Z","repository":{"id":48188129,"uuid":"516750525","full_name":"stiction/http","owner":"stiction","description":"An easy to use HTTP / HTTPS / REST client","archived":false,"fork":false,"pushed_at":"2022-08-28T13:50:55.000Z","size":157,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-25T00:03:27.580Z","etag":null,"topics":["curl","http","https","json","php","rest","swoole"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stiction.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-22T12:56:10.000Z","updated_at":"2022-07-23T14:55:28.000Z","dependencies_parsed_at":"2022-09-23T16:51:12.174Z","dependency_job_id":null,"html_url":"https://github.com/stiction/http","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/stiction/http","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stiction%2Fhttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stiction%2Fhttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stiction%2Fhttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stiction%2Fhttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stiction","download_url":"https://codeload.github.com/stiction/http/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stiction%2Fhttp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28529660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["curl","http","https","json","php","rest","swoole"],"created_at":"2026-01-18T04:31:50.961Z","updated_at":"2026-01-18T04:31:51.861Z","avatar_url":"https://github.com/stiction.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# http\n\nAn easy to use HTTP / HTTPS / REST client\n\n## Installation\n\n```bash\ncomposer require stiction/http\n```\n\n## Quick start\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$cat = new CurlCat();\n$text = $cat-\u003eurl('https://api.github.com/zen')\n    -\u003esslVerify()\n    -\u003etimeout(3)\n    -\u003etry(3, 500)\n    -\u003eencoding()\n    -\u003euserAgent('stiction/http')\n    -\u003eignoreCode()\n    -\u003efetch();\nvar_dump($text);\n\n$cat2 = clone $cat;\n$json = $cat2-\u003eurl('https://api.github.com/users/defunkt')\n    -\u003efetchJson();\nvar_dump($json);\n```\n\n## Documentation\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$cat = new CurlCat(); // construct a client\n\n$cat2 = clone $cat; // clone a client with the same options\nunset($cat2); // destruct\n\n// set HTTP request method (verb)\n$cat-\u003eget();\n$cat-\u003epost();\n$cat-\u003eput();\n$cat-\u003epatch();\n$cat-\u003edelete();\n$cat-\u003emethod(CurlCat::METHOD_OPTIONS);\n\n// set url\n$cat-\u003eurl('https://api.github.com/zen');\n$cat-\u003eurl('https://api.github.com/zen?foo=1\u0026bar=2');\n$cat-\u003eurl('https://api.github.com/zen', [\n    'foo' =\u003e '1',\n    'bar' =\u003e '2',\n]);\n$cat-\u003eurl('https://api.github.com/zen?foo=1\u0026bar=2', [\n    'baz' =\u003e '3',\n]);\n\n$cat-\u003eheader('TOKEN', 'foo-bar-baz'); // set header\n$cat-\u003eheader('TOKEN', null); // remove header\n$cat-\u003euserAgent('stiction/http'); // set User-Agent header\n$cat-\u003eencoding(); // Accept-Encoding Content-Encoding\n$cat-\u003etype('application/xml'); // set request body Content-Type header\n\n$cat-\u003ebody([ // multipart/form-data\n    'foo' =\u003e '1',\n    'file' =\u003e new CurlFile(__FILE__), // upload files\n]);\n$cat-\u003ebodyUrlencoded('foo=1\u0026bar=2'); // application/x-www-form-urlencoded\n$cat-\u003ebodyRaw('hello world', 'text/plain'); // custom request body type\n$cat-\u003ebodyJson([ // request with json data\n    'foo' =\u003e 1,\n    'bar' =\u003e 'world',\n    'baz' =\u003e [2, 3, 5],\n]);\n$cat-\u003ebodyRaw('3.14', 'application/json'); // request with json data\n\n$cat-\u003esetopt(CURLOPT_VERBOSE, true); // curl options\n$cat-\u003eunsetopt(CURLOPT_VERBOSE); // unset curl options\n\n$cat-\u003etimeout(3); // timeout 3 seconds\n$cat-\u003etimeoutMs(500); // timeout 500 milliseconds\n\n$cat-\u003emaxSize(1024 * 1024); // limit response size\n$cat-\u003emaxSize(-1); // no limit on response size\n\n$cat-\u003esslVerify(); // verify ssl/tls with builtin cacert.pem\n$cat-\u003esslVerify('/path/to/cacert.pem'); // verify ssl/tls with the specified cacert.pem\n\n$cat-\u003efollowLocation(); // allow HTTP 3xx redirection\n$cat-\u003efollowLocation(false); // not allow HTTP 3xx redirection\n$cat-\u003emaxRedirects(3); // allows 3 redirects\n\n$cat-\u003eignoreCode(); // return the response no matter what HTTP code the server sends\n$cat-\u003eignoreCode(false); // throws if the response HTTP code is not 2xx\n\n$cat-\u003etry(3, 500); // try at most 3 times with a 500 milliseconds interval\n\n$cat-\u003everbose(); // output verbose information\n$cat-\u003everbose(false); // no verbose information\n\n$cat-\u003efetch(); // fetch the response as a string\n$cat-\u003efetchJson(); // fetch the response as a json containing an object or an array\n$cat-\u003efetchJson(true); // check response Content-Type\n\n$cat-\u003eresTries(); // try times to finish the request\n$cat-\u003eresInfo(); // curl_getinfo()\n$cat-\u003eresInfo(CURLINFO_TOTAL_TIME); // curl_getinfo()\n$cat-\u003eresCode(); // response HTTP code\n$cat-\u003eresType(); // response Content-Type\n$cat-\u003eresHeaderLine('X-Powered-By'); // response header\n$cat-\u003eresHeader('X-Powered-By'); // response header\n$cat-\u003eresAllHeaders(); // all response headers\n$cat-\u003eresAllHeadersLine(); // all response headers\n$cat-\u003eresExceptions(); // exceptions thrown including failed tries\n```\n\n## Examples\n\n### headers also cloned\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$cat = new CurlCat();\n$cat-\u003eheader('TOKEN', 'abc-def');\n$cat-\u003ebodyJson(['foo' =\u003e 1]);\n\n// TOKEN: abc-def\n// Content-Type: application/json\n$cat2 = clone $cat;\n\n// body() and bodyUrlencoded() methods can set Content-Type properly\n$cat2-\u003ebody(['bar' =\u003e '2']);\n$cat2-\u003ebodyUrlencoded('foo=1\u0026bar=2');\n\n// remove other headers as needed\n$cat2-\u003eheader('TOKEN', null);\n```\n\n### wechat\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$cat = new CurlCat();\n$cat-\u003eurl('https://api.weixin.qq.com/cgi-bin/token', [\n    'grant_type' =\u003e 'client_credential',\n    'appid' =\u003e 'foobarbaz', // appid\n    'secret' =\u003e 'foobarbaz-secret', // secret\n]);\n$cat-\u003esslVerify();\n$res = $cat-\u003efetchJson();\n$errCode = $res['errcode'] ?? 0;\nif ($errCode !== 0) {\n    throw new RuntimeException($res['errmsg']);\n}\nvar_dump($res);\n$accessToken = $res['access_token'];\n\n$cat2 = clone $cat;\n$cat2-\u003eurl('https://api.weixin.qq.com/cgi-bin/user/get', [\n    'access_token' =\u003e $accessToken,\n]);\n$res2 = $cat2-\u003efetchJson();\nvar_dump($res2);\n```\n\n### aliyun OSS\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$accessKeyId = 'foobarbaz'; //\n$accessKeySecret = 'foobarbaz-secret'; //\n$bucketName = 'foo'; //\n$endpoint = 'oss-cn-shanghai.aliyuncs.com'; //\n$verb = CurlCat::METHOD_PUT;\n$body = 'hello world';\n$contentMd5 = '';\n$contentType = 'text/plain';\n$date = date(DATE_RFC7231);\n$canonicalizedOSSHeaders = '';\n$objectName = 'test/hello.txt';\n$canonicalizedResource = \"/$bucketName/$objectName\";\n\n$str = $verb . \"\\n\" .\n    $contentMd5 . \"\\n\" .\n    $contentType . \"\\n\" .\n    $date . \"\\n\" .\n    $canonicalizedOSSHeaders .\n    $canonicalizedResource;\n$signature = base64_encode(hash_hmac('sha1', $str, $accessKeySecret, true));\n$authorization = \"OSS $accessKeyId:$signature\";\n\n$cat = new CurlCat();\n$cat-\u003eurl(\"https://$bucketName.$endpoint/$objectName\")\n    -\u003emethod($verb)\n    -\u003esslVerify()\n    -\u003eignoreCode()\n    -\u003eheader('Date', $date)\n    -\u003eheader('Authorization', $authorization)\n    -\u003ebodyRaw($body, $contentType);\n$res = $cat-\u003efetch();\nvar_dump($res);\nvar_dump($cat-\u003eresHeaderLine('x-oss-request-id'));\n\n// PutObjectTagging\n$body = \u003c\u003c\u003cEOT\n\u003cTagging\u003e\n  \u003cTagSet\u003e\n    \u003cTag\u003e\n      \u003cKey\u003efoo\u003c/Key\u003e\n      \u003cValue\u003e42\u003c/Value\u003e\n    \u003c/Tag\u003e\n  \u003c/TagSet\u003e\n\u003c/Tagging\u003e\nEOT;\n$contentType = 'application/xml';\n$date = date(DATE_RFC7231);\n$canonicalizedResource = \"/$bucketName/$objectName?tagging\";\n$str = $verb . \"\\n\" .\n    $contentMd5 . \"\\n\" .\n    $contentType . \"\\n\" .\n    $date . \"\\n\" .\n    $canonicalizedOSSHeaders .\n    $canonicalizedResource;\n$signature = base64_encode(hash_hmac('sha1', $str, $accessKeySecret, true));\n$authorization = \"OSS $accessKeyId:$signature\";\n\n$cat2 = clone $cat;\n$cat2-\u003eurl(\"https://$bucketName.$endpoint/$objectName?tagging\")\n    -\u003eheader('Date', $date)\n    -\u003eheader('Authorization', $authorization)\n    -\u003ebodyRaw($body, $contentType);\n$res2 = $cat2-\u003efetch();\nvar_dump($res2);\nvar_dump($cat2-\u003eresHeaderLine('x-oss-request-id'));\n```\n\n### Amazon S3\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\n$awsAccessKeyId = 'xxx';\n$awsAccessSecret = 'xxx';\n$bucket = 'xxx';\n$region = 'xxx';\n\n$key = 'foo/bar/baz.txt';\n$date = date(DATE_RFC7231);\n$httpVerb = 'PUT';\n$content = 'hello';\n$contentType = 'text/plain';\n$contentMd5 = '';\n$url = \"https://$bucket.s3.$region.amazonaws.com/$key\";\n\n$canonicalizedAmzHeaders = '';\n$canonicalizedResource = \"/$bucket/$key\";\n$strToSign = $httpVerb . \"\\n\" . $contentMd5 . \"\\n\" . $contentType . \"\\n\" . $date . \"\\n\" . $canonicalizedAmzHeaders . $canonicalizedResource;\n$signature = base64_encode(hash_hmac('sha1', $strToSign, $awsAccessSecret, true));\n$authorization = \"AWS $awsAccessKeyId:$signature\";\n\n$cat = new CurlCat();\n$cat-\u003emethod($httpVerb)\n    -\u003eurl($url)\n    -\u003esslVerify()\n    -\u003eignoreCode()\n    -\u003eheader('Date', $date)\n    -\u003eheader('Authorization', $authorization)\n    -\u003etype($contentType)\n    -\u003ebodyRaw($content);\n$cat-\u003efetch();\nvar_dump($cat-\u003eresHeaderLine('x-amz-request-id'));\n```\n\n### swoole\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\nuse Swoole\\Http\\Server;\nuse Swoole\\Http\\Request;\nuse Swoole\\Http\\Response;\nuse Swoole\\Coroutine;\n\n$port = 8080;\necho \"server :$port\", PHP_EOL;\n\nCoroutine::set(['hook_flags' =\u003e SWOOLE_HOOK_ALL]);\n\n$http = new Server('0.0.0.0', $port);\n$http-\u003eon('Request', function (Request $request, Response $response) {\n    try {\n        $cat = new CurlCat();\n        $text = $cat-\u003eurl('https://api.github.com/zen')\n            -\u003esslVerify()\n            -\u003etimeout(3)\n            -\u003euserAgent('curl')\n            -\u003eignoreCode()\n            -\u003efetch();\n        $response-\u003eend($text);\n    } catch (Exception $e) {\n        $response-\u003estatus(500, 'Internal Server Error');\n        $response-\u003eend($e-\u003egetMessage());\n    }\n});\n$http-\u003estart();\n```\n\n### How about a lovely dog\n\n```php\n\u003c?php\n\nrequire 'vendor/autoload.php';\n\nuse Stiction\\Http\\CurlCat;\n\nclass CurlDog extends CurlCat\n{\n}\n\n$dog = new CurlDog();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstiction%2Fhttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstiction%2Fhttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstiction%2Fhttp/lists"}