All Projects → taylorwood → Clojurl

taylorwood / Clojurl

Licence: epl-2.0
An example Clojure CLI HTTP/S client using GraalVM native image

Programming Languages

clojure
4091 projects

Labels

Projects that are alternatives of or similar to Clojurl

Mirrorbits
Mirrorbits is a geographical download redirector written in Go for distributing files efficiently across a set of mirrors.
Stars: ✭ 365 (+518.64%)
Mutual labels:  cli, https
Wsdirector
All the world's a server, and all the men and women merely clients
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Mkcli
Markdown command line interface definition
Stars: ✭ 56 (-5.08%)
Mutual labels:  cli
Ntutils
Various Command Line Utilities Ported to Windows NT
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Gemfury
Gemfury CLI and API client
Stars: ✭ 56 (-5.08%)
Mutual labels:  cli
Taskbook
Tasks, boards & notes for the command-line habitat
Stars: ✭ 8,326 (+14011.86%)
Mutual labels:  cli
Dress
👗 Dress up your stdout
Stars: ✭ 55 (-6.78%)
Mutual labels:  cli
Node Google Play Cli
command line tools using the node-google-play library
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Q
q - Run SQL directly on CSV or TSV files
Stars: ✭ 8,809 (+14830.51%)
Mutual labels:  cli
Pizza Cli
🍕 Order a pizza in a CLI app (just for fun!)
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Dvm
Fast and simple Deno runtime version manager written in OCaml
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Netcore Postgres Oauth Boiler
A basic .NET Core website boilerplate using PostgreSQL for storage, Adminer for db management, Let's Encrypt for SSL certificates and NGINX for routing.
Stars: ✭ 57 (-3.39%)
Mutual labels:  https
Spotify Tui
Spotify for the terminal written in Rust 🚀
Stars: ✭ 11,061 (+18647.46%)
Mutual labels:  cli
Internet.nl
Internet standards compliance test suite
Stars: ✭ 56 (-5.08%)
Mutual labels:  https
12306 Cli
command line tool for 12306.cn 🚄
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli
Movtogif Cli
📺 Convert mov/mp4 to high-quality animated gifs
Stars: ✭ 56 (-5.08%)
Mutual labels:  cli
Unpuzzled
A colorful CLI library with variable provenance.
Stars: ✭ 57 (-3.39%)
Mutual labels:  cli
Wolfssl
wolfSSL (formerly CyaSSL) is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3!
Stars: ✭ 1,098 (+1761.02%)
Mutual labels:  https
Rbiam
A unified IAM+Kubernetes RBAC access control exploration tool
Stars: ✭ 59 (+0%)
Mutual labels:  cli
Changed Log
Returns all commit messages between 2 versions of an NPM module
Stars: ✭ 58 (-1.69%)
Mutual labels:  cli

Clojurl

An example HTTP/S client CLI using Clojure and GraalVM native image.

Generated with clj.native-cli template. Uses deps.edn and clj.native-image.

Prerequisites

  • GraalVM 1.0.0-RC9 or higher
  • Clojure

GraalVM 1.0.0-RC7 added HTTPS as a supported protocol, and this is a brief walkthrough for using it in a Clojure project with GraalVM Community Edition for macOS.

Enable HTTPS protocol support with native-image options --enable-https or --enable-url-protocols=https.

Earlier versions of GraalVM

The following steps are only necessary with GraalVM 19.2.1 and earlier:

  1. Configure path to libsunec.dylib on macOS (or libsunec.do on Linux)

    This shared object comes with the GraalVM distribution and can be found in $GRAALVM_HOME/jre/lib/. GraalVM uses System.loadLibrary to load it at run-time whenever it's first used. The file must either be in the current working directory, or in a path specified in Java system property java.library.path.

    I set the Java system property at run-time, before first HTTPS attempt:

    (System/setProperty "java.library.path"
                        (str (System/getenv "GRAALVM_HOME") "/jre/lib"))
    

    See this and this for more information on HTTPS support in GraalVM and native images. If you're distributing a native image, you'll need to include libsunec. If it's in the same directory as your image you don't need to set java.library.path.

    You'll see a warning at run-time if this hasn't been properly configured:

    WARNING: The sunec native library could not be loaded.
    
  2. Use more complete certificate store

    Some versions of GraalVM may have a smaller set of CA certificates. You can workaround this by replacing GraalVM's cacerts. I renamed the file and replaced it with a symbolic link to cacerts from the JRE that comes with macOS Mojave:

    $ mv $GRAALVM_HOME/jre/lib/security/cacerts $GRAALVM_HOME/jre/lib/security/cacerts.bak
    $ ln -s $(/usr/libexec/java_home)/jre/lib/security/cacerts $GRAALVM_HOME/jre/lib/security/cacerts
    

    If you don't do this, you might see errors like this when attempting HTTPS connections:

    Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    8<------------------------
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    8<------------------------
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    

