aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stdlib/source/lux/world/net/http.lux75
-rw-r--r--stdlib/source/lux/world/net/http/header.lux22
-rw-r--r--stdlib/source/lux/world/net/http/mime.lux90
-rw-r--r--stdlib/source/lux/world/net/http/response.lux45
-rw-r--r--stdlib/source/lux/world/net/http/status.lux80
-rw-r--r--stdlib/source/lux/world/net/http/version.lux12
6 files changed, 324 insertions, 0 deletions
diff --git a/stdlib/source/lux/world/net/http.lux b/stdlib/source/lux/world/net/http.lux
new file mode 100644
index 000000000..36809c28f
--- /dev/null
+++ b/stdlib/source/lux/world/net/http.lux
@@ -0,0 +1,75 @@
+(.module:
+ [lux #*
+ [data
+ [error (#+ Error)]
+ [format
+ [context (#+ Context)]]]
+ [concurrency
+ [promise (#+ Promise)]
+ [frp (#+ Channel)]]
+ [world
+ [binary (#+ Binary)]]]
+ [// (#+ URL)])
+
+(type: #export Version Text)
+
+(type: #export Method
+ #Post
+ #Get
+ #Put
+ #Delete
+ #Head
+ #Connect
+ #Options
+ #Trace)
+
+(type: #export Port Nat)
+
+(type: #export Status Nat)
+
+(type: #export Header
+ (-> Context Context))
+
+(type: #export Data
+ Binary)
+
+(type: #export Body
+ (Channel Data))
+
+(type: #export URI
+ Text)
+
+(type: #export Scheme
+ #HTTP
+ #HTTPS)
+
+(type: #export Address
+ {#port Port
+ #host Text})
+
+(type: #export Identification
+ {#local Address
+ #remote Address})
+
+(type: #export Protocol
+ {#version Version
+ #scheme Scheme})
+
+(type: #export Resource
+ {#method Method
+ #uri URI
+ #query Context
+ #form (Maybe Context)})
+
+(type: #export Payload
+ {#headers Context
+ #body Body})
+
+(type: #export Request
+ [Identification Protocol Resource Payload])
+
+(type: #export Response
+ [Status Payload])
+
+(type: #export Server
+ (-> Request (Promise (Error Response))))
diff --git a/stdlib/source/lux/world/net/http/header.lux b/stdlib/source/lux/world/net/http/header.lux
new file mode 100644
index 000000000..a5dd66748
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/header.lux
@@ -0,0 +1,22 @@
+(.module:
+ [lux #*
+ [data
+ [text
+ format]
+ [collection
+ ["." dictionary (#+ Dictionary)]]]]
+ [// (#+ Header)
+ ["." mime (#+ MIME)]
+ [// (#+ URL)]])
+
+(def: #export content-length
+ (-> Nat Header)
+ (|>> %n (dictionary.put "Content-Length")))
+
+(def: #export content-type
+ (-> MIME Header)
+ (|>> mime.name (dictionary.put "Content-Type")))
+
+(def: #export location
+ (-> URL Header)
+ (dictionary.put "Location"))
diff --git a/stdlib/source/lux/world/net/http/mime.lux b/stdlib/source/lux/world/net/http/mime.lux
new file mode 100644
index 000000000..4f090a54f
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/mime.lux
@@ -0,0 +1,90 @@
+(.module:
+ [lux #*
+ [type
+ abstract]])
+
+(abstract: #export MIME
+ {#doc "Multipurpose Internet Mail Extensions"}
+
+ Text
+
+ (def: #export mime
+ (-> Text MIME)
+ (|>> :abstraction))
+
+ (def: #export name
+ (-> MIME Text)
+ (|>> :representation))
+ )
+
+## https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
+(do-template [<name> <type>]
+ [(def: #export <name> MIME (..mime <type>))]
+
+ [aac-audio "audio/aac"]
+ [abiword "application/x-abiword"]
+ [avi "video/x-msvideo"]
+ [amazon-kindle-ebook "application/vnd.amazon.ebook"]
+ [binary "application/octet-stream"]
+ [bitmap "image/bmp"]
+ [bzip "application/x-bzip"]
+ [bzip2 "application/x-bzip2"]
+ [c-shell "application/x-csh"]
+ [css "text/css"]
+ [csv "text/csv"]
+ [microsoft-word "application/msword"]
+ [microsoft-word-openxml "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]
+ [ms-embedded-opentype-fonts "application/vnd.ms-fontobject"]
+ [epub "application/epub+zip"]
+ [ecmascript "application/ecmascript"]
+ [gif "image/gif"]
+ [html "text/html"]
+ [icon "image/x-icon"]
+ [icalendar "text/calendar"]
+ [jar "application/java-archive"]
+ [jpeg "image/jpeg"]
+ [javascript "application/javascript"]
+ [json "application/json"]
+ [midi "audio/midi"]
+ [mpeg "video/mpeg"]
+ [apple-installer-package "application/vnd.apple.installer+xml"]
+ [opendocument-presentation "application/vnd.oasis.opendocument.presentation"]
+ [opendocument-spreadsheet "application/vnd.oasis.opendocument.spreadsheet"]
+ [opendocument-text "application/vnd.oasis.opendocument.text"]
+ [ogg-audio "audio/ogg"]
+ [ogg-video "video/ogg"]
+ [ogg "application/ogg"]
+ [opentype-font "font/otf"]
+ [png "image/png"]
+ [pdf "application/pdf"]
+ [microsoft-powerpoint "application/vnd.ms-powerpoint"]
+ [microsoft-powerpoint-openxml "application/vnd.openxmlformats-officedocument.presentationml.presentation"]
+ [rar "application/x-rar-compressed"]
+ [rtf "application/rtf"]
+ [bourne-shell "application/x-sh"]
+ [svg "image/svg+xml"]
+ [flash "application/x-shockwave-flash"]
+ [tar "application/x-tar"]
+ [tiff "image/tiff"]
+ [typescript "application/typescript"]
+ [truetype-font "font/ttf"]
+ [text "text/plain"]
+ [microsoft-visio "application/vnd.visio"]
+ [wav "audio/wav"]
+ [webm-audio "audio/webm"]
+ [webm-video "video/webm"]
+ [webp "image/webp"]
+ [woff "font/woff"]
+ [woff2 "font/woff2"]
+ [xhtml "application/xhtml+xml"]
+ [microsoft-excel "application/vnd.ms-excel"]
+ [microsoft-excel-openxml "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]
+ [xml "application/xml"]
+ [xul "application/vnd.mozilla.xul+xml"]
+ [zip "application/zip"]
+ [!3gpp-audio "audio/3gpp"]
+ [!3gpp "video/3gpp"]
+ [!3gpp2-audio "audio/3gpp2"]
+ [!3gpp2 "video/3gpp2"]
+ [!7z "application/x-7z-compressed"]
+ )
diff --git a/stdlib/source/lux/world/net/http/response.lux b/stdlib/source/lux/world/net/http/response.lux
new file mode 100644
index 000000000..3bca36449
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/response.lux
@@ -0,0 +1,45 @@
+(.module:
+ [lux #*
+ [data
+ ["." text
+ format
+ ["." encoding]]
+ [collection
+ ["." array]
+ ["." dictionary (#+ Dictionary)]]]
+ ["." io]
+ [concurrency
+ ["." frp ("channel/." Monad<Channel>)]]
+ [world
+ ["." binary (#+ Binary)]]]
+ ["." // (#+ Body Response)
+ ["." status]
+ ["." mime]
+ ["." header]
+ [// (#+ URL)]])
+
+(def: #export (temporary-redirect to)
+ (-> URL Response)
+ [status.temporary-redirect
+ {#//.headers (|> (dictionary.new text.Hash<Text>)
+ (header.content-length 0)
+ (header.content-type mime.text)
+ (header.location to))
+ #//.body (channel/wrap (encoding.to-utf8 ""))}])
+
+(def: #export not-found
+ Response
+ [status.not-found
+ {#//.headers (|> (dictionary.new text.Hash<Text>)
+ (header.content-length 0)
+ (header.content-type mime.text))
+ #//.body (channel/wrap (encoding.to-utf8 ""))}])
+
+(def: #export (fail message)
+ (-> Text Response)
+ (let [data (encoding.to-utf8 message)]
+ [status.bad-request
+ {#//.headers (|> (dictionary.new text.Hash<Text>)
+ (header.content-length (binary.size data))
+ (header.content-type mime.text))
+ #//.body (channel/wrap data)}]))
diff --git a/stdlib/source/lux/world/net/http/status.lux b/stdlib/source/lux/world/net/http/status.lux
new file mode 100644
index 000000000..fef607b73
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/status.lux
@@ -0,0 +1,80 @@
+(.module:
+ [lux #*]
+ [// (#+ Status)])
+
+## https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
+(do-template [<status> <name>]
+ [(def: #export <name> Status <status>)]
+
+ ## 1xx Informational response
+ [100 continue]
+ [101 switching-protocols]
+ [102 processing]
+ [103 early-hints]
+
+ ## 2xx Success
+ [200 ok]
+ [201 created]
+ [202 accepted]
+ [203 non-authoritative-information]
+ [204 no-content]
+ [205 reset-content]
+ [206 partial-content]
+ [207 multi-status]
+ [208 already-reported]
+ [226 im-used]
+
+ ## 3xx Redirection
+ [300 multiple-choices]
+ [301 moved-permanently]
+ [302 found]
+ [303 see-other]
+ [304 not-modified]
+ [305 use-proxy]
+ [306 switch-proxy]
+ [307 temporary-redirect]
+ [308 permanent-redirect]
+
+ ## 4xx Client errors
+ [400 bad-request]
+ [401 unauthorized]
+ [402 payment-required]
+ [403 forbidden]
+ [404 not-found]
+ [405 method-not-allowed]
+ [406 not-acceptable]
+ [407 proxy-authentication-required]
+ [408 request-timeout]
+ [409 conflict]
+ [410 gone]
+ [411 length-required]
+ [412 precondition-failed]
+ [413 payload-too-large]
+ [414 uri-too-long]
+ [415 unsupported-media-type]
+ [416 range-not-satisfiable]
+ [417 expectation-failed]
+ [418 im-a-teapot]
+ [421 misdirected-request]
+ [422 unprocessable-entity]
+ [423 locked]
+ [424 failed-dependency]
+ [426 upgrade-required]
+ [428 precondition-required]
+ [429 too-many-requests]
+ [431 request-header-fields-too-large]
+ [451 unavailable-for-legal-reasons]
+
+ ## 5xx Server errors
+ [500 internal-server-error]
+ [501 not-implemented]
+ [502 bad-gateway]
+ [503 service-unavailable]
+ [504 gateway-timeout]
+ [505 http-version-not-supported]
+ [506 variant-also-negotiates]
+ [507 insufficient-storage]
+ [508 loop-detected]
+ [510 not-extended]
+ [511 network-authentication-required]
+ )
diff --git a/stdlib/source/lux/world/net/http/version.lux b/stdlib/source/lux/world/net/http/version.lux
new file mode 100644
index 000000000..a53b96b70
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/version.lux
@@ -0,0 +1,12 @@
+(.module:
+ [lux #*]
+ [// (#+ Version)])
+
+(do-template [<name> <version>]
+ [(def: #export <name> Version <version>)]
+
+ [v0_9 "0.9"]
+ [v1_0 "1.0"]
+ [v1_1 "1.1"]
+ [v2_0 "2.0"]
+ )