Golang開發的全功能單文件Web服務器

最新HTTP/2標準已經發布,是基於谷歌QUIC的技術升級而成。雖然標準已經發布,但是目前還鮮有應用支持,那麼有沒有方法進行技術嚐鮮呢?答案是肯定的。本文蟲蟲給大家介紹一個Golang Web服務器應用Algernon,作為一個單文件的Golang應用內置了HTTP/2,Lua,Markdown,Pongo2,HyperApp,Amber,Sass(SCSS),GCSS,JSX,BoltDB的功能,支持 Redis,PostgreSQL,MariaDB / MySQL數據庫。支持限速,插件,用戶和權限等各種功能。所有這些都包含在一個自包含可執行文件中,麻雀雖小五臟俱全。

Golang開發的全功能單文件Web服務器

技術架構

使用Golang開發,後端數據庫可以使用Bolt(內置),MySQL,PostgreSQL或Redis(推薦)。對各種功能支持總共使用了下面的類庫:

permissions2用於處理用戶和權限;gopher-lua用於解釋和運行Lua;http2用於服務HTTP/2,QUIC用於服務QUIC;blackfriday用於Markdown渲染;amber用於Amber模板;Pongo2用於Pongo2模板;Sass(SCSS)和GCSS用於CSS預處理;logrus用於日誌記錄;goja-babel用於從JSX轉換為JavaScript;tollbooth用於速率限制;pie用於插件支持;graceful用於優雅關閉。

設計思想

該項目源於用Markdown,Pongo2,Amber,HTML或JSX(+ React)等編寫應用,並用CSS樣式支持和設計。數據使用Lua腳本與Redis,BoltDB,PostgreSQL或MariaDB/MySQL鏈接操作。

Amber和GCSS是時下靜態網站的最佳組合方式,與HTML和CSS相比,它允許更清晰的架構,減少內容重複,也很容易使用Lua提供數據,支持MVC架構對模型(M),控制器(C)和視圖(V)的更好的分割。

Pongo2,Sass和Lua也是很好的一個選擇,而且Pongo2比Amber更靈活。

Bolt是一個純粹的key/value存儲,使用Golang編寫。Bolt無需預先安裝設置數據庫,內置在Algernon中使用。也支持廣泛使用的數據庫,比如MariaDB/MySQL和PostgreSQL。

Algernon以下文件進行特殊渲染和解析以下文件(後綴),按優先順序排列:

index.lua是Lua代碼,動態lua腳本處理。

index.html HTML默認頁面。

index.md 渲染為HTML下的Markdown代碼。

index.txt 純文本文件。

index.pongo2,index.po2或index.tmpl渲染為HTML的Pongo2代碼。

index.amber渲染為HTML的Amber代碼。

index.hyper.js或index.hyper.jsx渲染為HTML的JSX + HyperApp代碼

data.lua是Lua代碼,其中函數和變量可用於同一目錄中的Pongo2、Amber和Markdown頁面。

如果將單個Lua腳本作為命令行參數提供,用於獨立服務器。它可用於設置處理程序或為特定URL前綴提供文件和目錄。

style.gcss是GCSS代碼,支持對同目錄下的Pongo2,Amber和Markdown頁面的樣式。

總之,Algernon支持對以下文件擴展名的處理​​:

Markdown:.md(渲染為HTML)

Pongo2:.po2,.pongo2或.tpl(渲染為任何文本,通常為HTML)

琥珀色:.amber(渲染為HTML)

Sass:.scss(渲染為CSS)

GCSS:.gcss(渲染為CSS)

JSX:.jsx(渲染為JavaScript / ECMAScript)

Lua:.lua(提供自己的輸出和內容類型的腳本)

HyperApp:.hyper.js或.hyper.jsx(渲染為HTML)

根據擴展名為其他文件指定mimetype。

沒有索引文件的目錄顯示為目錄列表。

儘可能使用UTF-8。

可以通過命令行或lua腳本配置服務器,但是配置是非必須的,默認無需配置既可以使用。

技術特點

支持HTTP,HTTP/2,默認啟動HTTPS(HTTP/2需要瀏覽器支持)。

支持Lua動態程序,可以使用Lua腳本處理程序。

Algernon可執行文件為本機靜態編譯編,速度相當快。

適用於Linux,OS X和64位Windows。

Lua解釋器被編譯為可執行文件。

支持熱部署自動刷新功能,實時編輯/實時預覽。

自包含的Algernon應用程序可以壓縮到存檔(以.zip或.alg結尾),支持子啟動時加載。

內置支持Markdown,Pongo2,Amber,Sass(SCSS),GCSS和JSX。

