vweb: Implement chunked encoding transfer (#8179)
parent
5ddb70940e
commit
38881e4b20
|
@ -31,6 +31,7 @@ pub fn (mut app App) index() vweb.Result {
|
|||
// app.text('Hello world from vweb')
|
||||
hello := 'Hello world from vweb'
|
||||
numbers := [1, 2, 3]
|
||||
app.enable_chunked_transfer(40)
|
||||
return $vweb.html()
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,13 @@ fn test_http_client_index() {
|
|||
assert x.text == 'Welcome to VWeb'
|
||||
}
|
||||
|
||||
fn test_http_client_chunk_transfer() {
|
||||
x := http.get('http://127.0.0.1:$sport/chunk') or { panic(err) }
|
||||
assert_common_http_headers(x)
|
||||
assert x.headers['Transfer-Encoding'] == 'chunked'
|
||||
assert x.text == 'Lorem ipsum dolor sit amet, consetetur sadipscing'
|
||||
}
|
||||
|
||||
fn test_http_client_404() {
|
||||
url_404_list := [
|
||||
'http://127.0.0.1:$sport/zxcnbnm',
|
||||
|
|
|
@ -56,6 +56,11 @@ pub fn (mut app App) html_page() vweb.Result {
|
|||
return app.html('<h1>ok</h1>')
|
||||
}
|
||||
|
||||
pub fn (mut app App) chunk() vweb.Result {
|
||||
app.enable_chunked_transfer(20)
|
||||
return app.html('Lorem ipsum dolor sit amet, consetetur sadipscing')
|
||||
}
|
||||
|
||||
// the following serve custom routes
|
||||
['/:user/settings']
|
||||
pub fn (mut app App) settings(username string) vweb.Result {
|
||||
|
|
|
@ -56,6 +56,8 @@ pub mut:
|
|||
done bool
|
||||
page_gen_start i64
|
||||
form_error string
|
||||
chunked_transfer bool
|
||||
max_chunk_len int = 20
|
||||
}
|
||||
|
||||
// declaring init_once in your App struct is optional
|
||||
|
@ -88,10 +90,35 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bo
|
|||
sb.write('HTTP/1.1 $ctx.status')
|
||||
sb.write('\r\nContent-Type: $mimetype')
|
||||
sb.write('\r\nContent-Length: $res.len')
|
||||
if ctx.chunked_transfer {
|
||||
sb.write('\r\nTransfer-Encoding: chunked')
|
||||
}
|
||||
sb.write(ctx.headers)
|
||||
sb.write('\r\n')
|
||||
sb.write(headers_close)
|
||||
if ctx.chunked_transfer {
|
||||
mut i := 0
|
||||
mut len := res.len
|
||||
for {
|
||||
if len <= 0 {
|
||||
break
|
||||
}
|
||||
mut chunk := ''
|
||||
if len > ctx.max_chunk_len {
|
||||
chunk = res[i..i + ctx.max_chunk_len]
|
||||
i += ctx.max_chunk_len
|
||||
len -= ctx.max_chunk_len
|
||||
} else {
|
||||
chunk = res[i..]
|
||||
len = 0
|
||||
}
|
||||
sb.write(chunk.len.hex())
|
||||
sb.write('\r\n$chunk\r\n')
|
||||
}
|
||||
sb.write('0\r\n\r\n') // End of chunks
|
||||
} else {
|
||||
sb.write(res)
|
||||
}
|
||||
s := sb.str()
|
||||
defer {
|
||||
s.free()
|
||||
|
@ -140,6 +167,11 @@ pub fn (mut ctx Context) not_found() Result {
|
|||
return Result{}
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) enable_chunked_transfer(max_chunk_len int) {
|
||||
ctx.chunked_transfer = true
|
||||
ctx.max_chunk_len = max_chunk_len
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) set_cookie(cookie Cookie) {
|
||||
mut cookie_data := []string{}
|
||||
mut secure := if cookie.secure { 'Secure;' } else { '' }
|
||||
|
|
Loading…
Reference in New Issue