Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x.vweb: fix large payload #20155

Merged
merged 4 commits into from
Dec 12, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions vlib/x/vweb/vweb.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import picoev

// max read and write limits in bytes
const max_read = 8096

const max_write = 8096 * 2

// A type which doesn't get filtered inside templates
Expand Down Expand Up @@ -307,8 +306,12 @@ fn ev_callback[A, X](mut pv picoev.Picoev, fd int, events int) {

if params.file_responses[fd].open {
handle_write_file(mut pv, mut params, fd)
} else {
} else if params.string_responses[fd].open {
handle_write_string(mut pv, mut params, fd)
} else {
// this should never happen
eprintln('[vweb] error: write event on connection should be closed')
pv.close_conn(fd)
}
} else {
$if trace_picoev_callback ? {
Expand Down Expand Up @@ -461,6 +464,7 @@ fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) {
eprintln('[vweb] error parsing request: ${err}')
pv.close_conn(fd)
params.incomplete_requests[fd] = http.Request{}
params.idx[fd] = 0
return
}

Expand All @@ -476,18 +480,21 @@ fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) {
value: 'text/plain'
).join(vweb.headers_close)
)) or {}

pv.close_conn(fd)
params.incomplete_requests[fd] = http.Request{}
params.idx[fd] = 0
return
} else if n < bytes_to_read || params.idx[fd] + n < content_length.int() {
// request is incomplete wait until the socket becomes ready to read again
params.idx[fd] += n
// TODO: change this to a memcpy function?
req.data += buf.bytestr()
req.data += buf[0..n].bytestr()
params.incomplete_requests[fd] = req
return
} else {
// request is complete: n = bytes_to_read
params.idx[fd] += n
req.data += buf[0..n].bytestr()
}
}
Expand Down Expand Up @@ -522,6 +529,7 @@ fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) {
fast_send_resp(mut conn, completed_context.res) or {}
pv.close_conn(fd)
} else {
params.string_responses[fd].open = true
params.string_responses[fd].str = completed_context.res.body
res := pv.add(fd, picoev.picoev_write, params.timeout_in_seconds,
picoev.raw_callback)
Expand Down Expand Up @@ -587,7 +595,7 @@ fn handle_request[A, X](mut conn net.TcpConn, req http.Request, params &RequestP

// parse the URL, query and form data
mut url := urllib.parse(req.url) or {
eprintln('[vweb] error parsing path: ${err}')
eprintln('[vweb] error parsing path "${req.url}": ${err}')
return none
}
query := parse_query_from_url(url)
Expand Down
Loading