Usage

Compile the program with GraalVM native-image:

$ clojure -A:native-image

Print CLI options:

$ ./clojurl -h
  -u, --uri URI             URI of request
  -H, --header HEADER       Request header(s)
  -d, --data DATA           Request data
  -m, --method METHOD  GET  Request method e.g. GET, POST, etc.
  -o, --output FORMAT  edn  Output format e.g. edn, hickory
  -v, --verbose             Print verbose info
  -h, --help                Print this message

Responses can be printed in EDN or Hickory format.

Make a request and print response to stdout:

$ ./clojurl -u https://postman-echo.com/get
  {:headers
   {"content-encoding" "gzip",
    "content-type" "application/json; charset=utf-8",
    "date" "Fri, 05 Oct 2018 03:56:49 GMT",
    "etag" "W/\"10b-EZIoyNoyzUvEaPxY+kzMOEgaNh0\"",
    "server" "nginx",
    "vary" "Accept-Encoding",
    "content-length" "194",
    "connection" "keep-alive"},
   :status 200,
   :body
   "{\"args\":{},\"headers\":{\"host\":\"postman-echo.com\",\"accept\":\"text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\",\"accept-encoding\":\"gzip, deflate\",\"user-agent\":\"Java/1.8.0_172\",\"x-forwarded-port\":\"443\",\"x-forwarded-proto\":\"https\"},\"url\":\"https://postman-echo.com/get\"}"}
$ ./clojurl -H Accept=application/json -H X-Session-Id=1234 -H Content-Type=application/json \
     -u https://postman-echo.com/post \
     -m post -d "{'foo':true}"
  {:headers
   {"content-encoding" "gzip",
    "content-type" "application/json; charset=utf-8",
    "date" "Fri, 05 Oct 2018 03:57:06 GMT",
    "etag" "W/\"16d-FiL2opG823uS6YyXMHVrz5k+/Vk\"",
    "server" "nginx",
    "set-cookie"
    "sails.sid=s%3Af-U0lE-XKYPefMu_II_Sggg1HGVI4LlY.lbh1ZWAEX58lBuDVpo2vRZ%2FPAo1AHllJPSPsJ01RFvc; Path=/; HttpOnly",
    "vary" "Accept-Encoding",
    "content-length" "237",
    "connection" "keep-alive"},
   :status 200,
   :body
   "{\"args\":{},\"data\":\"{'foo':true}\",\"files\":{},\"form\":{},\"headers\":{\"host\":\"postman-echo.com\",\"content-length\":\"12\",\"accept\":\"application/json\",\"accept-encoding\":\"gzip, deflate\",\"content-type\":\"application/json\",\"user-agent\":\"Java/1.8.0_172\",\"x-session-id\":\"1234\",\"x-forwarded-port\":\"443\",\"x-forwarded-proto\":\"https\"},\"json\":null,\"url\":\"https://postman-echo.com/post\"}"}

As a proof-of-concept for using Clojure 1.9 + clojure.spec.alpha + Expound with GraalVM native-image, the CLI options are validated using specs and invalid options can be explained using Expound:

$ ./clojurl -u https://postman-echo.com/get -o foo --verbose
Invalid option(s)
-- Spec failed --------------------

  {:headers ...,
   :method ...,
   :output-fn nil,
              ^^^
   :url ...,
   :verbose? ...}

should satisfy

  ifn?

-- Relevant specs -------

:clojurl/output-fn:
  clojure.core/ifn?
:clojurl/options:
  (clojure.spec.alpha/keys
   :req-un
   [:clojurl/url :clojurl/output-fn]
   :opt-un
   [:clojurl/method :clojurl/headers :clojurl/body])

-------------------------
Detected 1 error
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].