types, client: more utilities to have clients working

master
nixo 2020-10-25 10:44:58 +01:00
parent ebc58a133e
commit 34a9a1a017
1 changed files with 33 additions and 2 deletions

View File

@ -74,6 +74,14 @@ function Request(data::String)
end
end
function Request(protocol, host, port, path, query)
Request(
something(protocol, "gemini"),
something(host, "."),
something(port, 1965),
path, query, true, "")
end
"unescape(percent_encoded_uri)::String
Replace %xx escaped chars with their single-character equivalent.
@ -107,6 +115,28 @@ function unescape(str)::String
return String(unescaped[1:chars])
end
# FIXME: Is @ reserved?
# Are those the only one that are reserved?
const reserved_chars = ";/?:@&= " |> collect
isreserved(c::Char) = c in reserved_chars
function escape_uri(str)
len = length(str)
# If everything must be escaped, the string is three times longer
escaped = Vector{UInt8}(undef, len * 3)
pos = 1
for char in str
if isreserved(char)
escaped[pos:pos+2] = string('%', string(Int(char), base=16, pad=2)) |>
collect
pos += 3
else
escaped[pos] = char
pos += 1
end
end
String(escaped[1:pos-1])
end
import Base.show
function show(io::IO, r::Request)
# Useful for debugging
@ -115,7 +145,6 @@ function show(io::IO, r::Request)
print(io, "[!invalid] ", String(r.raw))
return
end
printstyled(io, r.protocol, color = :red)
print(io, "://")
printstyled(io, r.host, color = :black, bold = :true)
@ -127,7 +156,9 @@ function show(io::IO, r::Request)
end
if !isnothing(r.query)
print(io, "?")
printstyled(io, r.query, color = :yellow)
# Escape it unless we are in a "terminal"
query = typeof(io) == IOBuffer ? escape_uri(r.query) : r.query
printstyled(io, query, color = :yellow)
end
end