@@ -3,14 +3,17 @@ module Test.Main where
3
3
import Prelude
4
4
5
5
import Data.Foldable (foldMap )
6
- import Data.Maybe (Maybe (..))
6
+ import Data.Maybe (Maybe (..), fromMaybe )
7
7
import Data.Options (Options , options , (:=))
8
+ import Data.Tuple (Tuple (..))
8
9
import Effect (Effect )
9
10
import Effect.Console (log , logShow )
11
+ import Foreign.Object (fromFoldable , lookup )
10
12
import Node.Encoding (Encoding (..))
11
- import Node.HTTP (Request , Response , listen , createServer , setHeader , requestMethod , requestURL , responseAsStream , requestAsStream , setStatusCode )
13
+ import Node.HTTP (Request , Response , listen , createServer , setHeader , requestHeaders , requestMethod , requestURL , responseAsStream , requestAsStream , setStatusCode , onUpgrade )
12
14
import Node.HTTP.Client as Client
13
15
import Node.HTTP.Secure as HTTPS
16
+ import Node.Net.Socket as Socket
14
17
import Node.Stream (Writable , end , pipe , writeString )
15
18
import Partial.Unsafe (unsafeCrashWith )
16
19
import Unsafe.Coerce (unsafeCoerce )
@@ -20,6 +23,7 @@ foreign import stdout :: forall r. Writable r
20
23
main :: Effect Unit
21
24
main = do
22
25
testBasic
26
+ testUpgrade
23
27
testHttpsServer
24
28
testHttps
25
29
testCookies
@@ -154,3 +158,67 @@ logResponse response = void do
154
158
log " Response:"
155
159
let responseStream = Client .responseAsStream response
156
160
pipe responseStream stdout
161
+
162
+ testUpgrade :: Effect Unit
163
+ testUpgrade = do
164
+ server <- createServer respond
165
+ onUpgrade server handleUpgrade
166
+ listen server { hostname: " localhost" , port: 3000 , backlog: Nothing }
167
+ $ void do
168
+ log " Listening on port 3000."
169
+ sendRequests
170
+ where
171
+ handleUpgrade req socket buffer = do
172
+ let upgradeHeader = fromMaybe " " $ lookup " upgrade" $ requestHeaders req
173
+ if upgradeHeader == " websocket" then
174
+ void $ Socket .writeString
175
+ socket
176
+ " HTTP/1.1 101 Switching Protocols\r\n Content-Length: 0\r\n\r\n "
177
+ UTF8
178
+ $ pure unit
179
+ else
180
+ void $ Socket .writeString
181
+ socket
182
+ " HTTP/1.1 426 Upgrade Required\r\n Content-Length: 0\r\n\r\n "
183
+ UTF8
184
+ $ pure unit
185
+
186
+ sendRequests = do
187
+ -- This tests that the upgrade callback is not called when the request is not an HTTP upgrade
188
+ reqSimple <- Client .request (Client .port := 3000 ) \response -> do
189
+ if (Client .statusCode response /= 200 ) then
190
+ unsafeCrashWith " Unexpected response to simple request on `testUpgrade`"
191
+ else
192
+ pure unit
193
+ end (Client .requestAsStream reqSimple) (pure unit)
194
+ {-
195
+ These two requests test that the upgrade callback is called and that it has
196
+ access to the original request and can write to the underlying TCP socket
197
+ -}
198
+ let headers = Client.RequestHeaders $ fromFoldable
199
+ [ Tuple " Connection" " upgrade"
200
+ , Tuple " Upgrade" " something"
201
+ ]
202
+ reqUpgrade <- Client .request
203
+ (Client .port := 3000 <> Client .headers := headers)
204
+ \response -> do
205
+ if (Client .statusCode response /= 426 ) then
206
+ unsafeCrashWith " Unexpected response to upgrade request on `testUpgrade`"
207
+ else
208
+ pure unit
209
+ end (Client .requestAsStream reqUpgrade) (pure unit)
210
+
211
+ let wsHeaders = Client.RequestHeaders $ fromFoldable
212
+ [ Tuple " Connection" " upgrade"
213
+ , Tuple " Upgrade" " websocket"
214
+ ]
215
+
216
+ reqWSUpgrade <- Client .request
217
+ (Client .port := 3000 <> Client .headers := wsHeaders)
218
+ \response -> do
219
+ if (Client .statusCode response /= 101 ) then
220
+ unsafeCrashWith " Unexpected response to websocket upgrade request on `testUpgrade`"
221
+ else
222
+ pure unit
223
+ end (Client .requestAsStream reqWSUpgrade) (pure unit)
224
+ pure unit
0 commit comments