frps: allow to use custom status code for not found page/vhost

This commit is contained in:
Daniel Kucera 2021-06-11 12:16:42 +02:00
parent c7d4637382
commit e0923a8b17
5 changed files with 17 additions and 6 deletions

View File

@ -121,6 +121,9 @@ type ServerCommonConf struct {
// value is "", a default page will be displayed. By default, this value is // value is "", a default page will be displayed. By default, this value is
// "". // "".
Custom404Page string `ini:"custom_404_page" json:"custom_404_page"` Custom404Page string `ini:"custom_404_page" json:"custom_404_page"`
// Custom404StatusCode specifies a status code for response when 404 page
// is being sent. By default, this value is 404.
Custom404StatusCode int `ini:"custom_404_status_code" json:"custom_404_status_code"`
// AllowPorts specifies a set of ports that clients are able to proxy to. // AllowPorts specifies a set of ports that clients are able to proxy to.
// If the length of this value is 0, all ports are allowed. By default, // If the length of this value is 0, all ports are allowed. By default,
@ -203,6 +206,7 @@ func GetDefaultServerConf() ServerCommonConf {
HeartbeatTimeout: 90, HeartbeatTimeout: 90,
UserConnTimeout: 10, UserConnTimeout: 10,
Custom404Page: "", Custom404Page: "",
Custom404StatusCode: 404,
HTTPPlugins: make(map[string]plugin.HTTPPluginOptions), HTTPPlugins: make(map[string]plugin.HTTPPluginOptions),
UDPPacketSize: 1500, UDPPacketSize: 1500,
} }

View File

@ -75,6 +75,7 @@ func Test_LoadServerCommonConf(t *testing.T) {
subdomain_host = frps.com subdomain_host = frps.com
tcp_mux tcp_mux
udp_packet_size = 1509 udp_packet_size = 1509
custom_404_status_code = 400
[plugin.user-manager] [plugin.user-manager]
addr = 127.0.0.1:9009 addr = 127.0.0.1:9009
path = /handler path = /handler
@ -125,6 +126,7 @@ func Test_LoadServerCommonConf(t *testing.T) {
DetailedErrorsToClient: true, DetailedErrorsToClient: true,
HeartbeatTimeout: 99, HeartbeatTimeout: 99,
UserConnTimeout: 9, UserConnTimeout: 9,
Custom404StatusCode: 400,
AllowPorts: map[int]struct{}{ AllowPorts: map[int]struct{}{
10: struct{}{}, 10: struct{}{},
11: struct{}{}, 11: struct{}{},
@ -189,6 +191,7 @@ func Test_LoadServerCommonConf(t *testing.T) {
LogMaxDays: 3, LogMaxDays: 3,
DetailedErrorsToClient: true, DetailedErrorsToClient: true,
TCPMux: true, TCPMux: true,
Custom404StatusCode: 404,
AllowPorts: make(map[int]struct{}), AllowPorts: make(map[int]struct{}),
MaxPoolCount: 5, MaxPoolCount: 5,
HeartbeatTimeout: 90, HeartbeatTimeout: 90,

View File

@ -20,6 +20,7 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -90,8 +91,9 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
ErrorLog: log.New(newWrapLogger(), "", 0), ErrorLog: log.New(newWrapLogger(), "", 0),
ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) { ErrorHandler: func(rw http.ResponseWriter, req *http.Request, err error) {
frpLog.Warn("do http proxy request error: %v", err) frpLog.Warn("do http proxy request error: %v", err)
rw.WriteHeader(http.StatusNotFound) res := notFoundResponse()
rw.Write(getNotFoundPageContent()) rw.WriteHeader(res.StatusCode)
io.Copy(rw, res.Body)
}, },
} }
rp.proxy = proxy rp.proxy = proxy

View File

@ -24,7 +24,8 @@ import (
) )
var ( var (
NotFoundPagePath = "" NotFoundPagePath = ""
NotFoundStatusCode = 404
) )
const ( const (
@ -74,8 +75,7 @@ func notFoundResponse() *http.Response {
header.Set("Content-Type", "text/html") header.Set("Content-Type", "text/html")
res := &http.Response{ res := &http.Response{
Status: "Not Found", StatusCode: NotFoundStatusCode,
StatusCode: 404,
Proto: "HTTP/1.0", Proto: "HTTP/1.0",
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 0, ProtoMinor: 0,
@ -89,7 +89,6 @@ func noAuthResponse() *http.Response {
header := make(map[string][]string) header := make(map[string][]string)
header["WWW-Authenticate"] = []string{`Basic realm="Restricted"`} header["WWW-Authenticate"] = []string{`Basic realm="Restricted"`}
res := &http.Response{ res := &http.Response{
Status: "401 Not authorized",
StatusCode: 401, StatusCode: 401,
Proto: "HTTP/1.1", Proto: "HTTP/1.1",
ProtoMajor: 1, ProtoMajor: 1,

View File

@ -163,6 +163,9 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
// Init 404 not found page // Init 404 not found page
vhost.NotFoundPagePath = cfg.Custom404Page vhost.NotFoundPagePath = cfg.Custom404Page
// Init not found status code
vhost.NotFoundStatusCode = cfg.Custom404StatusCode
var ( var (
httpMuxOn bool httpMuxOn bool
httpsMuxOn bool httpsMuxOn bool