Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e986651
Initial draft of a HTTP requests library
marzipankaiser May 23, 2025
3d61afa
Allow setting the request body (non-streamingly)
marzipankaiser May 23, 2025
4664a5d
Add to acme
marzipankaiser May 23, 2025
ade18e4
jsWeb: the fetch API *does* give us a UInt8Array
marzipankaiser May 23, 2025
bbdc92c
some documentation, define default ports
marzipankaiser May 23, 2025
84da228
Add simple URI parser library
marzipankaiser May 26, 2025
15e5fe5
Allow providing URI string instead of separate hostname and path
marzipankaiser May 26, 2025
3bd6d8f
Support basic auth url part
marzipankaiser May 26, 2025
c96103f
Add URI to acme
marzipankaiser May 26, 2025
d7e37e0
Move URI examples to tests
marzipankaiser May 26, 2025
9a632a2
Make strict urlencode the default
marzipankaiser May 26, 2025
2fffb6b
Cleanup URI implementations, move parts into proper stdlibs
marzipankaiser May 26, 2025
76ff9cf
More docs, default headers
marzipankaiser May 26, 2025
8abbe5b
Use better UA
marzipankaiser May 26, 2025
9c9baa2
Add simple API variant
marzipankaiser May 26, 2025
24ac777
Remember when the response body is done and then always return None
marzipankaiser May 26, 2025
e289c36
Add minimal API for generating requests and parsing responses to/from…
marzipankaiser May 26, 2025
f07db72
Extract events to async stream logic into helper function
marzipankaiser May 27, 2025
9018798
Arguably more understandable asyncStreamOf with a queue of waiting nexts
marzipankaiser May 27, 2025
a92c845
Minor fix
marzipankaiser May 27, 2025
7322257
Fix syntax errors due to named parameters #1070
marzipankaiser Jul 28, 2025
88c2182
Properly dispatch to implementations
marzipankaiser Jul 28, 2025
8da18f5
Prepare dispatch for more cases
marzipankaiser Jul 28, 2025
bb07dc1
Dispatch properly for the UA on jsweb
marzipankaiser Jul 28, 2025
09d7de9
Improve plain api, add decoder for chunked encoding
marzipankaiser Jul 28, 2025
a0fc6a2
Add TODO
marzipankaiser Jul 28, 2025
9406e88
Support multiline header fields
marzipankaiser Jul 28, 2025
a3e6fa4
Minor improvements
marzipankaiser Jul 28, 2025
abca149
toLower/toUpper for ASCII
marzipankaiser Jul 28, 2025
cf88469
Automatically decode chunked encoding
marzipankaiser Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/stdlib/acme.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import io/console
import io/error
import io/filesystem
import io/network
import io/requests
import io/time
import io/uri
import json
import list
import map
Expand Down
35 changes: 35 additions & 0 deletions examples/stdlib/io/uri.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/ !
Hallo Welt!/&^$@^*(&$)(*!_!_+")
Hallo%20Welt%21%2F%26^%24%40^%2A%28%26%24%29%28%2A%21_%21_%2B"%29
Hallo Welt!/&^$@^*(&$)(*!_!_+")
Hallo%20Welt%21%2F%26%5E%24%40%5E%2A%28%26%24%29%28%2A%21_%21_%2B%22%29
ftp://ftp.is.co.za/rfc/rfc1808.txt
Scheme: ftp
Host: ftp.is.co.za
Path: /rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
Scheme: http
Host: www.ietf.org
Path: /rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
Scheme: ldap
Host: [2001:db8::7]
Path: /c=GB
Query: objectClass?one
mailto:[email protected]
Scheme: mailto
Path: [email protected]
news:comp.infosystems.www.servers.unix
Scheme: news
Path: comp.infosystems.www.servers.unix
tel:+1-816-555-1212
Scheme: tel
Path: +1-816-555-1212
telnet://192.0.2.16:80/
Scheme: telnet
Host: 192.0.2.16
Port: 80
Path: /
urn:oasis:names:specification:docbook:dtd:xml:4.1
Scheme: urn
Path: oasis:names:specification:docbook:dtd:xml:4.1
32 changes: 32 additions & 0 deletions examples/stdlib/io/uri.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import io/uri

def report(uri: String): Unit = {
with on[WrongFormat].panic
println(uri)
try parseURI(uri) with URIBuilder {
def scheme(s) = resume(println(" Scheme: " ++ s))
def userinfo(u) = resume(println(" Userinfo: " ++ u))
def host(h) = resume(println(" Host: " ++ h))
def path(p) = resume(println(" Path: " ++ p))
def port(p) = resume(println(" Port: " ++ p.show))
def query(q) = resume(println(" Query: " ++ q))
def fragment(q) = resume(println(" Fragment: " ++ q))
}
}
def main() = {
println(urldecode("%2F%20%20!"))
println(urldecode(urlencodePermissive("Hallo Welt!/&^$@^*(&$)(*!_!_+\")")))
println(urlencodePermissive("Hallo Welt!/&^$@^*(&$)(*!_!_+\")"))
println(urldecode(urlencode("Hallo Welt!/&^$@^*(&$)(*!_!_+\")")))
println(urlencode("Hallo Welt!/&^$@^*(&$)(*!_!_+\")"))

// examples from the spec
report("ftp://ftp.is.co.za/rfc/rfc1808.txt")
report("http://www.ietf.org/rfc/rfc2396.txt")
report("ldap://[2001:db8::7]/c=GB?objectClass?one")
report("mailto:[email protected]")
report("news:comp.infosystems.www.servers.unix")
report("tel:+1-816-555-1212")
report("telnet://192.0.2.16:80/")
report("urn:oasis:names:specification:docbook:dtd:xml:4.1")
}
21 changes: 21 additions & 0 deletions libraries/common/char.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ def digitValue(char: Char, base: Int): Int / Exception[WrongFormat] = {
digit
}

/// Encodes a number in the range 0..15 as a hex character.
///
/// Panics on all other numbers.
def hexDigit(for: Int): Char = for match {
case i and i >= 0 and i < 10 => ('0'.toInt + i).toChar
case i and i >= 0 and i < 16 => ('A'.toInt + (i - 10)).toChar
case _ => panic(for.show ++ " is not in [0,16).")
}

/// Checks if the given character is an ASCII digit in base 10
/// Prefer using `digitValue(c: Char)` to get the numeric value out.
def isDigit(char: Char): Bool = result[Int, WrongFormat] { digitValue(char) }.isSuccess
Expand All @@ -70,9 +79,21 @@ def isASCII(c: Char): Bool = { c.toInt < 128 }
/// Checks if a given character is an ASCII lower alphabetic character
def isLower(c: Char): Bool = { c >= 'a' && c <= 'z' }

/// Lower-cases the given ASCII character
def toLower(c: Char): Char =
if (c >= 'A' && c <= 'Z') {
('a'.toInt + (c.toInt - 'A'.toInt)).toChar
} else { c }

/// Checks if a given character is an ASCII upper alphabetic character
def isUpper(c: Char): Bool = { c >= 'A' && c <= 'Z' }

/// Upper-cases the given ASCII character
def toUpper(c: Char): Char =
if (c >= 'a' && c <= 'z') {
('A'.toInt + (c.toInt - 'a'.toInt)).toChar
} else { c }

/// Checks if a given character is an ASCII alphabetic or numeric character
def isAlphanumeric(c: Char): Bool = isDigit(c) || isLower(c) || isUpper(c)

Expand Down
Loading