溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

caddy中怎么添加自定義插件

發(fā)布時(shí)間:2021-06-22 15:31:13 來源:億速云 閱讀:197 作者:Leah 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)caddy中怎么添加自定義插件,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

創(chuàng)建一個(gè) Go Package

首先為 caddy 創(chuàng)建一個(gè) 插件的 Go Package ,你可以新建一個(gè)文件夾達(dá)到這個(gè)效果。比如

├── caddy-plugin
│   ├── gizmo.go
│   └── setup.go

這里分為了兩個(gè) Go 文件,接下來詳細(xì)講每一個(gè) Go 文件的作用。

<a name="nmOnZ"></a>

代碼????:注冊(cè) caddy plugin

首先我們看到 setup.go

<a name="HXIC2"></a>

setup.go

創(chuàng)建 setup.go 文件并寫入以下信息

import "github.com/mholt/caddy"

func init() {
    caddy.RegisterPlugin("gizmo", caddy.Plugin{
        ServerType: "http",
        Action:     setup,
    })
}

這里是 建立了一個(gè)新插件,caddy 包來做到插件的注冊(cè)。

  1. 注意到 “gizmo” 這是 插件的名字,同時(shí)也是指令的名字,請(qǐng)為你的插件取一個(gè)獨(dú)一無二的名字吧。(注意:名字需要是單詞小寫哦。)

  2. 因?yàn)槭轻槍?duì) HTTP 服務(wù)器的插件,所以 ServerType 字段值是 “http”

  3. 另一個(gè)設(shè)置的字段是 setup ,實(shí)際上,我們接下來會(huì)填充這個(gè)函數(shù)的邏輯。它的作用就是將我們插件的處理邏輯安裝到 Caddy 中。

<a name="6sJEa"></a>

setup

現(xiàn)在我們來實(shí)現(xiàn) setup 函數(shù) <br /> <br />假如我們希望在Caddyfile中有一行這樣的行:

gizmo foobar

<br />我們可以得到剛才所說的 c.Next() 第一個(gè)參數(shù)(“foobar”)的值,如下所示:

for c.Next() {              // skip the directive name
    if !c.NextArg() {       // expect at least one value
        return c.ArgErr()   // otherwise it's an error
    }
    value := c.Val()        // use the value
}

我們首先注意到, c.Next() 是真正我們讀取 caddyfile 邏輯的地方,caddyfile 就是配置服務(wù)器的配置文件的名字。我們注意到,這里的操作實(shí)際上是使用 caddy.Controller 來實(shí)現(xiàn)的。它的存在 讓編寫插件的開發(fā)者只需要關(guān)注如何使用它來執(zhí)行你的命令,這是一項(xiàng)優(yōu)秀的設(shè)計(jì),有興趣可以看我的源碼閱讀部分關(guān)于 Plugin 的具體實(shí)現(xiàn)。

在 Caddy 解析了Caddyfile之后,它將迭代每個(gè)指令名(按照服務(wù)器類型規(guī)定的順序),并在每次遇到指令名時(shí)調(diào)用指令的setup函數(shù)。setup函數(shù)的職責(zé)是解析指令的標(biāo)識(shí)并配置自己。<br /> <br />您可以通過遍歷c.Next()來解析為指令提供的標(biāo)識(shí),只要有更多的標(biāo)識(shí)需要解析,那么c.Next()就會(huì)返回true。由于一個(gè)指令可能出現(xiàn)多次,你必須遍歷c.Next()以獲得所有出現(xiàn)的指令并使用第一個(gè)標(biāo)識(shí)(即指令名)。<br />有關(guān)caddyfile包,請(qǐng)參閱godoc以了解如何更充分地使用分發(fā)器,并查看任何其他現(xiàn)有插件。

<a name="fzu7b"></a>

代碼 ????:Handler 實(shí)現(xiàn)

<a name="iyY6W"></a>

gizmo.go:

查看httpserver包的godoc。最重要的兩種類型是httpserver.Handler和httpserver.Middleware。

  1. Handler是一個(gè)處理HTTP請(qǐng)求的函數(shù)。

  2. Middleware是一種連接Handler的方式。

Caddy將負(fù)責(zé)為你設(shè)置HTTP服務(wù)器的所有簿記(bookkeeping)工作,但是你需要實(shí)現(xiàn)這兩種類型。<br />

<a name="sPXzP"></a>

Struct

