mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vweb: fix serving static files
This commit is contained in:
parent
88c1ff91ac
commit
750f37fde7
19
examples/vweb/vweb_assets/assets/index.css
Normal file
19
examples/vweb/vweb_assets/assets/index.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
color: #eee;
|
||||||
|
background-color: #333;
|
||||||
|
background-image: url("v-logo.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 10em;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 11em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #6699CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.logo {
|
||||||
|
float: left;
|
||||||
|
width: 10em;
|
||||||
|
}
|
1
examples/vweb/vweb_assets/assets/v-logo.svg
Normal file
1
examples/vweb/vweb_assets/assets/v-logo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 500 500" width="500px" height="500px"><defs><clipPath id="_clipPath_8TWIgR1z3pxinjWBiigzcEIrVJKv9Gq4"><rect width="500" height="500"/></clipPath></defs><g clip-path="url(#_clipPath_8TWIgR1z3pxinjWBiigzcEIrVJKv9Gq4)"><path d=" M 318.422 453.543 L 463.705 49.541 C 466.168 42.689 462.285 37.693 455.037 38.392 L 340.786 49.398 C 333.539 50.097 325.71 56.246 323.316 63.121 L 188.843 449.216 C 186.447 456.091 190.414 461.673 197.695 461.673 L 308.901 461.673 C 312.541 461.673 316.497 458.893 317.729 455.466 L 318.422 453.543 Z " fill="rgb(83,107,138)"/><defs><filter id="Hmac7mZraFWHw0G84Yxj4QuzeTFp0E7Y" x="-200%" y="-200%" width="400%" height="400%" filterUnits="objectBoundingBox" color-interpolation-filters="sRGB"><feGaussianBlur xmlns="http://www.w3.org/2000/svg" in="SourceGraphic" stdDeviation="6.440413594258542"/><feOffset xmlns="http://www.w3.org/2000/svg" dx="0" dy="0" result="pf_100_offsetBlur"/><feFlood xmlns="http://www.w3.org/2000/svg" flood-color="#000000" flood-opacity="0.65"/><feComposite xmlns="http://www.w3.org/2000/svg" in2="pf_100_offsetBlur" operator="in" result="pf_100_dropShadow"/><feBlend xmlns="http://www.w3.org/2000/svg" in="SourceGraphic" in2="pf_100_dropShadow" mode="normal"/></filter></defs><g filter="url(#Hmac7mZraFWHw0G84Yxj4QuzeTFp0E7Y)"><path d=" M 301.848 455.466 L 241.359 280.725 L 250 275.324 L 311.57 453.543 L 301.848 455.466 Z " fill="rgb(235,235,235)"/></g><path d=" M 44.963 38.392 L 159.214 49.398 C 166.461 50.097 174.298 56.243 176.704 63.115 L 314.022 455.448 C 315.224 458.885 313.245 461.673 309.604 461.673 L 197.695 461.673 C 190.414 461.673 182.502 456.111 180.038 449.259 L 36.295 49.541 C 33.832 42.689 37.715 37.693 44.963 38.392 Z " fill="rgb(93,135,191)"/></g></svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/vweb/vweb_assets/favicon.ico
Normal file
BIN
examples/vweb/vweb_assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
12
examples/vweb/vweb_assets/index.html
Normal file
12
examples/vweb/vweb_assets/index.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<html>
|
||||||
|
<header>
|
||||||
|
<title>@title</title>
|
||||||
|
@css
|
||||||
|
</header>
|
||||||
|
<body>
|
||||||
|
<h1>@title</h1>
|
||||||
|
<h2>@subtitle</h2>
|
||||||
|
<p>@message</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
53
examples/vweb/vweb_assets/main.v
Normal file
53
examples/vweb/vweb_assets/main.v
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import (
|
||||||
|
vweb
|
||||||
|
vweb.assets
|
||||||
|
time
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
port = 8081
|
||||||
|
)
|
||||||
|
|
||||||
|
pub struct App {
|
||||||
|
mut:
|
||||||
|
vweb vweb.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
vweb.run<App>(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (app mut App) init() {
|
||||||
|
// Arbitary mime type.
|
||||||
|
app.vweb.serve_static('/favicon.ico', 'favicon.ico', 'img/x-icon')
|
||||||
|
// Automatically make available known static mime types found in given directory.
|
||||||
|
app.vweb.handle_static('assets')
|
||||||
|
// This would make available all known static mime types from current
|
||||||
|
// directory and below.
|
||||||
|
//app.vweb.handle_static('.')
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (app mut App) reset() {}
|
||||||
|
|
||||||
|
fn (app mut App) index() {
|
||||||
|
// We can dynamically specify which assets are to be used in template.
|
||||||
|
mut am := assets.new_manager()
|
||||||
|
am.add_css('assets/index.css')
|
||||||
|
|
||||||
|
css := am.include_css(false)
|
||||||
|
title := 'VWeb Assets Example'
|
||||||
|
subtitle := 'VWeb can serve static assets too!'
|
||||||
|
message := 'It also has an Assets Manager that allows dynamically specifying which CSS and JS files to be used.'
|
||||||
|
|
||||||
|
$vweb.html()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (app mut App) text() {
|
||||||
|
app.vweb.text('Hello, world from vweb!')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (app mut App) time() {
|
||||||
|
app.vweb.text(time.now().format())
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
net.http
|
net.http
|
||||||
net.urllib
|
net.urllib
|
||||||
strings
|
strings
|
||||||
|
filepath
|
||||||
)
|
)
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
@ -250,8 +251,8 @@ fn handle_conn<T>(conn net.Socket, app mut T) {
|
|||||||
req: req
|
req: req
|
||||||
conn: conn
|
conn: conn
|
||||||
form: map[string]string
|
form: map[string]string
|
||||||
static_files: map[string]string
|
static_files: app.vweb.static_files
|
||||||
static_mime_types: map[string]string
|
static_mime_types: app.vweb.static_mime_types
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
if req.method in methods_with_form {
|
if req.method in methods_with_form {
|
||||||
@ -269,10 +270,17 @@ fn handle_conn<T>(conn net.Socket, app mut T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Serve a static file if it's one
|
// Serve a static file if it's one
|
||||||
// if app.vweb.handle_static() {
|
static_file := app.vweb.static_files[app.vweb.req.url]
|
||||||
// conn.close()
|
mime_type := app.vweb.static_mime_types[app.vweb.req.url]
|
||||||
// continue
|
|
||||||
// }
|
if static_file != '' && mime_type != '' {
|
||||||
|
data := os.read_file(static_file) or {
|
||||||
|
conn.send_string(HTTP_404) or {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.vweb.send_response_to_client(mime_type, data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Call the right action
|
// Call the right action
|
||||||
$if debug {
|
$if debug {
|
||||||
@ -316,45 +324,40 @@ fn (ctx mut Context) parse_form(s string) {
|
|||||||
|
|
||||||
fn (ctx mut Context) scan_static_directory(directory_path, mount_path string) {
|
fn (ctx mut Context) scan_static_directory(directory_path, mount_path string) {
|
||||||
files := os.ls(directory_path) or { panic(err) }
|
files := os.ls(directory_path) or { panic(err) }
|
||||||
|
|
||||||
if files.len > 0 {
|
if files.len > 0 {
|
||||||
for file in files {
|
for file in files {
|
||||||
mut ext := ''
|
|
||||||
mut i := file.len
|
|
||||||
mut flag := true
|
|
||||||
for i > 0 {
|
|
||||||
i--
|
|
||||||
if flag {
|
|
||||||
ext = file[i..i + 1] + ext
|
|
||||||
}
|
|
||||||
if file[i..i + 1] == '.' {
|
|
||||||
flag = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: os.is_dir is broken now so we expect that file is dir it has no extension
|
|
||||||
// if flag {
|
|
||||||
if os.is_dir(file) {
|
if os.is_dir(file) {
|
||||||
ctx.scan_static_directory(directory_path + '/' + file, mount_path + '/' + file)
|
ctx.scan_static_directory(directory_path + '/' + file, mount_path + '/' + file)
|
||||||
} else {
|
} else if file.contains('.') && ! file.starts_with('.') && ! file.ends_with('.') {
|
||||||
ctx.static_files[mount_path + '/' + file] = directory_path + '/' + file
|
ext := filepath.ext(file)
|
||||||
ctx.static_mime_types[mount_path + '/' + file] = mime_types[ext]
|
|
||||||
|
// Rudimentary guard against adding files not in mime_types.
|
||||||
|
// Use serve_static directly to add non-standard mime types.
|
||||||
|
if ext in mime_types {
|
||||||
|
ctx.serve_static(mount_path + '/' + file, directory_path + '/' + file, mime_types[ext])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (ctx mut Context) handle_static(directory_path string) bool {
|
pub fn (ctx mut Context) handle_static(directory_path string) bool {
|
||||||
if ctx.done { return false }
|
if ctx.done || ! os.exists(directory_path) {
|
||||||
ctx.scan_static_directory(directory_path, '')
|
|
||||||
|
|
||||||
static_file := ctx.static_files[ctx.req.url]
|
|
||||||
mime_type := ctx.static_mime_types[ctx.req.url]
|
|
||||||
|
|
||||||
if static_file != '' {
|
|
||||||
data := os.read_file(static_file) or { return false }
|
|
||||||
return ctx.send_response_to_client(mime_type, data)
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
dir_path := directory_path.trim_space()
|
||||||
|
mut mount_path := ''
|
||||||
|
|
||||||
|
if dir_path != '.' && os.is_dir(dir_path) {
|
||||||
|
mount_path = '/' + dir_path
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.scan_static_directory(directory_path, mount_path)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (ctx mut Context) serve_static(url, file_path, mime_type string) {
|
pub fn (ctx mut Context) serve_static(url, file_path, mime_type string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user