1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

net.http: render each header value on a newline (#11270)

This commit is contained in:
Miccah 2021-08-22 16:38:09 -05:00 committed by GitHub
parent 352df873d5
commit 51d7aede68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 27 deletions

View File

@ -554,21 +554,17 @@ pub fn (h Header) render(flags HeaderRenderConfig) string {
} else { } else {
data_keys[0] data_keys[0]
} }
for k in data_keys {
for v in h.data[k] {
sb.write_string(key) sb.write_string(key)
sb.write_string(': ') sb.write_string(': ')
for i in 0 .. data_keys.len - 1 {
k := data_keys[i]
for v in h.data[k] {
sb.write_string(v) sb.write_string(v)
sb.write_string(',')
}
}
k := data_keys[data_keys.len - 1]
sb.write_string(h.data[k].join(','))
sb.write_string('\r\n') sb.write_string('\r\n')
} }
}
}
} else { } else {
for k, v in h.data { for k, vs in h.data {
key := if flags.version == .v2_0 { key := if flags.version == .v2_0 {
k.to_lower() k.to_lower()
} else if flags.canonicalize { } else if flags.canonicalize {
@ -576,12 +572,14 @@ pub fn (h Header) render(flags HeaderRenderConfig) string {
} else { } else {
k k
} }
for v in vs {
sb.write_string(key) sb.write_string(key)
sb.write_string(': ') sb.write_string(': ')
sb.write_string(v.join(',')) sb.write_string(v)
sb.write_string('\r\n') sb.write_string('\r\n')
} }
} }
}
res := sb.str() res := sb.str()
unsafe { sb.free() } unsafe { sb.free() }
return res return res

View File

