@@ -2,19 +2,22 @@ module Test.HTTP2Aff where
22
33import Prelude
44
5+ import Control.Alternative ((<|>))
6+ import Data.Foldable (traverse_ )
7+ import Data.Maybe (fromMaybe )
8+ import Data.String as String
59import Data.Tuple (fst )
6- import Effect.Aff (Aff , throwError )
10+ import Effect.Aff (Aff , parallel , sequential , throwError )
711import Effect.Class (liftEffect )
812import Effect.Console as Console
9- import Node.HTTP2 (fromStringUTF8 , toHeaders , toOptions , toStringUTF8 )
10- import Node.HTTP2.Client.Aff (waitResponse )
13+ import Node.HTTP2 (Headers , fromStringUTF8 , headerArray , headerKeys , headerString , toHeaders , toOptions , toStringUTF8 )
1114import Node.HTTP2.Client.Aff as Client.Aff
1215import Node.HTTP2.Server.Aff as Server.Aff
1316import Node.Stream.Aff (end , readAll , readSome , write )
1417import Node.URL as URL
1518
16- testHttp2ServerSecureAff :: Aff Unit
17- testHttp2ServerSecureAff = do
19+ push1_serverSecure :: Aff Unit
20+ push1_serverSecure = do
1821
1922 -- 1. Start the server, wait for a connection.
2023 void $ Server.Aff .listenSecure
@@ -34,6 +37,7 @@ testHttp2ServerSecureAff = do
3437
3538 -- 4. Push a new stream.
3639 stream2 <- Server.Aff .pushStream stream (toOptions {}) (toHeaders {})
40+ Server.Aff .respond stream2 (toOptions {}) (toHeaders {})
3741 let s2 = Server.Aff .toDuplex stream2
3842 write s2 =<< fromStringUTF8 " HTTP/2 secure push body Aff"
3943 end s2
@@ -42,11 +46,11 @@ testHttp2ServerSecureAff = do
4246 end s
4347
4448 -- 5. After one session, stop the server.
45- Server.Aff .closeServerSecure server
49+ Server.Aff .closeSecure server
4650
4751
48- testHttp2ClientAff :: Aff Unit
49- testHttp2ClientAff = do
52+ push1_client :: Aff Unit
53+ push1_client = do
5054
5155 -- 1. Begin the session, open a connection.
5256 session <- Client.Aff .connect
@@ -80,6 +84,87 @@ testHttp2ClientAff = do
8084
8185
8286
87+ headers_serverSecure :: Aff Unit
88+ headers_serverSecure = do
89+
90+ -- 1. Start the server, wait for a connection.
91+ void $ Server.Aff .listenSecure
92+ (toOptions {key: mockKey, cert: mockCert})
93+ (toOptions {port: 8444 })
94+ (\_server err -> throwError err)
95+ \server headers stream -> do
96+ liftEffect $ Console .log $ " SERVER " <> headersShow headers
97+
98+ -- 2. Receive a request.
99+ let s = Server.Aff .toDuplex stream
100+
101+ -- 3. Send a response.
102+ Server.Aff .respond stream (toOptions {}) $ toHeaders
103+ { " normal" : " server normal header"
104+ }
105+ -- Error [ERR_HTTP2_HEADERS_AFTER_RESPOND]: Cannot specify additional headers after response initiated
106+ -- Server.Aff.sendHeadersAdditional stream $ toHeaders
107+ -- { "additional": "server additional header"
108+ -- }
109+
110+ -- 4. Push a new stream.
111+ stream2 <- Server.Aff .pushStream stream (toOptions {}) (toHeaders {})
112+ Server.Aff .respond stream2 (toOptions {})
113+ ( toHeaders
114+ { " pushnormal" : " server normal pushed header"
115+ }
116+ )
117+ let s2 = Server.Aff .toDuplex stream2
118+ end s2
119+
120+ -- 5. Close the connection.
121+ end s
122+
123+ -- 5. After one session, stop the server.
124+ Server.Aff .closeSecure server
125+
126+
127+
128+ headers_client :: Aff Unit
129+ headers_client = do
130+
131+ -- 1. Begin the session, open a connection.
132+ session <- Client.Aff .connect
133+ (toOptions {ca: mockCert})
134+ (URL .parse " https://localhost:8444" )
135+
136+ -- 2. Send a request.
137+ stream <- Client.Aff .request session (toOptions {}) $ toHeaders
138+ { " normal" : " client normal header"
139+ }
140+ let s = Client.Aff .toDuplex stream
141+ end s
142+
143+
144+
145+ sequential $ traverse_ parallel
146+ [ do
147+ -- 4. Receive a pushed stream.
148+ {headersRequest, headersResponse} <- Client.Aff .waitPush session
149+ liftEffect $ Console .log $ " CLIENT Request " <> headersShow headersRequest
150+ liftEffect $ Console .log $ " CLIENT Response " <> headersShow headersResponse
151+ , do
152+ -- 3. Wait for the response.
153+ headers <- Client.Aff .waitResponse stream
154+ liftEffect $ Console .log $ " CLIENT " <> headersShow headers
155+ ]
156+
157+
158+ -- 6. Wait for the end of the session then close the connection.
159+ -- Client.Aff.waitEnd stream
160+ Client.Aff .close session
161+
162+
163+
164+
165+
166+
167+
83168
84169-- https://letsencrypt.org/docs/certificates-for-localhost/#making-and-trusting-your-own-certificates
85170--
@@ -88,6 +173,15 @@ testHttp2ClientAff = do
88173-- openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -nodes -sha256 -days 3650 -subj '/CN=localhost' -extensions EXT -config <( printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
89174--
90175
176+ headersShow :: Headers -> String
177+ headersShow headers = String .joinWith " , " $ headerKeys headers <#> \key ->
178+ key <> " : " <>
179+ ( fromMaybe " " $
180+ (headerString headers key)
181+ <|>
182+ (String .joinWith " " <$> headerArray headers key)
183+ )
184+
91185mockCert :: String
92186mockCert =
93187 """ -----BEGIN CERTIFICATE-----
0 commit comments