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) {
|
pub fn (b mut Builder) write_b(data byte) {
|
||||||
b.buf << data
|
b.buf << data
|
||||||
b.len++
|
b.len++
|
||||||
|
|
|
@ -32,6 +32,7 @@ const (
|
||||||
'.svg': 'image/svg+xml',
|
'.svg': 'image/svg+xml',
|
||||||
'.xml': 'text/xml; charset=utf-8'
|
'.xml': 'text/xml; charset=utf-8'
|
||||||
}
|
}
|
||||||
|
MAX_HTTP_POST_SIZE = 1024 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
|
@ -125,12 +126,25 @@ pub fn run<T>(app mut T, port int) {
|
||||||
conn := l.accept() or { panic('accept() failed') }
|
conn := l.accept() or { panic('accept() failed') }
|
||||||
//foobar<T>()
|
//foobar<T>()
|
||||||
// TODO move this to handle_conn<T>(conn, app)
|
// TODO move this to handle_conn<T>(conn, app)
|
||||||
first_line:= conn.read_line()
|
message := readall(conn)
|
||||||
if first_line == '' {
|
|
||||||
|
if message.len > MAX_HTTP_POST_SIZE {
|
||||||
|
println('message.len = $message.len > MAX_HTTP_POST_SIZE')
|
||||||
conn.send_string(HTTP_500) or {}
|
conn.send_string(HTTP_500) or {}
|
||||||
conn.close() or {}
|
conn.close() or {}
|
||||||
continue
|
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
|
// Parse the first line
|
||||||
// "GET / HTTP/1.1"
|
// "GET / HTTP/1.1"
|
||||||
//first_line := s.all_before('\n')
|
//first_line := s.all_before('\n')
|
||||||
|
@ -142,13 +156,18 @@ pub fn run<T>(app mut T, port int) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mut headers := []string
|
mut headers := []string
|
||||||
for {
|
mut body := ''
|
||||||
if headers.len >= 30 { break }
|
mut in_headers := true
|
||||||
header := conn.read_line()
|
for line in lines[1..] {
|
||||||
headers << header
|
sline := strip(line)
|
||||||
//println('header="$header" len = ' + header.len.str())
|
if sline == '' { in_headers = false }
|
||||||
if header.len <= 2 { break }
|
if in_headers {
|
||||||
|
headers << sline
|
||||||
|
} else {
|
||||||
|
body += strip(sline) + '\r\n'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mut action := vals[1][1..].all_before('/')
|
mut action := vals[1][1..].all_before('/')
|
||||||
if action.contains('?') {
|
if action.contains('?') {
|
||||||
action = action.all_before('?')
|
action = action.all_before('?')
|
||||||
|
@ -178,19 +197,8 @@ pub fn run<T>(app mut T, port int) {
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
if req.method in methods_with_form {
|
if req.method in methods_with_form {
|
||||||
/*
|
body = strip(body)
|
||||||
for {
|
app.vweb.parse_form(body)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
if vals.len < 2 {
|
if vals.len < 2 {
|
||||||
$if debug {
|
$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) {
|
fn (ctx mut Context) parse_form(s string) {
|
||||||
if !(ctx.req.method in methods_with_form) {
|
if !(ctx.req.method in methods_with_form) {
|
||||||
return
|
return
|
||||||
|
@ -248,6 +252,8 @@ fn (ctx mut Context) parse_form(s string) {
|
||||||
ctx.form[key] = val
|
ctx.form[key] = val
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
// todo: parse form-data and application/json
|
||||||
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (ctx mut Context) scan_static_directory(directory_path, mount_path string) {
|
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_files[url] = file_path
|
||||||
ctx.static_mime_types[url] = mime_type
|
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