{"id":18728771,"url":"https://github.com/rubyonworld/ftw","last_synced_at":"2025-07-26T02:42:07.280Z","repository":{"id":174007911,"uuid":"542162128","full_name":"RubyOnWorld/ftw","owner":"RubyOnWorld","description":"SPDY should automatically be attempted. The caller should be unaware.","archived":false,"fork":false,"pushed_at":"2022-09-28T01:15:37.000Z","size":596,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-28T14:26:23.207Z","etag":null,"topics":["rails","ruby","should","spdy"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RubyOnWorld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-09-27T15:38:11.000Z","updated_at":"2022-09-28T04:08:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"9c66d5cd-85ef-4772-b454-20db16623178","html_url":"https://github.com/RubyOnWorld/ftw","commit_stats":null,"previous_names":["rubyonworld/ftw"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fftw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fftw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fftw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fftw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RubyOnWorld","download_url":"https://codeload.github.com/RubyOnWorld/ftw/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239599039,"owners_count":19665911,"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":["rails","ruby","should","spdy"],"created_at":"2024-11-07T14:24:18.215Z","updated_at":"2025-02-19T04:49:27.400Z","avatar_url":"https://github.com/RubyOnWorld.png","language":"Ruby","readme":"# For The Web\n\n## Getting Started\n\n* For web agents: {FTW::Agent}\n* For dns: {FTW::DNS}\n* For tcp connections: {FTW::Connection}\n* For tcp servers: {FTW::Server}\n\n## Overview\n\nnet/http is pretty much not good. Additionally, DNS behavior in ruby changes quite frequently.\n\nI primarily want two things in both client and server operations:\n\n* A consistent API with good documentation, readable code, and high quality tests.\n* Modern web features: websockets, spdy, etc.\n\nDesired features:\n\n* Awesome documentation\n* A HTTP client that acts as a full user agent, not just a single connections. (With connection reuse)\n* HTTP and SPDY support.\n* WebSockets support.\n* SSL/TLS support.\n* Browser Agent features like cookies and caching\n* An API that lets me do what I need.\n* Server and Client modes.\n* Support for both normal operation and EventMachine would be nice.\n\nFor reference:\n\n* [DNS in Ruby stdlib is broken](https://github.com/jordansissel/experiments/tree/master/ruby/dns-resolving-bug), so I need to provide my own DNS api.\n\n## Agent API\n\nReference: {FTW::Agent}\n\n### Common case\n\n    agent = FTW::Agent.new\n\n    request = agent.get(\"http://www.google.com/\")\n    response = request.execute\n    puts response.body.read\n\n    # Simpler\n    response = agent.get!(\"http://www.google.com/\").read\n    puts response.body.read\n\n### SPDY\n\n* This is not implemented yet\n\nSPDY should automatically be attempted. The caller should be unaware.\n\nI do not plan on exposing any direct means for invoking SPDY.\n\n### WebSockets\n\n    # 'http(s)' or 'ws(s)' urls are valid here. They will mean the same thing.\n    websocket = agent.websocket!(\"http://somehost/endpoint\")\n\n    websocket.publish(\"Hello world\")\n    websocket.each do |message|\n      puts :received =\u003e message\n    end\n\n## Web Server API\n\nI have implemented a rack server, Rack::Handler::FTW. It does not comply fully\nwith the Rack spec. See 'Rack Compliance Issues' below.\n\nUnder the FTW rack handler, there is an environment variable added,\n\"ftw.connection\". This will be a FTW::Connection you can use for CONNECT,\nUpgrades, etc. \n\nThere's also a websockets wrapper, FTW::WebSockets::Rack, that will help you\nspecifically with websocket requests and such.\n\n## Rack Compliance issues\n\nDue to some awkward and bad requirements - specifically those around the\nspecified behavior of 'rack.input' - I can't support the rack specification fully.\n\nThe 'rack.input' must be an IO-like object supporting #rewind which rewinds to\nthe beginning of the request.\n\nFor high-data connections (like uploads, HTTP CONNECT, and HTTP Upgrade), it's\nnot practical to hold the entire history of time in a buffer. We'll run out of\nmemory, you crazy fools!\n\nDetails here: https://github.com/rack/rack/issues/347\n\n## Other Projects\n\nHere are some related projects that I have no affiliation with:\n\n* https://github.com/igrigorik/em-websocket - websocket server for eventmachine\n* https://github.com/faye/faye - pubsub for the web (includes a websockets implementation)\n* https://github.com/faye/faye-websocket-ruby - websocket client and server in ruby\n* https://github.com/lifo/cramp - real-time web framework (async, websockets)\n* https://github.com/igrigorik/em-http-request - HTTP client for EventMachine\n* https://github.com/geemus/excon - http client library\n\nGiven some of the above (especially the server-side stuff), I'm likely try and integrate\nwith those projects. For example, writing a Faye handler that uses the FTW server, if the\nFTW web server even stays around.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyonworld%2Fftw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubyonworld%2Fftw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyonworld%2Fftw/lists"}