mirror of
https://github.com/antoniomika/sish.git
synced 2025-09-26 19:21:15 +08:00
110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package httpmuxer
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/antoniomika/sish/utils"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// RoundTripper returns the specific handler for unix connections. This
|
|
// will allow us to use our created sockets cleanly.
|
|
func RoundTripper() *http.Transport {
|
|
dialer := func(network, addr string) (net.Conn, error) {
|
|
realAddr, err := base64.StdEncoding.DecodeString(strings.Split(addr, ":")[0])
|
|
if err != nil {
|
|
log.Println("Unable to parse socket:", err)
|
|
}
|
|
|
|
return net.Dial("unix", string(realAddr))
|
|
}
|
|
|
|
tlsConfig := &tls.Config{
|
|
InsecureSkipVerify: !viper.GetBool("verify-ssl"),
|
|
}
|
|
|
|
return &http.Transport{
|
|
Dial: dialer,
|
|
TLSClientConfig: tlsConfig,
|
|
}
|
|
}
|
|
|
|
// ResponseModifier implements a response modifier for the specified request.
|
|
// We don't actually modify any requests, but we do want to record the request
|
|
// so we can send it to the web console.
|
|
func ResponseModifier(state *utils.State, hostname string, reqBody []byte, c *gin.Context, currentListener *utils.HTTPHolder) func(*http.Response) error {
|
|
return func(response *http.Response) error {
|
|
if viper.GetBool("admin-console") || viper.GetBool("service-console") {
|
|
var err error
|
|
var resBody []byte
|
|
|
|
if viper.GetInt64("service-console-max-content-length") == -1 || (viper.GetInt64("service-console-max-content-length") > -1 && response.ContentLength > -1 && response.ContentLength < viper.GetInt64("service-console-max-content-length")) {
|
|
resBody, err = io.ReadAll(response.Body)
|
|
if err != nil {
|
|
log.Println("Error reading response body:", err)
|
|
}
|
|
}
|
|
|
|
if resBody != nil {
|
|
response.Body = io.NopCloser(bytes.NewBuffer(resBody))
|
|
|
|
if response.Header.Get("Content-Encoding") == "gzip" {
|
|
gzData := bytes.NewBuffer(resBody)
|
|
gzReader, err := gzip.NewReader(gzData)
|
|
if err != nil {
|
|
log.Println("Error reading gzip data:", err)
|
|
}
|
|
|
|
resBody, err = io.ReadAll(gzReader)
|
|
if err != nil {
|
|
log.Println("Error reading gzip data:", err)
|
|
}
|
|
}
|
|
} else {
|
|
resBody = []byte("{\"_sish_status\": false, \"_sish_message\": \"response body size exceeds limit for service console\"}")
|
|
}
|
|
|
|
startTime := c.GetTime("startTime")
|
|
|
|
requestHeaders := c.Request.Header.Clone()
|
|
requestHeaders.Add("Host", hostname)
|
|
|
|
data := map[string]any{
|
|
"startTime": startTime,
|
|
"startTimePretty": startTime.Format(viper.GetString("time-format")),
|
|
"requestIP": c.ClientIP(),
|
|
"requestMethod": c.Request.Method,
|
|
"requestUrl": c.Request.URL,
|
|
"originalRequestURI": c.GetString("originalURI"),
|
|
"requestHeaders": requestHeaders,
|
|
"requestBody": base64.StdEncoding.EncodeToString(reqBody),
|
|
"responseHeaders": response.Header,
|
|
"responseBody": base64.StdEncoding.EncodeToString(resBody),
|
|
}
|
|
|
|
if response.Request != nil {
|
|
hostLocation, err := base64.StdEncoding.DecodeString(response.Request.URL.Host)
|
|
if err != nil {
|
|
log.Println("Error loading proxy info from request", err)
|
|
}
|
|
|
|
c.Set("proxySocket", string(hostLocation))
|
|
}
|
|
|
|
c.Set("broadcastRoute", currentListener.HTTPUrl.String())
|
|
c.Set("broadcastData", data)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|