clear
This commit is contained in:
		
							parent
							
								
									3cfa44b99c
								
							
						
					
					
						commit
						729015c4ea
					
				@ -2,10 +2,9 @@ package http
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -15,7 +14,14 @@ var (
 | 
				
			|||||||
	SP   = []byte(" ")
 | 
						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, "http://")
 | 
				
			||||||
	url = strings.TrimPrefix(url, "https://")
 | 
						url = strings.TrimPrefix(url, "https://")
 | 
				
			||||||
	path := "/"
 | 
						path := "/"
 | 
				
			||||||
@ -27,48 +33,27 @@ func Do(method string, url string, headers []*Header) (*Response, error) {
 | 
				
			|||||||
		path = "/" + path
 | 
							path = "/" + path
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connectPath := arr[0]
 | 
						connectPath := getIP(arr[0])
 | 
				
			||||||
	// conn, err := net.Dial("tcp", connectPath)
 | 
						conn, err := net.Dial("tcp", connectPath)
 | 
				
			||||||
	conn, err := tls.Dial("tcp", connectPath, nil)
 | 
						// conn, err := tls.Dial("tcp", connectPath, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errors.New("connect " + connectPath)
 | 
							return nil, errors.New("connect " + connectPath)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer conn.Close()
 | 
						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)
 | 
						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) {
 | 
					func ReadResponse(r io.Reader) (*Response, error) {
 | 
				
			||||||
	b := bufio.NewReader(r)
 | 
						b := bufio.NewReader(r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,7 +78,7 @@ func ReadResponse(r io.Reader) (*Response, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	headerStr := ""
 | 
						headerStr := ""
 | 
				
			||||||
	contentLengthStr := ""
 | 
						contentLengthStr := ""
 | 
				
			||||||
	headers := []*Header{}
 | 
						headers := []Header{}
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		headerStr, err = b.ReadString('\n')
 | 
							headerStr, err = b.ReadString('\n')
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -104,7 +89,7 @@ func ReadResponse(r io.Reader) (*Response, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		arr := strings.Split(headerStr, ": ")
 | 
							arr := strings.Split(headerStr, ": ")
 | 
				
			||||||
		value := strings.TrimSpace(arr[1])
 | 
							value := strings.TrimSpace(arr[1])
 | 
				
			||||||
		header := &Header{Name: arr[0], Value: value}
 | 
							header := Header{Name: arr[0], Value: value}
 | 
				
			||||||
		if header.Name == "Content-Length" {
 | 
							if header.Name == "Content-Length" {
 | 
				
			||||||
			contentLengthStr = header.Value
 | 
								contentLengthStr = header.Value
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,14 @@ import (
 | 
				
			|||||||
func Test_WriteRequest(t *testing.T) {
 | 
					func Test_WriteRequest(t *testing.T) {
 | 
				
			||||||
	b := &strings.Builder{}
 | 
						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())
 | 
						assert.Equal(t, "GET / HTTP/1.0\r\n\r\n", b.String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
package http
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Header struct {
 | 
					 | 
				
			||||||
	Name  string
 | 
					 | 
				
			||||||
	Value string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								http/http.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								http/http.go
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,15 +10,15 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type Response struct {
 | 
					type Response struct {
 | 
				
			||||||
	StatusCode int
 | 
						StatusCode int
 | 
				
			||||||
	Headers    []*Header
 | 
						Headers    []Header
 | 
				
			||||||
	Body       []byte
 | 
						Body       []byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Response) GetHeader(name string) (*Header, error) {
 | 
					func (r *Response) GetHeader(name string) (Header, error) {
 | 
				
			||||||
	for _, h := range r.Headers {
 | 
						for _, h := range r.Headers {
 | 
				
			||||||
		if h.Name == name {
 | 
							if h.Name == name {
 | 
				
			||||||
			return h, nil
 | 
								return h, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, ErrHeaderNotFound
 | 
						return Header{}, ErrHeaderNotFound
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										32
									
								
								http/write_request.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								http/write_request.go
									
									
									
									
									
										Normal file
									
								
							@ -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())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,8 +9,8 @@ import (
 | 
				
			|||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	r, err := http.Do(
 | 
						r, err := http.Do(
 | 
				
			||||||
		"GET",
 | 
							"GET",
 | 
				
			||||||
		"https://3crabs.ru:443",
 | 
							"http://test.ru",
 | 
				
			||||||
		[]*http.Header{
 | 
							[]http.Header{
 | 
				
			||||||
			{Name: "Host", Value: "3crabs.ru"},
 | 
								{Name: "Host", Value: "3crabs.ru"},
 | 
				
			||||||
			{Name: "User-Agent", Value: "3crabs/0.0.1"},
 | 
								{Name: "User-Agent", Value: "3crabs/0.0.1"},
 | 
				
			||||||
			{Name: "Accept", Value: "*/*"},
 | 
								{Name: "Accept", Value: "*/*"},
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user