From 09bccbb04830a72836422e84559be2f3780035e2 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Mon, 14 Jan 2019 17:27:56 +0000 Subject: [PATCH 1/2] HTTPS support for the Lwt bindings --- .travis.yml | 4 +- certificates/server.key | 15 ++ certificates/server.pem | 15 ++ esy.json | 7 +- esy.lock/index.json | 180 ++++++++++++++++-- esy.lock/opam/conf-pkg-config.1.1/opam | 39 ++++ .../{hashcons.1.3 => hashcons.1.0.1}/opam | 7 +- esy.lock/opam/lwt_ssl.1.1.2/opam | 28 +++ esy.lock/opam/ssl.0.5.8/opam | 24 +++ .../.ci/build.yaml | 30 +++ .../.gitignore | 1 + .../.travis.yml | 15 ++ .../README.md | 98 ++++++++++ .../azure-pipelines.yml | 19 ++ .../esy.lock.json | 16 ++ .../esy/test.c | 32 ++++ .../esy/test.sh | 31 +++ .../package.json | 48 +++++ .../package.json | 11 ++ examples/lwt/dune | 2 +- examples/lwt/lwt_https_get.ml | 30 +++ examples/lwt/lwt_https_server.ml | 41 ++++ httpaf-lwt-unix.opam | 2 + lwt-unix/dune | 33 +++- lwt-unix/httpaf_lwt_unix.ml | 68 ++++++- lwt-unix/httpaf_lwt_unix.mli | 52 ++++- lwt-unix/ssl_io_dummy.ml | 64 +++++++ lwt-unix/ssl_io_real.ml | 114 +++++++++++ lwt-unix/tls_io_dummy.ml | 63 ++++++ lwt-unix/tls_io_real.ml | 115 +++++++++++ 30 files changed, 1175 insertions(+), 29 deletions(-) create mode 100644 certificates/server.key create mode 100644 certificates/server.pem create mode 100644 esy.lock/opam/conf-pkg-config.1.1/opam rename esy.lock/opam/{hashcons.1.3 => hashcons.1.0.1}/opam (84%) create mode 100644 esy.lock/opam/lwt_ssl.1.1.2/opam create mode 100644 esy.lock/opam/ssl.0.5.8/opam create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.ci/build.yaml create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.gitignore create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.travis.yml create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/README.md create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/azure-pipelines.yml create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy.lock.json create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.c create mode 100755 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.sh create mode 100644 esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/package.json create mode 100644 esy.lock/overrides/opam__s__conf_pkg_config_opam__c__1.1_opam_override/package.json create mode 100644 examples/lwt/lwt_https_get.ml create mode 100644 examples/lwt/lwt_https_server.ml create mode 100644 lwt-unix/ssl_io_dummy.ml create mode 100644 lwt-unix/ssl_io_real.ml create mode 100644 lwt-unix/tls_io_dummy.ml create mode 100644 lwt-unix/tls_io_real.ml diff --git a/.travis.yml b/.travis.yml index 7061fc6..ee94d98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,7 @@ env: - POST_INSTALL_HOOK="opam install --with-test httpaf-async httpaf-lwt-unix && opam exec -- make examples" matrix: - OCAML_VERSION="4.07" - - OCAML_VERSION="4.06" + - | + PRE_INSTALL_HOOK="sudo apt-get install -y libgmp-dev; opam install tls" + OCAML_VERSION="4.06" - OCAML_VERSION="4.05" diff --git a/certificates/server.key b/certificates/server.key new file mode 100644 index 0000000..5a92851 --- /dev/null +++ b/certificates/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQC2QEje5rwhlD2iq162+Ng3AH9BfA/jNJLDqi9VPk1eMUNGicJv +K+aOANKIsOOr9v4RiEXZSYmFEvGSy+Sf1bCDHwHLLSdNs6Y49b77POgatrVZOTRE +BE/t1soVT3a/vVJWCLtVCjm70u0S5tcfn4S6IapeIYAVAmcaqwSa+GQNoQIDAQAB +AoGAd/CShG8g/JBMh9Nz/8KAuKHRHc2BvysIM1C62cSosgaFmdRrazJfBrEv3Nlc +2/0uc2dVYIxuvm8bIFqi2TWOdX9jWJf6oXwEPXCD0SaDbJTaoh0b+wjyHuaGlttY +Ztvmf8mK1BOhyl3vNMxh/8Re0dGvGgPZHpn8zanaqfGVz+ECQQDngieUpwzxA0QZ +GZKRYhHoLEaPiQzBaXphqWcCLLN7oAKxZlUCUckxRRe0tKINf0cB3Kr9gGQjPpm0 +YoqXo8mNAkEAyYgdd+JDi9FH3Cz6ijvPU0hYkriwTii0V09+Ar5DvYQNzNEIEJu8 +Q3Yte/TPRuK8zhnp97Bsy9v/Ji/LSWbtZQJBAJe9y8u3otfmWCBLjrIUIcCYJLe4 +ENBFHp4ctxPJ0Ora+mjkthuLF+BfdSZQr1dBcX1a8giuuvQO+Bgv7r9t75ECQC7F +omEyaA7JEW5uGe9/Fgz0G2ph5rkdBU3GKy6jzcDsJu/EC6UfH8Bgawn7tSd0c/E5 +Xm2Xyog9lKfeK8XrV2kCQQCTico5lQPjfIwjhvn45ALc/0OrkaK0hQNpXgUNFJFQ +tuX2WMD5flMyA5PCx5XBU8gEMHYa8Kr5d6uoixnbS0cZ +-----END RSA PRIVATE KEY----- diff --git a/certificates/server.pem b/certificates/server.pem new file mode 100644 index 0000000..22a82fb --- /dev/null +++ b/certificates/server.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYzCCAcwCCQDLbE6ES1ih1DANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMRUwEwYDVQQDDAxZT1VSIE5BTUUhISExGDAWBgkqhkiG9w0BCQEW +CW1lQGJhci5kZTAeFw0xNDAyMTcyMjA4NDVaFw0xNTAyMTcyMjA4NDVaMHYxCzAJ +BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l +dCBXaWRnaXRzIFB0eSBMdGQxFTATBgNVBAMMDFlPVVIgTkFNRSEhITEYMBYGCSqG +SIb3DQEJARYJbWVAYmFyLmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2 +QEje5rwhlD2iq162+Ng3AH9BfA/jNJLDqi9VPk1eMUNGicJvK+aOANKIsOOr9v4R +iEXZSYmFEvGSy+Sf1bCDHwHLLSdNs6Y49b77POgatrVZOTREBE/t1soVT3a/vVJW +CLtVCjm70u0S5tcfn4S6IapeIYAVAmcaqwSa+GQNoQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAIo4ZppIlp3JRyltRC1/AyCC0tsh5TdM3W7258wdoP3lEe08UlLwpnPc +aJ/cX8rMG4Xf4it77yrbVrU3MumBEGN5TW4jn4+iZyFbp6TT3OUF55nsXDjNHBbu +deDVpGuPTI6CZQVhU5qEMF3xmlokG+VV+HCDTglNQc+fdLM0LoNF +-----END CERTIFICATE----- diff --git a/esy.json b/esy.json index 7a62d22..505c46a 100644 --- a/esy.json +++ b/esy.json @@ -13,7 +13,10 @@ "@opam/faraday-async": "*", "@opam/faraday-lwt-unix": "*", "@opam/async": "*", - "@opam/mirage-conduit": "*" + "@opam/mirage-conduit": "*", + "@opam/tls-lwt": "*", + "@opam/lwt_ssl": "*", + "@opam/ssl": " >= 0.5.8" }, "devDependencies": { "@opam/alcotest": "*", @@ -21,7 +24,7 @@ "@opam/odoc": "*" }, "resolutions": { - "@opam/conf-autoconf": "esy-packages/esy-autoconf#71a8836", + "@opam/conf-openssl": "esy-packages/esy-openssl#dafe9ad", "@opam/mirage-conduit": { "source": "mirage/ocaml-conduit:mirage-conduit.opam#0ce7ce3", "override": { diff --git a/esy.lock/index.json b/esy.lock/index.json index 1cd25c9..aa67616 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -1,7 +1,23 @@ { - "checksum": "949caf211198825a6a9e6df70dd8d0ad", + "checksum": "2286a1d0333bbcf7c85298e4210aa0ce", "root": "httpaf@link-dev:./esy.json", "node": { + "yarn-pkg-config@github:esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0@d41d8cd9": { + "id": + "yarn-pkg-config@github:esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0@d41d8cd9", + "name": "yarn-pkg-config", + "version": + "github:esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0", + "source": { + "type": "install", + "source": [ + "github:esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0" + ] + }, + "overrides": [], + "dependencies": [], + "devDependencies": [] + }, "ocaml@4.8.0@d41d8cd9": { "id": "ocaml@4.8.0@d41d8cd9", "name": "ocaml", @@ -24,8 +40,10 @@ "overrides": [], "dependencies": [ "ocaml@4.8.0@d41d8cd9", + "@opam/tls-lwt@github:dune-universe/ocaml-tls:tls-lwt.opam#9761033@d41d8cd9", + "@opam/ssl@opam:0.5.8@d93fd163", "@opam/mirage-conduit@github:mirage/ocaml-conduit:mirage-conduit.opam#0ce7ce3@d2859b4f", - "@opam/lwt@opam:4.2.1@c1888ec9", + "@opam/lwt_ssl@opam:1.1.2@ac833920", "@opam/lwt@opam:4.2.1@c1888ec9", "@opam/faraday-lwt-unix@opam:0.7.0@b0dea04f", "@opam/faraday-async@opam:0.7.0@9afefd91", "@opam/faraday@opam:0.7.0@6026a81f", @@ -508,6 +526,35 @@ "@opam/lwt@opam:4.2.1@c1888ec9", "@opam/cstruct@opam:4.0.0@27f747cf" ] }, + "@opam/tls-lwt@github:dune-universe/ocaml-tls:tls-lwt.opam#9761033@d41d8cd9": { + "id": + "@opam/tls-lwt@github:dune-universe/ocaml-tls:tls-lwt.opam#9761033@d41d8cd9", + "name": "@opam/tls-lwt", + "version": "github:dune-universe/ocaml-tls:tls-lwt.opam#9761033", + "source": { + "type": "install", + "source": [ "github:dune-universe/ocaml-tls:tls-lwt.opam#9761033" ] + }, + "overrides": [], + "dependencies": [ + "@opam/x509@opam:0.6.3@79901d68", + "@opam/tls@github:dune-universe/ocaml-tls:tls.opam#9761033@d41d8cd9", + "@opam/sexplib@opam:v0.12.0@c65643bb", + "@opam/result@opam:1.4@7add0d71", + "@opam/nocrypto@github:TheLortex/ocaml-nocrypto:nocrypto.opam#df2348d@d86b9d71", + "@opam/lwt@opam:4.2.1@c1888ec9", "@opam/dune@opam:1.10.0@b15ce221", + "@opam/cstruct@opam:4.0.0@27f747cf", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "@opam/x509@opam:0.6.3@79901d68", + "@opam/tls@github:dune-universe/ocaml-tls:tls.opam#9761033@d41d8cd9", + "@opam/sexplib@opam:v0.12.0@c65643bb", + "@opam/result@opam:1.4@7add0d71", + "@opam/nocrypto@github:TheLortex/ocaml-nocrypto:nocrypto.opam#df2348d@d86b9d71", + "@opam/lwt@opam:4.2.1@c1888ec9", "@opam/cstruct@opam:4.0.0@27f747cf" + ] + }, "@opam/tls@github:dune-universe/ocaml-tls:tls.opam#9761033@d41d8cd9": { "id": "@opam/tls@github:dune-universe/ocaml-tls:tls.opam#9761033@d41d8cd9", @@ -690,6 +737,35 @@ "ocaml@4.8.0@d41d8cd9", "@opam/base@opam:v0.12.2@e209c8f2" ] }, + "@opam/ssl@opam:0.5.8@d93fd163": { + "id": "@opam/ssl@opam:0.5.8@d93fd163", + "name": "@opam/ssl", + "version": "opam:0.5.8", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/md5/4b/4b2cd1e21f25989b958e880f7b4791d1#md5:4b2cd1e21f25989b958e880f7b4791d1", + "archive:https://github.com/savonet/ocaml-ssl/archive/0.5.8.tar.gz#md5:4b2cd1e21f25989b958e880f7b4791d1" + ], + "opam": { + "name": "ssl", + "version": "0.5.8", + "path": "esy.lock/opam/ssl.0.5.8" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.0@d41d8cd9", "@opam/dune@opam:1.10.0@b15ce221", + "@opam/conf-openssl@archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511@ee5c2c69", + "@opam/base-unix@opam:base@87d0b2eb", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.0@d41d8cd9", + "@opam/conf-openssl@archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511@ee5c2c69", + "@opam/base-unix@opam:base@87d0b2eb" + ] + }, "@opam/splittable_random@opam:v0.12.0@0c34c3be": { "id": "@opam/splittable_random@opam:v0.12.0@0c34c3be", "name": "@opam/splittable_random", @@ -2975,6 +3051,35 @@ "ocaml@4.8.0@d41d8cd9", "@opam/sexplib0@opam:v0.12.0@e823b4e9" ] }, + "@opam/lwt_ssl@opam:1.1.2@ac833920": { + "id": "@opam/lwt_ssl@opam:1.1.2@ac833920", + "name": "@opam/lwt_ssl", + "version": "opam:1.1.2", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/md5/d2/d239353b1e7c6e3fd4192c71a3b25ce2#md5:d239353b1e7c6e3fd4192c71a3b25ce2", + "archive:https://github.com/aantron/lwt_ssl/archive/1.1.2.tar.gz#md5:d239353b1e7c6e3fd4192c71a3b25ce2" + ], + "opam": { + "name": "lwt_ssl", + "version": "1.1.2", + "path": "esy.lock/opam/lwt_ssl.1.1.2" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.8.0@d41d8cd9", "@opam/ssl@opam:0.5.8@d93fd163", + "@opam/lwt@opam:4.2.1@c1888ec9", + "@opam/jbuilder@opam:transition@58bdfe0a", + "@opam/base-unix@opam:base@87d0b2eb", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.8.0@d41d8cd9", "@opam/ssl@opam:0.5.8@d93fd163", + "@opam/lwt@opam:4.2.1@c1888ec9", "@opam/base-unix@opam:base@87d0b2eb" + ] + }, "@opam/lwt@opam:4.2.1@c1888ec9": { "id": "@opam/lwt@opam:4.2.1@c1888ec9", "name": "@opam/lwt", @@ -3163,27 +3268,26 @@ "@opam/bigarray-compat@opam:1.0.0@77cde57f" ] }, - "@opam/hashcons@opam:1.3@35d35e80": { - "id": "@opam/hashcons@opam:1.3@35d35e80", + "@opam/hashcons@opam:1.0.1@30492c11": { + "id": "@opam/hashcons@opam:1.0.1@30492c11", "name": "@opam/hashcons", - "version": "opam:1.3", + "version": "opam:1.0.1", "source": { "type": "install", "source": [ - "archive:https://opam.ocaml.org/cache/md5/88/88b93515dd2667c4944574dfb50352bf#md5:88b93515dd2667c4944574dfb50352bf", - "archive:https://github.com/backtracking/ocaml-hashcons/archive/1.3.tar.gz#md5:88b93515dd2667c4944574dfb50352bf" + "archive:https://opam.ocaml.org/cache/md5/ca/caa6378c30d69baaf703e5f8b903a493#md5:caa6378c30d69baaf703e5f8b903a493", + "archive:https://github.com/dsheets/ocaml-hashcons/releases/download/1.0.1/ocaml-hashcons-1.0.1.tar.gz#md5:caa6378c30d69baaf703e5f8b903a493" ], "opam": { "name": "hashcons", - "version": "1.3", - "path": "esy.lock/opam/hashcons.1.3" + "version": "1.0.1", + "path": "esy.lock/opam/hashcons.1.0.1" } }, "overrides": [], "dependencies": [ "ocaml@4.8.0@d41d8cd9", "@opam/ocamlfind@opam:1.8.0@f744a0c5", "@opam/conf-which@opam:1@56319cdb", - "@opam/conf-autoconf@github:esy-packages/esy-autoconf#71a8836@d41d8cd9", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@4.8.0@d41d8cd9" ] @@ -3515,7 +3619,7 @@ "@opam/result@opam:1.4@7add0d71", "@opam/re@opam:1.9.0@7f4a36a5", "@opam/ppx_cstruct@opam:5.0.0@cea738b4", "@opam/ipaddr@opam:3.1.0@e0ecc70f", - "@opam/hashcons@opam:1.3@35d35e80", + "@opam/hashcons@opam:1.0.1@30492c11", "@opam/dune@opam:1.10.0@b15ce221", "@opam/cstruct@opam:4.0.0@27f747cf", "@opam/base64@opam:3.2.0@e1bac209", @@ -3526,7 +3630,7 @@ "@opam/result@opam:1.4@7add0d71", "@opam/re@opam:1.9.0@7f4a36a5", "@opam/ppx_cstruct@opam:5.0.0@cea738b4", "@opam/ipaddr@opam:3.1.0@e0ecc70f", - "@opam/hashcons@opam:1.3@35d35e80", + "@opam/hashcons@opam:1.0.1@30492c11", "@opam/cstruct@opam:4.0.0@27f747cf", "@opam/base64@opam:3.2.0@e1bac209" ] @@ -3748,6 +3852,31 @@ "dependencies": [ "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [] }, + "@opam/conf-pkg-config@opam:1.1@da0b7ce6": { + "id": "@opam/conf-pkg-config@opam:1.1@da0b7ce6", + "name": "@opam/conf-pkg-config", + "version": "opam:1.1", + "source": { + "type": "install", + "source": [ "no-source:" ], + "opam": { + "name": "conf-pkg-config", + "version": "1.1", + "path": "esy.lock/opam/conf-pkg-config.1.1" + } + }, + "overrides": [ + { + "opamoverride": + "esy.lock/overrides/opam__s__conf_pkg_config_opam__c__1.1_opam_override" + } + ], + "dependencies": [ + "yarn-pkg-config@github:esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0@d41d8cd9", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [] + }, "@opam/conf-perl@opam:1@3174af0e": { "id": "@opam/conf-perl@opam:1@3174af0e", "name": "@opam/conf-perl", @@ -3765,6 +3894,25 @@ "dependencies": [ "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [] }, + "@opam/conf-openssl@archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511@ee5c2c69": { + "id": + "@opam/conf-openssl@archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511@ee5c2c69", + "name": "@opam/conf-openssl", + "version": + "archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511", + "source": { + "type": "install", + "source": [ + "archive:https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#sha1:eb59b090bd757e30b676fb5e80c25ddb5a2f9511" + ] + }, + "overrides": [ "esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6" ], + "dependencies": [ + "@opam/conf-pkg-config@opam:1.1@da0b7ce6", + "@opam/conf-autoconf@github:esy-packages/esy-autoconf:package.json#71a8836@d41d8cd9" + ], + "devDependencies": [] + }, "@opam/conf-m4@opam:1@dd7dde42": { "id": "@opam/conf-m4@opam:1@dd7dde42", "name": "@opam/conf-m4", @@ -3807,14 +3955,14 @@ ], "devDependencies": [] }, - "@opam/conf-autoconf@github:esy-packages/esy-autoconf#71a8836@d41d8cd9": { + "@opam/conf-autoconf@github:esy-packages/esy-autoconf:package.json#71a8836@d41d8cd9": { "id": - "@opam/conf-autoconf@github:esy-packages/esy-autoconf#71a8836@d41d8cd9", + "@opam/conf-autoconf@github:esy-packages/esy-autoconf:package.json#71a8836@d41d8cd9", "name": "@opam/conf-autoconf", - "version": "github:esy-packages/esy-autoconf#71a8836", + "version": "github:esy-packages/esy-autoconf:package.json#71a8836", "source": { "type": "install", - "source": [ "github:esy-packages/esy-autoconf#71a8836" ] + "source": [ "github:esy-packages/esy-autoconf:package.json#71a8836" ] }, "overrides": [], "dependencies": [], diff --git a/esy.lock/opam/conf-pkg-config.1.1/opam b/esy.lock/opam/conf-pkg-config.1.1/opam new file mode 100644 index 0000000..1fbd0d5 --- /dev/null +++ b/esy.lock/opam/conf-pkg-config.1.1/opam @@ -0,0 +1,39 @@ +opam-version: "2.0" +maintainer: "unixjunkie@sdf.org" +authors: ["Francois Berenger"] +homepage: "http://www.freedesktop.org/wiki/Software/pkg-config/" +bug-reports: "https://github.com/ocaml/opam-repository/issues" +license: "GPL" +build: [ + ["pkg-config" "--help"] +] +install: [ + ["ln" "-s" "/usr/local/bin/pkgconf" "%{bin}%/pkg-config"] {os = "openbsd"} +] +remove: [ + ["rm" "-f" "%{bin}%/pkg-config"] {os = "openbsd"} +] +post-messages: [ + "conf-pkg-config: A symlink to /usr/local/bin/pkgconf has been installed in the OPAM bin directory (%{bin}%) on your PATH as 'pkg-config'. This is necessary for correct operation." {os = "openbsd"} +] +depexts: [ + ["pkg-config"] {os-distribution = "debian"} + ["pkg-config"] {os-distribution = "ubuntu"} + ["pkg-config"] {os-distribution = "arch"} + ["pkgconfig"] {os-distribution = "fedora"} + ["pkgconfig"] {os-distribution = "centos"} + ["pkgconfig"] {os-distribution = "mageia"} + ["pkgconfig"] {os-distribution = "rhel"} + ["pkgconfig"] {os-distribution = "ol"} + ["pkgconfig"] {os-distribution = "alpine"} + ["devel/pkgconf"] {os = "freebsd"} + ["devel/pkgconf"] {os = "openbsd"} + ["pkg-config"] {os = "macos" & os-distribution = "homebrew"} + ["pkgconf"] {os = "freebsd"} + ["pkg-config"] {os-distribution = "cygwinports"} +] +synopsis: "Virtual package relying on pkg-config installation" +description: """ +This package can only install if the pkg-config package is installed +on the system.""" +flags: conf diff --git a/esy.lock/opam/hashcons.1.3/opam b/esy.lock/opam/hashcons.1.0.1/opam similarity index 84% rename from esy.lock/opam/hashcons.1.3/opam rename to esy.lock/opam/hashcons.1.0.1/opam index e551d38..b774ca1 100644 --- a/esy.lock/opam/hashcons.1.3/opam +++ b/esy.lock/opam/hashcons.1.0.1/opam @@ -6,7 +6,6 @@ bug-reports: "https://github.com/backtracking/ocaml-hashcons/issues" authors: [ "Jean-Christophe Filliatre" ] license: "LGPL-2.1 with OCaml linking exception" build: [ - ["autoconf"] ["./configure"] [make "all"] ] @@ -16,7 +15,6 @@ install: [ remove: [["ocamlfind" "remove" "hashcons"]] depends: [ "ocaml" - "conf-autoconf" {build} "ocamlfind" {build} "conf-which" {build} ] @@ -30,6 +28,7 @@ The PDF is available at """ flags: light-uninstall url { - src: "https://github.com/backtracking/ocaml-hashcons/archive/1.3.tar.gz" - checksum: "md5=88b93515dd2667c4944574dfb50352bf" + src: + "https://github.com/dsheets/ocaml-hashcons/releases/download/1.0.1/ocaml-hashcons-1.0.1.tar.gz" + checksum: "md5=caa6378c30d69baaf703e5f8b903a493" } diff --git a/esy.lock/opam/lwt_ssl.1.1.2/opam b/esy.lock/opam/lwt_ssl.1.1.2/opam new file mode 100644 index 0000000..5c772d3 --- /dev/null +++ b/esy.lock/opam/lwt_ssl.1.1.2/opam @@ -0,0 +1,28 @@ +opam-version: "2.0" +version: "1.1.2" +homepage: "https://github.com/aantron/lwt_ssl" +doc: "https://github.com/aantron/lwt_ssl/blob/master/src/lwt_ssl.mli" +bug-reports: "https://github.com/aantron/lwt_ssl/issues" +license: "LGPL with OpenSSL linking exception" + +authors: [ + "Jérôme Vouillon" + "Jérémie Dimino" +] +maintainer: "Anton Bachin " +dev-repo: "git+https://github.com/aantron/lwt_ssl.git" +depends: [ + "ocaml" + "base-unix" + "jbuilder" {build & >= "1.0+beta10"} + "lwt" {>= "3.0.0"} + "ssl" {>= "0.5.0"} +] +build: [ + ["jbuilder" "build" "-p" name "-j" jobs] +] +synopsis: "OpenSSL binding with concurrent I/O" +url { + src: "https://github.com/aantron/lwt_ssl/archive/1.1.2.tar.gz" + checksum: "md5=d239353b1e7c6e3fd4192c71a3b25ce2" +} diff --git a/esy.lock/opam/ssl.0.5.8/opam b/esy.lock/opam/ssl.0.5.8/opam new file mode 100644 index 0000000..c0845ba --- /dev/null +++ b/esy.lock/opam/ssl.0.5.8/opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "Samuel Mimram " +homepage: "https://github.com/savonet/ocaml-ssl" +dev-repo: "git+https://github.com/savonet/ocaml-ssl.git" +bug-reports: "https://github.com/savonet/ocaml-ssl/issues" +build: [ + ["dune" "subst"] {pinned} + ["dune" "build" "-p" name "-j" jobs] +] +depends: [ + "ocaml" {>= "4.02.0"} + "dune" {build & >= "1.2.1"} + "base-unix" + "conf-openssl" +] +synopsis: "Bindings for OpenSSL" +authors: "Samuel Mimram " +url { + src: "https://github.com/savonet/ocaml-ssl/archive/0.5.8.tar.gz" + checksum: [ + "md5=4b2cd1e21f25989b958e880f7b4791d1" + "sha512=b9bdb1f9c7df9b49c9cda47909e5a9c0d05dbfed54df0d2dd378fda860c0d5e2f7cd4b675a505b8b325b796567ec7a88dcf7be2154cb407ce026ee4ecb9bc592" + ] +} diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.ci/build.yaml b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.ci/build.yaml new file mode 100644 index 0000000..853bef3 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.ci/build.yaml @@ -0,0 +1,30 @@ +parameters: + host: '' + pool: '' + sign: false + +jobs: +- job: ${{ parameters.host }} + pool: ${{ parameters.pool }} + steps: + - ${{ if eq(parameters.sign, 'true') }}: + - script: 'npm install -g esy@latest --unsafe-perm' + displayName: 'Installing deps' + - ${{ if eq(parameters.sign, 'false') }}: + - script: 'sudo npm install -g esy@latest --unsafe-perm' + displayName: 'Installing deps' + - script: mkdir -p test_dir + displayName: 'make test dir' + - bash: | + cd test_dir + echo '{"dependencies": {"@esy-packages/esy-openssl" : "esy-packages/esy-openssl:package.json#'$(git rev-parse --short HEAD)'"}}' > package.json + displayName: 'create test package.json' + - script: | + cd test_dir + esy install + displayName: 'Install esy-deps' + - script: | + cd test_dir + esy x which openssl + esy sh ../esy/test.sh + displayName: 'Building and dry run' diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.gitignore b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.gitignore new file mode 100644 index 0000000..ebfbaf2 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.gitignore @@ -0,0 +1 @@ +test_dir diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.travis.yml b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.travis.yml new file mode 100644 index 0000000..134b7af --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/.travis.yml @@ -0,0 +1,15 @@ +language: node_js +node_js: +- 8 +os: +- linux +- osx +install: +- npm install --global esy@0.3.0 +- esy install +script: +- travis_wait 40 esy build +cache: + timeout: 360 + directories: + - '$HOME/.esy/' diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/README.md b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/README.md new file mode 100644 index 0000000..b263f32 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/README.md @@ -0,0 +1,98 @@ +### `esy` build status +[![Build status](https://ci.appveyor.com/api/projects/status/54y3s6ip6ti7y3vm/branch/esy?svg=true)](https://ci.appveyor.com/project/bryphe/esy-openssl/branch/esy) +[![Build Status](https://travis-ci.org/bryphe/esy-openssl.svg?branch=esy)](https://travis-ci.org/bryphe/esy-openssl) + + ----------- + + OpenSSL 1.1.1 11 Sep 2018 + + Copyright (c) 1998-2018 The OpenSSL Project + Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson + All rights reserved. + + DESCRIPTION + ----------- + + The OpenSSL Project is a collaborative effort to develop a robust, + commercial-grade, fully featured, and Open Source toolkit implementing the + Transport Layer Security (TLS) protocols (including SSLv3) as well as a + full-strength general purpose cryptographic library. + + OpenSSL is descended from the SSLeay library developed by Eric A. Young + and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the + OpenSSL license plus the SSLeay license), which means that you are free to + get and use it for commercial and non-commercial purposes as long as you + fulfill the conditions of both licenses. + + OVERVIEW + -------- + + The OpenSSL toolkit includes: + + libssl (with platform specific naming): + Provides the client and server-side implementations for SSLv3 and TLS. + + libcrypto (with platform specific naming): + Provides general cryptographic and X.509 support needed by SSL/TLS but + not logically part of it. + + openssl: + A command line tool that can be used for: + Creation of key parameters + Creation of X.509 certificates, CSRs and CRLs + Calculation of message digests + Encryption and decryption + SSL/TLS client and server tests + Handling of S/MIME signed or encrypted mail + And more... + + INSTALLATION + ------------ + + See the appropriate file: + INSTALL Linux, Unix, Windows, OpenVMS, ... + NOTES.* INSTALL addendums for different platforms + + SUPPORT + ------- + + See the OpenSSL website www.openssl.org for details on how to obtain + commercial technical support. Free community support is available through the + openssl-users email list (see + https://www.openssl.org/community/mailinglists.html for further details). + + If you have any problems with OpenSSL then please take the following steps + first: + + - Download the latest version from the repository + to see if the problem has already been addressed + - Configure with no-asm + - Remove compiler optimization flags + + If you wish to report a bug then please include the following information + and create an issue on GitHub: + + - OpenSSL version: output of 'openssl version -a' + - Configuration data: output of 'perl configdata.pm --dump' + - OS Name, Version, Hardware platform + - Compiler Details (name, version) + - Application Details (name, version) + - Problem Description (steps that will reproduce the problem, if known) + - Stack Traceback (if the application dumps core) + + Just because something doesn't work the way you expect does not mean it + is necessarily a bug in OpenSSL. Use the openssl-users email list for this type + of query. + + HOW TO CONTRIBUTE TO OpenSSL + ---------------------------- + + See CONTRIBUTING + + LEGALITIES + ---------- + + A number of nations restrict the use or export of cryptography. If you + are potentially subject to such restrictions you should seek competent + professional legal advice before attempting to develop or distribute + cryptographic code. diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/azure-pipelines.yml b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/azure-pipelines.yml new file mode 100644 index 0000000..91ef313 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/azure-pipelines.yml @@ -0,0 +1,19 @@ +jobs: +- template: .ci/build.yaml # Template reference + parameters: + host: macOS + pool: + vmImage: 'macOS-10.13' + +- template: .ci/build.yaml # Template reference + parameters: + host: Linux + pool: + vmImage: 'Ubuntu-16.04' + +- template: .ci/build.yaml # Template reference + parameters: + host: Windows + pool: + vmImage: 'vs2017-win2016' + sign: true # Extra step on Windows only diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy.lock.json b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy.lock.json new file mode 100644 index 0000000..57e9c7a --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy.lock.json @@ -0,0 +1,16 @@ +{ + "hash": "d10585b707b5ab54802c6c85154328fd", + "root": "root@path:./package.json", + "node": { + "root@path:./package.json": { + "record": { + "name": "root", + "version": "path:./package.json", + "source": "path:./package.json", + "files": [], + "opam": null + }, + "dependencies": [] + } + } +} \ No newline at end of file diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.c b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.c new file mode 100644 index 0000000..ea32b03 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.c @@ -0,0 +1,32 @@ +/* From: https://wiki.openssl.org/index.php/Libcrypto_API */ + +#include +#include +#include + +int main(int arc, char *argv[]) +{ + /* Load the human readable error strings for libcrypto */ + ERR_load_crypto_strings(); + + /* Load all digest and cipher algorithms */ + OpenSSL_add_all_algorithms(); + + /* Load config file, and other important initialisation */ + OPENSSL_config(NULL); + + printf("OpenSSL successfully initialized.\n"); + + /* Clean up */ + + /* Removes all digests and ciphers */ + EVP_cleanup(); + + /* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */ + CRYPTO_cleanup_all_ex_data(); + + /* Remove error strings */ + ERR_free_strings(); + + return 0; +} diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.sh b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.sh new file mode 100755 index 0000000..bced3d0 --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/esy/test.sh @@ -0,0 +1,31 @@ +pwd +mkdir -p _test +cd _test + +if which x86_64-w64-mingw32-gcc; then + CC=x86_64-w64-mingw32-gcc +else + CC=gcc +fi + +echo "Using compiler: $CC" + +echo "include..." +#ls -a $INCLUDE +echo "lib.." +#ls -a $cur__lib + +$CC ./../../esy/test.c -o ./test.exe -I$OPENSSL_INCLUDE_PATH -L$OPENSSL_LIB_PATH -lssl -lcrypto + +#export PATH=$PATH:$cur__bin:$cur__lib +#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$cur__lib + +#echo "Augmented path: $PATH" + +echo "Copying binaries..." +#cp $cur__bin/*.dll . + +echo "Test executable path:" +ls -a . + +./test.exe diff --git a/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/package.json b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/package.json new file mode 100644 index 0000000..ff8d20b --- /dev/null +++ b/esy.lock/overrides/ee5c2c6906d87e3ea9a19e8e3dac5ec6/package.json @@ -0,0 +1,48 @@ +{ + "name": "esy-openssl", + "version": "0.1.0", + "description": "Mirror of OpenSSL", + "license": "Apache 2.0", + "source": "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz#eb59b090bd757e30b676fb5e80c25ddb5a2f9511", + "override": { + "build": [ + [ + "bash", + "-c", + "#{os == 'windows' ? './configure mingw64 --prefix=$cur__install --cross-compile-prefix=x86_64-w64-mingw32-' : './config --prefix=$cur__install'}" + ], + [ + "make" + ] + ], + "install": [ + [ + "make", + "install" + ] + ], + "buildsInSource": true, + "exportedEnv": { + "OPENSSL_LIB_PATH": { + "val": "#{self.lib}", + "scope": "global" + }, + "OPENSSL_INCLUDE_PATH": { + "val": "#{self.install / 'include'}", + "scope": "global" + }, + "OPENSSL_BIN_PATH": { + "val": "#{self.bin}", + "scope": "global" + }, + "PKG_CONFIG_PATH": { + "val": "#{self.lib / 'pkgconfig'}", + "scope": "global" + } + }, + "dependencies": { + "@opam/conf-autoconf": "esy-packages/esy-autoconf:package.json#71a8836", + "@opam/conf-pkg-config": "*" + } + } +} diff --git a/esy.lock/overrides/opam__s__conf_pkg_config_opam__c__1.1_opam_override/package.json b/esy.lock/overrides/opam__s__conf_pkg_config_opam__c__1.1_opam_override/package.json new file mode 100644 index 0000000..6d710b6 --- /dev/null +++ b/esy.lock/overrides/opam__s__conf_pkg_config_opam__c__1.1_opam_override/package.json @@ -0,0 +1,11 @@ +{ + "build": [ + [ + "pkg-config", + "--help" + ] + ], + "dependencies": { + "yarn-pkg-config": "esy-ocaml/yarn-pkg-config#cca65f99674ed2d954d28788edeb8c57fada5ed0" + } +} diff --git a/examples/lwt/dune b/examples/lwt/dune index a11adb8..1b84bf1 100644 --- a/examples/lwt/dune +++ b/examples/lwt/dune @@ -1,6 +1,6 @@ (executables (libraries httpaf httpaf-lwt-unix httpaf_examples base stdio lwt lwt.unix) - (names lwt_get lwt_post lwt_echo_post)) + (names lwt_get lwt_post lwt_echo_post lwt_https_get lwt_https_server)) (alias (name examples) diff --git a/examples/lwt/lwt_https_get.ml b/examples/lwt/lwt_https_get.ml new file mode 100644 index 0000000..cbdbcfc --- /dev/null +++ b/examples/lwt/lwt_https_get.ml @@ -0,0 +1,30 @@ +open Base +open Lwt.Infix +module Arg = Caml.Arg + +open Httpaf +open Httpaf_lwt_unix + +let error_handler _ = assert false + +let main port host = + Lwt_unix.getaddrinfo host (Int.to_string port) [Unix.(AI_FAMILY PF_INET)] + >>= fun addresses -> + let socket = Lwt_unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in + Lwt_unix.connect socket (List.hd_exn addresses).Unix.ai_addr + >>= fun () -> + let finished, notify_finished = Lwt.wait () in + let response_handler = + Httpaf_examples.Client.print ~on_eof:(Lwt.wakeup_later notify_finished) + in + let headers = Headers.of_list [ "host", host ] in + let request_body = + Client.TLS.request + ~error_handler + ~response_handler + socket + (Request.create ~headers `GET "/") + in + Body.close_writer request_body; + finished +;; diff --git a/examples/lwt/lwt_https_server.ml b/examples/lwt/lwt_https_server.ml new file mode 100644 index 0000000..5161101 --- /dev/null +++ b/examples/lwt/lwt_https_server.ml @@ -0,0 +1,41 @@ +open Base +open Lwt.Infix +module Arg = Caml.Arg + +open Httpaf_lwt_unix + +let request_handler (_ : Unix.sockaddr) = Httpaf_examples.Server.echo_post +let error_handler (_ : Unix.sockaddr) = Httpaf_examples.Server.error_handler + +let main port = + let listen_address = Unix.(ADDR_INET (inet_addr_loopback, port)) in + let certfile = "./certificates/server.pem" in + let keyfile = "./certificates/server.key" in + Lwt.async (fun () -> + Lwt_io.establish_server_with_client_socket + listen_address + (Server.TLS.create_connection_handler + ?server:None + ~certfile + ~keyfile + ?config:None + ~request_handler + ~error_handler) + >|= fun _server -> + Stdio.printf "Listening on port %i and echoing POST requests.\n" port; + Stdio.printf "To send a POST request, try one of the following\n\n"; + Stdio.printf " echo \"Testing echo POST\" | dune exec examples/async/async_post.exe\n"; + Stdio.printf " echo \"Testing echo POST\" | dune exec examples/lwt/lwt_post.exe\n"; + Stdio.printf " echo \"Testing echo POST\" | curl -XPOST --data @- http://localhost:8080\n\n%!"); + let forever, _ = Lwt.wait () in + Lwt_main.run forever +;; + +let () = + let port = ref 8080 in + Arg.parse + ["-p", Arg.Set_int port, " Listening port number (8080 by default)"] + ignore + "Echoes POST requests. Runs forever."; + main !port +;; diff --git a/httpaf-lwt-unix.opam b/httpaf-lwt-unix.opam index 9ee6534..6196f3c 100644 --- a/httpaf-lwt-unix.opam +++ b/httpaf-lwt-unix.opam @@ -18,6 +18,8 @@ depends: [ "httpaf" "httpaf-lwt" "dune" {build} + "ocamlfind" {build} "lwt" ] +depopts: ["tls" "lwt_ssl"] synopsis: "Lwt + Unix support for http/af" diff --git a/lwt-unix/dune b/lwt-unix/dune index 12e35ba..4b84d6e 100644 --- a/lwt-unix/dune +++ b/lwt-unix/dune @@ -1,6 +1,37 @@ +(* -*- tuareg -*- *) +(* This was inspired by `conduit-lwt-unix`'s dune file *) + +let v ~ssl ~tls () = + let ssl, ssl_d = + if ssl then "ssl_io_real", "lwt_ssl " + else "ssl_io_dummy", "" + in + let tls, tls_d = + if tls then "tls_io_real", "tls.lwt " + else "tls_io_dummy", "" + in + Printf.sprintf {| +(rule (copy %s.ml ssl_io.ml)) +(rule (copy %s.ml tls_io.ml)) + (library (name httpaf_lwt_unix) (public_name httpaf-lwt-unix) - (libraries faraday-lwt-unix httpaf httpaf-lwt lwt.unix) + (libraries faraday-lwt-unix httpaf httpaf-lwt lwt.unix %s%s) + (modules httpaf_lwt_unix tls_io ssl_io) (flags (:standard -safe-string))) +|} ssl tls ssl_d tls_d + +let main () = + let is_installed s = Printf.kprintf Sys.command "ocamlfind query %s" s = 0 in + let ssl = is_installed "lwt_ssl" in + let tls = Sys.unix && is_installed "tls.lwt" in + Printf.printf + "Configuration\n\ + \ ssl : %b\n\ + \ tls : %b\n%!" + ssl tls; + v ~ssl ~tls () + +let () = Jbuild_plugin.V1.send @@ main () diff --git a/lwt-unix/httpaf_lwt_unix.ml b/lwt-unix/httpaf_lwt_unix.ml index 8b4fc24..28d0547 100644 --- a/lwt-unix/httpaf_lwt_unix.ml +++ b/lwt-unix/httpaf_lwt_unix.ml @@ -82,6 +82,70 @@ module Io Lwt.return_unit end -module Server = Httpaf_lwt.Server (Io) +module Config = Httpaf.Config + +module Server = struct + include Httpaf_lwt.Server (Io) + + module TLS = struct + include Httpaf_lwt.Server (Tls_io.Io) + + let create_connection_handler + ?server + ?certfile + ?keyfile + ?(config=Config.default) + ~request_handler + ~error_handler = + let make_tls_server = Tls_io.make_server ?server ?certfile ?keyfile in + fun client_addr socket -> + make_tls_server socket >>= fun tls_server -> + create_connection_handler + ~config + ~request_handler + ~error_handler + client_addr + (socket, tls_server) + end + + module SSL = struct + include Httpaf_lwt.Server (Ssl_io.Io) + + let create_connection_handler + ?server + ?certfile + ?keyfile + ?(config=Config.default) + ~request_handler + ~error_handler = + let make_ssl_server = Ssl_io.make_server ?server ?certfile ?keyfile in + fun client_addr socket -> + make_ssl_server socket >>= fun ssl_server -> + create_connection_handler + ~config + ~request_handler + ~error_handler + client_addr + ssl_server + end +end + +module Client = struct + include Httpaf_lwt.Client (Io) + + module TLS = struct + include Httpaf_lwt.Client (Tls_io.Io) -module Client = Httpaf_lwt.Client (Io) + let request ?client ?(config=Config.default) socket request_headers ~error_handler ~response_handler = + Tls_io.make_client ?client socket >|= fun tls_client -> + request ~config (socket, tls_client) request_headers ~error_handler ~response_handler + end + + module SSL = struct + include Httpaf_lwt.Client (Ssl_io.Io) + + let request ?client ?(config=Config.default) socket request_headers ~error_handler ~response_handler = + Ssl_io.make_client ?client socket >|= fun ssl_client -> + request ~config ssl_client request_headers ~error_handler ~response_handler + end +end diff --git a/lwt-unix/httpaf_lwt_unix.mli b/lwt-unix/httpaf_lwt_unix.mli index 78c3d7b..f08c718 100644 --- a/lwt-unix/httpaf_lwt_unix.mli +++ b/lwt-unix/httpaf_lwt_unix.mli @@ -47,15 +47,63 @@ module Server : sig -> Unix.sockaddr -> Lwt_unix.file_descr -> unit Lwt.t + + module TLS : sig + val create_connection_handler + : ?server : Tls_io.server + -> ?certfile : string + -> ?keyfile : string + -> ?config : Config.t + -> request_handler : (Unix.sockaddr -> Server_connection.request_handler) + -> error_handler : (Unix.sockaddr -> Server_connection.error_handler) + -> Unix.sockaddr + -> Lwt_unix.file_descr + -> unit Lwt.t + end + + module SSL : sig + val create_connection_handler + : ?server : Ssl_io.server + -> ?certfile : string + -> ?keyfile : string + -> ?config : Config.t + -> request_handler : (Unix.sockaddr -> Server_connection.request_handler) + -> error_handler : (Unix.sockaddr -> Server_connection.error_handler) + -> Unix.sockaddr + -> Lwt_unix.file_descr + -> unit Lwt.t + end end (* For an example, see [examples/lwt_get.ml]. *) module Client : sig val request - : ?config : Httpaf.Config.t + : ?config : Config.t -> Lwt_unix.file_descr -> Request.t -> error_handler : Client_connection.error_handler -> response_handler : Client_connection.response_handler - -> [`write] Httpaf.Body.t + -> [`write] Body.t + + module TLS : sig + val request + : ?client : Tls_io.client + -> ?config : Config.t + -> Lwt_unix.file_descr + -> Request.t + -> error_handler : Client_connection.error_handler + -> response_handler : Client_connection.response_handler + -> [`write] Body.t Lwt.t + end + + module SSL : sig + val request + : ?client : Ssl_io.client + -> ?config : Config.t + -> Lwt_unix.file_descr + -> Request.t + -> error_handler : Client_connection.error_handler + -> response_handler : Client_connection.response_handler + -> [`write] Body.t Lwt.t + end end diff --git a/lwt-unix/ssl_io_dummy.ml b/lwt-unix/ssl_io_dummy.ml new file mode 100644 index 0000000..183ce78 --- /dev/null +++ b/lwt-unix/ssl_io_dummy.ml @@ -0,0 +1,64 @@ +(*---------------------------------------------------------------------------- + * Copyright (c) 2019 António Nuno Monteiro + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*) + +type nothing = [ `Ssl_not_available ] + +module Io : + Httpaf_lwt.IO + with type socket = Lwt_unix.file_descr * nothing + and type addr = Unix.sockaddr = struct + type socket = Lwt_unix.file_descr * nothing + + type addr = Unix.sockaddr + + let read _ _bigstring ~off:_ ~len:_ = Lwt.fail_with "Ssl not available" + + let writev _ _iovecs = Lwt.fail_with "Ssl not available" + + let shutdown_send _ = failwith "Ssl not available" + + let shutdown_receive _ = failwith "Ssl not available" + + let close _ = failwith "Ssl not available" +end + +type client = nothing + +type server = nothing + +let[@ocaml.warning "-21"] make_client ?client:_ = + failwith "Ssl not available"; + fun _socket -> Lwt.fail_with "Ssl not available" + +let[@ocaml.warning "-21"] make_server ?server:_ ?certfile:_ ?keyfile:_ = + failwith "Ssl not available"; + fun _socket -> Lwt.fail_with "Ssl not available" diff --git a/lwt-unix/ssl_io_real.ml b/lwt-unix/ssl_io_real.ml new file mode 100644 index 0000000..9583585 --- /dev/null +++ b/lwt-unix/ssl_io_real.ml @@ -0,0 +1,114 @@ +(*---------------------------------------------------------------------------- + * Copyright (c) 2019 António Nuno Monteiro + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*) + +open Lwt.Infix + +let () = Ssl.init () + +module Io : + Httpaf_lwt.IO with type socket = Lwt_ssl.socket and type addr = Unix.sockaddr = +struct + type socket = Lwt_ssl.socket + type addr = Unix.sockaddr + + let read ssl bigstring ~off ~len = + Lwt.catch + (fun () -> + (* Lwt_unix.blocking (Lwt_ssl.get_fd socket) >>= fun _ -> *) + Lwt_ssl.read_bytes ssl bigstring off len) + (function + | Unix.Unix_error (Unix.EBADF, _, _) as exn -> + Lwt.fail exn + | exn -> + Lwt.async (fun () -> + Lwt_ssl.ssl_shutdown ssl >>= fun () -> + Lwt_ssl.close ssl); + Lwt.fail exn) + >>= fun bytes_read -> + if bytes_read = 0 then + Lwt.return `Eof + else + Lwt.return (`Ok bytes_read) + + let writev ssl iovecs = + Lwt.catch + (fun () -> + Lwt_list.fold_left_s + (fun acc { Faraday.buffer; off; len } -> + Lwt_ssl.write_bytes ssl buffer off len >|= fun written -> + acc + written) + 0 + iovecs + >|= fun n -> + `Ok n) + (function + | Unix.Unix_error (Unix.EBADF, "check_descriptor", _) -> + Lwt.return `Closed + | exn -> + Lwt.fail exn) + + let shutdown_send ssl = + ignore + ( Lwt_ssl.ssl_shutdown ssl >|= fun () -> + Lwt_ssl.shutdown ssl Unix.SHUTDOWN_SEND ) + + let shutdown_receive ssl = + ignore + ( Lwt_ssl.ssl_shutdown ssl >|= fun () -> + Lwt_ssl.shutdown ssl Unix.SHUTDOWN_RECEIVE ) + + let close = Lwt_ssl.close +end + +type client = Lwt_ssl.socket +type server = Lwt_ssl.socket + +let make_client ?client socket = + match client with + | Some client -> Lwt.return client + | None -> + let client_ctx = Ssl.create_context Ssl.SSLv23 Ssl.Client_context in + Ssl.disable_protocols client_ctx [Ssl.SSLv23]; + Ssl.honor_cipher_order client_ctx; + Lwt_ssl.ssl_connect socket client_ctx + +let make_server ?server ?certfile ?keyfile socket + = + match server, certfile, keyfile with + | Some server, _, _ -> Lwt.return server + | None, Some cert, Some priv_key -> + let server_ctx = Ssl.create_context Ssl.SSLv23 Ssl.Server_context in + Ssl.disable_protocols server_ctx [Ssl.SSLv23]; + Ssl.use_certificate server_ctx cert priv_key; + Lwt_ssl.ssl_accept socket server_ctx + | _ -> + Lwt.fail (Invalid_argument "Certfile and Keyfile required when server isn't provided") diff --git a/lwt-unix/tls_io_dummy.ml b/lwt-unix/tls_io_dummy.ml new file mode 100644 index 0000000..6c5eac2 --- /dev/null +++ b/lwt-unix/tls_io_dummy.ml @@ -0,0 +1,63 @@ +(*---------------------------------------------------------------------------- + * Copyright (c) 2019 António Nuno Monteiro + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*) + +type nothing = [ `Tls_not_available ] + +module Io : + Httpaf_lwt.IO + with type socket = Lwt_unix.file_descr * nothing + and type addr = Unix.sockaddr = struct + type socket = Lwt_unix.file_descr * nothing + + type addr = Unix.sockaddr + + let read _ _bigstring ~off:_ ~len:_ = Lwt.fail_with "Tls not available" + + let writev _ _iovecs = Lwt.fail_with "Tls not available" + + let shutdown_send _ = failwith "Tls not available" + + let shutdown_receive _ = failwith "Tls not available" + + let close _ = Lwt.fail_with "Tls not available" +end + +type client = nothing +type server = nothing + +let[@ocaml.warning "-21"] make_client ?client:_ = + failwith "TLS not available"; + fun _socket -> Lwt.return `Tls_not_available + +let[@ocaml.warning "-21"] make_server ?server:_ ?certfile:_ ?keyfile:_ = + failwith "TLS not available"; + fun _socket -> Lwt.fail_with "TLS not available" diff --git a/lwt-unix/tls_io_real.ml b/lwt-unix/tls_io_real.ml new file mode 100644 index 0000000..7c9ba34 --- /dev/null +++ b/lwt-unix/tls_io_real.ml @@ -0,0 +1,115 @@ +(*---------------------------------------------------------------------------- + * Copyright (c) 2019 António Nuno Monteiro + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*) + +open Lwt.Infix + +let _ = Nocrypto_entropy_lwt.initialize () + +module Io : + Httpaf_lwt.IO + with type socket = Lwt_unix.file_descr * Tls_lwt.Unix.t + and type addr = Unix.sockaddr = struct + type socket = Lwt_unix.file_descr * Tls_lwt.Unix.t + + type addr = Unix.sockaddr + + let read (_, tls) bigstring ~off ~len = + Lwt.catch + (fun () -> Tls_lwt.Unix.read_bytes tls bigstring off len) + (function + | Unix.Unix_error (Unix.EBADF, _, _) as exn -> + Lwt.fail exn + | exn -> + Lwt.async (fun () -> Tls_lwt.Unix.close tls); + Lwt.fail exn) + >>= fun bytes_read -> + if bytes_read = 0 then + Lwt.return `Eof + else + Lwt.return (`Ok bytes_read) + + let writev (_, tls) iovecs = + Lwt.catch + (fun () -> + let cstruct_iovecs = + List.map + (fun { Faraday.len; buffer; off } -> + Cstruct.of_bigarray ~off ~len buffer) + iovecs + in + Tls_lwt.Unix.writev tls cstruct_iovecs >|= fun () -> + `Ok (Cstruct.lenv cstruct_iovecs)) + (function + | Unix.Unix_error (Unix.EBADF, "check_descriptor", _) -> + Lwt.return `Closed + | exn -> + Lwt.fail exn) + + let shutdown_send (_, tls) = ignore (Tls_lwt.Unix.close_tls tls) + + let shutdown_receive (_, tls) = ignore (Tls_lwt.Unix.close_tls tls) + + let close (_, tls) = Tls_lwt.Unix.close tls +end + +type client = Tls_lwt.Unix.t +type server = Tls_lwt.Unix.t + +let make_client ?client socket = + match client with + | Some client -> Lwt.return client + | None -> + X509_lwt.authenticator `No_authentication_I'M_STUPID >>= fun authenticator -> + let config = Tls.Config.client ~authenticator () in + Tls_lwt.Unix.client_of_fd config socket + +let make_server ?server ?certfile ?keyfile socket = + let server = + match server, certfile, keyfile with + | Some server, _, _ -> + Lwt.return server + | None, Some cert, Some priv_key -> + X509_lwt.private_of_pems ~cert ~priv_key >>= fun certificate -> + let config = + Tls.Config.server + ~alpn_protocols:[ "http/1.1" ] + ~certificates: + (`Single certificate) + () + in + Tls_lwt.Unix.server_of_fd config socket + | _ -> + Lwt.fail + (Invalid_argument + "Certfile and Keyfile required when server isn't provided") + in + server From dde7c67c6fdca7a1ae2fedc9729738a30fa3c036 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 6 Jul 2019 21:34:27 -0700 Subject: [PATCH 2/2] fix example after rebase --- examples/lwt/lwt_https_get.ml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/lwt/lwt_https_get.ml b/examples/lwt/lwt_https_get.ml index cbdbcfc..be50051 100644 --- a/examples/lwt/lwt_https_get.ml +++ b/examples/lwt/lwt_https_get.ml @@ -18,13 +18,12 @@ let main port host = Httpaf_examples.Client.print ~on_eof:(Lwt.wakeup_later notify_finished) in let headers = Headers.of_list [ "host", host ] in - let request_body = - Client.TLS.request - ~error_handler - ~response_handler - socket - (Request.create ~headers `GET "/") - in + Client.TLS.request + ~error_handler + ~response_handler + socket + (Request.create ~headers `GET "/") + >>= fun request_body -> Body.close_writer request_body; finished ;;