]> gitweb.factorcode.org Git - factor.git/commitdiff
http: allow using ws:// or wss:// and use it in discord
authorDoug Coleman <doug.coleman@gmail.com>
Wed, 29 Mar 2023 04:59:57 +0000 (23:59 -0500)
committerDoug Coleman <doug.coleman@gmail.com>
Fri, 14 Apr 2023 04:18:02 +0000 (23:18 -0500)
wss:// adds the websocket upgrade headers to the request and then gets replaced by https://

basis/http/client/client.factor
basis/http/http.factor
basis/http/server/server.factor
basis/http/websockets/websockets.factor
basis/io/sockets/sockets-tests.factor
basis/urls/urls.factor
extra/discord/discord.factor
extra/http2/server/server.factor

index 68b1c499b4fba96bbec88fb12ed95dfb38652480..d6ed9c684c6902c242c4c2b438896f87a138322d 100644 (file)
@@ -3,11 +3,11 @@
 USING: accessors arrays ascii assocs calendar combinators
 combinators.short-circuit continuations destructors effects
 environment hashtables http http.client.post-data http.parsers
-io io.crlf io.encodings io.encodings.ascii io.encodings.binary
-io.encodings.iana io.encodings.string io.files io.pathnames
-io.sockets io.sockets.secure io.timeouts kernel math math.order
-math.parser mime.types namespaces present sequences splitting
-urls vocabs.loader ;
+http.websockets io io.crlf io.encodings io.encodings.ascii
+io.encodings.binary io.encodings.iana io.encodings.string
+io.files io.pathnames io.sockets io.sockets.secure io.timeouts
+kernel math math.order math.parser mime.types namespaces present
+protocols sequences splitting urls vocabs.loader ;
 IN: http.client
 
 ERROR: too-many-redirects ;
@@ -48,7 +48,7 @@ ERROR: download-failed response ;
 : default-port? ( url -- ? )
     {
         [ port>> not ]
-        [ [ port>> ] [ protocol>> protocol-port ] bi = ]
+        [ [ port>> ] [ protocol>> lookup-protocol-port ] bi = ]
     } 1|| ;
 
 : unparse-host ( url -- string )
@@ -261,10 +261,18 @@ SYMBOL: request-socket
         ] with-destructors
     ] with-variable ; inline recursive
 
+: add-default-headers ( request -- request )
+    dup url>> protocol>> {
+        ! { [ dup { "http" "https" } member? ] [ drop add-connection-close-header ] }
+        { [ dup { "ws" "wss" } member? ] [ drop add-websocket-upgrade-headers ] }
+        [ drop ]
+    } cond ;
+
 : <client-request> ( url method -- request )
     <request>
         swap >>method
-        swap request-url >>url ; inline
+        swap request-url >>url
+        add-default-headers ; inline
 
 : with-http-request ( request quot: ( chunk -- ) -- response/stream )
     do-http-request check-response ; inline
index a2b7afffc903ec799a91782b961484a62c95c91b..6c05a2709768ff5d0131d15c48ac49d63d67b1e5 100644 (file)
@@ -170,6 +170,9 @@ TUPLE: request
         "Factor http.client" "User-Agent" set-header
         max-redirects >>redirects ;
 
+: add-connection-close-header ( request -- request )
+    "close" "Connection" set-header ;
+
 : header ( request/response key -- value )
     swap header>> at ;
 
index 56341b0d863e8079373a62e9fbbd976232f07dcd..2d5b333714bacf31357e192f97849a78420401d2 100644 (file)
@@ -7,8 +7,8 @@ http.server.remapping http.server.requests http.server.responses
 io io.crlf io.encodings io.encodings.ascii io.encodings.iana
 io.encodings.utf8 io.servers io.sockets io.sockets.secure
 io.streams.limited kernel logging logging.insomniac math
-mime.types namespaces present sequences splitting tools.time
-urls vectors vocabs vocabs.refresh xml.writer ;
+mime.types namespaces present protocols sequences splitting
+tools.time urls vectors vocabs vocabs.refresh xml.writer ;
 IN: http.server
 
 GENERIC: write-response ( response -- )
@@ -225,8 +225,8 @@ M: http-server handle-client*
 : <http-server> ( -- server )
     ascii http-server new-threaded-server
         "http.server" >>name
-        "http" protocol-port >>insecure
-        "https" protocol-port >>secure ;
+        "http" lookup-protocol-port >>insecure
+        "https" lookup-protocol-port >>secure ;
 
 : httpd ( port -- http-server )
     <http-server>
index c3c05e7a787821bb16c228de4c5f76468baba037..434dfcad377d2eef3663aa09386b6bcc5c1e1d0a 100644 (file)
@@ -21,7 +21,8 @@ CONSTANT: websocket-version "13"
     "no-cache" "Pragma" set-header
     "no-cache" "Cache-Control" set-header
     "permessage-deflate; client_max_window_bits" "Sec-WebSocket-Extensions" set-header
