diff --git a/http/client.go b/http/client.go index 13853df..04b42ec 100644 --- a/http/client.go +++ b/http/client.go @@ -2,10 +2,9 @@ package http import ( "bufio" - "crypto/tls" "errors" - "fmt" "io" + "net" "strconv" "strings" ) @@ -15,7 +14,14 @@ var ( SP = []byte(" ") ) -func Do(method string, url string, headers []*Header) (*Response, error) { +func getIP(domain string) string { + if domain == "test.ru" { + return "127.0.0.1:8081" + } + return "" +} + +func Do(method string, url string, headers []Header) (*Response, error) { url = strings.TrimPrefix(url, "http://") url = strings.TrimPrefix(url, "https://") path := "/" @@ -27,48 +33,27 @@ func Do(method string, url string, headers []*Header) (*Response, error) { path = "/" + path } - connectPath := arr[0] - // conn, err := net.Dial("tcp", connectPath) - conn, err := tls.Dial("tcp", connectPath, nil) + connectPath := getIP(arr[0]) + conn, err := net.Dial("tcp", connectPath) + // conn, err := tls.Dial("tcp", connectPath, nil) if err != nil { return nil, errors.New("connect " + connectPath) } defer conn.Close() - WriteRequest(conn, method, arr[0], path, "HTTP/1.0", headers) + DebugWrap( + conn, + &Request{ + Method: method, + Path: path, + Protocol: "HTTP/1.0", + Headers: headers, + }, + WriteRequest, + ) return ReadResponse(conn) } -func WriteRequest( - w io.Writer, - method string, - host string, - path string, - httpVersion string, - headers []*Header, -) { - io.WriteString(w, method) - w.Write(SP) - io.WriteString(w, path) - w.Write(SP) - io.WriteString(w, httpVersion) - w.Write(CRLF) - - for _, header := range headers { - WriteHeader(w, header.Name, header.Value) - } - - // headers end - w.Write(CRLF) - - // todo: body -} - -func WriteHeader(w io.Writer, name string, value string) { - fmt.Fprintf(w, "%s:%s", name, value) - w.Write(CRLF) -} - func ReadResponse(r io.Reader) (*Response, error) { b := bufio.NewReader(r) @@ -93,7 +78,7 @@ func ReadResponse(r io.Reader) (*Response, error) { headerStr := "" contentLengthStr := "" - headers := []*Header{} + headers := []Header{} for { headerStr, err = b.ReadString('\n') if err != nil { @@ -104,7 +89,7 @@ func ReadResponse(r io.Reader) (*Response, error) { } arr := strings.Split(headerStr, ": ") value := strings.TrimSpace(arr[1]) - header := &Header{Name: arr[0], Value: value} + header := Header{Name: arr[0], Value: value} if header.Name == "Content-Length" { contentLengthStr = header.Value } diff --git a/http/client_test.go b/http/client_test.go index 786c32c..57d7183 100644 --- a/http/client_test.go +++ b/http/client_test.go @@ -11,7 +11,14 @@ import ( func Test_WriteRequest(t *testing.T) { b := &strings.Builder{} - WriteRequest(b, "GET", "example.ru", "/", "HTTP/1.0", nil) + WriteRequest( + b, + &Request{ + Method: "GET", + Path: "/", + Protocol: "HTTP/1.0", + }, + ) assert.Equal(t, "GET / HTTP/1.0\r\n\r\n", b.String()) } diff --git a/http/header.go b/http/header.go deleted file mode 100644 index e4928ba..0000000 --- a/http/header.go +++ /dev/null @@ -1,6 +0,0 @@ -package http - -type Header struct { - Name string - Value string -} diff --git a/http/http.go b/http/http.go new file mode 100644 index 0000000..a5ce2a7 --- /dev/null +++ b/http/http.go @@ -0,0 +1,16 @@ +package http + +type Request struct { + Method string + Path string + Protocol string + + Headers []Header + + Body string +} + +type Header struct { + Name string + Value string +} diff --git a/http/response.go b/http/response.go index 249ba33..8db8786 100644 --- a/http/response.go +++ b/http/response.go @@ -10,15 +10,15 @@ var ( type Response struct { StatusCode int - Headers []*Header + Headers []Header Body []byte } -func (r *Response) GetHeader(name string) (*Header, error) { +func (r *Response) GetHeader(name string) (Header, error) { for _, h := range r.Headers { if h.Name == name { return h, nil } } - return nil, ErrHeaderNotFound + return Header{}, ErrHeaderNotFound } diff --git a/http/write_request.go b/http/write_request.go new file mode 100644 index 0000000..841b008 --- /dev/null +++ b/http/write_request.go @@ -0,0 +1,32 @@ +package http + +import ( + "bytes" + "fmt" + "io" +) + +func WriteRequest(w io.Writer, req *Request) { + fmt.Fprintf(w, "%s %s %s\r\n", req.Method, req.Path, req.Protocol) + + for _, header := range req.Headers { + fmt.Fprintf(w, "%s: %s\r\n", header.Name, header.Value) + } + fmt.Fprintf(w, "\r\n") + + if len(req.Body) > 0 { + fmt.Fprintf(w, "%s\r\n", req.Body) + } +} + +func DebugWrap(w io.Writer, req *Request, f func(w io.Writer, req *Request)) { + buffer := &bytes.Buffer{} + + f(buffer, req) + + fmt.Println("----- Debug Info -----") + fmt.Println(buffer.String()) + fmt.Println("----- Debug End Info -----") + + w.Write(buffer.Bytes()) +} diff --git a/test_client/main.go b/test_client/main.go index db517bf..13f3650 100644 --- a/test_client/main.go +++ b/test_client/main.go @@ -9,8 +9,8 @@ import ( func main() { r, err := http.Do( "GET", - "https://3crabs.ru:443", - []*http.Header{ + "http://test.ru", + []http.Header{ {Name: "Host", Value: "3crabs.ru"}, {Name: "User-Agent", Value: "3crabs/0.0.1"}, {Name: "Accept", Value: "*/*"},