antony@notes:~/misc$ cat "撰寫-Go-CGI-程式.md"
撰寫 Go CGI 程式
撰寫 Go 靜態網站並啟動 CGI
實作目標
建立一個簡單的 Go 網頁伺服器,能夠提供靜態檔案服務,並透過 CGI(Common Gateway Interface)執行 Bash script。
章節
[TOC]
第一步:建立專案目錄並進入
mkdir ~/gocgi/; cd ~/gocgi/mkdir ~/gocgi/:在使用者的家目錄下建立一個名為gocgi的資料夾。cd ~/gocgi/:進入剛建立的gocgi資料夾。
目的:為專案建立一個獨立的工作目錄,便於管理相關的程式碼和資源。
第二步:撰寫 Go 程式碼並儲存為 main.go
echo 'package main
import (
"net/http"
"net/http/cgi"
)
func cgiDB(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgidb.sh"}
handler.ServeHTTP(w, r)
}
func cgiTBL(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgitbl.sh"}
handler.ServeHTTP(w, r)
}
func main() {
static := http.FileServer(http.Dir("./www/"))
http.Handle("/", static)
http.HandleFunc("/db", cgiDB)
http.HandleFunc("/tbl", cgiTBL)
http.ListenAndServe(":8080", nil)
}' > main.go- 這段指令使用
echo將多行的 Go 程式碼寫入main.go檔案。
程式碼解析:
package main:定義此程式屬於main套件,表示這是一個可執行的程式。import:引入標準庫中的net/http和net/http/cgi套件,用於建立 HTTP 伺服器和處理 CGI。cgiDB和cgiTBL函式:分別處理/db和/tbl路徑的請求,執行對應的 Shell 腳本。main函式:http.FileServer:提供./www/目錄下的靜態檔案服務。http.Handle和http.HandleFunc:設定路由,將特定的路徑對應到處理函式。http.ListenAndServe(":8080", nil):啟動伺服器,監聽 8080 埠口。
- 目的:建立一個基本的網頁伺服器,能夠提供靜態檔案服務,並透過 CGI 執行特定的 Shell 腳本。
第三步:初始化 Go 模組
go mod init gocgigo mod init gocgi:初始化一個名為gocgi的 Go 模組,會在當前目錄下建立一個go.mod檔案。
目的:使用 Go Modules 管理專案的相依性,這是 Go 官方推薦的依賴管理方式。
第四步:編譯 Go 程式
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o mainCGO_ENABLED=0:禁用 CGO,確保編譯出的二進位檔案是純 Go 程式,無需依賴 C 語言的函式庫。GOOS=linux:設定目標作業系統為 Linux。GOARCH=amd64:設定目標架構為 64 位元。go build -o main:編譯main.go,輸出為名為main的可執行檔案。
總結
整體流程如下:
- 建立並進入專案目錄。
- 撰寫並儲存 Go 程式碼,建立一個簡單的網頁伺服器。
- 初始化 Go 模組,管理相依性。
- 編譯程式,生成適用於 Linux 64 位元系統的可執行檔案。
程式介紹
package main
import (
"net/http"
"net/http/cgi"
)
func cgiDB(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgidb.sh"}
handler.ServeHTTP(w, r)
}
func cgiTBL(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgitbl.sh"}
handler.ServeHTTP(w, r)
}
func main() {
static := http.FileServer(http.Dir("./www/"))
http.Handle("/",static)
http.HandleFunc("/db", cgiDB)
http.HandleFunc("/tbl", cgiTBL)
http.ListenAndServe(":8080", nil)
}這段 Go 程式碼建立了一個簡單的 HTTP 伺服器,具備以下功能:
- 提供靜態檔案服務:透過
http.FileServer,伺服器會從./www/目錄提供靜態檔案,如 HTML、CSS、JavaScript 等。 - 處理 CGI 請求:對於特定路徑(
/db和/tbl),伺服器會執行對應的 CGI 腳本(cgidb.sh和cgitbl.sh),並將其輸出作為 HTTP 回應返回給用戶端。
📁 靜態檔案服務
static := http.FileServer(http.Dir("./www/"))
http.Handle("/", static)http.FileServer建立一個處理器,用於提供指定目錄中的靜態檔案。http.Dir("./www/")指定了靜態檔案的根目錄。http.Handle("/", static)將根路徑/的請求導向這個處理器。
效果:當用戶端請求 http://localhost:8080/index.html 時,伺服器會返回 ./www/index.html 檔案的內容。
⚙️ CGI 處理器
func cgiDB(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgidb.sh"}
handler.ServeHTTP(w, r)
}
func cgiTBL(w http.ResponseWriter, r *http.Request) {
handler := cgi.Handler{Path: "./www/cgi/cgitbl.sh"}
handler.ServeHTTP(w, r)
}- 這兩個函式分別處理
/db和/tbl路徑的請求。 cgi.Handler是 Go 標準庫net/http/cgi提供的類型,用於執行 CGI 腳本。Path指定了要執行的 CGI 腳本路徑。ServeHTTP方法會執行指定的 CGI 腳本,並將其輸出作為 HTTP 回應返回給用戶端。
效果:當用戶端請求 http://localhost:8080/db 時,伺服器會執行 ./www/cgi/cgidb.sh 腳本,並將其輸出返回給用戶端。
🚀 主函式
func main() {
static := http.FileServer(http.Dir("./www/"))
http.Handle("/", static)
http.HandleFunc("/db", cgiDB)
http.HandleFunc("/tbl", cgiTBL)
http.ListenAndServe(":8080", nil)
}- 設定靜態檔案服務處理器。
- 註冊
/db和/tbl路徑的處理函式。 - 啟動 HTTP 伺服器,監聽本地端口 8080。
📌 總結
這段 Go 程式碼建立了一個基本的 HTTP 伺服器,能夠提供靜態檔案服務,並透過 CGI 腳本處理特定路徑的請求。這種架構適合用於簡單的網站或內部工具,但在實際部署時,仍需考慮安全性和錯誤處理等因素。