{"id":13429741,"url":"https://github.com/taf2/curb","last_synced_at":"2025-05-11T14:00:01.623Z","repository":{"id":414789,"uuid":"34274","full_name":"taf2/curb","owner":"taf2","description":"Ruby bindings for libcurl","archived":false,"fork":false,"pushed_at":"2025-03-13T21:51:54.000Z","size":1268,"stargazers_count":1299,"open_issues_count":20,"forks_count":231,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-05-11T13:59:53.368Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","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/taf2.png","metadata":{"files":{"readme":"README.markdown","changelog":"ChangeLog.md","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,"zenodo":null}},"created_at":"2008-07-15T15:31:43.000Z","updated_at":"2025-04-16T13:03:52.000Z","dependencies_parsed_at":"2023-01-13T10:16:01.066Z","dependency_job_id":"ecc3352d-ced0-4698-b49c-17d745b9b175","html_url":"https://github.com/taf2/curb","commit_stats":{"total_commits":714,"total_committers":141,"mean_commits":"5.0638297872340425","dds":0.73109243697479,"last_synced_commit":"96b874f08c30208cf4182b1e4cf1c727d839f7ba"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taf2%2Fcurb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taf2%2Fcurb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taf2%2Fcurb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taf2%2Fcurb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taf2","download_url":"https://codeload.github.com/taf2/curb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253576264,"owners_count":21930169,"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":[],"created_at":"2024-07-31T02:00:44.494Z","updated_at":"2025-05-11T14:00:01.591Z","avatar_url":"https://github.com/taf2.png","language":"C","readme":"# Curb - Libcurl bindings for Ruby\n\n* [CI Build Status](https://github.com/taf2/curb/actions/workflows/CI.yml)\n* [rubydoc rdoc](http://www.rubydoc.info/github/taf2/curb/)\n* [github project](http://github.com/taf2/curb/tree/master)\n\nCurb (probably CUrl-RuBy or something) provides Ruby-language bindings for the\nlibcurl(3), a fully-featured client-side URL transfer library.\ncURL and libcurl live at [https://curl.se/libcurl/](https://curl.se/libcurl/) .\n\nCurb is a work-in-progress, and currently only supports libcurl's `easy` and `multi` modes.\n\nA big advantage to Curb over all other known ruby http libraries is it's ability to handle timeouts without the use of threads.\n\n## License\n\nCurb is copyright (c) 2006 Ross Bamford, and released under the terms of the\nRuby license. See the LICENSE file for the gory details.\n\n## Easy mode\n\nGET request\n```\n  res = Curl.get(\"https://www.google.com/\") {|http|\n    http.timeout = 10 # raise exception if request/response not handled within 10 seconds\n  }\n  puts res.code\n  puts res.head\n  puts res.body\n```\n\nPOST request\n```\n  res = Curl.post(\"https://your-server.com/endpoint\", {post: \"this\"}.to_json) {|http|\n    http.headers[\"Content-Type\"] = \"application/json\"\n  }\n  puts res.code\n  puts res.head\n  puts res.body\n```\n\n## FTP Support\n\nrequire 'curb'\n\n### Basic FTP Download\n```ruby\nputs \"=== FTP Download Example ===\"\nftp = Curl::Easy.new('ftp://ftp.example.com/remote/file.txt')\nftp.username = 'user'\nftp.password = 'password'\nftp.perform\nputs ftp.body\n```\n\n### FTP Upload\n```ruby\nputs \"\\n=== FTP Upload Example ===\"\nupload = Curl::Easy.new('ftp://ftp.example.com/remote/upload.txt')\nupload.username = 'user'\nupload.password = 'password'\nupload.upload = true\nupload.put_data = File.read('local_file.txt')\nupload.perform\n```\n\n### List Directory Contents\n```ruby\nputs \"\\n=== FTP Directory Listing Example ===\"\nlist = Curl::Easy.new('ftp://ftp.example.com/remote/directory/')\nlist.username = 'user'\nlist.password = 'password'\nlist.dirlistonly = true\nlist.perform\nputs list.body\n```\n\n### Advanced FTP Usage with Various Options\n```\nputs \"\\n=== Advanced FTP Example ===\"\nadvanced = Curl::Easy.new do |curl|\n  curl.url = 'ftp://ftp.example.com/remote/file.txt'\n  curl.username = 'user'\n  curl.password = 'password'\n\n  # FTP Options\n  curl.ftp_response_timeout = 30\n  curl.ftp_create_missing_dirs = true   # Create directories if they don't exist\n  curl.ftp_filemethod = Curl::CURL_MULTICWD  # Use multicwd method for traversing paths\n\n  # SSL/TLS Options for FTPS\n  curl.use_ssl = Curl::CURLUSESSL_ALL  # Use SSL/TLS for control and data\n  curl.ssl_verify_peer = true\n  curl.ssl_verify_host = true\n  curl.cacert = \"/path/to/cacert.pem\"\n\n  # Progress callback\n  curl.on_progress do |dl_total, dl_now, ul_total, ul_now|\n    puts \"Download: #{dl_now}/#{dl_total} Upload: #{ul_now}/#{ul_total}\"\n    true # must return true to continue\n  end\n\n  # Debug output\n  curl.verbose = true\n  curl.on_debug do |type, data|\n    puts \"#{type}: #{data}\"\n    true\n  end\nend\n\nadvanced.perform\n```\n\n### Parallel FTP Downloads\n```\nputs \"\\n=== Parallel FTP Downloads Example ===\"\nurls = [\n  'ftp://ftp.example.com/file1.txt',\n  'ftp://ftp.example.com/file2.txt',\n  'ftp://ftp.example.com/file3.txt'\n]\n```\n\n### Common options for all connections\n```\noptions = {\n  :username =\u003e 'user',\n  :password =\u003e 'password',\n  :timeout =\u003e 30,\n  :on_success =\u003e proc { |easy| puts \"Successfully downloaded: #{easy.url}\" },\n  :on_failure =\u003e proc { |easy, code| puts \"Failed to download: #{easy.url} (#{code})\" }\n}\n\nCurl::Multi.download(urls, options) do |curl, file_path|\n  puts \"Completed downloading to: #{file_path}\"\nend\n```\n\n## You will need\n\n* A working Ruby installation (`2.0.0+` will work but `2.1+` preferred) (it's possible it still works with 1.8.7 but you'd have to tell me if not...)\n* A working libcurl development installation\n(Ideally one of the versions listed in the compatibility chart below that maps to your `curb` version)\n* A sane build environment (e.g. gcc, make)\n\n## Version Compatibility chart\n\nA **non-exhaustive** set of compatibility versions of the libcurl library\nwith this gem are as follows. (Note that these are only the ones that have been\ntested and reported to work across a variety of platforms / rubies)\n\n| Gem Version | Release Date   | libcurl versions  |\n| ----------- | -------------- | ----------------- |\n| 1.0.8       | Feb 10, 2025   | 7.58 – 8.12.1     |\n| 1.0.7       | Feb 09, 2025   | 7.58 – 8.12.1     |\n| 1.0.6       | Aug 23, 2024   | 7.58 – 8.12.1     |\n| 1.0.5       | Jan 2023       | 7.58 – 8.12.1     |\n| 1.0.4       | Jan 2023       | 7.58 – 8.12.1     |\n| 1.0.3*      | Dec 2022       | 7.58 – 8.12.1     |\n| 1.0.2*      | Dec 2022       | 7.58 – 8.12.1     |\n| 1.0.1       | Apr 2022       | 7.58 – 8.12.1     |\n| 1.0.0       | Jan 2022       | 7.58 – 8.12.1     |\n| 0.9.8       | Jan 2019       | 7.58 – 7.81       |\n| 0.9.7       | Nov 2018       | 7.56 – 7.60       |\n| 0.9.6       | May 2018       | 7.51 – 7.59       |\n| 0.9.5       | May 2018       | 7.51 – 7.59       |\n| 0.9.4       | Aug 2017       | 7.41 – 7.58       |\n| 0.9.3       | Apr 2016       | 7.26 – 7.58       |\n\n  ```*avoid using these version are known to have issues with segmentation faults```\n\n## Installation...\n\n... will usually be as simple as:\n\n    $ gem install curb\n\nOn Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloads/) and\nthe [development version of libcurl](http://curl.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command\nline (alter paths to your curl location, but remember to use forward slashes):\n\n    gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/lib --with-curl-include=C:/curl-7.39.0-devel-mingw32/include\n    \nNote that with Windows moving from one method of compiling to another as of Ruby `2.4` (DevKit -\u003e MYSYS2),\nthe usage of Ruby `2.4+` with this gem on windows is unlikely to work. It is advised to use the\nlatest version of Ruby 2.3 available [HERE](https://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.3.3.exe)\n\nOr, if you downloaded the archive:\n\n    $ rake compile \u0026\u0026 rake install\n\nIf you have a weird setup, you might need extconf options. In this case, pass\nthem like so:\n\n    $ rake compile EXTCONF_OPTS='--with-curl-dir=/path/to/libcurl --prefix=/what/ever' \u0026\u0026 rake install\n\nCurb is tested only on GNU/Linux x86 and Mac OSX - YMMV on other platforms.\nIf you do use another platform and experience problems, or if you can\nexpand on the above instructions, please report the issue at http://github.com/taf2/curb/issues\n\nOn Ubuntu, the dependencies can be satisfied by installing the following packages:\n\n18.04 and onwards\n    \n    $ sudo apt-get install libcurl4 libcurl3-gnutls libcurl4-openssl-dev\n\n\u003c 18.04\n\n    $ sudo apt-get install libcurl3 libcurl3-gnutls libcurl4-openssl-dev\n\nOn RedHat:\n\n    $ sudo yum install ruby-devel libcurl-devel openssl-devel\n\nCurb has fairly extensive RDoc comments in the source. You can build the\ndocumentation with:\n\n    $ rake doc\n\n## Usage \u0026 examples\n\nCurb provides two classes:\n\n* `Curl::Easy` - simple API, for day-to-day tasks.\n* `Curl::Multi` - more advanced API, for operating on multiple URLs simultaneously.\n\nTo use either, you will need to require the curb gem:\n\n```ruby\nrequire 'curb'\n```\n\n### Super simple API (less typing)\n\n```ruby\nhttp = Curl.get(\"http://www.google.com/\")\nputs http.body\n\nhttp = Curl.post(\"http://www.google.com/\", {:foo =\u003e \"bar\"})\nputs http.body\n\nhttp = Curl.get(\"http://www.google.com/\") do |http|\n  http.headers['Cookie'] = 'foo=1;bar=2'\nend\nputs http.body\n```\n\n### Simple fetch via HTTP:\n\n```ruby\nc = Curl::Easy.perform(\"http://www.google.co.uk\")\nputs c.body\n```\n\nSame thing, more manual:\n\n```ruby\nc = Curl::Easy.new(\"http://www.google.co.uk\")\nc.perform\nputs c.body\n```\n\n### Additional config:\n\n```ruby\nhttp = Curl::Easy.perform(\"http://www.google.co.uk\") do |curl|\n  curl.headers[\"User-Agent\"] = \"myapp-0.0\"\n  curl.verbose = true\nend\n```\n\nSame thing, more manual:\n\n```ruby\nc = Curl::Easy.new(\"http://www.google.co.uk\") do |curl|\n  curl.headers[\"User-Agent\"] = \"myapp-0.0\"\n  curl.verbose = true\nend\n\nc.perform\n```\n\n### HTTP basic authentication:\n\n```ruby\nc = Curl::Easy.new(\"http://github.com/\")\nc.http_auth_types = :basic\nc.username = 'foo'\nc.password = 'bar'\nc.perform\n```\n\n### HTTP \"insecure\" SSL connections (like curl -k, --insecure) to avoid Curl::Err::SSLCACertificateError:\n\n```ruby\nc = Curl::Easy.new(\"https://github.com/\")\nc.ssl_verify_peer = false\nc.perform\n```\n\n### Supplying custom handlers:\n\n```ruby\nc = Curl::Easy.new(\"http://www.google.co.uk\")\n\nc.on_body { |data| print(data) }\nc.on_header { |data| print(data) }\n\nc.perform\n```\n\n### Reusing Curls:\n\n```ruby\nc = Curl::Easy.new\n\n[\"http://www.google.co.uk\", \"http://www.ruby-lang.org/\"].map do |url|\n  c.url = url\n  c.perform\n  c.body\nend\n```\n\n### HTTP POST form:\n\n```ruby\nc = Curl::Easy.http_post(\"http://my.rails.box/thing/create\",\n                         Curl::PostField.content('thing[name]', 'box'),\n                         Curl::PostField.content('thing[type]', 'storage'))\n```\n\n### HTTP POST file upload:\n\n```ruby\nc = Curl::Easy.new(\"http://my.rails.box/files/upload\")\nc.multipart_form_post = true\nc.http_post(Curl::PostField.file('thing[file]', 'myfile.rb'))\n```\n\n### Using HTTP/2\n\n```ruby\nc = Curl::Easy.new(\"https://http2.akamai.com\")\nc.set(:HTTP_VERSION, Curl::HTTP_2_0)\n\nc.perform\nputs (c.body.include? \"You are using HTTP/2 right now!\") ? \"HTTP/2\" : \"HTTP/1.x\"\n```\n\n### Multi Interface (Basic HTTP GET):\n\n```ruby\n# make multiple GET requests\neasy_options = {:follow_location =\u003e true}\n# Use Curl::CURLPIPE_MULTIPLEX for HTTP/2 multiplexing\nmulti_options = {:pipeline =\u003e Curl::CURLPIPE_HTTP1}\n\nCurl::Multi.get(['url1','url2','url3','url4','url5'], easy_options, multi_options) do|easy|\n  # do something interesting with the easy response\n  puts easy.last_effective_url\nend\n```\n\n### Multi Interface (Basic HTTP POST):\n\n```ruby\n# make multiple POST requests\neasy_options = {:follow_location =\u003e true, :multipart_form_post =\u003e true}\nmulti_options = {:pipeline =\u003e Curl::CURLPIPE_HTTP1}\n\n\nurl_fields = [\n  { :url =\u003e 'url1', :post_fields =\u003e {'f1' =\u003e 'v1'} },\n  { :url =\u003e 'url2', :post_fields =\u003e {'f1' =\u003e 'v1'} },\n  { :url =\u003e 'url3', :post_fields =\u003e {'f1' =\u003e 'v1'} }\n]\n\nCurl::Multi.post(url_fields, easy_options, multi_options) do|easy|\n  # do something interesting with the easy response\n  puts easy.last_effective_url\nend\n```\n\n### Multi Interface (Advanced):\n\n```ruby\nresponses = {}\nrequests = [\"http://www.google.co.uk/\", \"http://www.ruby-lang.org/\"]\nm = Curl::Multi.new\n# add a few easy handles\nrequests.each do |url|\n  responses[url] = \"\"\n  c = Curl::Easy.new(url) do|curl|\n    curl.follow_location = true\n    curl.on_body{|data| responses[url] \u003c\u003c data; data.size }\n    curl.on_success {|easy| puts \"success, add more easy handles\" }\n  end\n  m.add(c)\nend\n\nm.perform do\n  puts \"idling... can do some work here\"\nend\n\nrequests.each do|url|\n  puts responses[url]\nend\n```\n\n### Easy Callbacks\n\n* `on_success`  is called when the response code is 2xx\n* `on_redirect` is called when the response code is 3xx\n* `on_missing` is called when the response code is 4xx\n* `on_failure` is called when the response code is 5xx\n* `on_complete` is called in all cases.\n","funding_links":[],"categories":["C","Web Apps, Services \u0026 Interaction"],"sub_categories":["HTTP clients"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaf2%2Fcurb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaf2%2Fcurb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaf2%2Fcurb/lists"}