mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
package idlewatcher
|
|
|
|
import (
|
|
"bytes"
|
|
_ "embed"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
type templateData struct {
|
|
Title string
|
|
Message string
|
|
RequestHeaders http.Header
|
|
SpinnerClass string
|
|
}
|
|
|
|
//go:embed html/loading_page.html
|
|
var loadingPage []byte
|
|
var loadingPageTmpl = template.Must(template.New("loading_page").Parse(string(loadingPage)))
|
|
|
|
const (
|
|
htmlContentType = "text/html; charset=utf-8"
|
|
|
|
errPrefix = "\u1000"
|
|
|
|
headerGoProxyTargetURL = "X-GoProxy-Target"
|
|
headerContentType = "Content-Type"
|
|
|
|
spinnerClassSpinner = "spinner"
|
|
spinnerClassErrorSign = "error"
|
|
)
|
|
|
|
func (w *watcher) makeSuccResp(redirectURL string, resp *http.Response) (*http.Response, error) {
|
|
h := make(http.Header)
|
|
h.Set("Location", redirectURL)
|
|
h.Set("Content-Length", "0")
|
|
h.Set(headerContentType, htmlContentType)
|
|
return &http.Response{
|
|
StatusCode: http.StatusTemporaryRedirect,
|
|
Header: h,
|
|
Body: http.NoBody,
|
|
TLS: resp.TLS,
|
|
}, nil
|
|
}
|
|
|
|
func (w *watcher) makeErrResp(errFmt string, args ...any) (*http.Response, error) {
|
|
return w.makeResp(errPrefix+errFmt, args...)
|
|
}
|
|
|
|
func (w *watcher) makeResp(format string, args ...any) (*http.Response, error) {
|
|
msg := fmt.Sprintf(format, args...)
|
|
|
|
data := new(templateData)
|
|
data.Title = w.ContainerName
|
|
data.Message = strings.ReplaceAll(msg, "\n", "<br>")
|
|
data.Message = strings.ReplaceAll(data.Message, " ", " ")
|
|
data.RequestHeaders = make(http.Header)
|
|
data.RequestHeaders.Add(headerGoProxyTargetURL, "window.location.href")
|
|
if strings.HasPrefix(data.Message, errPrefix) {
|
|
data.Message = strings.TrimLeft(data.Message, errPrefix)
|
|
data.SpinnerClass = spinnerClassErrorSign
|
|
} else {
|
|
data.SpinnerClass = spinnerClassSpinner
|
|
}
|
|
|
|
buf := bytes.NewBuffer(make([]byte, 128)) // more than enough
|
|
err := loadingPageTmpl.Execute(buf, data)
|
|
if err != nil { // should never happen
|
|
panic(err)
|
|
}
|
|
return &http.Response{
|
|
StatusCode: http.StatusAccepted,
|
|
Header: http.Header{
|
|
headerContentType: {htmlContentType},
|
|
"Cache-Control": {
|
|
"no-cache",
|
|
"no-store",
|
|
"must-revalidate",
|
|
},
|
|
},
|
|
Body: io.NopCloser(buf),
|
|
ContentLength: int64(buf.Len()),
|
|
}, nil
|
|
}
|