OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / toqueteos / webbrowser / webbrowser.go
1 // Package webbrowser provides a simple API for opening web pages on your
2 // default browser.
3 package webbrowser
4
5 import (
6         "errors"
7         "fmt"
8         "net/url"
9         "os"
10         "os/exec"
11         "runtime"
12         "strings"
13 )
14
15 var (
16         ErrCantOpenBrowser = errors.New("webbrowser: can't open browser")
17         ErrNoCandidates    = errors.New("webbrowser: no browser candidate found for your OS")
18 )
19
20 // Candidates contains a list of registered `Browser`s that will be tried with Open.
21 var Candidates []Browser
22
23 type Browser interface {
24         // Command returns a ready to be used Cmd that will open an URL.
25         Command(string) (*exec.Cmd, error)
26         // Open tries to open a URL in your default browser. NOTE: This may cause
27         // your program to hang until the browser process is closed in some OSes,
28         // see https://github.com/toqueteos/webbrowser/issues/4.
29         Open(string) error
30 }
31
32 // Open tries to open a URL in your default browser ensuring you have a display
33 // set up and not running this from SSH. NOTE: This may cause your program to
34 // hang until the browser process is closed in some OSes, see
35 // https://github.com/toqueteos/webbrowser/issues/4.
36 func Open(s string) (err error) {
37         if len(Candidates) == 0 {
38                 return ErrNoCandidates
39         }
40
41         // Try to determine if there's a display available (only linux) and we
42         // aren't on a terminal (all but windows).
43         switch runtime.GOOS {
44         case "linux":
45                 // No display, no need to open a browser. Lynx users **MAY** have
46                 // something to say about this.
47                 if os.Getenv("DISPLAY") == "" {
48                         return fmt.Errorf("webbrowser: tried to open %q, no screen found", s)
49                 }
50                 fallthrough
51         case "darwin":
52                 // Check SSH env vars.
53                 if os.Getenv("SSH_CLIENT") != "" || os.Getenv("SSH_TTY") != "" {
54                         return fmt.Errorf("webbrowser: tried to open %q, but you are running a shell session", s)
55                 }
56         }
57
58         // Try all candidates
59         for _, candidate := range Candidates {
60                 err := candidate.Open(s)
61                 if err == nil {
62                         return nil
63                 }
64         }
65
66         return ErrCantOpenBrowser
67 }
68
69 func init() {
70         // Register the default Browser for current OS, if it exists.
71         if os, ok := osCommand[runtime.GOOS]; ok {
72                 Candidates = append(Candidates, browserCommand{os.cmd, os.args})
73         }
74 }
75
76 var (
77         osCommand = map[string]*browserCommand{
78                 "android": &browserCommand{"xdg-open", nil},
79                 "darwin":  &browserCommand{"open", nil},
80                 "freebsd": &browserCommand{"xdg-open", nil},
81                 "linux":   &browserCommand{"xdg-open", nil},
82                 "netbsd":  &browserCommand{"xdg-open", nil},
83                 "openbsd": &browserCommand{"xdg-open", nil}, // It may be open instead
84                 "windows": &browserCommand{"cmd", []string{"/c", "start"}},
85         }
86         winSchemes = [3]string{"https", "http", "file"}
87 )
88
89 type browserCommand struct {
90         cmd  string
91         args []string
92 }
93
94 func (b browserCommand) Command(s string) (*exec.Cmd, error) {
95         u, err := url.Parse(s)
96         if err != nil {
97                 return nil, err
98         }
99
100         validUrl := ensureValidURL(u)
101
102         b.args = append(b.args, validUrl)
103
104         return exec.Command(b.cmd, b.args...), nil
105 }
106
107 func (b browserCommand) Open(s string) error {
108         cmd, err := b.Command(s)
109         if err != nil {
110                 return err
111         }
112
113         return cmd.Run()
114 }
115
116 func ensureScheme(u *url.URL) {
117         for _, s := range winSchemes {
118                 if u.Scheme == s {
119                         return
120                 }
121         }
122         u.Scheme = "http"
123 }
124
125 func ensureValidURL(u *url.URL) string {
126         // Enforce a scheme (windows requires scheme to be set to work properly).
127         ensureScheme(u)
128         s := u.String()
129
130         // Escape characters not allowed by cmd/bash
131         switch runtime.GOOS {
132         case "windows":
133                 s = strings.Replace(s, "&", `^&`, -1)
134         }
135
136         return s
137 }