默認情況下,使用Redis作為數據庫後端,如果沒有可用的Redis服務器,Algernon將使用內置的Bolt數據庫。

可以對Markdown渲染的HTML頁面指定以MultiMarkdown語法的標題:

title: Title內容。

後臺無需要文件轉換器(如SASS)即可進行文件轉化。

如果設置了autorefresh,源文件時自動刷新頁面。

交互式REPL。

如果Markdown文件名作為第一個參數,則它將在端口3000上提供預覽,無需任何數據庫。方便在本地查看README.md文件。

完全多線程。將使用所有可用的CPU。

支持通過tollbooth進行速率限制。

Lua REPL提供了幫助命令,可快速瀏覽可用的Lua功能。

可以加載用任何語言編寫的插件。插件必須提供Lua.Code和Lua.Help函數,並通過stderr + stdin來交互JSON-RPC。

內置線程安全文件緩存,具有多種可用緩存模式(例如,僅用於緩存圖像)。

可以讀取並保存到JSON文檔。支持簡單的JSON路徑表達式(如簡單版本的XPath,但對於JSON)。

支持緩存壓縮,可以將緩存中存儲的文件直接從緩存發送到客戶端,無需解壓縮。

對大於4096B的文件發送到客戶端的文件默認使用gzip壓縮。

使用PostgreSQL作為後端數據庫時候,默認使用HSTORE鍵/值類型(PostgreSQL 9.1或更高版本)。

沒有外部依賴,純Golang程序。

需要Go 1.12或更高版本。另外用於QUIC支持的包不支持使用gccgo(GCC)構建。

安裝

OS X

蘋果OS X系統可以使用包管理器直接安裝:

brew install algernon

如果沒有安裝Homebrew包管理器,請先安裝。

Arch Linux

可以使用AUR源安裝:

pacman -S algernon

二進制包

其他系統請下載對應二進制包即可使用。

Golang開發的全功能單文件Web服務器

源碼安裝

從源碼編譯安裝,適用於任何系統。用get命令從官方主分支下載最新源碼

get -u github/xyproto/algernon

使用該方法安裝,需要先設置GOPATH, 並將$GOPATH/bin添加到執行PATH中

export GOPATH =~/go

export PATH = $PATH:$GOPATH/bin

也可以先git clone到本地然後編譯安裝

Golang 1.12版本

Golang開發的全功能單文件Web服務器

早期Golang版本

Golang開發的全功能單文件Web服務器

docker容器

Golang開發的全功能單文件Web服務器

Algernon基本使用

運行Algernon:

Golang開發的全功能單文件Web服務器

以開發者模式運行

algernon -e

該命令啟用調試模式,以內置的Bolt數據庫,以HTTP形式啟動,並對除了以下類型的其他文件啟用緩存,這些類型包括Pongo2,Amber,Lua,Sass,GCSS,Markdown和JSX。

新建一個簡單的hello lua文件index.lua:

Golang開發的全功能單文件Web服務器

瀏覽器訪問,結果如下:

Golang開發的全功能單文件Web服務器

自定義Algernon應用程序

創建應用目錄:

mkdir mypage && cd mypage

創建名為index.lua的文件,其中包含以下內容和上面一樣。

啟動:

algernon --httponly --autorefresh .

啟動增加參數autorefresh,使得文件編輯後可以熱加載實時生效。可以試著編輯下index.lua並刷新瀏覽器以查看新結果。

注意—autorefresh對Markdown,Pongo2和Amber頁面也生效,比如我新建一個chongchong.md頁面:

Golang開發的全功能單文件Web服務器

然後瀏覽器訪問:

Golang開發的全功能單文件Web服務器

HTTP/2 和HTTPS支持應用

利用openssl創建創建自簽名證書,僅用於測試:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 3000 -nodes

結果中,按照提示中按Return鍵,在Common Name時候輸入任意名稱,我們輸入的是CC,就會在本目錄生成cert.pem和key.pem兩個證書文件

啟動

algernon .

然後通過瀏覽器以https訪問:

https://localhost:3000

由於使用子簽名證書,沒有添加根域證書,需要在瀏覽器添加信息才能訪問。

Golang開發的全功能單文件Web服務器

注意https頭信息,確實是HTTP/2。

Lua支持

基本的Lua功能

//返回服務器的版本字符串。

version() -> string

//睡眠給定的秒數(可以是浮點數)。

sleep(number)

//將給定的字符串記錄為信息。採用可變數量的字符串。

log(...)

//將給定的字符串記錄為警告。採用可變數量的字符串。

warn(...)

//將給定的字符串記錄為錯誤。採用可變數量的字符串。