@ -190,15 +190,18 @@ fn test_render_version() ? {
s1_0 := h.render(version: .v1_0) s1_0 := h.render(version: .v1_0)
assert s1_0.contains('accept: foo\r\n') assert s1_0.contains('accept: foo\r\n')
assert s1_0.contains('Accept: bar,baz\r\n') assert s1_0.contains('Accept: bar\r\n')
assert s1_0.contains('Accept: baz\r\n')
s1_1 := h.render(version: .v1_1) s1_1 := h.render(version: .v1_1)
assert s1_1.contains('accept: foo\r\n') assert s1_1.contains('accept: foo\r\n')
assert s1_1.contains('Accept: bar,baz\r\n') assert s1_1.contains('Accept: bar\r\n')
assert s1_1.contains('Accept: baz\r\n')
s2_0 := h.render(version: .v2_0) s2_0 := h.render(version: .v2_0)
assert s2_0.contains('accept: foo\r\n') assert s2_0.contains('accept: foo\r\n')
assert s2_0.contains('accept: bar,baz\r\n') assert s2_0.contains('accept: bar\r\n')
assert s2_0.contains('accept: baz\r\n')
} }
fn test_render_coerce() ? { fn test_render_coerce() ? {
@ -209,15 +212,21 @@ fn test_render_coerce() ? {
h.add(.host, 'host') h.add(.host, 'host')
s1_0 := h.render(version: .v1_1, coerce: true) s1_0 := h.render(version: .v1_1, coerce: true)
assert s1_0.contains('accept: foo,bar,baz\r\n') assert s1_0.contains('accept: foo\r\n')
assert s1_0.contains('accept: bar\r\n')
assert s1_0.contains('accept: baz\r\n')
assert s1_0.contains('Host: host\r\n') assert s1_0.contains('Host: host\r\n')
s1_1 := h.render(version: .v1_1, coerce: true) s1_1 := h.render(version: .v1_1, coerce: true)
assert s1_1.contains('accept: foo,bar,baz\r\n') assert s1_1.contains('accept: foo\r\n')
assert s1_1.contains('accept: bar\r\n')
assert s1_1.contains('accept: baz\r\n')
assert s1_1.contains('Host: host\r\n') assert s1_1.contains('Host: host\r\n')
s2_0 := h.render(version: .v2_0, coerce: true) s2_0 := h.render(version: .v2_0, coerce: true)
assert s2_0.contains('accept: foo,bar,baz\r\n') assert s2_0.contains('accept: foo\r\n')
assert s2_0.contains('accept: bar\r\n')
assert s2_0.contains('accept: baz\r\n')
assert s2_0.contains('host: host\r\n') assert s2_0.contains('host: host\r\n')
} }
@ -230,17 +239,20 @@ fn test_render_canonicalize() ? {
s1_0 := h.render(version: .v1_1, canonicalize: true) s1_0 := h.render(version: .v1_1, canonicalize: true)
assert s1_0.contains('Accept: foo\r\n') assert s1_0.contains('Accept: foo\r\n')
assert s1_0.contains('Accept: bar,baz\r\n') assert s1_0.contains('Accept: bar\r\n')
assert s1_0.contains('Accept: baz\r\n')
assert s1_0.contains('Host: host\r\n') assert s1_0.contains('Host: host\r\n')
s1_1 := h.render(version: .v1_1, canonicalize: true) s1_1 := h.render(version: .v1_1, canonicalize: true)
assert s1_1.contains('Accept: foo\r\n') assert s1_1.contains('Accept: foo\r\n')
assert s1_1.contains('Accept: bar,baz\r\n') assert s1_1.contains('Accept: bar\r\n')
assert s1_1.contains('Accept: baz\r\n')
assert s1_1.contains('Host: host\r\n') assert s1_1.contains('Host: host\r\n')
s2_0 := h.render(version: .v2_0, canonicalize: true) s2_0 := h.render(version: .v2_0, canonicalize: true)
assert s2_0.contains('accept: foo\r\n') assert s2_0.contains('accept: foo\r\n')
assert s2_0.contains('accept: bar,baz\r\n') assert s2_0.contains('accept: bar\r\n')
assert s2_0.contains('accept: baz\r\n')
assert s2_0.contains('host: host\r\n') assert s2_0.contains('host: host\r\n')
} }
@ -252,15 +264,21 @@ fn test_render_coerce_canonicalize() ? {
h.add(.host, 'host') h.add(.host, 'host')
s1_0 := h.render(version: .v1_1, coerce: true, canonicalize: true) s1_0 := h.render(version: .v1_1, coerce: true, canonicalize: true)
assert s1_0.contains('Accept: foo,bar,baz\r\n') assert s1_0.contains('Accept: foo\r\n')
assert s1_0.contains('Accept: bar\r\n')
assert s1_0.contains('Accept: baz\r\n')
assert s1_0.contains('Host: host\r\n') assert s1_0.contains('Host: host\r\n')
s1_1 := h.render(version: .v1_1, coerce: true, canonicalize: true) s1_1 := h.render(version: .v1_1, coerce: true, canonicalize: true)
assert s1_1.contains('Accept: foo,bar,baz\r\n') assert s1_1.contains('Accept: foo\r\n')
assert s1_1.contains('Accept: bar\r\n')
assert s1_1.contains('Accept: baz\r\n')
assert s1_1.contains('Host: host\r\n') assert s1_1.contains('Host: host\r\n')
s2_0 := h.render(version: .v2_0, coerce: true, canonicalize: true) s2_0 := h.render(version: .v2_0, coerce: true, canonicalize: true)
assert s2_0.contains('accept: foo,bar,baz\r\n') assert s2_0.contains('accept: foo\r\n')
assert s2_0.contains('accept: bar\r\n')
assert s2_0.contains('accept: baz\r\n')
assert s2_0.contains('host: host\r\n') assert s2_0.contains('host: host\r\n')
} }
@ -271,8 +289,8 @@ fn test_str() ? {
h.add_custom('X-custom', 'Hello') ? h.add_custom('X-custom', 'Hello') ?
// key order is not guaranteed // key order is not guaranteed
assert h.str() == 'Accept: text/html,image/jpeg\r\nX-custom: Hello\r\n' assert h.str() == 'Accept: text/html\r\nAccept: image/jpeg\r\nX-custom: Hello\r\n'
|| h.str() == 'X-custom: Hello\r\nAccept:text/html,image/jpeg\r\n' || h.str() == 'X-custom: Hello\r\nAccept:text/html\r\nAccept: image/jpeg\r\n'
} }
fn test_header_from_map() ? { fn test_header_from_map() ? {
@ -359,3 +377,11 @@ fn test_parse_headers() ? {
return error('should have errored, but got $x') return error('should have errored, but got $x')
} }
} }
fn test_set_cookie() {
// multiple Set-Cookie headers should be sent when rendered
mut h := new_header()
h.add(.set_cookie, 'foo')
h.add(.set_cookie, 'bar')
assert h.render() == 'Set-Cookie: foo\r\nSet-Cookie: bar\r\n'
}