mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 10:18:59 +02:00
Feat/fileserver (#60)
* cleanup code for URL type * fix makefile for trace mode * refactor, merge Entry, RawEntry and Route into one. * Implement fileserver. * refactor: rename HTTPRoute to ReverseProxyRoute to avoid confusion * refactor: move metrics logger to middleware package - fix prometheus metrics for load balanced routes - route will now fail when health monitor fail to start * fix extra output of ls-* commands by defer initializaing stuff, speed up start time * add test for path traversal attack, small fix on FileServer.Start method * rename rule.on.bypass to pass * refactor and fixed map-to-map deserialization * updated route loading logic * schemas: add "add_prefix" option to modify_request middleware * updated route JSONMarshalling --------- Co-authored-by: yusing <yusing@6uo.me>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"CIDR":{"anyOf":[{"pattern":"^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*$","type":"string"},{"pattern":"^.*:.*:.*:.*:.*:.*:.*:.*$","type":"string"},{"pattern":"^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*/[0-9]*$","type":"string"},{"pattern":"^::[0-9]*$","type":"string"},{"pattern":"^.*::/[0-9]*$","type":"string"},{"pattern":"^.*:.*::/[0-9]*$","type":"string"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"MiddlewareComposeMap":{"anyOf":[{"additionalProperties":false,"properties":{"use":{"enum":["CustomErrorPage","ErrorPage","customErrorPage","custom_error_page","errorPage","error_page"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["RedirectHTTP","redirectHTTP","redirect_http"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["SetXForwarded","setXForwarded","set_x_forwarded"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["HideXForwarded","hideXForwarded","hide_x_forwarded"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"allow":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"message":{"default":"IP not allowed","description":"Error message when blocked","type":"string"},"status":{"$ref":"#/definitions/StatusCode","default":403,"description":"HTTP status code when blocked (alias of status_code)"},"status_code":{"$ref":"#/definitions/StatusCode","default":403,"description":"HTTP status code when blocked"},"use":{"enum":["CIDRWhitelist","cidrWhitelist","cidr_whitelist"],"type":"string"}},"required":["allow","use"],"type":"object"},{"additionalProperties":false,"properties":{"recursive":{"default":false,"description":"Recursively resolve the IP","type":"boolean"},"use":{"enum":["CloudflareRealIP","cloudflareRealIp","cloudflare_real_ip"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"},"use":{"enum":["ModifyRequest","Request","modifyRequest","modify_request","request"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"},"use":{"enum":["ModifyResponse","Response","modifyResponse","modify_response","response"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"allowed_groups":{"description":"Allowed groups","items":{"type":"string"},"minItems":1,"type":"array"},"allowed_users":{"description":"Allowed users","items":{"type":"string"},"minItems":1,"type":"array"},"use":{"enum":["OIDC","oidc"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"average":{"description":"Average number of requests allowed in a period","type":"number"},"burst":{"description":"Maximum number of requests allowed in a period","type":"number"},"period":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"},"use":{"enum":["RateLimit","rateLimit","rate_limit"],"type":"string"}},"required":["average","burst","use"],"type":"object"},{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"},"use":{"enum":["RealIP","realIP","real_ip"],"type":"string"}},"required":["from","use"],"type":"object"}]},"StatusCode":{"anyOf":[{"pattern":"^[0-9]*$","type":"string"},{"type":"number"}]}},"items":{"$ref":"#/definitions/MiddlewareComposeMap"},"type":"array"}
|
||||
{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"CIDR":{"anyOf":[{"pattern":"^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*$","type":"string"},{"pattern":"^.*:.*:.*:.*:.*:.*:.*:.*$","type":"string"},{"pattern":"^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*/[0-9]*$","type":"string"},{"pattern":"^::[0-9]*$","type":"string"},{"pattern":"^.*::/[0-9]*$","type":"string"},{"pattern":"^.*:.*::/[0-9]*$","type":"string"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"MiddlewareComposeMap":{"anyOf":[{"additionalProperties":false,"properties":{"use":{"enum":["CustomErrorPage","ErrorPage","customErrorPage","custom_error_page","errorPage","error_page"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["RedirectHTTP","redirectHTTP","redirect_http"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["SetXForwarded","setXForwarded","set_x_forwarded"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"use":{"enum":["HideXForwarded","hideXForwarded","hide_x_forwarded"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"allow":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"message":{"default":"IP not allowed","description":"Error message when blocked","type":"string"},"status":{"$ref":"#/definitions/StatusCode","default":403,"description":"HTTP status code when blocked (alias of status_code)"},"status_code":{"$ref":"#/definitions/StatusCode","default":403,"description":"HTTP status code when blocked"},"use":{"enum":["CIDRWhitelist","cidrWhitelist","cidr_whitelist"],"type":"string"}},"required":["allow","use"],"type":"object"},{"additionalProperties":false,"properties":{"recursive":{"default":false,"description":"Recursively resolve the IP","type":"boolean"},"use":{"enum":["CloudflareRealIP","cloudflareRealIp","cloudflare_real_ip"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"add_prefix":{"description":"Add prefix to request URL","type":"string"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"},"use":{"enum":["ModifyRequest","Request","modifyRequest","modify_request","request"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"},"use":{"enum":["ModifyResponse","Response","modifyResponse","modify_response","response"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"allowed_groups":{"description":"Allowed groups","items":{"type":"string"},"minItems":1,"type":"array"},"allowed_users":{"description":"Allowed users","items":{"type":"string"},"minItems":1,"type":"array"},"use":{"enum":["OIDC","oidc"],"type":"string"}},"required":["use"],"type":"object"},{"additionalProperties":false,"properties":{"average":{"description":"Average number of requests allowed in a period","type":"number"},"burst":{"description":"Maximum number of requests allowed in a period","type":"number"},"period":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"},"use":{"enum":["RateLimit","rateLimit","rate_limit"],"type":"string"}},"required":["average","burst","use"],"type":"object"},{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"},"use":{"enum":["RealIP","realIP","real_ip"],"type":"string"}},"required":["from","use"],"type":"object"}]},"StatusCode":{"anyOf":[{"pattern":"^[0-9]*$","type":"string"},{"type":"number"}]}},"items":{"$ref":"#/definitions/MiddlewareComposeMap"},"type":"array"}
|
||||
2
schemas/middlewares/middlewares.d.ts
vendored
2
schemas/middlewares/middlewares.d.ts
vendored
@@ -65,6 +65,8 @@ export type ModifyRequest = {
|
||||
};
|
||||
/** Hide HTTP headers */
|
||||
hide_headers?: types.HTTPHeader[];
|
||||
/** Add prefix to request URL */
|
||||
add_prefix?: string;
|
||||
};
|
||||
export type ModifyResponse = {
|
||||
use: "response" | "Response" | "modify_response" | "modifyResponse" | "ModifyResponse";
|
||||
|
||||
@@ -117,6 +117,8 @@ export type ModifyRequest = {
|
||||
add_headers?: { [key: types.HTTPHeader]: string };
|
||||
/** Hide HTTP headers */
|
||||
hide_headers?: types.HTTPHeader[];
|
||||
/** Add prefix to request URL */
|
||||
add_prefix?: string;
|
||||
};
|
||||
|
||||
export type ModifyResponse = {
|
||||
|
||||
29
schemas/providers/routes.d.ts
vendored
29
schemas/providers/routes.d.ts
vendored
@@ -9,7 +9,7 @@ export declare const PROXY_SCHEMES: readonly ["http", "https"];
|
||||
export declare const STREAM_SCHEMES: readonly ["tcp", "udp"];
|
||||
export type ProxyScheme = (typeof PROXY_SCHEMES)[number];
|
||||
export type StreamScheme = (typeof STREAM_SCHEMES)[number];
|
||||
export type Route = ReverseProxyRoute | StreamRoute;
|
||||
export type Route = ReverseProxyRoute | FileServerRoute | StreamRoute;
|
||||
export type Routes = {
|
||||
[key: string]: Route;
|
||||
};
|
||||
@@ -65,6 +65,31 @@ export type ReverseProxyRoute = {
|
||||
*/
|
||||
access_log?: AccessLogConfig;
|
||||
};
|
||||
export type FileServerRoute = {
|
||||
/** Alias (subdomain or FDN)
|
||||
* @minLength 1
|
||||
*/
|
||||
alias?: string;
|
||||
scheme: "fileserver";
|
||||
root: string;
|
||||
/** Path patterns (only patterns that match will be proxied).
|
||||
*
|
||||
* See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux
|
||||
*/
|
||||
path_patterns?: PathPattern[];
|
||||
/** Middlewares */
|
||||
middlewares?: MiddlewaresMap;
|
||||
/** Homepage config
|
||||
*
|
||||
* @examples require(".").homepageExamples
|
||||
*/
|
||||
homepage?: HomepageConfig;
|
||||
/** Access log config
|
||||
*
|
||||
* @examples require(".").accessLogExamples
|
||||
*/
|
||||
access_log?: AccessLogConfig;
|
||||
};
|
||||
export type StreamRoute = {
|
||||
/** Alias (subdomain or FDN)
|
||||
* @minLength 1
|
||||
@@ -74,7 +99,7 @@ export type StreamRoute = {
|
||||
*
|
||||
* @default tcp
|
||||
*/
|
||||
scheme: StreamScheme;
|
||||
scheme?: StreamScheme;
|
||||
/** Stream host
|
||||
*
|
||||
* @default localhost
|
||||
|
||||
@@ -11,7 +11,7 @@ export const STREAM_SCHEMES = ["tcp", "udp"] as const;
|
||||
export type ProxyScheme = (typeof PROXY_SCHEMES)[number];
|
||||
export type StreamScheme = (typeof STREAM_SCHEMES)[number];
|
||||
|
||||
export type Route = ReverseProxyRoute | StreamRoute;
|
||||
export type Route = ReverseProxyRoute | FileServerRoute | StreamRoute;
|
||||
export type Routes = {
|
||||
[key: string]: Route;
|
||||
};
|
||||
@@ -69,6 +69,33 @@ export type ReverseProxyRoute = {
|
||||
access_log?: AccessLogConfig;
|
||||
};
|
||||
|
||||
export type FileServerRoute = {
|
||||
/** Alias (subdomain or FDN)
|
||||
* @minLength 1
|
||||
*/
|
||||
alias?: string;
|
||||
scheme: "fileserver";
|
||||
/* File server root path */
|
||||
root: string;
|
||||
/** Path patterns (only patterns that match will be proxied).
|
||||
*
|
||||
* See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux
|
||||
*/
|
||||
path_patterns?: PathPattern[];
|
||||
/** Middlewares */
|
||||
middlewares?: MiddlewaresMap;
|
||||
/** Homepage config
|
||||
*
|
||||
* @examples require(".").homepageExamples
|
||||
*/
|
||||
homepage?: HomepageConfig;
|
||||
/** Access log config
|
||||
*
|
||||
* @examples require(".").accessLogExamples
|
||||
*/
|
||||
access_log?: AccessLogConfig;
|
||||
}
|
||||
|
||||
export type StreamRoute = {
|
||||
/** Alias (subdomain or FDN)
|
||||
* @minLength 1
|
||||
@@ -78,7 +105,7 @@ export type StreamRoute = {
|
||||
*
|
||||
* @default tcp
|
||||
*/
|
||||
scheme: StreamScheme;
|
||||
scheme?: StreamScheme;
|
||||
/** Stream host
|
||||
*
|
||||
* @default localhost
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user