Files
zern/examples/curl.zr

78 lines
2.1 KiB
Plaintext

func main[argc: i64, argv: ptr] : i64
if argc < 2
io.println("ERROR: url is missing")
return 1
url := mem.read64(argv + 8) as str
if str.len(url) <= 7
io.println("ERROR: invalid url (Did you forget \"http://\"?)")
return 1
if !str.equal(str.substr(url, 0, 7), "http://")
io.println("ERROR: only http scheme is supported")
return 1
url_len := str.len(url)
host_start := 7
i := host_start
while i < url_len
if url[i] == '/'
break
i = i + 1
host := str.substr(url, host_start, i - host_start)
path := "/"
if i < url_len
path = str.substr(url, i, url_len - i)
~addr, ok := net.resolve(host)
if !ok
panic("failed to resolve host")
~s, ok := net.connect(addr, 80)
if !ok
panic("failed to connect")
req := new str.Builder
str.Builder.append(req, "GET ")
str.Builder.append(req, path)
str.Builder.append(req, " HTTP/1.0\r\nHost: ")
str.Builder.append(req, host)
str.Builder.append(req, "\r\nConnection: close\r\n\r\n")
net.send(s, req->data, req->size)
mem.free(req->data)
header_buf := mem.alloc(8192) as str
header_size := 0
found := false
end_index := -1
while !found && header_size < 8192
n := net.read(s, header_buf as ptr + header_size, 8192 - header_size)
if n <= 0
break
current_size := header_size + n
i = 0
while i <= current_size - 4
if header_buf[i] == '\r' && header_buf[i + 1] == '\n' && header_buf[i + 2] == '\r' && header_buf[i + 3] == '\n'
found = true
end_index = i + 4
break
i = i + 1
header_size = current_size
if end_index < header_size
io.print_sized(header_buf as ptr + end_index, header_size as i64 - end_index)
mem.free(header_buf)
buffer := mem.alloc(4096)
while true
n := net.read(s, buffer, 4096)
if n <= 0
break
io.print_sized(buffer, n)
mem.free(buffer)
net.close(s)