fastkiss NIM的FastCGI网络框架
配x警告:这个框架仍处于重大发展。配x
Fast & k eep i t s Mall和S Imple是NIM Web应用程序的FastCGI主机/服务器框架。它是针对NGINX开发的,但应与任何实现FCGI规格的Web服务器一起使用。这项工作基于NIM的FastCGI库。
FastCGI服务器允许您轻松地将fastkiss Web应用程序集成到标准的Web服务器环境中,利用为此目的开发的Web服务器提供的现有功能。这使您可以使用所有最先进的功能,例如高级协议支持(HTTPS,HTTP/2.0),HTTP保持稳定,高性能静态文件传递,HTTP压缩或URL REDIRECT/REWRITE服务,而无需增加在应用程序代码中构建任何内容的间接费用和复杂性。
fastkiss
from fastkiss /utils import decodeData
import regex
from strformat import `&`
proc main() =
let app = newApp()
app.config.port = 9000 # optional if default port
app.get(\”/\”, proc (req: Request) {.async.} =
respond \”Hello World!\”
)
app.get(r\”/test/(\\w+)\”.re, proc (req: Request) {.async.} =
respond &\”Hello {req.matches.groupCaptures(0)[0]}\”
)
# http://ex*ampl*e*:8080/test/abc-012/def-345/test/xpto
app.get(r\”/test/(?:([a-z\\d]+-[a-z\\d]+)/)+test/(\\w+)\”.re, proc (req: Request) {.async.} =
respond &\”Hello Multi Capture {$req.matches.groupCaptures(0)} and {$req.matches.groupCaptures(1)}\”
)
# http://exampl*e:8**080/myquery?a=1&b=2&c=3
app.get(\”/myquery\”, proc (req: Request) {.async.} =
resp \”My Query:\\n\”
for k, v in decodeData(req.url.query):
resp &\”{k} = {v}\\n\”
)
app.match([\”GET\”, \”POST\”], \”/method\”, proc (req: Request) {.async.} =
respond &\”Hello Method {$req.reqMethod}\”
)
app.get(\”/static\”, proc (req: Request) {.async.} =
sendFile \”./test.txt\”
)
app.run()
main()\”>
import fastkiss from fastkiss / utils import decodeData import regex from strformat import `&` proc main() = let app = newApp() app.config.port = 9000 # optional if default port app.get( \" / \" , proc (req: Request) {.async.} = respond \" Hello World! \" ) app.get( r \" /test/(\\w+) \" .re, proc (req: Request) {.async.} = respond & \" Hello { req.matches.groupCaptures( 0 )[ 0 ] } \" ) # http://ex*ampl*e*:8080/test/abc-012/def-345/test/xpto app.get( r \" /test/(?:([a-z\\d]+-[a-z\\d]+)/)+test/(\\w+) \" .re, proc (req: Request) {.async.} = respond & \" Hello Multi Capture { $ req.matches.groupCaptures( 0 ) } and { $ req.matches.groupCaptures( 1 ) } \" ) # http://exampl*e:8**080/myquery?a=1&b=2&c=3 app.get( \" /myquery \" , proc (req: Request) {.async.} = resp \" My Query: \\n \" for k, v in decodeData(req.url.query): resp & \" { k } = { v } \\n \" ) app.match([ \" GET \" , \" POST \" ], \" /method \" , proc (req: Request) {.async.} = respond & \" Hello Method { $ req.reqMethod } \" ) app.get( \" /static \" , proc (req: Request) {.async.} = sendFile \" ./test.txt \" ) app.run() main()
如果您使用fastkiss生成具有显着尺寸的动态内容,例如大型二进制图像或大型基于文本的数据集,则需要考虑使用“ RESS ”功能而不是“响应”以最大程度地减少内存足迹并保持可伸缩性。
使用“ RESP ”功能使fastkiss无需构建整个结构或内存资源,将大量数据返回给客户端。请参见示例。您可以像php“ echo”功能一样使用“ RESP ”函数。您甚至可以以与PHP相同的方式包含具有代码的文件。请参阅此示例。
fastkiss
import tables
from strformat import `&`
proc showPage(req: Request) {.async.} =
let t = {1: \”one\”, 2: \”two\”, 3: \”three\”}.toTable
\”\”\”<!DOCTYPE html>
<html lang=\”en\”>
<head>
<meta charset=\”utf-8\”>
<meta name=\”viewport\” content=\”width=device-width\”>
<title>Test</title>
</head>
<body>
<table>\”\”\”.resp
for k, v in pairs(t):
resp &\”\”\”<tr>
<td><strong>{k}</strong></td>
<td>{v}</td>
</tr>
\”\”\”
\”\”\”</table>
</body>
</html>\”\”\”.resp
proc main() =
let app = newApp()
app.get(\”/\”, showPage)
app.run()
main()\”>
import fastkiss import tables from strformat import `&` proc showPage(req: Request) {.async.} = let t = { 1 : \" one \" , 2 : \" two \" , 3 : \" three \" }.toTable \"\"\" <!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"utf-8\"> <meta name=\"viewport\" content=\"width=device-width\"> <title>Test</title> </head> <body> <table> \"\"\" .resp for k, v in pairs(t): resp & \"\"\" <tr> <td><strong> { k } </strong></td> <td> { v } </td> </tr> \"\"\" \"\"\" </table> </body> </html> \"\"\" .resp proc main() = let app = newApp() app.get( \" / \" , showPage) app.run() main()
这是一个应用程序的完整示例,可以发送带有附件的电子邮件。
nginx fastcgi配置文件示例
server {
listen 8080;
server_name example;
# add example to hosts file
# nano -w /etc/hosts
#
# 127.0.0.1 example
#
location / {
# Comment this line if you if you don\'t need http cookies
fastcgi_param HTTP_COOKIE $http_cookie;
# Comment this line if you if you don\'t need Basic Autentication
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
# Uses REMOTE_ADDR value whenever it needs to deal with visitor IP address.
fastcgi_param REMOTE_ADDR $http_x_real_ip;
client_max_body_size 1000M;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
}
apache2 fastcgi配置文件示例
Listen 127.0.0.1:8080
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule rewrite_module modules/mod_rewrite.so
# Need a server with SSL support
# LoadModule http2_module modules/mod_http2.so
<IfModule mod_proxy_fcgi.c>
<VirtualHost *:8080>
ServerName example
ServerAlias anotherexample
ServerAdmin admin@example.tld
ErrorLog /var/log/httpd/example_error.log
CustomLog /var/log/httpd/example_requests.log combined
ProxyPass \"/\" \"fcgi://localhost:9000/\"
# https://httpd.*apa**che.org/docs/2.4/custom-error.html
ErrorDocument 503 \"Service Temporary Unavailable\"
# Need a server with SSL support
# Protocols h2 http/1.1
# Comment this two lines below if you if you don\'t need Basic Autentication
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</VirtualHost>
</IfModule>
测试
$ nimble install https://**github.c*om/mrhdias/fastkiss
$ nano -w example.nim
$ nim c -r example.nim
$ sudo systemctl start nginx / httpd
$ wget -qO- http://*exa*mp*le:8080/test
Hello World!!⏎
编译发布版本使用:
$ nim c -d:release example.nim
$ ./example
配置选项
config.port = 9000 # Default Port config.address = \" \" config.reuseAddr = true # Default value config.reusePort = false # Default value # Default temporary directory of the current user to save temporary files config.tmpUploadDir = getTempDir() # The value true will cause the temporary files left after request processing to be removed. config.autoCleanTmpUploadDir = true # To serve static files such as images, CSS files, and JavaScript files config.staticDir = \" \" # Sets the maximum allowed size of the client request body config.maxBody = 8388608 # Default 8MB = 8388608 Bytes
可用的路由器方法
响应任何HTTP动词的路线
get * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} ) post * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} ) put * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} ) patch * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} ) delete * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} ) options * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} )
响应多个HTTP动词的路线
match * ( server: AsyncFCGIServer, methods: openArray [ string ], pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} )
响应所有HTTP动词的路线
any * ( server: AsyncFCGIServer, pattern: string | Regex, callback: proc (request: Request): Future[ void ] {.closure, gcsafe.} )
