mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package webbrowser provides a simple API for opening web pages on your
 | 
						|
// default browser.
 | 
						|
package webbrowser
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"runtime"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	ErrCantOpenBrowser = errors.New("webbrowser: can't open browser")
 | 
						|
	ErrNoCandidates    = errors.New("webbrowser: no browser candidate found for your OS")
 | 
						|
)
 | 
						|
 | 
						|
// Candidates contains a list of registered `Browser`s that will be tried with Open.
 | 
						|
var Candidates []Browser
 | 
						|
 | 
						|
type Browser interface {
 | 
						|
	// Command returns a ready to be used Cmd that will open an URL.
 | 
						|
	Command(string) (*exec.Cmd, error)
 | 
						|
	// Open tries to open a URL in your default browser. NOTE: This may cause
 | 
						|
	// your program to hang until the browser process is closed in some OSes,
 | 
						|
	// see https://github.com/toqueteos/webbrowser/issues/4.
 | 
						|
	Open(string) error
 | 
						|
}
 | 
						|
 | 
						|
// Open tries to open a URL in your default browser ensuring you have a display
 | 
						|
// set up and not running this from SSH. NOTE: This may cause your program to
 | 
						|
// hang until the browser process is closed in some OSes, see
 | 
						|
// https://github.com/toqueteos/webbrowser/issues/4.
 | 
						|
func Open(s string) (err error) {
 | 
						|
	if len(Candidates) == 0 {
 | 
						|
		return ErrNoCandidates
 | 
						|
	}
 | 
						|
 | 
						|
	// Try to determine if there's a display available (only linux) and we
 | 
						|
	// aren't on a terminal (all but windows).
 | 
						|
	switch runtime.GOOS {
 | 
						|
	case "linux":
 | 
						|
		// No display, no need to open a browser. Lynx users **MAY** have
 | 
						|
		// something to say about this.
 | 
						|
		if os.Getenv("DISPLAY") == "" {
 | 
						|
			return fmt.Errorf("webbrowser: tried to open %q, no screen found", s)
 | 
						|
		}
 | 
						|
		fallthrough
 | 
						|
	case "darwin":
 | 
						|
		// Check SSH env vars.
 | 
						|
		if os.Getenv("SSH_CLIENT") != "" || os.Getenv("SSH_TTY") != "" {
 | 
						|
			return fmt.Errorf("webbrowser: tried to open %q, but you are running a shell session", s)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Try all candidates
 | 
						|
	for _, candidate := range Candidates {
 | 
						|
		err := candidate.Open(s)
 | 
						|
		if err == nil {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return ErrCantOpenBrowser
 | 
						|
}
 | 
						|
 | 
						|
func init() {
 | 
						|
	// Register the default Browser for current OS, if it exists.
 | 
						|
	if os, ok := osCommand[runtime.GOOS]; ok {
 | 
						|
		Candidates = append(Candidates, browserCommand{os.cmd, os.args})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var (
 | 
						|
	osCommand = map[string]*browserCommand{
 | 
						|
		"android": &browserCommand{"xdg-open", nil},
 | 
						|
		"darwin":  &browserCommand{"open", nil},
 | 
						|
		"freebsd": &browserCommand{"xdg-open", nil},
 | 
						|
		"linux":   &browserCommand{"xdg-open", nil},
 | 
						|
		"netbsd":  &browserCommand{"xdg-open", nil},
 | 
						|
		"openbsd": &browserCommand{"xdg-open", nil}, // It may be open instead
 | 
						|
		"windows": &browserCommand{"cmd", []string{"/c", "start"}},
 | 
						|
	}
 | 
						|
	winSchemes = [3]string{"https", "http", "file"}
 | 
						|
)
 | 
						|
 | 
						|
type browserCommand struct {
 | 
						|
	cmd  string
 | 
						|
	args []string
 | 
						|
}
 | 
						|
 | 
						|
func (b browserCommand) Command(s string) (*exec.Cmd, error) {
 | 
						|
	u, err := url.Parse(s)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	validUrl := ensureValidURL(u)
 | 
						|
 | 
						|
	b.args = append(b.args, validUrl)
 | 
						|
 | 
						|
	return exec.Command(b.cmd, b.args...), nil
 | 
						|
}
 | 
						|
 | 
						|
func (b browserCommand) Open(s string) error {
 | 
						|
	cmd, err := b.Command(s)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return cmd.Run()
 | 
						|
}
 | 
						|
 | 
						|
func ensureScheme(u *url.URL) {
 | 
						|
	for _, s := range winSchemes {
 | 
						|
		if u.Scheme == s {
 | 
						|
			return
 | 
						|
		}
 | 
						|
	}
 | 
						|
	u.Scheme = "http"
 | 
						|
}
 | 
						|
 | 
						|
func ensureValidURL(u *url.URL) string {
 | 
						|
	// Enforce a scheme (windows requires scheme to be set to work properly).
 | 
						|
	ensureScheme(u)
 | 
						|
	s := u.String()
 | 
						|
 | 
						|
	// Escape characters not allowed by cmd/bash
 | 
						|
	switch runtime.GOOS {
 | 
						|
	case "windows":
 | 
						|
		s = strings.Replace(s, "&", `^&`, -1)
 | 
						|
	}
 | 
						|
 | 
						|
	return s
 | 
						|
}
 |