high level curl library for crystal Build Status

High level curl library for Crystal. This is a handy wrapper for blocknotes's curl-crystal


  1. Add the dependency to your shard.yml:
    github: maiha/
    version: 0.4.0
  1. Run shards install


libcurl provides two interfaces those are Easy and Multi. Easy Interface is standard api that provides synchronous access, and well used by many applications.

Easy Interface

Curl::Easy#get returns Curl::Easy::Response.

require "curl"

curl ="")
res = curl.get
res.code         # => 200
res.content_type # => "text/html; charset=UTF-8"
res.body         # => "<html>..."

curl.to_s        # => "200"

See src/curl/ for all variables.

  var uri      : URI
  var logger   : Logger
  var response : Response
  var info     : Info

  # behavior
  var dump_header = false # Pass headers to the data stream
  var verbose     = false # Set verbose mode
  var timeout         : Time::Span
  var connect_timeout : Time::Span

  var compress : Bool     = false
  var encoding : Encoding = Encoding::ALL
  var decoding : Bool     = true


Curl::Easy::Response#info returns Curl::Easy::Info.

info =
info.namelookup_time # => 0.00439
info.to_s            # => "[10.0KB](232KB/s, 0.0s)"
(0.004s) |--NAMELOOKUP
(0.018s) |--|--CONNECT
(0.000s) |--|--|--APPCONNECT
(0.018s) |--|--|--|--PRETRANSFER
(0.032s) |--|--|--|--|--STARTTRANSFER
(0.032s) |--|--|--|--|--|--TOTAL
(0.000s) |--|--|--|--|--|--REDIRECT

Write file

By specifying the output file path with the output method, you can write it directly to a file instead of in-memory.

curl ="")
curl.output = "index.html"


Compression is enabled by default, but you can use three variables to control fine behavior. For example, it is possible to acquire route compressed gzip data as it is by requesting encoding by gzip compression and skipping decoding, as follows.

curl.compress = true
curl.encoding = Curl::Easy::Encoding::GZIP
curl.decoding = false

Multi Interface

Execution of requests by Easy is blocked at the libcurl level, so even if executed within spawn, execution of crystal is blocked there.

Multi Interface provides asynchronous access. It enables multiple simultaneous transfers in the same thread without making forks.

multi =
multi <<"")
multi <<"") 10.seconds)       # => [200, 200]
multi.human_code_counts # => {"200" => 2}
multi.summary           # => "2 Requests (0.5s) {\"200\" => 2}"


  • Core
    • Auth
      • #basic_auth
      • #digest_auth
    • Callback
      • before_execute
    • Compress
      • #compress=(v : Bool) # control 'Accept-Encoding' header
      • #encoding=(v : Easy::Encoding) # specify the value of encoding
      • #decoding=(v : Bool) # control automatic decompression
    • Info
      • times stats
    • Logging
      • #logger
    • Response
      • #headers
      • #code
      • #body
      • #io
      • #success?
    • Timeout
      • connect_timeout
      • timeout
    • URI
      • #uri=(v)
      • #port
    • Verbose
      • #verbose
  • Easy Interface :
    • #get
    • #post
    • #put
  • Multi Interface :
    • #<<(easy : Easy)
    • #run(timeout)
    • #requests : Array(Easy)
    • #responses : Array(Multi::Response)


samples/ is an example using libcurl to make a curl compatible application in Crystal.

$ make build


curl is a very multifunctional and large library, and the functionality implemented in this library is very small. If there is a missing function, please implement it. PR is greatly appreciated.

$ make spec

Here, libcurl.* is needed. For ubuntu, it can be installed by following packages.

  • libcurl4-openssl-dev
  • libidn2-0-dev


All constants in libcurl are mapped to Curl::XXX. For example, CURLOPT_VERBOSE is declared as enum. So it can be used as follows.

Curl::CURLOPT_VERBOSE.value # => 41

See doc/ for further details.


All symbols are extracted to LibCurlSymbols from

LibCurlSymbols.each do |symbol|
  symbol # => LibCurlSymbols::CurlSymbol(@name="CURLAUTH_ANY", @introduced="7.10.6", @deprecated="", @removed="")

Automatically generated files

$ make gen


Rebuild docker containers if you modified docker/*.

$ make rebuild-docker

Static link

Minimum libcurl.a will be prepared as follows.

$ make libcurl.a
  curl version:     7.64.0-DEV
  Protocols:        HTTP HTTPS
   LIBS:            -lidn2 -lssl -lcrypto -lssl -lcrypto -lz

Then you can compile your apps by adding --link-flags "-static $PWD/libcurl.a".

$ crystal build --link-flags "-static $PWD/libcurl.a"

If your environment does not have a dependent library it will result in an error. In that case, you can easily create it by using the container that created libcurl.a as follows.

$ docker-compose run --rm static crystal build --link-flags "-static /v/libcurl.a"


  1. Fork it (
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request


  • maiha - creator and maintainer for this repository.
  • blocknotes - author of LibCurl which is a function of lower layer
Github statistic:
  • 1
  • 1
  • 0
  • 1
  • 1
  • 4 months ago


MIT License