78 lines
2.0 KiB
Plaintext
78 lines
2.0 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 url->len() <= 7
|
|
io.println("ERROR: invalid url (Did you forget \"http://\"?)")
|
|
return 1
|
|
|
|
if !url->substr(0, 7)->equal("http://")
|
|
io.println("ERROR: only http scheme is supported")
|
|
return 1
|
|
|
|
url_len := url->len()
|
|
host_start := 7
|
|
i := host_start
|
|
while i < url_len
|
|
if url[i] == '/'
|
|
break
|
|
i += 1
|
|
|
|
host := url->substr(host_start, i - host_start)
|
|
path := "/"
|
|
if i < url_len
|
|
path = url->substr(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
|
|
req->append("GET ")
|
|
req->append(path)
|
|
req->append(" HTTP/1.0\r\nHost: ")
|
|
req->append(host)
|
|
req->append("\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 += 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)
|