v/vlib/net/http/request_test.v

161 lines
3.7 KiB
V

module http
import io
struct StringReader {
text string
mut:
place int
}
fn (mut s StringReader) read(mut buf []byte) ?int {
if s.place >= s.text.len {
return none
}
max_bytes := 100
end := if s.place + max_bytes >= s.text.len { s.text.len } else { s.place + max_bytes }
n := copy(buf, s.text[s.place..end].bytes())
s.place += n
return n
}
fn reader(s string) &io.BufferedReader {
return io.new_buffered_reader(
reader: &StringReader{
text: s
}
)
}
fn test_parse_request_not_http() {
mut reader__ := reader('hello')
parse_request(mut reader__) or { return }
panic('should not have parsed')
}
fn test_parse_request_no_headers() {
mut reader_ := reader('GET / HTTP/1.1\r\n\r\n')
req := parse_request(mut reader_) or { panic('did not parse: $err') }
assert req.method == .get
assert req.url == '/'
assert req.version == .v1_1
}
fn test_parse_request_two_headers() {
mut reader_ := reader('GET / HTTP/1.1\r\nTest1: a\r\nTest2: B\r\n\r\n')
req := parse_request(mut reader_) or { panic('did not parse: $err') }
assert req.header.custom_values('Test1') == ['a']
assert req.header.custom_values('Test2') == ['B']
}
fn test_parse_request_two_header_values() {
mut reader_ := reader('GET / HTTP/1.1\r\nTest1: a; b\r\nTest2: c\r\nTest2: d\r\n\r\n')
req := parse_request(mut reader_) or { panic('did not parse: $err') }
assert req.header.custom_values('Test1') == ['a; b']
assert req.header.custom_values('Test2') == ['c', 'd']
}
fn test_parse_request_body() {
mut reader_ := reader('GET / HTTP/1.1\r\nTest1: a\r\nTest2: b\r\nContent-Length: 4\r\n\r\nbodyabc')
req := parse_request(mut reader_) or { panic('did not parse: $err') }
assert req.data == 'body'
}
fn test_parse_request_line() {
method, target, version := parse_request_line('GET /target HTTP/1.1') or {
panic('did not parse: $err')
}
assert method == .get
assert target.str() == '/target'
assert version == .v1_1
}
fn test_parse_form() {
assert parse_form('foo=bar&bar=baz') == {
'foo': 'bar'
'bar': 'baz'
}
assert parse_form('foo=bar=&bar=baz') == {
'foo': 'bar='
'bar': 'baz'
}
assert parse_form('foo=bar%3D&bar=baz') == {
'foo': 'bar='
'bar': 'baz'
}
assert parse_form('foo=b%26ar&bar=baz') == {
'foo': 'b&ar'
'bar': 'baz'
}
assert parse_form('a=b& c=d') == {
'a': 'b'
' c': 'd'
}
assert parse_form('a=b&c= d ') == {
'a': 'b'
'c': ' d '
}
}
fn test_parse_multipart_form() {
boundary := '6844a625b1f0b299'
names := ['foo', 'fooz']
file := 'bar.v'
ct := 'application/octet-stream'
contents := ['baz', 'buzz']
data := "--------------------------$boundary
Content-Disposition: form-data; name=\"${names[0]}\"; filename=\"$file\"
Content-Type: $ct
${contents[0]}
--------------------------$boundary
Content-Disposition: form-data; name=\"${names[1]}\"
${contents[1]}
--------------------------$boundary--
"
form, files := parse_multipart_form(data, boundary)
assert files == {
names[0]: [
FileData{
filename: file
content_type: ct
data: contents[0]
},
]
}
assert form == {
names[1]: contents[1]
}
}
fn test_multipart_form_body() {
files := {
'foo': [
FileData{
filename: 'bar.v'
content_type: 'application/octet-stream'
data: 'baz'
},
]
}
form := {
'fooz': 'buzz'
}
body, boundary := multipart_form_body(form, files)
parsed_form, parsed_files := parse_multipart_form(body, boundary)
assert parsed_files == files
assert parsed_form == form
}
fn test_parse_large_body() ? {
body := 'A'.repeat(101) // greater than max_bytes
req := 'GET / HTTP/1.1\r\nContent-Length: $body.len\r\n\r\n$body'
mut reader_ := reader(req)
result := parse_request(mut reader_) ?
assert result.data.len == body.len
assert result.data == body
}