vweb: fix empty post request blocking
parent
7dcd47369b
commit
28f76f10db
|
@ -19,6 +19,11 @@ pub fn new_builder(initial_size int) Builder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn (b mut Builder) write_bytes(bytes byteptr, howmany int) {
|
||||
b.buf.push_many(bytes, howmany)
|
||||
b.len += howmany
|
||||
}
|
||||
|
||||
pub fn (b mut Builder) write_b(data byte) {
|
||||
b.buf << data
|
||||
b.len++
|
||||
|
|
|
@ -32,6 +32,7 @@ const (
|
|||
'.svg': 'image/svg+xml',
|
||||
'.xml': 'text/xml; charset=utf-8'
|
||||
}
|
||||
MAX_HTTP_POST_SIZE = 1024 * 1024
|
||||
)
|
||||
|
||||
pub struct Context {
|
||||
|
@ -125,12 +126,25 @@ pub fn run<T>(app mut T, port int) {
|
|||
conn := l.accept() or { panic('accept() failed') }
|
||||
//foobar<T>()
|
||||
// TODO move this to handle_conn<T>(conn, app)
|
||||
first_line:= conn.read_line()
|
||||
if first_line == '' {
|
||||
message := readall(conn)
|
||||
|
||||
if message.len > MAX_HTTP_POST_SIZE {
|
||||
println('message.len = $message.len > MAX_HTTP_POST_SIZE')
|
||||
conn.send_string(HTTP_500) or {}
|
||||
conn.close() or {}
|
||||
continue
|
||||
}
|
||||
|
||||
lines := message.split_into_lines()
|
||||
|
||||
if lines.len < 2 {
|
||||
conn.send_string(HTTP_500) or {}
|
||||
conn.close() or {}
|
||||
continue
|
||||
}
|
||||
|
||||
first_line := strip(lines[0])
|
||||
$if debug { println(first_line) }
|
||||
// Parse the first line
|
||||
// "GET / HTTP/1.1"
|
||||
//first_line := s.all_before('\n')
|
||||
|
@ -142,13 +156,18 @@ pub fn run<T>(app mut T, port int) {
|
|||
continue
|
||||
}
|
||||
mut headers := []string
|
||||
for {
|
||||
if headers.len >= 30 { break }
|
||||
header := conn.read_line()
|
||||
headers << header
|
||||
//println('header="$header" len = ' + header.len.str())
|
||||
if header.len <= 2 { break }
|
||||
mut body := ''
|
||||
mut in_headers := true
|
||||
for line in lines[1..] {
|
||||
sline := strip(line)
|
||||
if sline == '' { in_headers = false }
|
||||
if in_headers {
|
||||
headers << sline
|
||||
} else {
|
||||
body += strip(sline) + '\r\n'
|
||||
}
|
||||
}
|
||||
|
||||
mut action := vals[1][1..].all_before('/')
|
||||
if action.contains('?') {
|
||||
action = action.all_before('?')
|
||||
|
@ -178,19 +197,8 @@ pub fn run<T>(app mut T, port int) {
|
|||
}
|
||||
//}
|
||||
if req.method in methods_with_form {
|
||||
/*
|
||||
for {
|
||||
line := conn.read_line()
|
||||
if line == '' || line == '\r\n' {
|
||||
break
|
||||
}
|
||||
//if line.contains('POST') || line == '' {
|
||||
//break
|
||||
//}
|
||||
}
|
||||
*/
|
||||
line := conn.read_line()
|
||||
app.vweb.parse_form(line)
|
||||
body = strip(body)
|
||||
app.vweb.parse_form(body)
|
||||
}
|
||||
if vals.len < 2 {
|
||||
$if debug {
|
||||
|
@ -219,10 +227,6 @@ pub fn run<T>(app mut T, port int) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn foobar<T>() {
|
||||
}
|
||||
|
||||
fn (ctx mut Context) parse_form(s string) {
|
||||
if !(ctx.req.method in methods_with_form) {
|
||||
return
|
||||
|
@ -248,6 +252,8 @@ fn (ctx mut Context) parse_form(s string) {
|
|||
ctx.form[key] = val
|
||||
}
|
||||
//}
|
||||
// todo: parse form-data and application/json
|
||||
// ...
|
||||
}
|
||||
|
||||
fn (ctx mut Context) scan_static_directory(directory_path, mount_path string) {
|
||||
|
@ -297,3 +303,23 @@ pub fn (ctx mut Context) serve_static(url, file_path, mime_type string) {
|
|||
ctx.static_files[url] = file_path
|
||||
ctx.static_mime_types[url] = mime_type
|
||||
}
|
||||
|
||||
|
||||
fn readall(conn net.Socket) string {
|
||||
// read all message from socket
|
||||
mut message := ''
|
||||
buf := [1024]byte
|
||||
for {
|
||||
n := C.recv(conn.sockfd, buf, 1024, 2)
|
||||
m := conn.crecv(buf, 1024)
|
||||
message += string( byteptr(buf), m )
|
||||
if message.len > MAX_HTTP_POST_SIZE { break }
|
||||
if n == m { break }
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
fn strip(s string) string {
|
||||
// strip('\nabc\r\n') => 'abc'
|
||||
return s.trim('\r\n')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue