mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vweb: add handle static root & documentation (#8865)
This commit is contained in:
parent
0ccd9f9c6e
commit
7a35131721
@ -15,7 +15,7 @@ fn main() {
|
|||||||
|
|
||||||
pub fn (mut app App) init_once() {
|
pub fn (mut app App) init_once() {
|
||||||
app.serve_static('/favicon.ico', 'favicon.ico', 'img/x-icon')
|
app.serve_static('/favicon.ico', 'favicon.ico', 'img/x-icon')
|
||||||
app.handle_static('.')
|
app.handle_static('.', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut app App) index() vweb.Result {
|
pub fn (mut app App) index() vweb.Result {
|
||||||
|
@ -23,7 +23,7 @@ pub fn (mut app App) init_once() {
|
|||||||
// app.handle_static('assets')
|
// app.handle_static('assets')
|
||||||
// This would make available all known static mime types from current
|
// This would make available all known static mime types from current
|
||||||
// directory and below.
|
// directory and below.
|
||||||
app.handle_static('.')
|
app.handle_static('.', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut app App) init() {
|
pub fn (mut app App) init() {
|
||||||
|
@ -18,7 +18,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut app App) init_once() {
|
pub fn (mut app App) init_once() {
|
||||||
app.handle_static('.')
|
app.handle_static('.', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut app App) json_endpoint() vweb.Result {
|
pub fn (mut app App) json_endpoint() vweb.Result {
|
||||||
|
@ -74,9 +74,6 @@ pub fn (ctx Context) init_once() {}
|
|||||||
// declaring init in your App struct is optional
|
// declaring init in your App struct is optional
|
||||||
pub fn (ctx Context) init() {}
|
pub fn (ctx Context) init() {}
|
||||||
|
|
||||||
// declaring uninit in your App struct is optional
|
|
||||||
pub fn (ctx Context) uninit() {}
|
|
||||||
|
|
||||||
pub struct Cookie {
|
pub struct Cookie {
|
||||||
name string
|
name string
|
||||||
value string
|
value string
|
||||||
@ -89,6 +86,7 @@ pub struct Cookie {
|
|||||||
pub struct Result {
|
pub struct Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vweb intern function
|
||||||
pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bool {
|
pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bool {
|
||||||
if ctx.done {
|
if ctx.done {
|
||||||
return false
|
return false
|
||||||
@ -138,26 +136,31 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bo
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response HTTP_OK with s as payload with content-type `text/html`
|
||||||
pub fn (mut ctx Context) html(s string) Result {
|
pub fn (mut ctx Context) html(s string) Result {
|
||||||
ctx.send_response_to_client('text/html', s)
|
ctx.send_response_to_client('text/html', s)
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response HTTP_OK with s as payload with content-type `text/plain`
|
||||||
pub fn (mut ctx Context) text(s string) Result {
|
pub fn (mut ctx Context) text(s string) Result {
|
||||||
ctx.send_response_to_client('text/plain', s)
|
ctx.send_response_to_client('text/plain', s)
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response HTTP_OK with s as payload with content-type `application/json`
|
||||||
pub fn (mut ctx Context) json(s string) Result {
|
pub fn (mut ctx Context) json(s string) Result {
|
||||||
ctx.send_response_to_client('application/json', s)
|
ctx.send_response_to_client('application/json', s)
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response HTTP_OK with s as payload
|
||||||
pub fn (mut ctx Context) ok(s string) Result {
|
pub fn (mut ctx Context) ok(s string) Result {
|
||||||
ctx.send_response_to_client(ctx.content_type, s)
|
ctx.send_response_to_client(ctx.content_type, s)
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response a server error
|
||||||
pub fn (mut ctx Context) server_error(ecode int) Result {
|
pub fn (mut ctx Context) server_error(ecode int) Result {
|
||||||
$if debug {
|
$if debug {
|
||||||
eprintln('> ctx.server_error ecode: $ecode')
|
eprintln('> ctx.server_error ecode: $ecode')
|
||||||
@ -169,6 +172,7 @@ pub fn (mut ctx Context) server_error(ecode int) Result {
|
|||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirect to an url
|
||||||
pub fn (mut ctx Context) redirect(url string) Result {
|
pub fn (mut ctx Context) redirect(url string) Result {
|
||||||
if ctx.done {
|
if ctx.done {
|
||||||
return Result{}
|
return Result{}
|
||||||
@ -180,6 +184,7 @@ pub fn (mut ctx Context) redirect(url string) Result {
|
|||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send an not_found response
|
||||||
pub fn (mut ctx Context) not_found() Result {
|
pub fn (mut ctx Context) not_found() Result {
|
||||||
if ctx.done {
|
if ctx.done {
|
||||||
return Result{}
|
return Result{}
|
||||||
@ -189,11 +194,13 @@ pub fn (mut ctx Context) not_found() Result {
|
|||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enables chunk transfer with max_chunk_len per chunk
|
||||||
pub fn (mut ctx Context) enable_chunked_transfer(max_chunk_len int) {
|
pub fn (mut ctx Context) enable_chunked_transfer(max_chunk_len int) {
|
||||||
ctx.chunked_transfer = true
|
ctx.chunked_transfer = true
|
||||||
ctx.max_chunk_len = max_chunk_len
|
ctx.max_chunk_len = max_chunk_len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets a cookie
|
||||||
pub fn (mut ctx Context) set_cookie(cookie Cookie) {
|
pub fn (mut ctx Context) set_cookie(cookie Cookie) {
|
||||||
mut cookie_data := []string{}
|
mut cookie_data := []string{}
|
||||||
mut secure := if cookie.secure { 'Secure;' } else { '' }
|
mut secure := if cookie.secure { 'Secure;' } else { '' }
|
||||||
@ -206,20 +213,25 @@ pub fn (mut ctx Context) set_cookie(cookie Cookie) {
|
|||||||
ctx.add_header('Set-Cookie', '$cookie.name=$cookie.value; $data')
|
ctx.add_header('Set-Cookie', '$cookie.name=$cookie.value; $data')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Old function
|
||||||
|
[deprecated]
|
||||||
pub fn (mut ctx Context) set_cookie_old(key string, val string) {
|
pub fn (mut ctx Context) set_cookie_old(key string, val string) {
|
||||||
// TODO support directives, escape cookie value (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)
|
// TODO support directives, escape cookie value (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)
|
||||||
// ctx.add_header('Set-Cookie', '${key}=${val}; Secure; HttpOnly')
|
// ctx.add_header('Set-Cookie', '${key}=${val}; Secure; HttpOnly')
|
||||||
ctx.add_header('Set-Cookie', '$key=$val; HttpOnly')
|
ctx.add_header('Set-Cookie', '$key=$val; HttpOnly')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the response content type
|
||||||
pub fn (mut ctx Context) set_content_type(typ string) {
|
pub fn (mut ctx Context) set_content_type(typ string) {
|
||||||
ctx.content_type = typ
|
ctx.content_type = typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets a cookie with a `expire_data`
|
||||||
pub fn (mut ctx Context) set_cookie_with_expire_date(key string, val string, expire_date time.Time) {
|
pub fn (mut ctx Context) set_cookie_with_expire_date(key string, val string, expire_date time.Time) {
|
||||||
ctx.add_header('Set-Cookie', '$key=$val; Secure; HttpOnly; expires=$expire_date.utc_string()')
|
ctx.add_header('Set-Cookie', '$key=$val; Secure; HttpOnly; expires=$expire_date.utc_string()')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets a cookie by a key
|
||||||
pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor
|
pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor
|
||||||
mut cookie_header := ctx.get_header('cookie')
|
mut cookie_header := ctx.get_header('cookie')
|
||||||
if cookie_header == '' {
|
if cookie_header == '' {
|
||||||
@ -239,6 +251,7 @@ pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor
|
|||||||
return error('Cookie not found')
|
return error('Cookie not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the response status
|
||||||
pub fn (mut ctx Context) set_status(code int, desc string) {
|
pub fn (mut ctx Context) set_status(code int, desc string) {
|
||||||
if code < 100 || code > 599 {
|
if code < 100 || code > 599 {
|
||||||
ctx.status = '500 Internal Server Error'
|
ctx.status = '500 Internal Server Error'
|
||||||
@ -247,12 +260,14 @@ pub fn (mut ctx Context) set_status(code int, desc string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds an header to the response with key and val
|
||||||
pub fn (mut ctx Context) add_header(key string, val string) {
|
pub fn (mut ctx Context) add_header(key string, val string) {
|
||||||
// println('add_header($key, $val)')
|
// println('add_header($key, $val)')
|
||||||
ctx.headers = ctx.headers + '\r\n$key: $val'
|
ctx.headers = ctx.headers + '\r\n$key: $val'
|
||||||
// println(ctx.headers)
|
// println(ctx.headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the header data from the key
|
||||||
pub fn (ctx &Context) get_header(key string) string {
|
pub fn (ctx &Context) get_header(key string) string {
|
||||||
return ctx.req.headers[key]
|
return ctx.req.headers[key]
|
||||||
}
|
}
|
||||||
@ -615,6 +630,7 @@ fn handle_conn<T>(mut conn net.TcpConn, mut app T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vweb intern function
|
||||||
pub fn (mut ctx Context) parse_form(s string) {
|
pub fn (mut ctx Context) parse_form(s string) {
|
||||||
if ctx.req.method !in vweb.methods_with_form {
|
if ctx.req.method !in vweb.methods_with_form {
|
||||||
return
|
return
|
||||||
@ -644,6 +660,7 @@ pub fn (mut ctx Context) parse_form(s string) {
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vweb intern function
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn (mut ctx Context) parse_multipart_form(s string, b string) {
|
pub fn (mut ctx Context) parse_multipart_form(s string, b string) {
|
||||||
if ctx.req.method !in vweb.methods_with_form {
|
if ctx.req.method !in vweb.methods_with_form {
|
||||||
@ -712,13 +729,15 @@ fn (mut ctx Context) scan_static_directory(directory_path string, mount_path str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut ctx Context) handle_static(directory_path string) bool {
|
// Handles a directory static
|
||||||
|
// If `root` is set the mount path for the dir will be in '/'
|
||||||
|
pub fn (mut ctx Context) handle_static(directory_path string, root bool) bool {
|
||||||
if ctx.done || !os.exists(directory_path) {
|
if ctx.done || !os.exists(directory_path) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
dir_path := directory_path.trim_space().trim_right('/')
|
dir_path := directory_path.trim_space().trim_right('/')
|
||||||
mut mount_path := ''
|
mut mount_path := ''
|
||||||
if dir_path != '.' && os.is_dir(dir_path) {
|
if dir_path != '.' && os.is_dir(dir_path) && !root {
|
||||||
// Mount point hygene, "./assets" => "/assets".
|
// Mount point hygene, "./assets" => "/assets".
|
||||||
mount_path = '/' + dir_path.trim_left('.').trim('/')
|
mount_path = '/' + dir_path.trim_left('.').trim('/')
|
||||||
}
|
}
|
||||||
@ -726,11 +745,14 @@ pub fn (mut ctx Context) handle_static(directory_path string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serves a file static
|
||||||
|
// `url` is the access path on the site, `file_path` is the real path to the file, `mime_type` is the file type
|
||||||
pub fn (mut ctx Context) serve_static(url string, file_path string, mime_type string) {
|
pub fn (mut ctx Context) serve_static(url string, file_path string, 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the ip address from the current user
|
||||||
pub fn (ctx &Context) ip() string {
|
pub fn (ctx &Context) ip() string {
|
||||||
mut ip := ctx.req.headers['X-Forwarded-For']
|
mut ip := ctx.req.headers['X-Forwarded-For']
|
||||||
if ip == '' {
|
if ip == '' {
|
||||||
@ -745,6 +767,7 @@ pub fn (ctx &Context) ip() string {
|
|||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set s to the form error
|
||||||
pub fn (mut ctx Context) error(s string) {
|
pub fn (mut ctx Context) error(s string) {
|
||||||
ctx.form_error = s
|
ctx.form_error = s
|
||||||
}
|
}
|
||||||
@ -770,6 +793,7 @@ fn strip(s string) string {
|
|||||||
return s.trim('\r\n')
|
return s.trim('\r\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an empty result
|
||||||
pub fn not_found() Result {
|
pub fn not_found() Result {
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
@ -785,6 +809,7 @@ fn filter(s string) string {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A type which don't get filtered inside templates
|
||||||
pub type RawHtml = string
|
pub type RawHtml = string
|
||||||
|
|
||||||
fn send_string(mut conn net.TcpConn, s string) ? {
|
fn send_string(mut conn net.TcpConn, s string) ? {
|
||||||
|
Loading…
Reference in New Issue
Block a user