{"id":15605129,"url":"https://github.com/ostinelli/net-http2","last_synced_at":"2025-05-15T04:04:22.699Z","repository":{"id":52706246,"uuid":"57323428","full_name":"ostinelli/net-http2","owner":"ostinelli","description":"NetHttp2 is an HTTP/2 client for Ruby.","archived":false,"fork":false,"pushed_at":"2025-02-25T18:25:37.000Z","size":132,"stargazers_count":141,"open_issues_count":18,"forks_count":32,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-10T10:09:51.330Z","etag":null,"topics":["client","gem","http2"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/ostinelli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2016-04-28T18:05:14.000Z","updated_at":"2025-02-25T18:24:56.000Z","dependencies_parsed_at":"2024-06-18T15:18:21.662Z","dependency_job_id":"53d86282-7712-4fb7-bb7c-2c98fc9f313c","html_url":"https://github.com/ostinelli/net-http2","commit_stats":{"total_commits":135,"total_committers":8,"mean_commits":16.875,"dds":"0.059259259259259234","last_synced_commit":"49387b55a58efea7357035811753757b535b62d6"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostinelli%2Fnet-http2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostinelli%2Fnet-http2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostinelli%2Fnet-http2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostinelli%2Fnet-http2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ostinelli","download_url":"https://codeload.github.com/ostinelli/net-http2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253487694,"owners_count":21916147,"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":["client","gem","http2"],"created_at":"2024-10-03T04:02:31.298Z","updated_at":"2025-05-15T04:04:22.677Z","avatar_url":"https://github.com/ostinelli.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/net-http2.svg)](https://badge.fury.io/rb/net-http2)\n\n# NetHttp2\n\nNetHttp2 is an HTTP/2 client for Ruby.\n\n## Installation\nJust install the gem:\n\n```\n$ gem install net-http2\n```\n\nOr add it to your Gemfile:\n\n```ruby\ngem 'net-http2'\n```\n\n## Usage\nNetHttp2 can perform sync and async calls. Sync calls are very similar to the HTTP/1 calls, while async calls take advantage of the streaming properties of HTTP/2.\n\nTo perform a sync call:\n```ruby\nrequire 'net-http2'\n\n# create a client\nclient = NetHttp2::Client.new(\"http://nghttp2.org\")\n\n# send request\nresponse = client.call(:get, '/')\n\n# read the response\nresponse.ok?      # =\u003e true\nresponse.status   # =\u003e '200'\nresponse.headers  # =\u003e {\":status\"=\u003e\"200\"}\nresponse.body     # =\u003e \"A body\"\n\n# close the connection\nclient.close\n```\n\nTo perform an async call:\n```ruby\nrequire 'net-http2'\n\n# create a client\nclient = NetHttp2::Client.new(\"http://nghttp2.org\")\n\n# prepare request\nrequest = client.prepare_request(:get, '/')\nrequest.on(:headers) { |headers| p headers }\nrequest.on(:body_chunk) { |chunk| p chunk }\nrequest.on(:close) { puts \"request completed!\" }\n\n# send\nclient.call_async(request)\n\n# Wait for all outgoing stream to be closed\nclient.join(timeout: 5)\n\n# close the connection\nclient.close\n```\n\n## Objects\n\n### `NetHttp2::Client`\n\n#### Methods\n\n * **new(url, options={})** → **`NetHttp2::Client`**\n\n Returns a new client. `url` is a `string` such as `http://nghttp2.org`.\n The current options are:\n\n  * `:connect_timeout`, specifies the max connect timeout in seconds (defaults to 60).\n  * `:ssl_context`, in case the url has an https scheme and you want your SSL client to use a custom context.\n  * `:proxy_addr`, `:proxy_port`, `:proxy_user`, `:proxy_pass`, specify Proxy connection parameters.\n\n To create a new client:\n ```ruby\n NetHttp2::Client.new(\"http://nghttp2.org\")\n ```\n\n To create a new client with a custom SSL context:\n ```ruby\n certificate = File.read(\"cert.pem\")\n ctx         = OpenSSL::SSL::SSLContext.new\n ctx.key     = OpenSSL::PKey::RSA.new(certificate, \"cert_password\")\n ctx.cert    = OpenSSL::X509::Certificate.new(certificate)\n\n NetHttp2::Client.new(\"https://nghttp2.org\", ssl_context: ctx)\n ```\n\n * **on(event, \u0026block)**\n\nAllows to set a callback for the client. The only available event is `:error`, which allows to set a callback when an error is raised at socket level, hence in the underlying socket thread.\n\n```ruby\nclient.on(:error) { |exception| puts \"Exception has been raised: #{exception}\" }\n```\n\n\u003e It is RECOMMENDED to set the `:error` callback: if none is defined, the underlying socket thread may raise an error in the main thread at unexpected execution times.\n\n * **uri** → **`URI`**\n\n Returns the URI of the endpoint.\n\n##### Blocking calls\nThese behave similarly to HTTP/1 calls.\n\n * **call(method, path, options={})** → **`NetHttp2::Response` or `nil`**\n\n Sends a request. Returns `nil` in case a timeout occurs.\n\n `method` is a symbol that specifies the `:method` header (`:get`, `:post`, `:put`, `:patch`, `:delete`, `:options`). The body, headers and query-string params of the request can be specified in the options, together with the timeout.\n\n ```ruby\n response_1 = client.call(:get, '/path1')\n response_2 = client.call(:get, '/path2', headers: { 'x-custom' =\u003e 'custom' })\n response_3 = client.call(:post, '/path3', body: \"the request body\", timeout: 1)\n response_3 = client.call(:post, '/path4', params: { page: 4 })\n ```\n\n##### Non-blocking calls\nThe real benefit of HTTP/2 is being able to receive body and header streams. Instead of buffering the whole response, you might want to react immediately upon receiving those streams. This is what non-blocking calls are for.\n\n * **prepare_request(method, path, options={})** → **`NetHttp2::Request`**\n\n Prepares an async request. Arguments are the same as the `call` method, with the difference that the `:timeout` option will be ignored. In an async call, you will need to write your own logic for timeouts.\n\n ```ruby\n request = client.prepare_request(:get, '/path', headers: { 'x-custom-header' =\u003e 'custom' })\n ```\n\n * **call_async(request)**\n\n Calls the server with the async request.\n\n * **join(timeout:)**\n\n Wait for all outstanding requests to be completed, optionally with a timeout for this condition to be met. Raises NetHttp2::AsyncRequestTimeout if the timeout is reached.\n\n\n### `NetHttp2::Request`\n\n#### Methods\n\n * **method** → **`symbol`**\n\n The request's method.\n\n * **uri** → **`URI`**\n\n The request's URI.\n\n * **path** → **`string`**\n\n The request's path.\n\n * **params** → **`hash`**\n\n The query string params in hash format, for example `{one: 1, two: 2}`. These will be encoded and appended to `path`.\n\n * **body** → **`string`**\n\n The request's body.\n\n * **timeout** → **`integer`**\n\n The request's timeout.\n\n * **on(event, \u0026block)**\n\n Allows to set a callback for the request. Available events are:\n\n  * `:headers`: triggered when headers are received (called once).\n  * `:body_chunk`: triggered when body chunks are received (may be called multiple times).\n  * `:close`: triggered when the request has been completed (called once).\n\n Even if NetHttp2 is thread-safe, the async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.\n\n ```ruby\n request.on(:headers) { |headers| p headers }\n request.on(:body_chunk) { |chunk| p chunk }\n request.on(:close) { puts \"request completed!\" }\n ```\n\n\n### `NetHttp2::Response`\n\n#### Methods\n\n * **ok?** → **`boolean`**\n\n Returns if the request was successful.\n\n * **headers** → **`hash`**\n\n Returns a Hash containing the Headers of the response.\n\n * **status** → **`string`**\n\n Returns the status code.\n\n * **body** → **`string`**\n\n Returns the RAW body of the response.\n\n\n## Thread-Safety\nNetHttp2 is thread-safe. However, some caution is imperative:\n\n  * The async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.\n  * Errors in the underlying socket loop thread will be raised in the main thread at unexpected execution times, unless you specify the `:error` callback on the Client (recommended).\n\n## Contributing\nSo you want to contribute? That's great! Please follow the guidelines below. It will make it easier to get merged in.\n\nBefore implementing a new feature, please submit a ticket to discuss what you intend to do. Your feature might already be in the works, or an alternative implementation might have already been discussed.\n\nDo not commit to master in your fork. Provide a clean branch without merge commits. Every pull request should have its own topic branch. In this way, every additional adjustments to the original pull request might be done easily, and squashed with `git rebase -i`. The updated branch will be visible in the same pull request, so there will be no need to open new pull requests when there are changes to be applied.\n\nEnsure to include proper testing. To run tests you simply have to be in the project's root directory and run:\n\n```bash\n$ rake\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fostinelli%2Fnet-http2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fostinelli%2Fnet-http2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fostinelli%2Fnet-http2/lists"}