| 15 | ) |
| 16 | |
| 17 | func Main() error { |
| 18 | var args struct { |
| 19 | Addr string `arg:"positional,required"` |
| 20 | Hostname string `arg:"positional,required"` |
| 21 | } |
| 22 | arg.MustParse(&args) |
| 23 | |
| 24 | // dial the server |
| 25 | conn, err := net.Dial("tcp", args.Addr) |
| 26 | if err != nil { |
| 27 | return fmt.Errorf("error dialing server: %w", err) |
| 28 | } |
| 29 | |
| 30 | tlsconn := tls.Client(conn, &tls.Config{ServerName: args.Hostname}) |
| 31 | |
| 32 | err = tlsconn.Handshake() |
| 33 | if err != nil { |
| 34 | return fmt.Errorf("tls handshake failed: %w", err) |
| 35 | } |
| 36 | |
| 37 | err = tlsconn.VerifyHostname(args.Hostname) |
| 38 | if err != nil { |
| 39 | return fmt.Errorf("tls hostname not verified: %w", err) |
| 40 | } |
| 41 | |
| 42 | // create http request |
| 43 | req, err := http.NewRequest("GET", "https://"+args.Hostname, nil) |
| 44 | if err != nil { |
| 45 | return err |
| 46 | } |
| 47 | |
| 48 | // write the request to the TLS connection |
| 49 | err = req.Write(tlsconn) |
| 50 | if err != nil { |
| 51 | return fmt.Errorf("error sending http request over tls: %w", err) |
| 52 | } |
| 53 | |
| 54 | // read the response from the TLS connection |
| 55 | resp, err := http.ReadResponse(bufio.NewReader(tlsconn), req) |
| 56 | if err != nil { |
| 57 | return fmt.Errorf("error reading http response over tls: %w", err) |
| 58 | } |
| 59 | defer resp.Body.Close() |
| 60 | |
| 61 | // read the whole body |
| 62 | body, err := io.ReadAll(resp.Body) |
| 63 | if err != nil { |
| 64 | return fmt.Errorf("error reading http body over tls: %w", err) |
| 65 | } |
| 66 | |
| 67 | // log the result |
| 68 | log.Println(strings.TrimSpace(string(body))) |
| 69 | |
| 70 | return nil |
| 71 | } |
| 72 | |
| 73 | func main() { |
| 74 | log.SetOutput(os.Stdout) |