isitup/main.go

99 lines
2.0 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"github.com/fatih/color"
)
var Version = "develop"
func main() {
fs := flag.NewFlagSet("isitup", flag.ExitOnError)
versionFlag := fs.Bool("version", false, "Display version and exit")
fs.BoolVar(versionFlag, "v", *versionFlag, "--version")
if err := fs.Parse(os.Args[1:]); err != nil {
fmt.Println(err)
return
}
if *versionFlag {
fmt.Printf("isitup %s\n", Version)
return
}
if fs.NArg() < 1 {
fmt.Println("isitup requires a host to check")
return
}
host := fs.Arg(0)
r, err := Check(host)
if err != nil {
fmt.Println(err)
return
}
var status string
switch r.StatusCode {
case 1:
status = color.GreenString("up")
case 2:
status = color.RedString("down")
case 3:
status = color.BlackString("an invalid domain")
default:
fmt.Printf("isitup returned an invalid status %d\n", r.StatusCode)
return
}
fmt.Printf("%s is %s!\n", color.YellowString(host), status)
}
// Response is a response from the API
type Response struct {
Domain string `json:"domain"`
Port int `json:"port"`
StatusCode int `json:"status_code"`
ResponseIP string `json:"response_ip"`
ResponseCode int `json:"response_code"`
ResponseTime float64 `json:"response_time"`
}
// Check checks a given host
func Check(host string) (*Response, error) {
u, err := url.Parse(host)
if err != nil {
return nil, fmt.Errorf("could not parse host %q: %w", host, err)
}
var h string
switch {
case u.Scheme != "":
h = u.Hostname()
case u.Path != "":
p := strings.TrimPrefix(u.Path, "/")
h = strings.Split(p, "/")[0]
default:
return nil, fmt.Errorf("could not derive host from %q", host)
}
res, err := http.Get(fmt.Sprintf("https://isitup.org/%s.json", h))
if err != nil {
return nil, fmt.Errorf("could not get from API: %w", err)
}
var r Response
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
return nil, fmt.Errorf("could not decode response body: %w", err)
}
return &r, nil
}