vdoc: fix segfault in -autofree mode

pull/5451/head
Delyan Angelov 2020-06-21 17:41:43 +03:00
parent 0d6233cd45
commit fbe5599526
1 changed files with 61 additions and 16 deletions

View File

@ -149,26 +149,70 @@ fn (mut cfg DocConfig) serve_html() {
.json { 'application/json' } .json { 'application/json' }
else { 'text/plain' } else { 'text/plain' }
} }
server_context := VdocHttpServerContext {
docs: docs
content_type: content_type
default_filename: def_name
}
for { for {
con := server.accept() or { con := server.accept() or {
server.close() or { } server.close() or { }
panic(err) panic(err)
} }
s := con.read_line() handle_http_connection(mut con, server_context)
first_line := s.all_before('\n') con.close() or {
mut filename := def_name eprintln('error closing the connection: $err')
if first_line.len != 0 {
data := first_line.split(' ')
url := urllib.parse(data[1]) or { return }
filename = if url.path == '/' { def_name } else { url.path.trim_left('/') }
} }
html := docs[filename].trim_space() }
content_length := html.len }
con.send_string('HTTP/1.1 200 OK\r\nServer: VDoc\r\nContent-Type: ${content_type}\r\nContent-Length: ${content_length}\r\nConnection: close\r\n\r\n${html}') or {
con.close() or { return } struct VdocHttpServerContext {
docs map[string]string
content_type string
default_filename string
}
fn handle_http_connection(mut con net.Socket, ctx &VdocHttpServerContext) {
s := con.read_line()
first_line := s.all_before('\r\n')
if first_line.len == 0 {
send_http_response(mut con, 501, ctx.content_type, 'bad request')
return return
} }
con.close() or { return } request_parts := first_line.split(' ')
if request_parts.len != 3 {
send_http_response(mut con, 501, ctx.content_type, 'bad request')
return
}
urlpath := request_parts[1]
filename := if urlpath == '/' { ctx.default_filename.trim_left('/') } else { urlpath.trim_left('/') }
if ctx.docs[filename].len == 0 {
send_http_response(mut con, 404, ctx.content_type, 'file not found')
return
}
send_http_response(mut con, 200, ctx.content_type, ctx.docs[filename])
}
fn send_http_response(mut con net.Socket, http_code int, content_type string, html string) {
content_length := html.len.str()
shttp_code := http_code.str()
mut http_response := strings.new_builder(20000)
http_response.write('HTTP/1.1 ')
http_response.write(shttp_code)
http_response.write(' OK\r\n')
http_response.write('Server: VDoc\r\n')
http_response.write('Content-Type: ')
http_response.write(content_type)
http_response.write('\r\n')
http_response.write('Content-Length: ')
http_response.write(content_length)
http_response.write('\r\n')
http_response.write('Connection: close\r\n')
http_response.write('\r\n')
http_response.write(html)
sresponse := http_response.str()
con.send_string(sresponse) or {
eprintln('error sending http response: $err')
} }
} }
@ -531,12 +575,13 @@ fn (cfg DocConfig) render() map[string]string {
.json { '.json' } .json { '.json' }
else { '.txt' } else { '.txt' }
} }
docs[name] = match cfg.output_type { output := match cfg.output_type {
.html { cfg.gen_html(i) } .html { cfg.gen_html(i) }
.markdown { cfg.gen_markdown(i, true) } .markdown { cfg.gen_markdown(i, true) }
.json { cfg.gen_json(i) } .json { cfg.gen_json(i) }
else { cfg.gen_plaintext(i) } else { cfg.gen_plaintext(i) }
} }
docs[name] = output.trim_space()
} }
cfg.vprintln('Rendered: ' + docs.keys().str()) cfg.vprintln('Rendered: ' + docs.keys().str())
return docs return docs
@ -751,7 +796,7 @@ fn (cfg DocConfig) get_resource(name string, minify bool) string {
} }
fn main() { fn main() {
args := os.args[2..] args := os.args[2..].clone()
if args.len == 0 || args[0] in ['help', '-h', '--help'] { if args.len == 0 || args[0] in ['help', '-h', '--help'] {
os.system('${@VEXE} help doc') os.system('${@VEXE} help doc')
exit(0) exit(0)