diff --git a/cmd/root.go b/cmd/root.go index 90269fcd4b8be18e168c15074b8fafc7c2bdbdda..721e89de134d6bf7f264de8c28050e11b3207220 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "os" "github.com/joho/godotenv" @@ -11,37 +12,51 @@ import ( "github.com/spf13/viper" ) -type Tunnel struct { +type tunnel struct { Name string `json:"name"` + URI string `json:"uri"` PublicURL string `json:"public_url"` + Proto string `json:"proto"` + Config struct { + Address string `json:"addr"` + Inspect bool `json:"inspect"` + } `json:"config"` } var ngrok bool var rootCmd = &cobra.Command{ - Use: "go-ipa", + Use: "dipa", Short: "Root Short", Long: `Root Long`, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if ngrok { - resp, err := http.Get("http://127.0.0.1:4040/api/tunnels/command_line") + tunnel, err := getNgrokTunnel() if err != nil { return err } - defer resp.Body.Close() - var tunnel Tunnel - err = json.NewDecoder(resp.Body).Decode(&tunnel) + url, err := url.Parse(tunnel.Config.Address) if err != nil { return err } viper.Set("BASE_URL", tunnel.PublicURL) - viper.Set("SSL", "false") - return err + viper.Set("ADDR", url.Host) + viper.Set("CERT", "") + viper.Set("KEY", "") } return nil }, } +func getNgrokTunnel() (t tunnel, err error) { + resp, err := http.Get("http://127.0.0.1:4040/api/tunnels/command_line") + if err == nil { + defer resp.Body.Close() + err = json.NewDecoder(resp.Body).Decode(&t) + } + return +} + func init() { cobra.OnInitialize(initEnv) rootCmd.PersistentFlags().StringP("url", "b", "", "Set a base URL") diff --git a/cmd/share.go b/cmd/share.go index 79b6cfb415eca289984777ca6ddf611dd9d00d68..58d6fecb0b5febd6e82d162be2daf15d9271be8e 100644 --- a/cmd/share.go +++ b/cmd/share.go @@ -1,15 +1,19 @@ package cmd import ( + "crypto/x509" + "encoding/pem" "errors" "fmt" "image/png" + "io/ioutil" "net/http" "os" "path" "strings" "text/template" + "github.com/grantae/certinfo" "github.com/mdp/qrterminal" "github.com/phinexdaz/ipapk" "github.com/skip2/go-qrcode" @@ -18,7 +22,7 @@ import ( "gitlab.hedenstroem.com/go/dipa/constant" ) -type ExtendedAppInfo struct { +type extendedAppInfo struct { *ipapk.AppInfo IsIPA bool Filename string @@ -28,16 +32,20 @@ type ExtendedAppInfo struct { var useHalfBlock bool -var scheme string var file string var appInfo *ipapk.AppInfo -func getExtendedAppInfo(host string) ExtendedAppInfo { +func getExtendedAppInfo(req *http.Request) extendedAppInfo { fileName := path.Base(file) isIPA := strings.ToLower(path.Ext(fileName)) == ".ipa" - baseURL := fmt.Sprintf("%s://%s", scheme, host) - if viper.IsSet("BASE_URL") { + + var baseURL string + if req != nil && req.TLS != nil { + baseURL = fmt.Sprintf("https://%s", req.Host) + } else if req != nil { + baseURL = fmt.Sprintf("http://%s", req.Host) + } else { baseURL = viper.GetString("BASE_URL") } @@ -48,7 +56,7 @@ func getExtendedAppInfo(host string) ExtendedAppInfo { downloadURL = fmt.Sprintf("%s/%s", baseURL, fileName) } - return ExtendedAppInfo{ + return extendedAppInfo{ AppInfo: appInfo, Filename: fileName, IsIPA: isIPA, @@ -63,8 +71,8 @@ func iconHandler(w http.ResponseWriter, req *http.Request) { } func qrcodeHandler(w http.ResponseWriter, req *http.Request) { - appInfo := getExtendedAppInfo(req.Host) w.Header().Set("Content-Type", "image/png") + appInfo := getExtendedAppInfo(req) image, _ := qrcode.Encode(appInfo.DownloadURL, qrcode.Medium, 256) w.Write(image) } @@ -72,13 +80,13 @@ func qrcodeHandler(w http.ResponseWriter, req *http.Request) { func indexHandler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/html") tmpl, _ := template.New("index").Parse(constant.IndexTemplate) - tmpl.Execute(w, getExtendedAppInfo(req.Host)) + tmpl.Execute(w, getExtendedAppInfo(req)) } func manifestHandler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/xml") tmpl, _ := template.New("manifest").Parse(constant.ManifestTemplate) - tmpl.Execute(w, getExtendedAppInfo(req.Host)) + tmpl.Execute(w, getExtendedAppInfo(req)) } func fileDownloadHandler(w http.ResponseWriter, req *http.Request) { @@ -110,39 +118,65 @@ var shareCmd = &cobra.Command{ http.HandleFunc("/manifest.plist", manifestHandler) } + addr := viper.GetString("ADDR") + if viper.IsSet("BASE_URL") { - extAppInfo := getExtendedAppInfo("") - fmt.Println(extAppInfo.DownloadURL) + extAppInfo := getExtendedAppInfo(nil) + fmt.Printf("Accepting requests to %s on %s\n", extAppInfo.BaseURL, addr) + fmt.Printf("Download URL: %s\n", extAppInfo.DownloadURL) + var config qrterminal.Config if useHalfBlock { - qrterminal.GenerateHalfBlock(extAppInfo.DownloadURL, qrterminal.L, os.Stdout) + config = qrterminal.Config{ + Level: qrterminal.L, + Writer: os.Stdout, + HalfBlocks: true, + BlackChar: qrterminal.BLACK_BLACK, + WhiteBlackChar: qrterminal.WHITE_BLACK, + WhiteChar: qrterminal.WHITE_WHITE, + BlackWhiteChar: qrterminal.BLACK_WHITE, + QuietZone: 1, + } } else { - qrterminal.Generate(extAppInfo.DownloadURL, qrterminal.L, os.Stdout) + config = qrterminal.Config{ + Level: qrterminal.L, + Writer: os.Stdout, + BlackChar: qrterminal.BLACK, + WhiteChar: qrterminal.WHITE, + QuietZone: 1, + } } + qrterminal.GenerateWithConfig(extAppInfo.DownloadURL, config) } else { - fmt.Println("Base url not set") + fmt.Printf("Accepting requests on %s\n", addr) } - fmt.Println(viper.GetBool("SSL")) - - addr := viper.GetString("ADDR") - if viper.GetBool("SSL") { - scheme = "https" + if viper.GetString("CERT") != "" { + //printCert(viper.GetString("CERT")) return http.ListenAndServeTLS(addr, viper.GetString("CERT"), viper.GetString("KEY"), nil) } - scheme = "http" return http.ListenAndServe(addr, nil) }, } +func printCert(file string) { + var block *pem.Block + var rest []byte + rest, _ = ioutil.ReadFile(file) + for len(rest) > 0 { + block, rest = pem.Decode([]byte(rest)) + cert, _ := x509.ParseCertificate(block.Bytes) + result, _ := certinfo.CertificateText(cert) + fmt.Print(result) + } +} + func init() { rootCmd.AddCommand(shareCmd) shareCmd.Flags().BoolVar(&useHalfBlock, "half", false, "generate a smaller QR code in the terminal") shareCmd.Flags().StringP("addr", "a", ":8080", "address and port on which the server will accept requests") shareCmd.Flags().StringP("cert", "c", "", "path to SSL certificate") shareCmd.Flags().StringP("key", "k", "", "path to SSL secret key") - shareCmd.Flags().Bool("ssl", true, "enable SSL/TLS") viper.BindPFlag("ADDR", shareCmd.Flags().Lookup("addr")) viper.BindPFlag("CERT", shareCmd.Flags().Lookup("cert")) viper.BindPFlag("KEY", shareCmd.Flags().Lookup("key")) - viper.BindPFlag("SSL", shareCmd.Flags().Lookup("ssl")) }