mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -04:00
121 lines
2.7 KiB
V
121 lines
2.7 KiB
V
import net.mbedtls
|
|
import os
|
|
import io
|
|
import net.http
|
|
|
|
// first run cert/makecerts.sh to generate the certificates for this server
|
|
|
|
// start the server with:
|
|
// v run server_sni_advanced.v
|
|
|
|
// test using curl:
|
|
|
|
// connection using the 1x.dk certificate
|
|
// curl -vik --resolve 1x.dk:8443:0.0.0.0 https://1x.dk:8443/
|
|
|
|
// connection using the 2x.dk certificate
|
|
// curl -vik --resolve 2x.dk:8443:0.0.0.0 https://2x.dk:8443/
|
|
|
|
// default certificate (no sni callback)
|
|
// curl -vik https://0.0.0.0:8443/
|
|
|
|
@[heap]
|
|
struct CertManager {
|
|
mut:
|
|
// cache for the certificates
|
|
certs map[string]&mbedtls.SSLCerts
|
|
}
|
|
|
|
fn (mut cm CertManager) get_cert(mut l mbedtls.SSLListener, host string) !&mbedtls.SSLCerts {
|
|
println('${host}')
|
|
|
|
if c := cm.certs[host] {
|
|
println('read certs for ${host} already ready')
|
|
return c
|
|
} else {
|
|
cert := os.read_file('cert/${host}.crt') or {
|
|
return error('Failed to read certificate ${host}: ${err}')
|
|
}
|
|
key := os.read_file('cert/${host}.key') or {
|
|
return error('Failed to read key ${host}: ${err}')
|
|
}
|
|
println('read certs for ${host}')
|
|
|
|
if mut c := mbedtls.new_sslcerts_in_memory('', cert, key) {
|
|
cm.certs[host] = c
|
|
return c
|
|
} else {
|
|
return error('mbedtls.new_sslcerts_in_memory err: ${err}')
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// Load the default certificates
|
|
cert := os.read_file('cert/0x.dk.crt') or {
|
|
eprintln('Failed to read certificate: ${err}')
|
|
return
|
|
}
|
|
key := os.read_file('cert/0x.dk.key') or {
|
|
eprintln('Failed to read key: ${err}')
|
|
return
|
|
}
|
|
|
|
cm := CertManager{}
|
|
|
|
// Create the SSL configuration
|
|
mut config := mbedtls.SSLConnectConfig{
|
|
cert: cert
|
|
cert_key: key
|
|
in_memory_verification: true // !importent
|
|
get_certificate: cm.get_cert
|
|
}
|
|
|
|
mut server := mbedtls.new_ssl_listener('0.0.0.0:8443', config) or {
|
|
println('new_ssl_listener : ${err.msg()} : ${err.code()}')
|
|
return
|
|
}
|
|
println('Listening on https://0.0.0.0:8443')
|
|
|
|
// Accept and handle connections
|
|
for {
|
|
mut client := server.accept() or {
|
|
println('accept : ${err.msg()} : ${err.code()}')
|
|
continue
|
|
}
|
|
go handle_connection(mut client)
|
|
}
|
|
|
|
server.shutdown() or {
|
|
println('server.shutdown : ${err.msg()} : ${err.code()}')
|
|
return
|
|
}
|
|
}
|
|
|
|
fn handle_connection(mut ssl_conn mbedtls.SSLConn) {
|
|
mut reader := io.new_buffered_reader(reader: ssl_conn)
|
|
|
|
request := http.parse_request(mut reader) or {
|
|
println('parse_request failed : ${err}')
|
|
return
|
|
}
|
|
|
|
println('Received request: ${request.url}')
|
|
|
|
// Respond to the request
|
|
body := 'Hello, HTTPS!'
|
|
res := http.new_response(http.ResponseConfig{
|
|
body: body
|
|
})
|
|
|
|
ssl_conn.write(res.bytes()) or {
|
|
eprintln('Failed to write response: ${err}')
|
|
return
|
|
}
|
|
|
|
ssl_conn.shutdown() or {
|
|
eprintln('Failed to shutdown connection: ${err}')
|
|
return
|
|
}
|
|
}
|