err(...)

//返回1970年的納秒數(Unix時間)

unixnano() -> number

//將Markdown轉換為HTML

markdown(string) -> string

//返回運行REPL或腳本的目錄。如果給出了文件名(可選),則返回腳本運行的路徑,使用路徑分隔符和給定的文件名連接。

scriptdir([string]) -> string

//返回運行服務器的目錄。如果給出了文件名(可選),則返回服務器運行的路徑,使用路徑分隔符和給定的文件名連接。

serverdir([string]) -> string

Lua插件

//在給定可執行文件路徑的情況下加載插件。成功時返回true。如果在Lua提示符上調用,將返回插件幫助文本。

Plugin(string)

//給定一個插件路徑,返回插件中Lua.Code函數返回的Lua代碼。可能會返回一個空字符串。

PluginCode(string) -> string

//獲取插件路徑,函數名稱和參數。如果函數調用失敗,則返回空字符串;如果成功,則返回結果為JSON字符串。

CallPlugin(string, string, ...) -> string

Lua代碼庫函數

這些函數可以與插件函數結合使用,用於存儲加載serverconf.lua時插件返回的Lua代碼,然後在處理請求時檢索Lua代碼。

//創建或使用代碼庫對象。 (可選)將數據結構名稱作為第一個參數。

CodeLib([string]) -> userdata

//給定命名空間和Lua代碼,將給定代碼添加到命名空間。成功時返回true。

codelib:add(string, string) -> bool

//給定命名空間和Lua代碼,將給定代碼設置為命名空間中的唯一代碼。成功時返回true。

codelib:set(string, string) -> bool

//給定命名空間,返回Lua代碼或空字符串。

codelib:get(string) -> string

//將給定命名空間中的(eval)代碼導入當前的Lua狀態。成功時返回true。

codelib:import(string) -> bool

//完全清除代碼庫。成功時返回true。

codelib:clear() -> bool

Lua文件上傳函數

//創建文件上傳對象。採用表單ID(來自POST請求)作為第一個參數。將可選的最大上載大小(以MiB為單位)作為第二個參數。

//失敗時返回nil和錯誤字符串,成功時返回userdata和空字符串。

UploadedFile(string[, number]) -> userdata, string

//返回客戶端指定的上傳文件名

uploadedfile:filename() -> string

//返回已接收數據的大小

uploadedfile:size() -> number

Lua處理請求函數

//設置頁面的Content-Type。

content(string)

//返回請求的HTTP方法(GET,POST等)。

method() -> string

//將文本輸出到瀏覽器/客戶端。採用可變數量的字符串。

print(...)

//返回請求的URL路徑。

urlpath() -> string

//返回請求中的HTTP標頭,給定鍵或空字符串。

header(string) -> string

//在給定鍵和值的情況下設置HTTP標頭。

setheader(string, string)

更多函數支持請參考官方文檔,此處略。

Markdown支持

Algernon實現對Markdown的快速瀏覽,實現在線webMarkdown查看器。-m標誌用來啟動:

algernon -m README.md在瀏覽器中查看README.md。

除了常規的Markdown語法之外,Algernon還支持在Markdown文件的頂部設置頁眉標題和語法高亮樣式,如下所示:

Golang開發的全功能單文件Web服務器

該代碼將使用highlight.js突出顯示代碼,並提供多種樣式。

replace_with_theme後面的字符串將用於替換當前主題字符串與給定字符串。這使得可以為一個主題使用一個圖像(如logo_default_theme.png)。主題可以是light,dark,redbox,bw,github,wing,material,neon,default,werc或CSS文件的路徑。或者同一目錄下的style.gcss文件自定義的樣式。

範例和截圖

官方提供了大量的範例可以供使用,可以在官方倉下載samplepack.zip安裝包,解壓到web目錄更目錄然後通過瀏覽器就可以訪問。

Golang開發的全功能單文件Web服務器

bootstrap小應用

Golang開發的全功能單文件Web服務器

hyperapp計數

Golang開發的全功能單文件Web服務器

這是在啟用調試模式時處理Lua腳本中的錯誤的方法。

three.js

Algernon Charles Swinburne的一首詩,背景中有三個旋轉的圓環。使用CSS3高斯模糊,使用three.js作為3D圖形。

Golang開發的全功能單文件Web服務器

prettify代碼美化

美化樣本的屏幕截圖,由單個Lua腳本提供。

Golang開發的全功能單文件Web服務器

todo小程序

Golang開發的全功能單文件Web服務器

使用Alact和Algernon交互使用

tiles圖片拼圖小遊戲

Golang開發的全功能單文件Web服務器


分享到:


相關文章: