refactor: Migrate from vweb to veb web framework

- Update all references from `vweb` to `veb`
- Add `veb.StaticHandler` to `Playground` struct
- Ensure error propagation for static file serving calls
- Apply consistent indentation across various module definitions
- Adjust documentation and comments for `veb` framework
This commit is contained in:
Mahmoud-Emad
2025-09-01 13:00:17 +03:00
parent dde5f2f7e6
commit 46a3bcb840
8 changed files with 163 additions and 156 deletions

View File

@@ -305,9 +305,7 @@ fn (mut l TcpListener) accept() !&TcpConn
fn (mut l TcpListener) accept_only() !&TcpConn fn (mut l TcpListener) accept_only() !&TcpConn
accept_only accepts a tcp connection from an external source to the listener `l`. Unlike `accept`, `accept_only` *will not call* `.set_sock()!` on the result, and is thus faster. accept_only accepts a tcp connection from an external source to the listener `l`. Unlike `accept`, `accept_only` *will not call* `.set_sock()!` on the result, and is thus faster.
Note: you *need* to call `.set_sock()!` manually, before using theconnection after calling `.accept_only()!`, but that does not have to happen in the same thread that called `.accept_only()!`. The intention of this API, is to have a more efficient way to accept connections, that are later processed by a thread pool, while the main thread remains active, so that it can accept other connections. See also vlib/veb/veb.v .
Note: you *need* to call `.set_sock()!` manually, before using theconnection after calling `.accept_only()!`, but that does not have to happen in the same thread that called `.accept_only()!`. The intention of this API, is to have a more efficient way to accept connections, that are later processed by a thread pool, while the main thread remains active, so that it can accept other connections. See also vlib/vweb/vweb.v .
If you do not need that, just call `.accept()!` instead, which will call `.set_sock()!` for you. If you do not need that, just call `.accept()!` instead, which will call `.set_sock()!` for you.
fn (c &TcpListener) accept_deadline() !time.Time fn (c &TcpListener) accept_deadline() !time.Time

View File

@@ -1,6 +1,6 @@
# **WebDAV Server in V** # **WebDAV Server in V**
This project implements a WebDAV server using the `vweb` framework and modules from `crystallib`. The server supports essential WebDAV file operations such as reading, writing, copying, moving, and deleting files and directories. It also includes **authentication** and **request logging** for better control and debugging. This project implements a WebDAV server using the `veb` framework and modules from `crystallib`. The server supports essential WebDAV file operations such as reading, writing, copying, moving, and deleting files and directories. It also includes **authentication** and **request logging** for better control and debugging.
--- ---
@@ -47,6 +47,7 @@ sudo mount -t davfs <server_url> <mount_point>
``` ```
For example: For example:
```bash ```bash
sudo mount -t davfs http://localhost:8080 /mnt/webdav sudo mount -t davfs http://localhost:8080 /mnt/webdav
``` ```
@@ -82,6 +83,7 @@ Authorization: Basic <base64-encoded-credentials>
**Example**: **Example**:
For the credentials `admin:admin`, the header would look like this: For the credentials `admin:admin`, the header would look like this:
```http ```http
Authorization: Basic YWRtaW46YWRtaW4= Authorization: Basic YWRtaW46YWRtaW4=
``` ```
@@ -103,25 +105,32 @@ You can configure the WebDAV server using the following parameters when calling
## **Example Workflow** ## **Example Workflow**
1. Start the server: 1. Start the server:
```bash ```bash
v run webdav_server.v v run webdav_server.v
``` ```
2. Mount the server using `davfs`: 2. Mount the server using `davfs`:
```bash ```bash
sudo mount -t davfs http://localhost:8080 /mnt/webdav sudo mount -t davfs http://localhost:8080 /mnt/webdav
``` ```
3. Perform operations: 3. Perform operations:
- Create a new file: - Create a new file:
```bash ```bash
echo "Hello WebDAV!" > /mnt/webdav/hello.txt echo "Hello WebDAV!" > /mnt/webdav/hello.txt
``` ```
- List files: - List files:
```bash ```bash
ls /mnt/webdav ls /mnt/webdav
``` ```
- Delete a file: - Delete a file:
```bash ```bash
rm /mnt/webdav/hello.txt rm /mnt/webdav/hello.txt
``` ```
@@ -150,7 +159,6 @@ You can configure the WebDAV server using the following parameters when calling
- Integration with persistent databases for user credentials. - Integration with persistent databases for user credentials.
- TLS/SSL support for secure connections. - TLS/SSL support for secure connections.
# WebDAV Property Model # WebDAV Property Model
This file implements the WebDAV property model as defined in [RFC 4918](https://tools.ietf.org/html/rfc4918). It provides a set of property types that represent various WebDAV properties used in PROPFIND and PROPPATCH operations. This file implements the WebDAV property model as defined in [RFC 4918](https://tools.ietf.org/html/rfc4918). It provides a set of property types that represent various WebDAV properties used in PROPFIND and PROPPATCH operations.
@@ -173,6 +181,7 @@ pub interface Property {
``` ```
All WebDAV properties must implement: All WebDAV properties must implement:
- `xml()`: Returns the full XML representation of the property with its value - `xml()`: Returns the full XML representation of the property with its value
- `xml_name()`: Returns just the XML tag name of the property (used in property requests) - `xml_name()`: Returns just the XML tag name of the property (used in property requests)
@@ -200,7 +209,6 @@ The file implements the following WebDAV property types:
These property types are used when responding to WebDAV PROPFIND requests to describe resources in the WebDAV server. These property types are used when responding to WebDAV PROPFIND requests to describe resources in the WebDAV server.
# WebDAV Locker # WebDAV Locker
This file implements a locking mechanism for resources in a WebDAV context. It provides functionality to manage locks on resources, ensuring that they are not modified by multiple clients simultaneously. This file implements a locking mechanism for resources in a WebDAV context. It provides functionality to manage locks on resources, ensuring that they are not modified by multiple clients simultaneously.

View File

@@ -4,12 +4,13 @@ import x.json2 as json
// import freeflowuniverse.herolib.develop.gittools // import freeflowuniverse.herolib.develop.gittools
import freeflowuniverse.herolib.core.pathlib import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.core.texttools import freeflowuniverse.herolib.core.texttools
import vweb import veb
import os import os
pub struct Playground { pub struct Playground {
vweb.Context veb.Context
build pathlib.Path @[vweb_global] veb.StaticHandler
build pathlib.Path @[veb_global]
} }
@[params] @[params]
@@ -50,11 +51,11 @@ pub fn new_playground(config PlaygroundConfig) !&Playground {
build: build_dir build: build_dir
} }
pg.serve_examples(config.specs) or { return error('failed to serve examples:\n${err}') } pg.serve_examples(config.specs) or { return error('failed to serve examples:\n${err}') }
pg.mount_static_folder_at('${build_dir.path}/static', '/static') pg.mount_static_folder_at('${build_dir.path}/static', '/static')!
mut env_file := pathlib.get_file(path: '${build_dir.path}/env.js')! mut env_file := pathlib.get_file(path: '${build_dir.path}/env.js')!
env_file.write(encode_env(config.specs)!)! env_file.write(encode_env(config.specs)!)!
pg.serve_static('/env.js', env_file.path) pg.serve_static('/env.js', env_file.path)!
return &pg return &pg
} }
@@ -86,11 +87,11 @@ fn (mut pg Playground) serve_examples(specs_ []pathlib.Path) ! {
return error('Failed to decode OpenRPC Spec ${spec}:\n${err}') return error('Failed to decode OpenRPC Spec ${spec}:\n${err}')
} }
name := texttools.name_fix(o.info.title) name := texttools.name_fix(o.info.title)
pg.serve_static('/specs/${name}.json', spec.path) pg.serve_static('/specs/${name}.json', spec.path)!
} }
} }
pub fn (mut pg Playground) index() vweb.Result { pub fn (mut pg Playground) index() veb.Result {
mut index := pathlib.get_file(path: '${pg.build.path}/index.html') or { panic(err) } mut index := pathlib.get_file(path: '${pg.build.path}/index.html') or { panic(err) }
return pg.html(index.read() or { panic(err) }) return pg.html(index.read() or { panic(err) })
} }

View File

@@ -4,7 +4,7 @@ import net.http
import time import time
import json import json
// session controller that be be added to vweb projects // session controller that be be added to veb projects
pub struct EmailClient { pub struct EmailClient {
url string @[required] url string @[required]
} }

View File

@@ -1,6 +1,6 @@
module authentication module authentication
import vweb import veb
import time import time
import json import json
import log import log
@@ -8,13 +8,13 @@ import freeflowuniverse.herolib.ui.console
const agent = 'Email Authentication Controller' const agent = 'Email Authentication Controller'
// email authentication controller that be be added to vweb projects // email authentication controller that be be added to veb projects
@[heap] @[heap]
pub struct Controller { pub struct Controller {
vweb.Context veb.Context
callback string @[vweb_global] callback string @[veb_global]
mut: mut:
authenticator Authenticator @[vweb_global] authenticator Authenticator @[veb_global]
} }
@[params] @[params]
@@ -32,7 +32,7 @@ pub fn new_controller(params ControllerParams) Controller {
// route responsible for verifying email, email form should be posted here // route responsible for verifying email, email form should be posted here
@[POST] @[POST]
pub fn (mut app Controller) send_verification_mail() !vweb.Result { pub fn (mut app Controller) send_verification_mail() !veb.Result {
config := json.decode(SendMailConfig, app.req.data)! config := json.decode(SendMailConfig, app.req.data)!
app.authenticator.send_verification_mail(config) or { panic(err) } app.authenticator.send_verification_mail(config) or { panic(err) }
return app.ok('') return app.ok('')
@@ -40,7 +40,7 @@ pub fn (mut app Controller) send_verification_mail() !vweb.Result {
// route responsible for verifying email, email form should be posted here // route responsible for verifying email, email form should be posted here
@[POST] @[POST]
pub fn (mut app Controller) is_verified() vweb.Result { pub fn (mut app Controller) is_verified() veb.Result {
address := app.req.data address := app.req.data
// checks if email verified every 2 seconds // checks if email verified every 2 seconds
for { for {
@@ -55,7 +55,7 @@ pub fn (mut app Controller) is_verified() vweb.Result {
// route responsible for verifying email, email form should be posted here // route responsible for verifying email, email form should be posted here
@[POST] @[POST]
pub fn (mut app Controller) email_authentication() vweb.Result { pub fn (mut app Controller) email_authentication() veb.Result {
config_ := json.decode(SendMailConfig, app.req.data) or { config_ := json.decode(SendMailConfig, app.req.data) or {
app.set_status(422, 'Request payload does not follow anticipated formatting.') app.set_status(422, 'Request payload does not follow anticipated formatting.')
return app.text('Request payload does not follow anticipated formatting.') return app.text('Request payload does not follow anticipated formatting.')
@@ -84,7 +84,7 @@ pub fn (mut app Controller) email_authentication() vweb.Result {
// route responsible for verifying email, email form should be posted here // route responsible for verifying email, email form should be posted here
@[POST] @[POST]
pub fn (mut app Controller) verify() vweb.Result { pub fn (mut app Controller) verify() veb.Result {
config_ := json.decode(SendMailConfig, app.req.data) or { config_ := json.decode(SendMailConfig, app.req.data) or {
app.set_status(422, 'Request payload does not follow anticipated formatting.') app.set_status(422, 'Request payload does not follow anticipated formatting.')
return app.text('Request payload does not follow anticipated formatting.') return app.text('Request payload does not follow anticipated formatting.')
@@ -126,7 +126,7 @@ pub:
} }
@[POST] @[POST]
pub fn (mut app Controller) authenticate() !vweb.Result { pub fn (mut app Controller) authenticate() !veb.Result {
attempt := json.decode(AuthAttempt, app.req.data)! attempt := json.decode(AuthAttempt, app.req.data)!
app.authenticator.authenticate(attempt.address, attempt.cypher) or { app.authenticator.authenticate(attempt.address, attempt.cypher) or {
app.set_status(401, err.msg()) app.set_status(401, err.msg())
@@ -136,7 +136,7 @@ pub fn (mut app Controller) authenticate() !vweb.Result {
} }
@['/authentication_link/:address/:cypher'] @['/authentication_link/:address/:cypher']
pub fn (mut app Controller) authentication_link(address string, cypher string) !vweb.Result { pub fn (mut app Controller) authentication_link(address string, cypher string) !veb.Result {
app.authenticator.authenticate(address, cypher) or { app.authenticator.authenticate(address, cypher) or {
app.set_status(401, err.msg()) app.set_status(401, err.msg())
return app.text('Failed to authenticate') return app.text('Failed to authenticate')

View File

@@ -10,7 +10,7 @@ import crypto.rand
import os import os
// JWT code in this page is from // JWT code in this page is from
// https://github.com/vlang/v/blob/master/examples/vweb_orm_jwt/src/auth_services.v // https://github.com/vlang/v/blob/master/examples/veb_orm_jwt/src/auth_services.v
// credit to https://github.com/enghitalo // credit to https://github.com/enghitalo
pub struct JsonWebToken { pub struct JsonWebToken {

View File

@@ -2,7 +2,7 @@ module @{name}
import os import os
import cli { Command } import cli { Command }
import vweb import veb
import freeflowuniverse.herolib.schemas.openrpc import freeflowuniverse.herolib.schemas.openrpc
import freeflowuniverse.herolib.core.pathlib import freeflowuniverse.herolib.core.pathlib
@@ -54,7 +54,7 @@ fn playground(cmd Command) ! {
dest: pathlib.get_dir(path: playground_path)! dest: pathlib.get_dir(path: playground_path)!
specs: [pathlib.get_file(path:openrpc_path)!] specs: [pathlib.get_file(path:openrpc_path)!]
)! )!
vweb.run(pg, 8080) veb.run(pg, 8080)
} }

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env -S v -n -cg -w -enable-globals run #!/usr/bin/env -S v -n -cg -w -enable-globals run
import freeflowuniverse.herolib.baobab.stages.accountant import freeflowuniverse.herolib.baobab.stages.accountant
import vweb import veb
import freeflowuniverse.herolib.schemas.openrpc import freeflowuniverse.herolib.schemas.openrpc
import os import os
import freeflowuniverse.herolib.core.pathlib import freeflowuniverse.herolib.core.pathlib
@@ -13,4 +13,4 @@ pg := openrpc.new_playground(
dest: pathlib.get_dir(path: playground_path)! dest: pathlib.get_dir(path: playground_path)!
specs: [pathlib.get_file(path:openrpc_path)!] specs: [pathlib.get_file(path:openrpc_path)!]
)! )!
vweb.run(pg, 8080) veb.run(pg, 8080)