mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
x.vweb, picoev: fix timeout event (#20377)
This commit is contained in:
parent
870e6189db
commit
7c310a1bd7
3 changed files with 49 additions and 7 deletions
|
@ -216,6 +216,12 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
$if trace_fd ? {
|
$if trace_fd ? {
|
||||||
eprintln('timeout ${fd}')
|
eprintln('timeout ${fd}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !isnil(pv.raw_cb) {
|
||||||
|
pv.raw_cb(mut pv, fd, events)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
pv.close_conn(fd)
|
pv.close_conn(fd)
|
||||||
return
|
return
|
||||||
} else if events & picoev.picoev_read != 0 {
|
} else if events & picoev.picoev_read != 0 {
|
||||||
|
|
|
@ -91,8 +91,8 @@ fn test_bigger_content_length() {
|
||||||
data: data
|
data: data
|
||||||
})!
|
})!
|
||||||
|
|
||||||
assert x.status() == .bad_request
|
// Content-length is larger than the data sent, so the request should timeout
|
||||||
assert x.body == 'Mismatch of body length and Content-Length header'
|
assert x.status() == .request_timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_smaller_content_length() {
|
fn test_smaller_content_length() {
|
||||||
|
|
|
@ -57,6 +57,15 @@ pub const http_404 = http.new_response(
|
||||||
).join(headers_close)
|
).join(headers_close)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pub const http_408 = http.new_response(
|
||||||
|
status: .request_timeout
|
||||||
|
body: '408 Request Timeout'
|
||||||
|
header: http.new_header(
|
||||||
|
key: .content_type
|
||||||
|
value: 'text/plain'
|
||||||
|
).join(headers_close)
|
||||||
|
)
|
||||||
|
|
||||||
pub const http_413 = http.new_response(
|
pub const http_413 = http.new_response(
|
||||||
status: .request_entity_too_large
|
status: .request_entity_too_large
|
||||||
body: '413 Request entity is too large'
|
body: '413 Request entity is too large'
|
||||||
|
@ -256,6 +265,13 @@ mut:
|
||||||
string_responses []StringResponse
|
string_responses []StringResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset request parameters for `fd`:
|
||||||
|
// reset content-length index and the http request
|
||||||
|
pub fn (mut params RequestParams) request_done(fd int) {
|
||||||
|
params.incomplete_requests[fd] = http.Request{}
|
||||||
|
params.idx[fd] = 0
|
||||||
|
}
|
||||||
|
|
||||||
// run_at - start a new VWeb server, listening only on a specific address `host`, at the specified `port`
|
// run_at - start a new VWeb server, listening only on a specific address `host`, at the specified `port`
|
||||||
// Example: vweb.run_at(new_app(), vweb.RunParams{ host: 'localhost' port: 8099 family: .ip }) or { panic(err) }
|
// Example: vweb.run_at(new_app(), vweb.RunParams{ host: 'localhost' port: 8099 family: .ip }) or { panic(err) }
|
||||||
@[direct_array_access; manualfree]
|
@[direct_array_access; manualfree]
|
||||||
|
@ -306,7 +322,13 @@ pub fn run_at[A, X](mut global_app A, params RunParams) ! {
|
||||||
fn ev_callback[A, X](mut pv picoev.Picoev, fd int, events int) {
|
fn ev_callback[A, X](mut pv picoev.Picoev, fd int, events int) {
|
||||||
mut params := unsafe { &RequestParams(pv.user_data) }
|
mut params := unsafe { &RequestParams(pv.user_data) }
|
||||||
|
|
||||||
if events == picoev.picoev_write {
|
if events == picoev.picoev_timeout {
|
||||||
|
$if trace_picoev_callback ? {
|
||||||
|
eprintln('> request timeout on file descriptor ${fd}')
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_timeout(mut pv, mut params, fd)
|
||||||
|
} else if events == picoev.picoev_write {
|
||||||
$if trace_picoev_callback ? {
|
$if trace_picoev_callback ? {
|
||||||
eprintln('> write event on file descriptor ${fd}')
|
eprintln('> write event on file descriptor ${fd}')
|
||||||
}
|
}
|
||||||
|
@ -320,14 +342,30 @@ fn ev_callback[A, X](mut pv picoev.Picoev, fd int, events int) {
|
||||||
eprintln('[vweb] error: write event on connection should be closed')
|
eprintln('[vweb] error: write event on connection should be closed')
|
||||||
pv.close_conn(fd)
|
pv.close_conn(fd)
|
||||||
}
|
}
|
||||||
} else {
|
} else if events == picoev.picoev_read {
|
||||||
$if trace_picoev_callback ? {
|
$if trace_picoev_callback ? {
|
||||||
eprintln('> read event on file descriptor ${fd}')
|
eprintln('> read event on file descriptor ${fd}')
|
||||||
}
|
}
|
||||||
handle_read[A, X](mut pv, mut params, fd)
|
handle_read[A, X](mut pv, mut params, fd)
|
||||||
|
} else {
|
||||||
|
// should never happen
|
||||||
|
eprintln('[vweb] error: invalid picoev event ${events}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_timeout(mut pv picoev.Picoev, mut params RequestParams, fd int) {
|
||||||
|
mut conn := &net.TcpConn{
|
||||||
|
sock: net.tcp_socket_from_handle_raw(fd)
|
||||||
|
handle: fd
|
||||||
|
is_blocking: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fast_send_resp(mut conn, vweb.http_408) or {}
|
||||||
|
pv.close_conn(fd)
|
||||||
|
|
||||||
|
params.request_done(fd)
|
||||||
|
}
|
||||||
|
|
||||||
// handle_write_file reads data from a file and sends that data over the socket.
|
// handle_write_file reads data from a file and sends that data over the socket.
|
||||||
@[direct_array_access; manualfree]
|
@[direct_array_access; manualfree]
|
||||||
fn handle_write_file(mut pv picoev.Picoev, mut params RequestParams, fd int) {
|
fn handle_write_file(mut pv picoev.Picoev, mut params RequestParams, fd int) {
|
||||||
|
@ -507,9 +545,7 @@ fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
// reset content-length index, the http request and close the connection
|
params.request_done(fd)
|
||||||
params.incomplete_requests[fd] = http.Request{}
|
|
||||||
params.idx[fd] = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if completed_context := handle_request[A, X](mut conn, req, params) {
|
if completed_context := handle_request[A, X](mut conn, req, params) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue