mruby-curl is an mruby wrapper for libcurl. It provides HTTP client capabilities with support for GET, POST, PUT, PATCH, DELETE, streaming responses, concurrent requests through the multi interface, and configurable timeouts, SSL verification, and HTTP version selection.
Responses are parsed through
mruby-http, which returns structured
HTTP::Response objects with body, headers, status_code, and other
attributes.
curl = Curl.new
headers = {
"User-Agent" => "mruby-curl"
}
response = curl.get("https://www.ruby-lang.org/en/", headers)
puts response.bodyExplanation
Curl.new
Creates a new curl easy handle. EachCurlinstance manages one HTTP connection at a time.curl.get(url, headers)
Sends a GET request. The second argument is an optional hash of HTTP headers. Returns anHTTP::Responseparsed by mruby-http.response.body
The response body as a string. The response object also exposesheaders,status_code, and other attributes through mruby-http.
HTTP methods that accept a body require two positional arguments: the URL and the data string. Headers are optional:
curl = Curl.new
headers = {"Content-Type" => "application/json"}
data = '{"title": "Hello"}'
response = curl.post("https://api.example.com/posts", data, headers)
puts response.status_codeThe same pattern works for put, patch, and delete:
curl.patch("https://api.example.com/posts/1", '{"title": "Updated"}', headers)
curl.put("https://api.example.com/posts/1", '{"title": "Replaced"}', headers)
curl.delete("https://api.example.com/posts/1", headers)Each instance method has a corresponding class method that lazily creates
and reuses a singleton Curl instance:
response = Curl.get("https://api.example.com/data")
response = Curl.post("https://api.example.com/data", "body")
response = Curl.put("https://api.example.com/data", "body")
response = Curl.patch("https://api.example.com/data", "body")
response = Curl.delete("https://api.example.com/data")Pass a block to receive the response incrementally. The block receives the parsed header and a body chunk on each invocation. This is useful for large responses or streaming APIs:
Curl.new.get("https://stream.example.com/data") do |header, chunk|
puts "chunk received: #{chunk}"
endUse Curl::Multi to send multiple requests concurrently through libcurl's
multi interface. Create a Multi, call send for each request, then poll
with perform and check done?:
multi = Curl::Multi.new
req1 = HTTP::Request.new
req1.method = "GET"
req2 = HTTP::Request.new
req2.method = "GET"
r1 = multi.send("https://api.example.com/data1", req1)
r2 = multi.send("https://api.example.com/data2", req2)
while !multi.done?
multi.perform
end
puts r1.response.body
puts r2.response.bodyEach send call returns a Curl::Multi::Request object that provides:
done?
Whether the request has finished.response
The parsedHTTP::Responseon success. Raises on error.error
A string describing the error, ornilif the request succeeded.
For full control over the request, build an HTTP::Request object and pass
it to Curl#send:
req = HTTP::Request.new
req.method = "POST"
req.body = '{"key": "value"}'
req.headers["Authorization"] = "token secret"
response = Curl.new.send("https://api.example.com/endpoint", req)
puts response.bodyTimeouts
Set timeouts in seconds or milliseconds:
curl = Curl.new
curl.timeout = 30 # 30 seconds
curl.timeout_ms = 5000 # 5 seconds (overrides timeout if both are set)SSL verification
Disable SSL peer verification (not recommended for production):
Curl::SSL_VERIFYPEER = 0HTTP version
The default is Curl::HTTP_2TLS, which tries HTTP/2 for HTTPS requests and
falls back when HTTP/2 is not available.
Switch to HTTP/1.0 explicitly:
Curl::HTTP_VERSION = Curl::HTTP_1_0Or set a custom CA info path:
Curl::CAINFO = "/etc/ssl/certs/ca-certificates.crt"By default mruby-curl does not call curl_global_init. If you use
mruby-curl from multiple threads, call Curl.global_init before starting
any threads:
Curl.global_initThis initializes libcurl with CURL_GLOBAL_DEFAULT flags. It must be
called once and only once. See the
curl_global_init
documentation for more details.
Add to your mruby build configuration:
MRuby::Build.new("app") do |conf|
conf.toolchain
curldir = File.expand_path(ENV["CURLDIR"] || "/usr/local")
conf.cc.include_paths << File.join(curldir, "include")
conf.linker.library_paths << File.join(curldir, "lib")
conf.gembox "default"
conf.gem github: "llmrb/mruby-curl", branch: "main"
endThe gem depends on mruby-http and links against libcurl.
MIT
See LICENSE.