httpserver.Handler是一個(gè)幾乎和http.Handler完全一樣的接口,除了ServeHTTP方法返回(int, error)。<br />這個(gè)方法簽名遵循Go語言博客中關(guān)于與中間件相關(guān)的錯(cuò)誤處理的建議。<br />int是HTTP狀態(tài)碼,error應(yīng)該被處理和/或記錄。有關(guān)這些返回值的詳細(xì)信息,請(qǐng)參閱godoc。<br /> <br />Handler通常是一個(gè)結(jié)構(gòu)體,至少包含一個(gè)Next字段,用來鏈接下一個(gè)Handler

type gizmoHandler struct {
	next httpserver.Handler
}

<br />除了這些之外,可以添加一些自己使用的參數(shù),考慮 grpc 的 plugin 實(shí)現(xiàn),解釋放在代碼塊中的注釋中

type server struct {
	backendAddr       string // 監(jiān)聽地址
	next              httpserver.Handler // 作為中間件必須有的字段
    backendIsInsecure bool // 是否啟用 Insecure() 選項(xiàng),是 grpc 的一項(xiàng)配置
	backendTLS        *tls.Config // 關(guān)于 TLS 的使用的證書文件
	wrappedGrpc       *grpcweb.WrappedGrpcServer // 通過 grpcweb 的 協(xié)議實(shí)現(xiàn) HTTP 請(qǐng)求等
}

這就是參考的一個(gè) 字段的使用??梢愿鶕?jù)自己的需要,調(diào)整在 caddyfile 中讀取的指令應(yīng)該如何配置。

<a name="K5EDA"></a>

httpserver.Handler

為了實(shí)現(xiàn)httpserver.Handler接口,我們需要編寫一個(gè)名為ServeHTTP的方法。這個(gè)方法是實(shí)際的處理程序函數(shù),除非它自己處理完畢請(qǐng)求,否則它應(yīng)該調(diào)用鏈中的下一個(gè)Handler:即使用 g.next.ServeHTTP(w, r)

func (g gizmoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
	return g.next.ServeHTTP(w, r)
}

這里只是框架,具體邏輯可以自行填充,可以參照已有的 Plugin 實(shí)現(xiàn)。<br />

<a name="RiOqc"></a>

第二步,注冊(cè) Middleware

然后我們可以進(jìn)行第二步,將這個(gè) handler 注冊(cè)到整個(gè) caddy 的 http 調(diào)用鏈上。

我們需要回到 剛才的 setup.go 文件中,<br />回到設(shè)置函數(shù)。你剛剛解析了標(biāo)識(shí)并使用所有適當(dāng)?shù)呐渲迷O(shè)置了中間件處理程序:

func setup(c *caddy.Controller) error {
	g := gizmoHandler{} // 用來實(shí)現(xiàn) HTTPHandler 的 next 的結(jié)構(gòu),用來構(gòu)建 中間件。也可以加入一些自己的字段

    for c.Next() {
        // 獲取配置文件,并處理
    }
    // 現(xiàn)在開始注冊(cè)中間件
	httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
		g.next = next
		return g
	})
	
	return nil
}

這樣,代碼部分就全部完成了。

下面我們查看需要注意的事項(xiàng)。實(shí)際上是關(guān)乎于怎樣將寫好的插件集成在 caddy 中。

<a name="WTOo3"></a>

排序

要做的事情是告訴服務(wù)器類型在進(jìn)程的什么地方執(zhí)行你的指令。這一點(diǎn)很重要,因?yàn)槠渌噶羁赡軙?huì)設(shè)置你所依賴的更原始的配置,因此執(zhí)行指令的順序不能是隨意的。<br /> <br />每個(gè)服務(wù)器類型都有一個(gè)字符串列表,其中每個(gè)項(xiàng)都是一個(gè)指令的名稱。例如,查看HTTP服務(wù)器支持的指令列表。將指令添加到適當(dāng)?shù)奈恢谩?lt;br />

<a name="c75IF"></a>

插入你的插件

最后,不要忘記導(dǎo)入你的插件包!Caddy必須導(dǎo)入插件來注冊(cè)并執(zhí)行它。這通常是在run.go的import部分的尾部完成的:<br />

_ "your/plugin/package/here"

請(qǐng)注意:包名前的_是必需的。

<a name="1aHEv"></a>

上述就是小編為大家分享的caddy中怎么添加自定義插件了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI