Fennel wiki: http

There are a few different options for making HTTPS requests in Lua/Fennel. Unfortunately none of them are without their downsides, so it's up to you to choose which is the best fit for the problem at hand based on the trade-offs.

love2d lua-https

https://github.com/love2d/lua-https

The LÖVE people have created a nice and simple client called lua-https. It is built-in to newer versions of love2d but can be used standalone as well. This works on Linux, Windows, Mac OS, Android and iOS and wraps the "native" HTTPS client on each platform, or curl on Linux.

This one is my first recommendation for where to start, unless you know you will need streaming responses.

pros

cons

[TODO: see whether this can be compiled into a static binary; probably can???]

lua-http

https://daurnimator.github.io/lua-http/

This one is potentially the most flexible. It integrates with cqueues so if you are already using that you may want this one.

pros

cons

(local req (case (pcall require :http.request)
             (true request) request
             _ (do
                 ;; work around a bug in Debian packaging for lua-http:
                 ;; https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1081208
                 (set package.path (.. package.path ";/usr/share/lua/5.2/?.lua"))
                 (require :http.request))))

(local http-headers (require :http.headers))

(let [url "https://example.com/"
      ;; you can't use a normal table; you have to use a special constructor
      req-headers (http-headers.new)
      ;; for some reason, the method is stored as a "pseudo-header" here
      ;; and you HAVE to set it before the request is constructed; it will
      ;; error out if you try to do it afterwards.
      _ (req-headers:append ":method" "GET")
      request (req.new_from_uri url req-headers)
      ;; if you want to set a *real* HTTP header, you have to do it after
      ;; the request is constructed; doing it earlier will cause it to error out
      _ (req-headers:append "authorization" "Bearer XYZABC6514478")
      (headers stream) (assert (request:go))
      body (assert (stream:get_body_as_string))]
  ;; yeah, it will not give you the status normally either, you have to go
  ;; fish it out of the headers
  {:status (tonumber (headers:get ":status")) : body : headers})

lua-curl

https://github.com/Lua-cURL/Lua-cURLv3

Unfortunately there are several different libraries out there called "lua-curl" so make sure you're looking at the right one.

The main advantage of this one is that you can bundle it in a static binary if you are building a program you want to distribute to end users. Of course, the binary will not include curl or openssl itself (that would be a bad idea because it would not get security updates) but you can guarantee 99% of users will already have those libraries on their system.

For a simple example of how to do the build, see the fennel-http-example repo. See squirtleci for an example of a full application.

pros

cons

luasec

https://github.com/lunarmodules/luasec

This uses the same API as luasocket but adds support for TLS. Unfortunately, its default settings are to skip certificate verification, which makes it unsafe to use out of the box. It's recommended not to use this unless you are knowledgeable about TLS and are able to ensure the settings you choose are safe.

fnl-http

https://gitlab.com/andreyorst/fnl-http

This one is written in Fennel! Unfortunately it does not support HTTPS, only HTTP/1.1.

pros

cons

lua-resty-http

https://github.com/ledgetech/lua-resty-http

TODO: might only work inside OpenResty?

shelling out to curl

https://curl.se/

Depending on your use case... maybe?

pros

cons