{"id":14990008,"url":"https://github.com/puzza007/katipo","last_synced_at":"2025-05-16T06:05:13.625Z","repository":{"id":35944849,"uuid":"40233902","full_name":"puzza007/katipo","owner":"puzza007","description":"HTTP2 client for Erlang based on libcurl and libevent","archived":false,"fork":false,"pushed_at":"2025-03-23T04:44:02.000Z","size":2849,"stargazers_count":122,"open_issues_count":6,"forks_count":19,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-01T14:14:47.280Z","etag":null,"topics":["curl","erlang","hacktoberfest","http-client","http2","http2-client","libcurl","libcurl-multi","libevent"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/puzza007.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-05T08:28:14.000Z","updated_at":"2025-01-25T00:47:20.000Z","dependencies_parsed_at":"2024-05-28T00:58:45.974Z","dependency_job_id":"1dfa3d1d-a08e-47c6-ac8c-38943943c3cc","html_url":"https://github.com/puzza007/katipo","commit_stats":{"total_commits":227,"total_committers":14,"mean_commits":"16.214285714285715","dds":0.1145374449339207,"last_synced_commit":"352536bf639506ff17a29b8ba19a1053e9c9de5e"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puzza007%2Fkatipo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puzza007%2Fkatipo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puzza007%2Fkatipo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puzza007%2Fkatipo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/puzza007","download_url":"https://codeload.github.com/puzza007/katipo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247878017,"owners_count":21011158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","erlang","hacktoberfest","http-client","http2","http2-client","libcurl","libcurl-multi","libevent"],"created_at":"2024-09-24T14:19:19.457Z","updated_at":"2025-04-08T16:03:36.420Z","avatar_url":"https://github.com/puzza007.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"katipo\n=====\n\nAn HTTP/HTTP2 client library for Erlang built around libcurl-multi and libevent.\n\n### Status\n\n![build status](https://github.com/puzza007/katipo/actions/workflows/ci.yml/badge.svg)\n[![Hex pm](http://img.shields.io/hexpm/v/katipo.svg?style=flat)](https://hex.pm/packages/katipo)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-blue.svg)](https://hexdocs.pm/katipo)\n\n### Usage\n\n```erlang\n{ok, _} = application:ensure_all_started(katipo).\nPool = api_server,\n{ok, _} = katipo_pool:start(Pool, 2, [{pipelining, multiplex}]).\nUrl = \u003c\u003c\"https://example.com\"\u003e\u003e.\nReqHeaders = [{\u003c\u003c\"User-Agent\"\u003e\u003e, \u003c\u003c\"katipo\"\u003e\u003e}].\nOpts = #{headers =\u003e ReqHeaders,\n         body =\u003e \u003c\u003c\"0d5cb3c25b0c5678d5297efa448e1938\"\u003e\u003e,\n         connecttimeout_ms =\u003e 5000,\n         proxy =\u003e \u003c\u003c\"http://127.0.0.1:9000\"\u003e\u003e,\n         ssl_verifyhost =\u003e false,\n         ssl_verifypeer =\u003e false},\n{ok, #{status := 200,\n       headers := RespHeaders,\n       cookiejar := CookieJar,\n       body := RespBody}} = katipo:post(Pool, Url, Opts).\n```\n\nOr passing the entire request as a map\n\n```erlang\n{ok, _} = application:ensure_all_started(katipo).\nPool = api_server,\n{ok, _} = katipo_pool:start(Pool, 2, [{pipelining, multiplex}]).\nReqHeaders = [{\u003c\u003c\"User-Agent\"\u003e\u003e, \u003c\u003c\"katipo\"\u003e\u003e}].\nReq = #{url =\u003e \u003c\u003c\"https://example.com\"\u003e\u003e.\n        method =\u003e post,\n        headers =\u003e ReqHeaders,\n        body =\u003e \u003c\u003c\"0d5cb3c25b0c5678d5297efa448e1938\"\u003e\u003e,\n        connecttimeout_ms =\u003e 5000,\n        proxy =\u003e \u003c\u003c\"http://127.0.0.1:9000\"\u003e\u003e,\n        ssl_verifyhost =\u003e false,\n        ssl_verifypeer =\u003e false},\n{ok, #{status := 200,\n       headers := RespHeaders,\n       cookiejar := CookieJar,\n       body := RespBody}} = katipo:req(Pool, Req).\n```\n\n### Why\n\nWe wanted a compatible and high-performance HTTP client so took\nadvantage of the 15+ years of development that has gone into libcurl.\nTo allow large numbers of simultaneous connections libevent is used\nalong with the libcurl-multi interface.\n\n### Documentation\n\n#### API\n\n```erlang\n-type method() :: get | post | put | head | options.\nkatipo_pool:start(Name :: atom(), size :: pos_integer(), PoolOptions :: proplist()).\nkatipo_pool:stop(Name :: atom()).\n\nkatipo:req(Pool :: atom(), Req :: map()).\nkatipo:Method(Pool :: atom(), URL :: binary()).\nkatipo:Method(Pool :: atom(), URL :: binary(), ReqOptions :: map()).\n\n```\n\n#### Application Config\n| Option | Values | Default | Notes |\n|:-------|:-------|:--------|:------|\n| `mod_metrics` | \u003ccode\u003efolsom \u0026#124; exometer \u0026#124; noop\u003c/code\u003e | `noop` | see [erlang-metrics](https://github.com/benoitc/erlang-metrics) |\n\n#### Request options\n\n| Option                  | Type                                | Default     | Notes                                                                               |\n|:------------------------|:------------------------------------|:------------|:------------------------------------------------------------------------------------|\n| `headers`               | `[{binary(), iodata()}]`            | `[]`        |                                                                                     |\n| `cookiejar`             | opaque (returned in response)       | `[]`        |                                                                                     |\n| `body`                  | `iodata()`                          | `\u003c\u003c\u003e\u003e`      |                                                                                     |\n| `connecttimeout_ms`     | `pos_integer()`                     | 30000       | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html)                  |\n| `followlocation`        | `boolean()`                         | `false`     | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_FOLLOWLOCATION.html)                  |\n| `ssl_verifyhost`        | `boolean()`                         | `true`      | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html)                  |\n| `ssl_verifypeer`        | `boolean()`                         | `true`      | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html)                  |\n| `capath`                | `binary()`                          | `undefined` |                                                                                     |\n| `cacert`                | `binary()`                          | `undefined` |                                                                                     |\n| `timeout_ms`            | `pos_integer()`                     | 30000       |                                                                                     |\n| `maxredirs`             | `non_neg_integer()`                 | 9           |                                                                                     |\n| `proxy`                 | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html)                           |\n| `return_metrics`        | `boolean()`                         | `false`     |                                                                                     |\n| `tcp_fastopen`          | `boolean()`                         | `false`     | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_TCP_FASTOPEN.html) curl \u003e= 7.49.0     |\n| `interface`             | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_INTERFACE.html)                       |\n| `unix_socket_path`      | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_UNIX_SOCKET_PATH.html) curl \u003e= 7.40.0 |\n| `lock_data_ssl_session` | `boolean()`                         | `false`     | [docs](https://curl.haxx.se/libcurl/c/curl_share_setopt.html) curl \u003e= 7.23.0        |\n| `doh_url`               | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_DOH_URL.html) curl \u003e= 7.62.0          |\n| `http_version`          | `curl_http_version_none` \u003cbr\u003e `curl_http_version_1_0` \u003cbr\u003e `curl_http_version_1_1` \u003cbr\u003e `curl_http_version_2_0` \u003cbr\u003e `curl_http_version_2tls` \u003cbr\u003e `curl_http_version_2_prior_knowledge` | `curl_http_version_none` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_HTTP_VERSION.html) curl \u003e= 7.62.0 |\n| `sslcert`               | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_SSLCERT.html)                         |\n| `sslkey`                | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_SSLKEY.html)                          |\n| `sslkey_blob`           | `binary()` (DER format)             | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_SSLKEY_BLOB.html) curl \u003e= 7.71.0      |\n| `keypasswd`             | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_KEYPASSWD.html)                       |\n| `http_auth`             | `basic` \u003cbr\u003e `digest` \u003cbr\u003e `ntlm` \u003cbr\u003e `negotiate` | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html)                        |\n| `userpwd`               | `binary()`                          | `undefined` | [docs](https://curl.haxx.se/libcurl/c/CURLOPT_USERPWD.html)                         |\n\n#### Responses\n\n```erlang\n{ok, #{status := pos_integer(),\n       headers := headers(),\n       cookiejar := cookiejar(),\n       body := body(),\n       metrics =\u003e proplist()}}\n\n{error, #{code := atom(), message := binary()}}\n```\n\n#### Pool Options\n\n| Option                  | Type                          | Default      | Note                                                                                           |\n|:------------------------|:------------------------------|:-------------|:-----------------------------------------------------------------------------------------------|\n| `pipelining`            | `nothing` \u003cbr\u003e `http1` \u003cbr\u003e `multiplex` | `nothing`    | HTTP pipelining [CURLMOPT_PIPELINING](https://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html) |\n| `max_pipeline_length`   | `non_neg_integer()`           | 100          |                                                                                                |\n| `max_total_connections` | `non_neg_integer()`           | 0 (no limit) | [docs](https://curl.haxx.se/libcurl/c/CURLMOPT_MAX_TOTAL_CONNECTIONS.html)                     |\n\n#### Metrics\n\n* ok\n* error\n* status.XXX\n* total_time\n* curl_time\n* namelookup_time\n* connect_time\n* appconnect_time\n* pretransfer_time\n* redirect_time\n* starttransfer_time\n\n### System dependencies\n\n* libevent-dev\n* libcurl4-openssl-dev\n* make\n* curl\n* libssl-dev\n* gcc\n\n## Testing\n\nThe official Erlang Docker [image](https://hub.docker.com/_/erlang)\nhas everything needed to build and test Katipo\n\n### TODO\n\n* A more structured way to ifdef features based on curl version\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpuzza007%2Fkatipo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpuzza007%2Fkatipo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpuzza007%2Fkatipo/lists"}