From 84cda3e64edf4c481c2200abb5e59976b8733c8e Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 30 Dec 2018 23:43:59 -0400 Subject: Added HTTP abstractions. --- stdlib/source/lux/world/net/http.lux | 75 ++++++++++++++++++++++ stdlib/source/lux/world/net/http/header.lux | 22 +++++++ stdlib/source/lux/world/net/http/mime.lux | 90 +++++++++++++++++++++++++++ stdlib/source/lux/world/net/http/response.lux | 45 ++++++++++++++ stdlib/source/lux/world/net/http/status.lux | 80 ++++++++++++++++++++++++ stdlib/source/lux/world/net/http/version.lux | 12 ++++ 6 files changed, 324 insertions(+) create mode 100644 stdlib/source/lux/world/net/http.lux create mode 100644 stdlib/source/lux/world/net/http/header.lux create mode 100644 stdlib/source/lux/world/net/http/mime.lux create mode 100644 stdlib/source/lux/world/net/http/response.lux create mode 100644 stdlib/source/lux/world/net/http/status.lux create mode 100644 stdlib/source/lux/world/net/http/version.lux 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 [ ] + [(def: #export MIME (..mime ))] + + [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)]] + [world + ["." binary (#+ Binary)]]] + ["." // (#+ Body Response) + ["." status] + ["." mime] + ["." header] + [// (#+ URL)]]) + +(def: #export (temporary-redirect to) + (-> URL Response) + [status.temporary-redirect + {#//.headers (|> (dictionary.new text.Hash) + (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) + (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) + (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 [ ] + [(def: #export 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 [ ] + [(def: #export Version )] + + [v0_9 "0.9"] + [v1_0 "1.0"] + [v1_1 "1.1"] + [v2_0 "2.0"] + ) -- cgit v1.2.3