package main import ( "crypto/tls" "fmt" "io" "log" "net/url" "strings" ) type Responce struct { Status string Meta string Body string } type Request struct { URL string } type Client struct { InsecureSkipVerify bool } var config = tls.Config{ InsecureSkipVerify: true, } var DefaultClient = &Client{} func Fetch(args ...string) { DefaultPort := "1965" if len(args) < 2 { DefaultClient.Fetch(args[0], DefaultPort) } if len(args) > 2 { log.Fatal("too many args passed, just want URL and PORT") } if len(args) == 2 { DefaultClient.Fetch(args[0], args[1]) } } func (c Client) Fetch(URL string, port string) { conn := c.connect(URL, port) defer conn.Close() resp, err := c.getResponse(conn, URL) if err != nil { log.Fatal(err) } //fmt.Printf("resp: %s, %s\n", resp.Status, resp.Meta) fmt.Printf("----------\n%s", resp.Body) } func (c Client) connect(URL string, port string) *tls.Conn { parsedURL, err := url.Parse(URL) if err != nil { log.Fatal(err) } conn, err := tls.Dial("tcp", parsedURL.Host+":"+port, &config) if err != nil { log.Fatalf("failed to connect: %v", err) } return conn } // func (c Client) getResponse(connection *tls.Conn, URL string) { func (c Client) getResponse(connection *tls.Conn, URL string) (Responce, error) { err := c.sendRequest(connection, URL) if err != nil { log.Fatal(err) return Responce{}, err } body := handleBody(connection) first, second := getFirstTwoWords(body) return Responce{ Status: first, Meta: second, Body: body[(len(first) + len(second)):], }, nil } func getFirstTwoWords(input string) (string, string) { reply := strings.Split(strings.Split(input, "\n")[0], " ") return reply[0], reply[1] } func handleBody(connection *tls.Conn) string { buf := make([]byte, 4096) var body []byte for { n, err := connection.Read(buf) if err != nil { //handle EOF if err == io.EOF { break } log.Fatal(err) } body = append(body, buf[:n]...) } return string(body) } func (c Client) sendRequest(connection *tls.Conn, requestURL string) error { CRLF := "\r\n" _, err := connection.Write([]byte(requestURL + CRLF)) if err != nil { log.Fatal(err) return err } //fmt.Printf("request (%d bytes) sent...\n", reqSize) return nil }