A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

paddy 简介

paddy是一款单进程的独立运行的web server,基于golang的标准库net/http实现。
paddy提供以下功能:

  • 直接配置http响应
  • 目录文件服务器
  • proxy_pass代理
  • http反向代理
  • 支持请求和响应插件

部署

编译

$ go build ./main/paddy.go

运行

$ ./paddy -configFile default.config

若不附带-configFile参数,则paddy默认从paddy执行程序文件所在目录查找并加载default.config

参数文件校验

$ ./paddy -t default.config

热重启

热重启一般发生在修改配置之后需要使参数生效。

$ kill -USR2 `cat paddy.pid`

paddy配置文件

paddy配置文件基于json语法,支持双斜线开头的单行注释。配置格式请参考默认配置文件
paddy配置文件支持强大的"json表达式"语法。
paddy的location配置支持"正则表达式"和"jsonexp"两种方式。 通过在request_filter和response_filter中对请求和响应进行灵活的处理
location配置中,优先级从高到低次序: 直接配置响应 > file_root > proxy_pass > backend

paddy的流量生命周期图

image

直接配置http响应

可在location_regexp的request_filter和rewponse_filter,或location_jsonexp中直接写入http响应,json表达式变量$set_response=1表示直接响应。如:

...
"location_regexp": [
			{
				"exp": "^\\/response_direct\\?.*",
				"response_filter": [
					[
						[
							// 表示直接响应
							["$set_response","=",1],
							// 设置响应的http status code = 200
							["$resp.status","=",200],
							// 设置响应的http body
							["$resp.body","=","response from {{$req.path}},{{$req_param.echo}}"]
						]
					]
				]
			}
            ...

目录文件服务器

paddy通过goutil.LRUFileCache以LRU策略执行文件缓存,并提供目录文件服务。配置目录文件的方式通过file_root参数进行,如下:

...
"location_regexp": [			
			{
				"exp": "^/paddy/default\\.config$",
				// 返回本地目录 /tmp/paddy/default.config文件的内容
				"file_root": "/tmp"
			}
            ...

proxy_pass

与nginx类似,proxy_pass指示一个url,服务器向该url请求获取响应,并响应给客户端。如下:

...
"location_regexp": [
			{
				"exp": "^\\/proxy_pass.*",
				"proxy_pass": "http://192.168.0.1:80/real_path"
			}
...

backend

backend主要用来支持paddy作为http反向代理。paddy预先定义后端服务器或服务器组,一个backend包含一组后端服务器地址,paddy支持对backend的多种负载策略:

  • roundrobin 轮询
  • minpending 最低负载+轮询
  • iphash 按客户端ip地址进行哈希分布
  • uri_param 根据uri参数值进行哈希分布
  • random 随机选择
    配置举例:
...
"location_regexp": [
			{
				"exp": "^\\/backend.*",
				"backend": "login_server",
				// 负载策略
				"method": "roundrobin"
			},
 ...

除了这上述负载策略以外, 可以通过json表达式(jsonexp),以语义控制的方式选择后端服务器,达到非常灵活的负载能力。这也是"json表达式"的强大之处,举例:

{
	"request_filter": [
		[
			// 如果url参数user_name是“bob,tom,franky”之一,则选择backend_engineer作为后端服务器
			["$req_param.user_name", "in", "bob,tom,franky"],
			[
				["$backend","=","backend_engineer"],
				["$break","=",1]
			]
		],
		[
			// 如果url参数user_age > 18, 则选择向http://192.168.0.1/adult?{{params}}获取响应
			["$req_param.user_age", ">", 18],
			["$proxy_pass","=","http://192.168.0.1/adult?{{params}}"]
		]
	]
}

插件管理

paddy除了可以支持上述配置功能以外。如果需要非常个性化的处理,或希望减少流量转发而是直接处理请求,处理web socket...其他功能,则可以通过编写插件,然后将包含插件代码的整个代码完整编译部署。paddy插件提供最高的可控性。编写插件的方式: 编写支持插件接口的组件,并通过Paddy.RegisterPlugin注册即可。

// 插件接口
type Plugin interface {
	// 唯一身份ID
	ID() string

	// 在http请求接收完成后介入
	// hijacked 是否劫持:true则必须实现respWriter写响应;false时不准向respWriter写响应,可以返回backend(此时框架直接去请求backend而不再走location匹配流程,否则框架执行location匹配)
	RequestHeaderCompleted(req *http.Request, respWriter http.ResponseWriter, context goutil.Context) (hijacked bool, proxyPass, backend string, err goutil.Error)

	// 框架在得到响应后,给客户端发送响应之前介入
	// hijacked 是否劫持:true则必须实现respWriter写响应;false时,不准向respWriter写响应,可以返回newResponse(此时框架以newResponse写响应,否则以originResponse写响应)
	ResponseHeaderCompleted(originResponse *http.Response, respWriter http.ResponseWriter, context goutil.Context) (hijacked bool, newResponse *http.Response, err goutil.Error)
}

宏与全局变量

宏将在运行时被实际值替换,location的配置的proxy_pass参数支持如下宏:

paddy的json表达式支持以下paddy专有jsonexp变量:

  • $proxy_pass 设置proxy_pass
  • $backend 设置backend
  • $file_root 设置file_root
  • $set_response 设置set_response

以及paddy专有jsonexp对象:

  • $req 当前http请求对象,支持属性: ver,host,method,path,uri
  • $req_param 当前http请求对象的url参数对象,可以通过.操作符读取或设置参数值,如 $req_param.arg1
  • $req_header 当前http请求对象header对象,可以通过.操作符读取或设置header信息, 如 $req_header.content_type
  • $resp 当前http响应对象,支持属性:status,body
  • $resp_header 当前http响应对象的header对象,可用通过.操作符读取或设置header信息, 如["$resp_header.Content_Encoding","=","gzip"]
Similar Resources

Websockify-go - A reverse proxy that support tcp, http, https, and the most important, noVNC, which makes it a websockify

websockify-go | mproxy a reverse proxy that support tcp, http, https, and the mo

Aug 14, 2022

A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

frp README | 中文文档 What is frp? frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it s

Jan 5, 2023

Simple edge server / reverse proxy

reproxy Reproxy is simple edge HTTP(s) sever / reverse proxy supporting various providers (docker, static, file). One or more providers supply informa

Dec 29, 2022

4chain is a simple、fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet.

4Chain What is 4chain? 4chain is a simple、fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. Using the ssh

Nov 1, 2022

Reverse proxy server to filter traffic based on JA3 fingerprint/hash

JA3RP (JA3 Reverse Proxy) Ja3RP is a basic reverse proxy server that filters traffic based on JA3 fingerprints. It can also operate as a regular HTTP

Sep 17, 2022

A paywall bypassing reverse proxy and DNS server written in go 🔨💵🧱

FreeNews 🔨 💵 🧱 A paywall bypassing reverse proxy and DNS server written in go. This project is still hard work in progress. Expect stuff to just no

Dec 7, 2022

A flexible configuration manager for Wireguard networks

A flexible configuration manager for Wireguard networks

Drago A flexible configuration manager for WireGuard networks Drago is a flexible configuration manager for WireGuard networks which is designed to ma

Jan 7, 2023

Go HTTP tunnel is a reverse tunnel based on HTTP/2.

Go HTTP tunnel is a reverse tunnel based on HTTP/2. It enables you to share your localhost when you don't have a public IP.

Dec 28, 2022
Tcp-proxy - A dead simple reverse proxy server.

tcp-proxy A proxy that forwords from a host to another. Building go build -ldflags="-X 'main.Version=$(git describe --tags $(git rev-list --tags --max

Jan 2, 2022
mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together

mt-multiserver-proxy mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together. It is the successor to multiserv

Nov 17, 2022
httpstream provides HTTP handlers for simultaneous streaming uploads and downloads of objects, as well as persistence and a standalone server.

httpfstream httpfstream provides HTTP handlers for simultaneous streaming uploads and downloads of files, as well as persistence and a standalone serv

May 1, 2021
Self-hosted reverse-proxy for F1 web viewer.
Self-hosted reverse-proxy for F1 web viewer.

F1WebViewer-SelfHosted Self-hosted reverse-proxy for F1 web viewer and includes a web server at port 13331. You can also run this proxy on a server if

Dec 21, 2022
Http-logging-proxy - A HTTP Logging Proxy For Golang

http-logging-proxy HTTP Logging Proxy Description This project builds a simple r

Aug 1, 2022
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator

Trickster is an HTTP reverse proxy/cache for http applications and a dashboard query accelerator for time series databases. Learn more below, and chec

Jan 2, 2023
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies

Weaver - A modern HTTP Proxy with Advanced features Description Features Installation Architecture Configuration Contributing License Description Weav

Dec 24, 2022
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies

Weaver - A modern HTTP Proxy with Advanced features Description Features Installation Architecture Configuration Contributing License Description Weav

Jan 1, 2023
Goproxy - HTTP/HTTPS Forward and Reverse Proxy

Go HTTP(s) Forward/Reverse Proxy This is intended to provide the proxy for the goproxy frontend. It is currently a work in progress, and is not very s

Jan 4, 2022