Skip to content

Commit dd87dba

Browse files
author
Connor Prussin
committed
Add https server support
1 parent 8c06790 commit dd87dba

File tree

4 files changed

+345
-29
lines changed

4 files changed

+345
-29
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"purescript-node-streams": "^3.0.0",
2020
"purescript-node-url": "^3.0.0",
2121
"purescript-options": "^3.0.0",
22-
"purescript-unsafe-coerce": "^3.0.0"
22+
"purescript-unsafe-coerce": "^3.0.0",
23+
"purescript-node-buffer": "^3.0.1"
2324
}
2425
}

src/Node/HTTP.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
"use strict";
22

33
var http = require("http");
4+
var https = require("https");
5+
6+
exports.createServerSImpl = function (options) {
7+
return function (handleRequest) {
8+
return function () {
9+
return https.createServer(options, function (req, res) {
10+
handleRequest(req)(res)();
11+
});
12+
};
13+
};
14+
};
415

516
exports.createServer = function (handleRequest) {
617
return function () {

src/Node/HTTP.purs

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,29 @@ module Node.HTTP
66
, Response
77
, HTTP
88

9+
, createServerS
10+
, SSLOptions
11+
, handshakeTimeout
12+
, requestCert
13+
, rejectUnauthorized
14+
, npnProtocols
15+
, alpnProtocols
16+
, sessionTimeout
17+
, ticketKeys
18+
, pfx
19+
, key
20+
, passphrase
21+
, cert
22+
, ca
23+
, crl
24+
, ciphers
25+
, honorCipherOrder
26+
, ecdhCurve
27+
, dhparam
28+
, secureProtocol
29+
, secureOptions
30+
, sessionIdContext
31+
932
, createServer
1033
, listen
1134
, ListenOptions
@@ -28,10 +51,13 @@ import Prelude
2851

2952
import Control.Monad.Eff (Eff, kind Effect)
3053

54+
import Data.Foreign (Foreign)
3155
import Data.Maybe (Maybe)
3256
import Data.Nullable (Nullable, toNullable)
57+
import Data.Options (Options, Option, options, opt)
3358
import Data.StrMap (StrMap)
3459

60+
import Node.Buffer (Buffer)
3561
import Node.Stream (Writable, Readable)
3662

3763
import Unsafe.Coerce (unsafeCoerce)
@@ -51,6 +77,202 @@ foreign import data HTTP :: Effect
5177
-- | Create a HTTP server, given a function to be executed when a request is received.
5278
foreign import createServer :: forall eff. (Request -> Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Server
5379

80+
-- | The type of HTTPS server options
81+
data SSLOptions
82+
83+
-- | Abort the connection if the SSL/TLS handshake does not finish in the
84+
-- | specified number of milliseconds. Defaults to 120 seconds. A
85+
-- | 'tlsClientError' is emitted on the tls.Server object whenever a handshake
86+
-- | times out.
87+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
88+
handshakeTimeout :: Option SSLOptions Int
89+
handshakeTimeout = opt "handshakeTimeout"
90+
91+
-- | If true the server will request a certificate from clients that connect and
92+
-- | attempt to verify that certificate. Defaults to false.
93+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
94+
requestCert :: Option SSLOptions Boolean
95+
requestCert = opt "requestCert"
96+
97+
-- | If not false the server will reject any connection which is not authorized
98+
-- | with the list of supplied CAs. This option only has an effect if
99+
-- | requestCert is true. Defaults to true.
100+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
101+
rejectUnauthorized :: Option SSLOptions Boolean
102+
rejectUnauthorized = opt "rejectUnauthorized"
103+
104+
-- | An array of strings, Buffers or Uint8Arrays, or a single Buffer or
105+
-- | Uint8Array containing supported NPN protocols. Buffers should have the
106+
-- | format [len][name][len][name]... e.g. 0x05hello0x05world, where the first
107+
-- | byte is the length of the next protocol name. Passing an array is usually
108+
-- | much simpler, e.g. ['hello', 'world']. (Protocols should be ordered by
109+
-- | their priority.)
110+
-- | The type variable t should be a string[], Buffer[], Uint8Array[], Buffer,
111+
-- | or Uint8Array.
112+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
113+
npnProtocols :: forall t. Option SSLOptions t
114+
npnProtocols = opt "NPNProtocols"
115+
116+
-- | An array of strings, Buffers or Uint8Arrays, or a single Buffer or
117+
-- | Uint8Array containing the supported ALPN protocols. Buffers should have the
118+
-- | format [len][name][len][name]... e.g. 0x05hello0x05world, where the first
119+
-- | byte is the length of the next protocol name. Passing an array is usually
120+
-- | much simpler, e.g. ['hello', 'world']. (Protocols should be ordered by
121+
-- | their priority.) When the server receives both NPN and ALPN extensions from
122+
-- | the client, ALPN takes precedence over NPN and the server does not send an
123+
-- | NPN extension to the client.
124+
-- | The type variable t should be a string[], Buffer[], Uint8Array[], Buffer,
125+
-- | or Uint8Array.
126+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
127+
alpnProtocols :: forall t. Option SSLOptions t
128+
alpnProtocols = opt "ALPNProtocols"
129+
130+
-- | An integer specifying the number of seconds after which the TLS session
131+
-- | identifiers and TLS session tickets created by the server will time out.
132+
-- | See SSL_CTX_set_timeout for more details.
133+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
134+
sessionTimeout :: Option SSLOptions Int
135+
sessionTimeout = opt "sessionTimeout"
136+
137+
-- | A 48-byte Buffer instance consisting of a 16-byte prefix, a 16-byte HMAC
138+
-- | key, and a 16-byte AES key. This can be used to accept TLS session tickets
139+
-- | on multiple instances of the TLS server.
140+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener)
141+
ticketKeys :: Option SSLOptions Buffer
142+
ticketKeys = opt "ticketKeys"
143+
144+
-- | Optional PFX or PKCS12 encoded private key and certificate chain. pfx is an
145+
-- | alternative to providing key and cert individually. PFX is usually
146+
-- | encrypted, if it is, passphrase will be used to decrypt it.
147+
-- | The type variable t should be a string or Buffer.
148+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
149+
pfx :: forall t. Option SSLOptions t
150+
pfx = opt "pfx"
151+
152+
-- | Optional private keys in PEM format. PEM allows the option of private keys
153+
-- | being encrypted. Encrypted keys will be decrypted with options.passphrase.
154+
-- | Multiple keys using different algorithms can be provided either as an array
155+
-- | of unencrypted key strings or buffers, or an array of objects in the form
156+
-- | {pem: <string|buffer>[, passphrase: <string>]}. The object form can only
157+
-- | occur in an array. object.passphrase is optional. Encrypted keys will be
158+
-- | decrypted with object.passphrase if provided, or options.passphrase if it
159+
-- | is not.
160+
-- | The type variable t should be a string, string[], Buffer, Buffer[], or
161+
-- | Object[].
162+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
163+
key :: forall t. Option SSLOptions t
164+
key = opt "key"
165+
166+
-- | Optional shared passphrase used for a single private key and/or a PFX.
167+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
168+
passphrase :: Option SSLOptions String
169+
passphrase = opt "passphrase"
170+
171+
-- | Optional cert chains in PEM format. One cert chain should be provided per
172+
-- | private key. Each cert chain should consist of the PEM formatted
173+
-- | certificate for a provided private key, followed by the PEM formatted
174+
-- | intermediate certificates (if any), in order, and not including the root CA
175+
-- | (the root CA must be pre-known to the peer, see ca). When providing
176+
-- | multiple cert chains, they do not have to be in the same order as their
177+
-- | private keys in key. If the intermediate certificates are not provided, the
178+
-- | peer will not be able to validate the certificate, and the handshake will
179+
-- | fail.
180+
-- | The type variable t should be a string, string[], Buffer, or Buffer[].
181+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
182+
cert :: forall t. Option SSLOptions t
183+
cert = opt "cert"
184+
185+
-- | Optionally override the trusted CA certificates. Default is to trust the
186+
-- | well-known CAs curated by Mozilla. Mozilla's CAs are completely replaced
187+
-- | when CAs are explicitly specified using this option. The value can be a
188+
-- | string or Buffer, or an Array of strings and/or Buffers. Any string or
189+
-- | Buffer can contain multiple PEM CAs concatenated together. The peer's
190+
-- | certificate must be chainable to a CA trusted by the server for the
191+
-- | connection to be authenticated. When using certificates that are not
192+
-- | chainable to a well-known CA, the certificate's CA must be explicitly
193+
-- | specified as a trusted or the connection will fail to authenticate. If the
194+
-- | peer uses a certificate that doesn't match or chain to one of the default
195+
-- | CAs, use the ca option to provide a CA certificate that the peer's
196+
-- | certificate can match or chain to. For self-signed certificates, the
197+
-- | certificate is its own CA, and must be provided.
198+
-- | The type variable t should be a string, string[], Buffer, or Buffer[].
199+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
200+
ca :: forall t. Option SSLOptions t
201+
ca = opt "ca"
202+
203+
-- | Optional PEM formatted CRLs (Certificate Revocation Lists).
204+
-- | The type variable t should be a string, string[], Buffer, or Buffer[].
205+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
206+
crl :: forall t. Option SSLOptions t
207+
crl = opt "crl"
208+
209+
-- | Optional cipher suite specification, replacing the default. For more
210+
-- | information, see modifying the default cipher suite.
211+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
212+
ciphers :: Option SSLOptions String
213+
ciphers = opt "ciphers"
214+
215+
-- | Attempt to use the server's cipher suite preferences instead of the
216+
-- | client's. When true, causes SSL_OP_CIPHER_SERVER_PREFERENCE to be set in
217+
-- | secureOptions, see OpenSSL Options for more information.
218+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
219+
honorCipherOrder :: Option SSLOptions Boolean
220+
honorCipherOrder = opt "honorCipherOrder"
221+
222+
-- | A string describing a named curve to use for ECDH key agreement or false to
223+
-- | disable ECDH. Defaults to tls.DEFAULT_ECDH_CURVE. Use crypto.getCurves() to
224+
-- | obtain a list of available curve names. On recent releases, openssl ecparam
225+
-- | -list_curves will also display the name and description of each available
226+
-- | elliptic curve.
227+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
228+
ecdhCurve :: Option SSLOptions String
229+
ecdhCurve = opt "ecdhCurve"
230+
231+
-- | Diffie Hellman parameters, required for Perfect Forward Secrecy. Use
232+
-- | openssl dhparam to create the parameters. The key length must be greater
233+
-- | than or equal to 1024 bits, otherwise an error will be thrown. It is
234+
-- | strongly recommended to use 2048 bits or larger for stronger security. If
235+
-- | omitted or invalid, the parameters are silently discarded and DHE ciphers
236+
-- | will not be available.
237+
-- | The type variable t should be a string or Buffer.
238+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
239+
dhparam :: forall t. Option SSLOptions t
240+
dhparam = opt "dhparam"
241+
242+
-- | Optional SSL method to use, default is "SSLv23_method". The possible values
243+
-- | are listed as SSL_METHODS, use the function names as strings. For example,
244+
-- | "SSLv3_method" to force SSL version 3.
245+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
246+
secureProtocol :: Option SSLOptions String
247+
secureProtocol = opt "secureProtocol"
248+
249+
-- | Optionally affect the OpenSSL protocol behavior, which is not usually
250+
-- | necessary. This should be used carefully if at all! Value is a numeric
251+
-- | bitmask of the SSL_OP_* options from OpenSSL Options.
252+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
253+
secureOptions :: Option SSLOptions Int
254+
secureOptions = opt "secureOptions"
255+
256+
-- | Optional opaque identifier used by servers to ensure session state is not
257+
-- | shared between applications. Unused by clients.
258+
-- | See the [node docs](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options)
259+
sessionIdContext :: Option SSLOptions String
260+
sessionIdContext = opt "sessionIdContext"
261+
262+
foreign import createServerSImpl ::
263+
forall eff.
264+
Foreign ->
265+
(Request -> Response -> Eff (http :: HTTP | eff) Unit) ->
266+
Eff (http :: HTTP | eff) Server
267+
268+
-- | Create an HTTPS server, given the SSL options and a function to be executed
269+
-- | when a request is received.
270+
createServerS :: forall eff.
271+
Options SSLOptions ->
272+
(Request -> Response -> Eff (http :: HTTP | eff) Unit) ->
273+
Eff (http :: HTTP | eff) Server
274+
createServerS = createServerSImpl <<< options
275+
54276
foreign import listenImpl :: forall eff. Server -> Int -> String -> Nullable Int -> Eff (http :: HTTP | eff) Unit -> Eff (http :: HTTP | eff) Unit
55277

56278
-- | Listen on a port in order to start accepting HTTP requests. The specified callback will be run when setup is complete.

0 commit comments

Comments
 (0)