mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vdoc: heavy refactor, immutable config (#7945)
This commit is contained in:
95
cmd/tools/vdoc/httpserver.v
Normal file
95
cmd/tools/vdoc/httpserver.v
Normal file
@@ -0,0 +1,95 @@
|
||||
module main
|
||||
|
||||
import io
|
||||
import net
|
||||
import strings
|
||||
|
||||
fn (mut vd VDoc) serve_html(out Output) {
|
||||
cfg := vd.cfg
|
||||
if out.typ == .html {
|
||||
vd.render_static_html(true, out)
|
||||
}
|
||||
docs := vd.render(out)
|
||||
dkeys := docs.keys()
|
||||
if dkeys.len < 1 {
|
||||
eprintln('no documentation created, the module has no `pub` functions')
|
||||
exit(1)
|
||||
}
|
||||
def_name := docs.keys()[0]
|
||||
server_url := 'http://localhost:' + cfg.server_port.str()
|
||||
server := net.listen_tcp(cfg.server_port) or { panic(err) }
|
||||
println('Serving docs on: $server_url')
|
||||
if cfg.open_docs {
|
||||
open_url(server_url)
|
||||
}
|
||||
content_type := match out.typ {
|
||||
.html { 'text/html' }
|
||||
.markdown { 'text/markdown' }
|
||||
.json { 'application/json' }
|
||||
else { 'text/plain' }
|
||||
}
|
||||
server_context := VdocHttpServerContext{
|
||||
docs: docs
|
||||
content_type: content_type
|
||||
default_filename: def_name
|
||||
}
|
||||
for {
|
||||
mut conn := server.accept() or {
|
||||
server.close() or { }
|
||||
panic(err)
|
||||
}
|
||||
handle_http_connection(mut conn, server_context)
|
||||
conn.close() or { eprintln('error closing the connection: $err') }
|
||||
}
|
||||
}
|
||||
|
||||
struct VdocHttpServerContext {
|
||||
docs map[string]string
|
||||
content_type string
|
||||
default_filename string
|
||||
}
|
||||
|
||||
fn handle_http_connection(mut con net.TcpConn, ctx &VdocHttpServerContext) {
|
||||
mut reader := io.new_buffered_reader(reader: io.make_reader(con))
|
||||
first_line := reader.read_line() or {
|
||||
send_http_response(mut con, 501, ctx.content_type, 'bad request')
|
||||
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.TcpConn, 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.write_str(sresponse) or { eprintln('error sending http response: $err') }
|
||||
}
|
||||
Reference in New Issue
Block a user