mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Implement loading screen for slow requests
This commit is contained in:
parent
9aafa18254
commit
cca211de0e
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.rice"
|
||||
"html/template"
|
||||
@ -9,6 +8,8 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WebUiHandler struct {
|
||||
@ -19,6 +20,8 @@ type WebUiHandler struct {
|
||||
tunMan *TunnelManager
|
||||
box *rice.Box
|
||||
headHtml template.HTML
|
||||
pendingRequests map[string]chan string
|
||||
mutex *sync.Mutex
|
||||
}
|
||||
|
||||
type IndexData struct {
|
||||
@ -41,6 +44,11 @@ type ConfirmData struct {
|
||||
CancelUrl string
|
||||
}
|
||||
|
||||
type LoadingData struct {
|
||||
Head template.HTML
|
||||
TargetUrl string
|
||||
}
|
||||
|
||||
type AlertData struct {
|
||||
Head template.HTML
|
||||
Message string
|
||||
@ -81,6 +89,8 @@ func NewWebUiHandler(config *BoringProxyConfig, db *Database, api *Api, auth *Au
|
||||
api: api,
|
||||
auth: auth,
|
||||
tunMan: tunMan,
|
||||
pendingRequests: make(map[string]chan string),
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,6 +301,8 @@ func (h *WebUiHandler) handleWebUiRequest(w http.ResponseWriter, r *http.Request
|
||||
cookie := &http.Cookie{Name: "access_token", Value: "", Secure: true, HttpOnly: true}
|
||||
http.SetCookie(w, cookie)
|
||||
http.Redirect(w, r, "/#/tunnels", 303)
|
||||
case "/loading":
|
||||
h.handleLoading(w, r)
|
||||
default:
|
||||
w.WriteHeader(404)
|
||||
h.alertDialog(w, r, "Unknown page "+r.URL.Path, "/#/tunnels")
|
||||
@ -377,16 +389,57 @@ func (h *WebUiHandler) handleTunnels(w http.ResponseWriter, r *http.Request, tok
|
||||
|
||||
func (h *WebUiHandler) handleCreateTunnel(w http.ResponseWriter, r *http.Request, tokenData TokenData) {
|
||||
|
||||
pendingId, err := genRandomCode(16)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
h.alertDialog(w, r, err.Error(), "/#/tunnels")
|
||||
}
|
||||
|
||||
doneSignal := make(chan string)
|
||||
h.mutex.Lock()
|
||||
h.pendingRequests[pendingId] = doneSignal
|
||||
h.mutex.Unlock()
|
||||
|
||||
go func() {
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
_, err := h.api.CreateTunnel(tokenData, r.Form)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
h.alertDialog(w, r, err.Error(), "/#/tunnels")
|
||||
}
|
||||
|
||||
doneSignal <- "/#/tunnels"
|
||||
}()
|
||||
|
||||
timeout := make(chan bool, 1)
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
timeout <- true
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-timeout:
|
||||
url := fmt.Sprintf("/loading?id=%s", pendingId)
|
||||
|
||||
tmpl, err := h.loadTemplate("loading.tmpl")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
h.alertDialog(w, r, err.Error(), "/#/tunnels")
|
||||
return
|
||||
}
|
||||
|
||||
data := &LoadingData{
|
||||
Head: h.headHtml,
|
||||
TargetUrl: url,
|
||||
}
|
||||
|
||||
tmpl.Execute(w, data)
|
||||
|
||||
case <-doneSignal:
|
||||
http.Redirect(w, r, "/#/tunnels", 303)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) sendLoginPage(w http.ResponseWriter, r *http.Request, code int) {
|
||||
@ -555,16 +608,36 @@ func (h *WebUiHandler) alertDialog(w http.ResponseWriter, r *http.Request, messa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) handleLoading(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if r.Method != "GET" {
|
||||
w.WriteHeader(405)
|
||||
h.alertDialog(w, r, "Invalid method for users", "/#/tunnels")
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
pendingId := r.Form.Get("id")
|
||||
|
||||
h.mutex.Lock()
|
||||
doneSignal := h.pendingRequests[pendingId]
|
||||
h.mutex.Unlock()
|
||||
|
||||
redirUrl := <-doneSignal
|
||||
|
||||
http.Redirect(w, r, redirUrl, 303)
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) loadTemplate(name string) (*template.Template, error) {
|
||||
|
||||
tmplStr, err := h.box.String(name)
|
||||
if err != nil {
|
||||
return nil, errors.New("Error reading template " + name)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tmpl, err := template.New(name).Parse(tmplStr)
|
||||
if err != nil {
|
||||
return nil, errors.New("Error compiling template " + name)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tmpl, nil
|
||||
|
17
webui/loading.tmpl
Normal file
17
webui/loading.tmpl
Normal file
@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL='{{$.TargetUrl}}'" />
|
||||
{{.Head}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<div class='dialog'>
|
||||
<p>
|
||||
Loading...
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user