-    dup url>> host>> "Host" set-header ;
+    dup url>> host>> "Host" set-header
+    dup url>> [ "ws" = "http" "https" ? ] change-protocol drop ;
 
 CONSTANT: websocket-opcode-continue-frame 0
 CONSTANT: websocket-opcode-text-frame 1
index 56f707de6cd24ccb1f29f79b4f666fc3b5c104a5..851579cb2e4ad45556148955859ec153c978cae8 100644 (file)
@@ -170,8 +170,8 @@ os unix? [
 { } [ f 0 <inet4> <datagram> dispose ] unit-test
 { } [ f 0 <inet6> <datagram> dispose ] unit-test
 
-{ 80 } [ "http" protocol-port ] unit-test
-{ f } [ f protocol-port ] unit-test
+{ 80 } [ "http" lookup-protocol-port ] unit-test
+{ f } [ f lookup-protocol-port ] unit-test
 
 { "http" } [ 80 port-protocol ] unit-test
 { f } [ f port-protocol ] unit-test
index 543a5ff6c439a194b71722b5421c95c2058e1214..33eeb94b2ecfd0c6a20793c6d5e0b92dcf9d874f 100644 (file)
@@ -4,7 +4,7 @@
 USING: accessors ascii assocs combinators
 combinators.short-circuit io.pathnames io.sockets
 io.sockets.secure kernel lexer linked-assocs make math.parser
-multiline namespaces peg.ebnf present sequences
+multiline namespaces peg.ebnf present protocols sequences
 sequences.generalizations splitting strings strings.parser
 urls.encoding vocabs.loader ;
 
@@ -115,7 +115,7 @@ M: pathname >url string>> >url ;
     ] [ 2drop ] if ;
 
 : url-port ( url -- port/f )
-    [ port>> ] [ protocol>> protocol-port ] bi over =
+    [ port>> ] [ protocol>> lookup-protocol-port ] bi over =
     [ drop f ] when ;
 
 : ipv6-host ( host -- host/ipv6 ipv6? )
@@ -201,7 +201,7 @@ PRIVATE>
     [
         [ host>> ipv6-host drop ]
         [ port>> ]
-        [ protocol>> protocol-port ]
+        [ protocol>> lookup-protocol-port ]
         tri or <inet>
     ] [
         dup protocol>> secure-protocol?
@@ -213,7 +213,7 @@ PRIVATE>
     [ port>> >>port ] bi ;
 
 : ensure-port ( url -- url' )
-    clone dup protocol>> '[ _ protocol-port or ] change-port ;
+    clone dup protocol>> '[ _ lookup-protocol-port or ] change-port ;
 
 ! Literal syntax
 SYNTAX: URL" lexer get skip-blank parse-string >url suffix! ;
index be761b9b3b4334c0b8441b13eedf038e87a9035e..e2aab5b6052700d71266225c112c4043463d8c44 100644 (file)
@@ -8,7 +8,7 @@ threads tools.hexdump ;
 IN: discord
 
 CONSTANT: discord-api-url "https://discord.com/api/v10"
-CONSTANT: discord-bot-gateway  "https://gateway.discord.gg/gateway/bot?v=10&encoding=json"
+CONSTANT: discord-bot-gateway  "wss://gateway.discord.gg/gateway/bot?v=10&encoding=json"
 
 TUPLE: discord-webhook url id token ;
 
@@ -264,18 +264,21 @@ ENUM: discord-opcode
 : discord-connect ( config -- discord-bot )
     \ discord-bot-config [
         discord-bot-gateway <get-request>
-        add-websocket-upgrade-headers
         add-discord-auth-header
         [ drop ] do-http-request
-        [ in>> stream>> ] [ out>> stream>> ] bi
-        \ discord-bot-config get <discord-bot>
-        dup '[
-            _ \ discord-bot [
-                discord-bot get [ in>> ] [ out>> ] bi
-                [
-                    [ handle-discord-websocket ] read-websocket-loop
-                ] with-streams
-            ] with-variable
-        ] "Discord Bot" spawn
-        >>bot-thread
+        dup response? [
+            throw
+        ] [
+            [ in>> stream>> ] [ out>> stream>> ] bi
+            \ discord-bot-config get <discord-bot>
+            dup '[
+                _ \ discord-bot [
+                    discord-bot get [ in>> ] [ out>> ] bi
+                    [
+                        [ handle-discord-websocket ] read-websocket-loop
+                    ] with-streams
+                ] with-variable
+            ] "Discord Bot" spawn
+            >>bot-thread
+        ] if
     ] with-variable ;
index 3d5c1349e99ab43d6d0ac9e4e12693c9fa1bf5a2..fee70a2f12c4b3a61782605b2bd72dfaa9cf8430 100644 (file)
@@ -63,6 +63,6 @@ M: http2-server handle-client*
 : <http2-server> ( -- server )
     ascii http2-server new-threaded-server
         "http2.server" >>name
-        "http" protocol-port >>insecure
-        "https" protocol-port >>secure ;
+        "http" lookup-protocol-port >>insecure
+        "https" lookup-protocol-port >>secure ;