2020-10-08 10:12:26 +00:00
|
|
|
package connection
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/logger"
|
|
|
|
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Observer struct {
|
|
|
|
logger.Service
|
2020-11-30 20:05:37 +00:00
|
|
|
metrics *tunnelMetrics
|
|
|
|
tunnelEventChans []chan Event
|
|
|
|
uiEnabled bool
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
|
2020-11-30 20:05:37 +00:00
|
|
|
func NewObserver(logger logger.Service, tunnelEventChans []chan Event, uiEnabled bool) *Observer {
|
2020-10-08 10:12:26 +00:00
|
|
|
return &Observer{
|
|
|
|
logger,
|
2020-10-14 13:42:00 +00:00
|
|
|
newTunnelMetrics(),
|
2020-11-30 20:05:37 +00:00
|
|
|
tunnelEventChans,
|
|
|
|
uiEnabled,
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-09 11:40:48 +00:00
|
|
|
func (o *Observer) logServerInfo(connIndex uint8, location, msg string) {
|
2020-11-30 20:05:37 +00:00
|
|
|
o.sendEvent(Event{Index: connIndex, EventType: Connected, Location: location})
|
2020-10-08 10:12:26 +00:00
|
|
|
o.Infof(msg)
|
2020-11-09 11:40:48 +00:00
|
|
|
o.metrics.registerServerLocation(uint8ToString(connIndex), location)
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) logTrialHostname(registration *tunnelpogs.TunnelRegistration) error {
|
|
|
|
// Print out the user's trial zone URL in a nice box (if they requested and got one and UI flag is not set)
|
2020-11-30 20:05:37 +00:00
|
|
|
if !o.uiEnabled {
|
2020-10-08 10:12:26 +00:00
|
|
|
if registrationURL, err := url.Parse(registration.Url); err == nil {
|
|
|
|
for _, line := range asciiBox(trialZoneMsg(registrationURL.String()), 2) {
|
|
|
|
o.Info(line)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
o.Error("Failed to connect tunnel, please try again.")
|
|
|
|
return fmt.Errorf("empty URL in response from Cloudflare edge")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print out the given lines in a nice ASCII box.
|
|
|
|
func asciiBox(lines []string, padding int) (box []string) {
|
|
|
|
maxLen := maxLen(lines)
|
|
|
|
spacer := strings.Repeat(" ", padding)
|
|
|
|
|
|
|
|
border := "+" + strings.Repeat("-", maxLen+(padding*2)) + "+"
|
|
|
|
|
|
|
|
box = append(box, border)
|
|
|
|
for _, line := range lines {
|
|
|
|
box = append(box, "|"+spacer+line+strings.Repeat(" ", maxLen-len(line))+spacer+"|")
|
|
|
|
}
|
|
|
|
box = append(box, border)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func maxLen(lines []string) int {
|
|
|
|
max := 0
|
|
|
|
for _, line := range lines {
|
|
|
|
if len(line) > max {
|
|
|
|
max = len(line)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return max
|
|
|
|
}
|
|
|
|
|
|
|
|
func trialZoneMsg(url string) []string {
|
|
|
|
return []string{
|
|
|
|
"Your free tunnel has started! Visit it:",
|
|
|
|
" " + url,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) sendRegisteringEvent() {
|
2020-11-30 20:05:37 +00:00
|
|
|
o.sendEvent(Event{EventType: RegisteringTunnel})
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) sendConnectedEvent(connIndex uint8, location string) {
|
2020-11-30 20:05:37 +00:00
|
|
|
o.sendEvent(Event{Index: connIndex, EventType: Connected, Location: location})
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) sendURL(url string) {
|
2020-11-30 20:05:37 +00:00
|
|
|
o.sendEvent(Event{EventType: SetURL, URL: url})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) SendReconnect(connIndex uint8) {
|
|
|
|
o.sendEvent(Event{Index: connIndex, EventType: Reconnecting})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) SendDisconnect(connIndex uint8) {
|
|
|
|
o.sendEvent(Event{Index: connIndex, EventType: Disconnected})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *Observer) sendEvent(e Event) {
|
|
|
|
for _, ch := range o.tunnelEventChans {
|
|
|
|
ch <- e
|
2020-10-08 10:12:26 +00:00
|
|
|
}
|
|
|
|
}
|