本文整理汇总了Golang中ngrok/version.MajorMinor函数的典型用法代码示例。如果您正苦于以下问题:Golang MajorMinor函数的具体用法?Golang MajorMinor怎么用?Golang MajorMinor使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了MajorMinor函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: versionCheck
func versionCheck(s *State, ctl *ui.Controller) {
check := func() {
resp, err := http.Get(versionEndpoint)
if err != nil {
log.Warn("Failed to get version info %s: %v", versionEndpoint, err)
return
}
defer resp.Body.Close()
var payload struct {
Client struct {
Version string
}
}
err = json.NewDecoder(resp.Body).Decode(&payload)
if err != nil {
log.Warn("Failed to read version info: %v", err)
return
}
if payload.Client.Version != version.MajorMinor() {
s.newVersion = payload.Client.Version
ctl.Update(s)
}
}
// check immediately and then at a set interval
check()
for _ = range time.Tick(versionCheckInterval) {
check()
}
}
示例2: parseArgs
func parseArgs() *Options {
authtoken := flag.String(
"authtoken",
"",
"Authentication token for identifying a premium ngrok.com account")
server := flag.String(
"server",
"ngrok.com:4443",
"The remote ngrok server")
httpAuth := flag.String(
"httpauth",
"",
"username:password HTTP basic auth creds protecting the public tunnel endpoint")
subdomain := flag.String(
"subdomain",
"",
"Request a custom subdomain from the ngrok server. (HTTP mode only)")
protocol := flag.String(
"proto",
"http",
"The protocol of the traffic over the tunnel {'http', 'tcp'} (default: 'http')")
webport := flag.Int(
"webport",
4040,
"The port on which the web interface is served")
logto := flag.String(
"log",
"none",
"Write log messages to this file. 'stdout' and 'none' have special meanings")
v := flag.Bool(
"version",
false,
"Print ngrok version and exit")
flag.Parse()
if *v {
fmt.Println(version.MajorMinor())
os.Exit(0)
}
return &Options{
server: *server,
httpAuth: *httpAuth,
subdomain: *subdomain,
localaddr: parseLocalAddr(),
protocol: parseProtocol(*protocol),
webport: *webport,
logto: *logto,
authtoken: parseAuthToken(*authtoken),
}
}
示例3: autoUpdate
func autoUpdate(s mvc.State, token string) {
up, err := update.New().VerifySignatureWithPEM([]byte(publicKey))
if err != nil {
log.Error("Failed to create update with signature: %v", err)
return
}
update := func() (tryAgain bool) {
log.Info("Checking for update")
params := check.Params{
AppId: appId,
AppVersion: version.MajorMinor(),
UserId: token,
}
result, err := params.CheckForUpdate(updateEndpoint, up)
if err == check.NoUpdateAvailable {
log.Info("No update available")
return true
} else if err != nil {
log.Error("Error while checking for update: %v", err)
return true
}
if result.Initiative == check.INITIATIVE_AUTO {
if err := up.CanUpdate(); err != nil {
log.Error("Can't update: insufficient permissions: %v", err)
// tell the user to update manually
s.SetUpdateStatus(mvc.UpdateAvailable)
} else {
applyUpdate(s, result)
}
} else if result.Initiative == check.INITIATIVE_MANUAL {
// this is the way the server tells us to update manually
log.Info("Server wants us to update manually")
s.SetUpdateStatus(mvc.UpdateAvailable)
} else {
log.Info("Update available, but ignoring")
}
// stop trying after a single download attempt
// XXX: improve this so the we can:
// 1. safely update multiple times
// 2. only retry after temporary errors
return false
}
// try to update immediately and then at a set interval
for {
if tryAgain := update(); !tryAgain {
break
}
time.Sleep(updateCheckInterval)
}
}
示例4: NewControl
func NewControl(ctlConn conn.Conn, authMsg *msg.Auth) {
var err error
// create the object
// channels are buffered because we read and write to them
// from the same goroutine in managerThread()
c := &Control{
auth: authMsg,
conn: ctlConn,
out: make(chan msg.Message, 5),
in: make(chan msg.Message, 5),
stop: make(chan msg.Message, 5),
proxies: make(chan conn.Conn, 10),
lastPing: time.Now(),
}
failAuth := func(e error) {
_ = msg.WriteMsg(ctlConn, &msg.AuthResp{Error: e.Error()})
ctlConn.Close()
}
// register the clientid
c.id = authMsg.ClientId
if c.id == "" {
// it's a new session, assign an ID
if c.id, err = util.SecureRandId(16); err != nil {
failAuth(err)
return
}
}
if authMsg.Version != version.Proto {
failAuth(fmt.Errorf("Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com", version.MajorMinor(), authMsg.Version))
return
}
// register the control
controlRegistry.Add(c.id, c)
c.out <- &msg.AuthResp{
Version: version.Proto,
MmVersion: version.MajorMinor(),
ClientId: c.id,
}
// As a performance optimization, ask for a proxy connection up front
c.out <- &msg.ReqProxy{}
// set logging prefix
ctlConn.SetType("ctl")
// manage the connection
go c.managerThread()
go c.readThread()
}
示例5: managerThread
func (c *Control) managerThread() {
reap := time.NewTicker(connReapInterval)
// all shutdown functionality in here
defer func() {
if err := recover(); err != nil {
c.conn.Info("Control::managerThread failed with error %v: %s", err, debug.Stack())
}
reap.Stop()
c.conn.Close()
// shutdown the tunnel if it's open
if c.tun != nil {
c.tun.shutdown()
}
}()
for {
select {
case m := <-c.out:
msg.WriteMsg(c.conn, m)
case <-reap.C:
if time.Since(c.lastPing) > pingTimeoutInterval {
c.conn.Info("Lost heartbeat")
metrics.lostHeartbeatMeter.Mark(1)
return
}
case m := <-c.stop:
if m != nil {
msg.WriteMsg(c.conn, m)
}
return
case mRaw := <-c.in:
switch m := mRaw.(type) {
case *msg.RegMsg:
c.conn.Info("Registering new tunnel")
c.tun = newTunnel(m, c)
case *msg.PingMsg:
c.lastPing = time.Now()
c.out <- &msg.PongMsg{}
case *msg.VersionMsg:
c.out <- &msg.VersionRespMsg{
Version: version.Proto,
MmVersion: version.MajorMinor(),
}
}
}
}
}
示例6: newTunnel
func newTunnel(m *msg.RegMsg, ctl *Control) (t *Tunnel) {
t = &Tunnel{
regMsg: m,
start: time.Now(),
ctl: ctl,
proxies: make(chan conn.Conn),
Logger: log.NewPrefixLogger(),
}
switch t.regMsg.Protocol {
case "tcp":
var err error
t.listener, err = net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 0})
if err != nil {
t.ctl.conn.Error("Failed to create tunnel. Error binding TCP listener: %v", err)
t.ctl.stop <- &msg.RegAckMsg{Error: "Internal server error"}
}
go t.listenTcp(t.listener)
default:
}
if err := tunnels.Add(t); err != nil {
t.ctl.stop <- &msg.RegAckMsg{Error: fmt.Sprint(err)}
return
}
if m.Version != version.Proto {
t.ctl.stop <- &msg.RegAckMsg{Error: fmt.Sprintf("Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com", version.MajorMinor(), m.Version)}
}
// pre-encode the http basic auth for fast comparisons later
if m.HttpAuth != "" {
m.HttpAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(m.HttpAuth))
}
t.ctl.conn.AddLogPrefix(t.Id())
t.AddLogPrefix(t.Id())
t.Info("Registered new tunnel")
t.ctl.out <- &msg.RegAckMsg{
Url: t.url,
ProxyAddr: fmt.Sprintf("%s", proxyAddr),
Version: version.Proto,
MmVersion: version.MajorMinor(),
}
metrics.OpenTunnel(t)
return
}
示例7: GetClientVersion
// implement client.ui.State
func (s State) GetClientVersion() string { return version.MajorMinor() }
示例8: ParseArgs
func ParseArgs() (opts *Options, err error) {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, usage1, os.Args[0])
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, usage2)
}
config := flag.String(
"config",
"",
"Path to ngrok configuration file. (default: $HOME/.ngrok)")
logto := flag.String(
"log",
"none",
"Write log messages to this file. 'stdout' and 'none' have special meanings")
authtoken := flag.String(
"authtoken",
"",
"Authentication token for identifying an ngrok.com account")
httpauth := flag.String(
"httpauth",
"",
"username:password HTTP basic auth creds protecting the public tunnel endpoint")
subdomain := flag.String(
"subdomain",
"",
"Request a custom subdomain from the ngrok server. (HTTP only)")
hostname := flag.String(
"hostname",
"",
"Request a custom hostname from the ngrok server. (HTTP only) (requires CNAME of your DNS)")
protocol := flag.String(
"proto",
"http+https",
"The protocol of the traffic over the tunnel {'http', 'https', 'tcp'} (default: 'http+https')")
flag.Parse()
opts = &Options{
config: *config,
logto: *logto,
httpauth: *httpauth,
subdomain: *subdomain,
protocol: *protocol,
authtoken: *authtoken,
hostname: *hostname,
command: flag.Arg(0),
}
switch opts.command {
case "start":
opts.args = flag.Args()[1:]
case "version":
fmt.Println(version.MajorMinor())
os.Exit(0)
case "help":
flag.Usage()
os.Exit(0)
case "":
err = fmt.Errorf("Error: Specify a local port to tunnel to, or " +
"an ngrok command.\n\nExample: To expose port 80, run " +
"'ngrok 80'")
return
default:
if len(flag.Args()) > 1 {
err = fmt.Errorf("You may only specify one port to tunnel to on the command line, got %d: %v",
len(flag.Args()),
flag.Args())
return
}
opts.command = "default"
opts.args = flag.Args()
}
return
}
示例9: control
// Establishes and manages a tunnel control connection with the server
func (c *ClientModel) control() {
defer func() {
if r := recover(); r != nil {
log.Error("control recovering from failure %v", r)
}
}()
// establish control channel
var (
ctlConn conn.Conn
err error
)
if c.proxyUrl == "" {
// simple non-proxied case, just connect to the server
ctlConn, err = conn.Dial(c.serverAddr, "ctl", c.tlsConfig)
} else {
ctlConn, err = conn.DialHttpProxy(c.proxyUrl, c.serverAddr, "ctl", c.tlsConfig)
}
if err != nil {
panic(err)
}
defer ctlConn.Close()
// authenticate with the server
auth := &msg.Auth{
ClientId: c.id,
OS: runtime.GOOS,
Arch: runtime.GOARCH,
Version: version.Proto,
MmVersion: version.MajorMinor(),
User: c.authToken,
}
if err = msg.WriteMsg(ctlConn, auth); err != nil {
panic(err)
}
// wait for the server to authenticate us
var authResp msg.AuthResp
if err = msg.ReadMsgInto(ctlConn, &authResp); err != nil {
panic(err)
}
if authResp.Error != "" {
emsg := fmt.Sprintf("Failed to authenticate to server: %s", authResp.Error)
c.ctl.Shutdown(emsg)
return
}
c.id = authResp.ClientId
c.serverVersion = authResp.MmVersion
c.Info("Authenticated with server, client id: %v", c.id)
c.update()
if err = SaveAuthToken(c.configPath, c.authToken); err != nil {
c.Error("Failed to save auth token: %v", err)
}
// request tunnels
reqIdToTunnelConfig := make(map[string]*TunnelConfiguration)
for _, config := range c.tunnelConfig {
// create the protocol list to ask for
var protocols []string
for proto, _ := range config.Protocols {
protocols = append(protocols, proto)
}
reqTunnel := &msg.ReqTunnel{
ReqId: util.RandId(8),
Protocol: strings.Join(protocols, "+"),
Hostname: config.Hostname,
Subdomain: config.Subdomain,
HttpAuth: config.HttpAuth,
RemotePort: config.RemotePort,
}
// send the tunnel request
if err = msg.WriteMsg(ctlConn, reqTunnel); err != nil {
panic(err)
}
// save request id association so we know which local address
// to proxy to later
reqIdToTunnelConfig[reqTunnel.ReqId] = config
}
// start the heartbeat
lastPong := time.Now().UnixNano()
c.ctl.Go(func() { c.heartbeat(&lastPong, ctlConn) })
// main control loop
for {
var rawMsg msg.Message
if rawMsg, err = msg.ReadMsg(ctlConn); err != nil {
panic(err)
}
switch m := rawMsg.(type) {
case *msg.ReqProxy:
c.ctl.Go(c.proxy)
//.........这里部分代码省略.........
示例10: GetClientVersion
func (c ClientModel) GetClientVersion() string { return version.MajorMinor() }
示例11: NewControl
func NewControl(ctlConn conn.Conn, authMsg *msg.Auth, required_secret string) {
var err error
// create the object
c := &Control{
auth: authMsg,
conn: ctlConn,
out: make(chan msg.Message),
in: make(chan msg.Message),
proxies: make(chan conn.Conn, 10),
lastPing: time.Now(),
writerShutdown: util.NewShutdown(),
readerShutdown: util.NewShutdown(),
managerShutdown: util.NewShutdown(),
shutdown: util.NewShutdown(),
}
failAuth := func(e error) {
_ = msg.WriteMsg(ctlConn, &msg.AuthResp{Error: e.Error()})
ctlConn.Close()
}
// register the clientid
c.id = authMsg.ClientId
if c.id == "" {
// it's a new session, assign an ID
if c.id, err = util.SecureRandId(16); err != nil {
failAuth(err)
return
}
}
// set logging prefix
ctlConn.SetType("ctl")
ctlConn.AddLogPrefix(c.id)
if authMsg.Version != version.Proto {
failAuth(fmt.Errorf("Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com", version.MajorMinor(), authMsg.Version))
return
}
if required_secret != "" && authMsg.User != required_secret {
failAuth(fmt.Errorf("Invalid authtoken %s", authMsg.User))
return
}
// register the control
if replaced := controlRegistry.Add(c.id, c); replaced != nil {
replaced.shutdown.WaitComplete()
}
// start the writer first so that the following messages get sent
go c.writer()
// Respond to authentication
c.out <- &msg.AuthResp{
Version: version.Proto,
MmVersion: version.MajorMinor(),
ClientId: c.id,
}
// As a performance optimization, ask for a proxy connection up front
c.out <- &msg.ReqProxy{}
// manage the connection
go c.manager()
go c.reader()
go c.stopper()
}
示例12: control
/**
* Establishes and manages a tunnel control connection with the server
*/
func control(s *State, ctl *ui.Controller) {
defer func() {
if r := recover(); r != nil {
log.Error("control recovering from failure %v", r)
}
}()
// establish control channel
conn, err := conn.Dial(s.opts.server, "ctl", tlsConfig)
if err != nil {
panic(err)
}
defer conn.Close()
// register with the server
err = msg.WriteMsg(conn, &msg.RegMsg{
Protocol: s.opts.protocol,
OS: runtime.GOOS,
HttpAuth: s.opts.httpAuth,
Hostname: s.opts.hostname,
Subdomain: s.opts.subdomain,
ClientId: s.id,
Version: version.Proto,
MmVersion: version.MajorMinor(),
User: s.opts.authtoken,
})
if err != nil {
panic(err)
}
// wait for the server to ack our register
var regAck msg.RegAckMsg
if err = msg.ReadMsgInto(conn, ®Ack); err != nil {
panic(err)
}
if regAck.Error != "" {
emsg := fmt.Sprintf("Server failed to allocate tunnel: %s", regAck.Error)
ctl.Cmds <- ui.CmdQuit{Message: emsg}
return
}
// update UI state
s.publicUrl = regAck.Url
conn.Info("Tunnel established at %v", s.GetPublicUrl())
s.status = "online"
s.serverVersion = regAck.MmVersion
ctl.Update(s)
SaveAuthToken(s.opts.authtoken)
// start the heartbeat
lastPong := time.Now().UnixNano()
go heartbeat(&lastPong, conn)
// main control loop
for {
var m msg.Message
if m, err = msg.ReadMsg(conn); err != nil {
panic(err)
}
switch m.(type) {
case *msg.ReqProxyMsg:
go proxy(regAck.ProxyAddr, s, ctl)
case *msg.PongMsg:
atomic.StoreInt64(&lastPong, time.Now().UnixNano())
}
}
}
示例13: newTunnel
func newTunnel(m *msg.RegMsg, ctl *Control) (t *Tunnel) {
t = &Tunnel{
regMsg: m,
start: time.Now(),
ctl: ctl,
proxies: make(chan conn.Conn),
Logger: log.NewPrefixLogger(),
}
failReg := func(err error) {
t.ctl.stop <- &msg.RegAckMsg{Error: err.Error()}
}
var err error
switch t.regMsg.Protocol {
case "tcp":
var port int = 0
// try to return to you the same port you had before
cachedUrl := tunnels.GetCachedRegistration(t)
if cachedUrl != "" {
parts := strings.Split(cachedUrl, ":")
portPart := parts[len(parts)-1]
port, err = strconv.Atoi(portPart)
if err != nil {
t.ctl.conn.Error("Failed to parse cached url port as integer: %s", portPart)
// continue with zero
port = 0
}
}
// Bind for TCP connections
t.listener, err = net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: port})
// If we failed with a custom port, try with a random one
if err != nil && port != 0 {
t.ctl.conn.Warn("Failed to get custom port %d: %v, trying a random one", port, err)
t.listener, err = net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 0})
}
// we tried to bind with a random port and failed (no more ports available?)
if err != nil {
failReg(t.ctl.conn.Error("Error binding TCP listener: %v", err))
return
}
// create the url
addr := t.listener.Addr().(*net.TCPAddr)
t.url = fmt.Sprintf("tcp://%s:%d", domain, addr.Port)
// register it
if err = tunnels.RegisterAndCache(t.url, t); err != nil {
// This should never be possible because the OS will
// only assign available ports to us.
t.listener.Close()
failReg(fmt.Errorf("TCP listener bound, but failed to register %s", t.url))
return
}
go t.listenTcp(t.listener)
case "http":
if strings.TrimSpace(t.regMsg.Hostname) != "" {
t.url = fmt.Sprintf("http://%s", t.regMsg.Hostname)
} else if strings.TrimSpace(t.regMsg.Subdomain) != "" {
t.url = fmt.Sprintf("http://%s.%s", t.regMsg.Subdomain, domain)
}
if t.url != "" {
if err := tunnels.Register(t.url, t); err != nil {
failReg(err)
return
}
} else {
t.url, err = tunnels.RegisterRepeat(func() string {
return fmt.Sprintf("http://%x.%s", rand.Int31(), domain)
}, t)
if err != nil {
failReg(err)
return
}
}
}
if m.Version != version.Proto {
failReg(fmt.Errorf("Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com", version.MajorMinor(), m.Version))
return
}
// pre-encode the http basic auth for fast comparisons later
if m.HttpAuth != "" {
m.HttpAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(m.HttpAuth))
}
t.ctl.conn.AddLogPrefix(t.Id())
t.AddLogPrefix(t.Id())
t.Info("Registered new tunnel")
t.ctl.out <- &msg.RegAckMsg{
//.........这里部分代码省略.........
示例14: newTunnel
func newTunnel(m *msg.RegMsg, ctl *Control) (t *Tunnel) {
t = &Tunnel{
regMsg: m,
start: time.Now(),
ctl: ctl,
proxies: make(chan conn.Conn),
Logger: log.NewPrefixLogger(),
}
failReg := func(err error) {
t.ctl.stop <- &msg.RegAckMsg{Error: err.Error()}
}
switch t.regMsg.Protocol {
case "tcp":
var err error
t.listener, err = net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 0})
if err != nil {
t.ctl.conn.Error("Failed to create tunnel. Error binding TCP listener: %v", err)
t.ctl.stop <- &msg.RegAckMsg{Error: "Internal server error"}
}
addr := t.listener.Addr().(*net.TCPAddr)
t.url = fmt.Sprintf("tcp://%s:%d", domain, addr.Port)
if err = tunnels.Register(t.url, t); err != nil {
// This should never be possible because the OS will only assign
// available ports to us.
t.Error("TCP listener bound, but failed to register: %s", err.Error())
t.listener.Close()
failReg(err)
return
}
go t.listenTcp(t.listener)
case "http":
if strings.TrimSpace(t.regMsg.Hostname) != "" {
t.url = fmt.Sprintf("http://%s", t.regMsg.Hostname)
} else if strings.TrimSpace(t.regMsg.Subdomain) != "" {
t.url = fmt.Sprintf("http://%s.%s", t.regMsg.Subdomain, domain)
}
if t.url != "" {
if err := tunnels.Register(t.url, t); err != nil {
failReg(err)
return
}
} else {
t.url = tunnels.RegisterRepeat(func() string {
return fmt.Sprintf("http://%x.%s", rand.Int31(), domain)
}, t)
}
}
if m.Version != version.Proto {
failReg(fmt.Errorf("Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com", version.MajorMinor(), m.Version))
return
}
// pre-encode the http basic auth for fast comparisons later
if m.HttpAuth != "" {
m.HttpAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(m.HttpAuth))
}
t.ctl.conn.AddLogPrefix(t.Id())
t.AddLogPrefix(t.Id())
t.Info("Registered new tunnel")
t.ctl.out <- &msg.RegAckMsg{
Url: t.url,
ProxyAddr: fmt.Sprintf("%s", proxyAddr),
Version: version.Proto,
MmVersion: version.MajorMinor(),
}
metrics.OpenTunnel(t)
return
}
示例15: autoUpdate
func autoUpdate(s mvc.State, token string) {
tryAgain := true
params := make(url.Values)
params.Add("version", version.MajorMinor())
params.Add("os", runtime.GOOS)
params.Add("arch", runtime.GOARCH)
params.Add("user", token)
updateUrl := updateEndpoint + "?" + params.Encode()
checkUrl := checkEndpoint + "?" + params.Encode()
update := func() {
log.Info("Checking for update")
available, err := update.NewDownload(checkUrl).Check()
if err != nil {
log.Error("Error while checking for update: %v", err)
return
}
if !available {
log.Info("No update available")
return
}
// stop trying after a single download attempt
// XXX: improve this so the we can:
// 1. safely update multiple times
// 2. only retry after a network connection failure
tryAgain = false
download := update.NewDownload(updateUrl)
downloadComplete := make(chan int)
go progressWatcher(s, download.Progress, downloadComplete)
log.Info("Trying to update . . .")
err, errRecover := download.GetAndUpdate()
<-downloadComplete
if err != nil {
// log error to console
log.Error("Error while updating ngrok: %v", err)
if errRecover != nil {
log.Error("Error while recovering from failed ngrok update, your binary may be missing: %v", errRecover.Error())
params.Add("errorRecover", errRecover.Error())
}
// log error to ngrok.com's servers for debugging purposes
params.Add("error", err.Error())
resp, reportErr := http.PostForm("https://dl.ngrok.com/update/error", params)
if err != nil {
log.Error("Error while reporting update error: %v, %v", err, reportErr)
}
resp.Body.Close()
// tell the user to update manually
s.SetUpdateStatus(mvc.UpdateAvailable)
} else {
if !download.Available {
// this is the way the server tells us to update manually
log.Info("Server wants us to update manually")
s.SetUpdateStatus(mvc.UpdateAvailable)
} else {
// tell the user the update is ready
log.Info("Update ready!")
s.SetUpdateStatus(mvc.UpdateReady)
}
}
return
}
// try to update immediately and then at a set interval
update()
for _ = range time.Tick(updateCheckInterval) {
if !tryAgain {
break
}
update()
}
}