{"id":13492930,"url":"https://github.com/gworley3/httpray","last_synced_at":"2025-08-23T13:10:59.075Z","repository":{"id":56876884,"uuid":"97152095","full_name":"gworley3/httpray","owner":"gworley3","description":"Non-blocking HTTP library for Ruby","archived":false,"fork":false,"pushed_at":"2018-01-12T00:45:19.000Z","size":16,"stargazers_count":20,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-22T17:09:04.841Z","etag":null,"topics":["http","http-client","non-blocking","nonblocking-sockets","ruby","tls","tls-support"],"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/gworley3.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":"2017-07-13T18:11:40.000Z","updated_at":"2024-03-14T05:29:33.000Z","dependencies_parsed_at":"2022-08-20T11:30:36.344Z","dependency_job_id":null,"html_url":"https://github.com/gworley3/httpray","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/gworley3/httpray","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gworley3%2Fhttpray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gworley3%2Fhttpray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gworley3%2Fhttpray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gworley3%2Fhttpray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gworley3","download_url":"https://codeload.github.com/gworley3/httpray/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gworley3%2Fhttpray/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261330120,"owners_count":23142482,"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":["http","http-client","non-blocking","nonblocking-sockets","ruby","tls","tls-support"],"created_at":"2024-07-31T19:01:10.552Z","updated_at":"2025-06-22T17:09:05.664Z","avatar_url":"https://github.com/gworley3.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# httpray\nNon-blocking HTTP library for Ruby\n\n[![Gem Version](https://badge.fury.io/rb/httpray.svg)](https://badge.fury.io/rb/httpray)\n\nStarted out the same as the [fire-and-forget](https://github.com/mattetti/fire-and-forget) gem but with a more exposed interface, TLS support, and a better name. Added ideas from [tcp_timeout](https://github.com/lann/tcp-timeout-ruby) and accidentally ended up creating a light-weight, non-blocking HTTP client.\n\nIt differs from other Ruby HTTP libraries that support async because it doesn't use Threads, making HTTPray much less resource intensive to use since it instead directly implements HTTP/HTTPS 1.0 using `Socket` and `IO#select` for timeouts. You can optionally ask to be handed back the socket before it is closed in case you want to listen for a response, but that's not really what you're here for.\n\nGreat for use with sending data to HTTP endpoints for which you are willing to accept a UDP-style best-effort approach, but with the added guarantee of TCP that the packets made it to the server. Only the server will know what it did with the data, though!\n\n## Install\n\n```ruby\ngem \"httpray\"\n```\n\n## Use\n\n```ruby\nrequire 'httpray'\n\n# def HTTParty.request!(method, uri, headers = {}, body = nil, timeout = 1, ssl_context = nil)\n\n# send an HTTP request and don't listen for the response\nHTTPray.request(\n  \"POST\",\n  \"https://your.diety/prayers\",\n  {\"Content-Type\" =\u003e \"application/prayer\"},\n  \"It's me, Margret\",\n  1) # timeout in seconds\n\n# party with a response, but costs a Fiber\nHTTPray.request(\"GET\", \"https://your.diety/answered_prayers\") do |socket|\n  socket.gets\nend\n\n# party dangerously (you have to close your own socket!)\nsocket = HTTPray.request!(\"GET\", \"https://your.diety/answered_prayers\")\nputs socket.gets\nsocket.close\n\n# use a persistent connection to keep the party rolling\n# will automatically reconnect if connection is lost\nuri = URI.parse(\"https://your.diety/pray\")\nark = HTTPray::Connection.new(\n  uri.host,\n  uri.port,\n  1, #timeout\n  OpenSSL::SSL::SSLContext.new, #ssl context\n  1, #retries on error\n  10) #seconds to wait after all retries failed before trying again on a subsequent request\nark.request(\"POST\", uri, \n  {\"Content-Type\" =\u003e \"application/prayer\"},\n  \"Why did it have to be snakes?\")\nark.socket.close\nark.request(\"POST\", uri, \n  {\"Content-Type\" =\u003e \"application/prayer\"},\n  \"Don't call me junior!\")\n\n```\n\n## Help\n\nHTTPray has minimal convenience and sanitization features because I didn't need them. All that it does is fill in the Host, User-Agent, Accept, and Content-Length headers for you. The body must be a string, so convert it yourself first. The URI can be a `URI` or a `String` that will go through `URI.parse`. You're welcome.\n\nIf you're using `Connection` with TLS you need to provide an `OpenSSL::SSL::SSLContext` when creating the connection. `HTTPray.request!` is more forgiving and if you don't give it one it will create it for you if needed. `Connection` also has some fancy retry and circuit breaker logic so you can assume your request always writes even if it doesn't without major performance impacts.\n\nTimeout support does not extend to the response since you just get back a `Socket`. You're on your own for how you want to handle that.\n\nIf you want it to be easier to use, feel free to submit pull requests. As long as you don't break existing functionality I will probably accept them.\n\n## Tests\n\nThere are some tests that exercise the code paths. You can run them with:\n\n```bash\nruby -I . test/httpray_test.rb\n```\n\nUnfortunately they have to hit real network endpoints, so they won't work without a network.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgworley3%2Fhttpray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgworley3%2Fhttpray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgworley3%2Fhttpray/lists"}