ipn/{ipnserver,localapi}: fix InUseOtherUser handling with WatchIPNBus
Updates tailscale/corp#8222 Change-Id: I2d6fa6514c7b8d0f89fded35a2d44e7df27e6fb1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
86b6ff61e6
commit
964d723aba
@ -40,6 +40,7 @@ import (
|
||||
"tailscale.com/tka"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/strs"
|
||||
@ -607,6 +608,32 @@ func (h *Handler) serveStatus(w http.ResponseWriter, r *http.Request) {
|
||||
e.Encode(st)
|
||||
}
|
||||
|
||||
// InUseOtherUserIPNStream reports whether r is a request for the watch-ipn-bus
|
||||
// handler. If so, it writes an ipn.Notify InUseOtherUser message to the user
|
||||
// and returns true. Otherwise it returns false, in which case it doesn't write
|
||||
// to w.
|
||||
//
|
||||
// Unlike the regular watch-ipn-bus handler, this one doesn't block. The caller
|
||||
// (in ipnserver.Server) provides the blocking until the connection is no longer
|
||||
// in use.
|
||||
func InUseOtherUserIPNStream(w http.ResponseWriter, r *http.Request, err error) (handled bool) {
|
||||
if r.Method != "GET" || r.URL.Path != "/localapi/v0/watch-ipn-bus" {
|
||||
return false
|
||||
}
|
||||
js, err := json.Marshal(&ipn.Notify{
|
||||
Version: version.Long,
|
||||
State: ptr.To(ipn.InUseOtherUser),
|
||||
ErrMessage: ptr.To(err.Error()),
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
js = append(js, '\n')
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(js)
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Handler) serveWatchIPNBus(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.PermitWrite {
|
||||
http.Error(w, "denied", http.StatusForbidden)
|
||||
|
Reference in New Issue
Block a user