在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本节主要内容: 1. http编程 1. http编程 (1)http编程分析
关于HTTP,TCP/IP相关知识可以看系列博客 https://www.jianshu.com/p/dfbac2ff2657 首先来看一个最简单的http服务器: 1 package main 2 3 import ( 4 "io" 5 "log" 6 "net/http" 7 ) 8 9 func main() { 10 // Hello world, the web server 11 12 helloHandler := func(w http.ResponseWriter, req *http.Request) { 13 io.WriteString(w, "Hello, world!\n") 14 } 15 16 http.HandleFunc("/hello", helloHandler) 17 log.Fatal(http.ListenAndServe(":8080", nil)) 18 } 执行结果: 几个函数及接口定义:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) HandleFunc registers the handler function for the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patterns 1 package main 2 3 import ( 4 "io" 5 "log" 6 "net/http" 7 ) 8 9 func main() { 10 h1 := func(w http.ResponseWriter, _ *http.Request) { 11 io.WriteString(w, "Hello from a HandleFunc #1!\n") 12 } 13 h2 := func(w http.ResponseWriter, _ *http.Request) { 14 io.WriteString(w, "Hello from a HandleFunc #2!\n") 15 } 16 17 http.HandleFunc("/", h1) 18 http.HandleFunc("/endpoint", h2) 19 20 log.Fatal(http.ListenAndServe(":8080", nil)) 21 }
A ResponseWriter interface is used by an HTTP handler to construct an HTTP response. A ResponseWriter may not be used after the Handler.ServeHTTP method has returned. 1 type ResponseWriter interface { 2 // Header returns the header map that will be sent by 3 // WriteHeader. The Header map also is the mechanism with which 4 // Handlers can set HTTP trailers. 5 // 6 // Changing the header map after a call to WriteHeader (or 7 // Write) has no effect unless the modified headers are 8 // trailers. 9 // 10 // There are two ways to set Trailers. The preferred way is to 11 // predeclare in the headers which trailers you will later 12 // send by setting the "Trailer" header to the names of the 13 // trailer keys which will come later. In this case, those 14 // keys of the Header map are treated as if they were 15 // trailers. See the example. The second way, for trailer 16 // keys not known to the Handler until after the first Write, 17 // is to prefix the Header map keys with the TrailerPrefix 18 // constant value. See TrailerPrefix. 19 // 20 // To suppress automatic response headers (such as "Date"), set 21 // their value to nil. 22 Header() Header 23 24 // Write writes the data to the connection as part of an HTTP reply. 25 // 26 // If WriteHeader has not yet been called, Write calls 27 // WriteHeader(http.StatusOK) before writing the data. If the Header 28 // does not contain a Content-Type line, Write adds a Content-Type set 29 // to the result of passing the initial 512 bytes of written data to 30 // DetectContentType. Additionally, if the total size of all written 31 // data is under a few KB and there are no Flush calls, the 32 // Content-Length header is added automatically. 33 // 34 // Depending on the HTTP protocol version and the client, calling 35 // Write or WriteHeader may prevent future reads on the 36 // Request.Body. For HTTP/1.x requests, handlers should read any 37 // needed request body data before writing the response. Once the 38 // headers have been flushed (due to either an explicit Flusher.Flush 39 // call or writing enough data to trigger a flush), the request body 40 // may be unavailable. For HTTP/2 requests, the Go HTTP server permits 41 // handlers to continue to read the request body while concurrently 42 // writing the response. However, such behavior may not be supported 43 // by all HTTP/2 clients. Handlers should read before writing if 44 // possible to maximize compatibility. 45 Write([]byte) (int, error) 46 47 // WriteHeader sends an HTTP response header with the provided 48 // status code. 49 // 50 // If WriteHeader is not called explicitly, the first call to Write 51 // will trigger an implicit WriteHeader(http.StatusOK). 52 // Thus explicit calls to WriteHeader are mainly used to 53 // send error codes. 54 // 55 // The provided code must be a valid HTTP 1xx-5xx status code. 56 // Only one header may be written. Go does not currently 57 // support sending user-defined 1xx informational headers, 58 // with the exception of 100-continue response header that the 59 // Server sends automatically when the Request.Body is read. 60 WriteHeader(statusCode int) 61 }
func ListenAndServe(addr string, handler Handler) error ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. 具体实现过程需要分析:后续补上。 (2)http常见请求方法 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 ) 8 9 func main() { 10 res, err := http.Get("https://www.baidu.com/") 11 if err != nil { 12 fmt.Println("get err:", err) 13 return 14 } 15 16 data, err := ioutil.ReadAll(res.Body) 17 if err != nil { 18 fmt.Println("get data err:", err) 19 return 20 } 21 22 fmt.Println(string(data)) 23 } 1 package main 2 3 import ( 4 "fmt" 5 "net/http" 6 ) 7 8 var url = []string{ 9 "http://www.baidu.com", 10 "http://google.com", 11 "http://taobao.com", 12 } 13 14 func main() { 15 16 for _, v := range url { 17 resp, err := http.Head(v) 18 if err != nil { 19 fmt.Printf("head %s failed, err:%v\n", v, err) 20 continue 21 } 22 23 fmt.Printf("head succ, status:%v\n", resp.Status) 24 } 25 }
1 func (c *Client) Get(url string) (resp *Response, err error) 2 3 Get issues a GET to the specified URL. If the response is one of the following redirect codes, Get follows the redirect after calling the Client's CheckRedirect function: 4 5 301 (Moved Permanently) 6 302 (Found) 7 303 (See Other) 8 307 (Temporary Redirect) 9 308 (Permanent Redirect) 10 An error is returned if the Client's CheckRedirect function fails or if there was an HTTP protocol error. A non-2xx response doesn't cause an error. Any returned error will be of type *url.Error. The url.Error value's Timeout method will report true if request timed out or was canceled. 11 12 When err is nil, resp always contains a non-nil resp.Body. Caller should close resp.Body when done reading from it. 13 14 To make a request with custom headers, use NewRequest and Client.Do.
1 func Head(url string) (resp *Response, err error) 2 3 func (c *Client) Head(url string) (resp *Response, err error) 4 Head issues a HEAD to the specified URL. If the response is one of the following redirect codes, Head follows the redirect after calling the Client's CheckRedirect function: 5 6 301 (Moved Permanently) 7 302 (Found) 8 303 (See Other) 9 307 (Temporary Redirect) 10 308 (Permanent Redirect)
1 type Response struct { 2 Status string // e.g. "200 OK" 3 StatusCode int // e.g. 200 4 Proto string // e.g. "HTTP/1.0" 5 ProtoMajor int // e.g. 1 6 ProtoMinor int // e.g. 0 7 8 // Header maps header keys to values. If the response had multiple 9 // headers with the same key, they may be concatenated, with comma 10 // delimiters. (RFC 7230, section 3.2.2 requires that multiple headers 11 // be semantically equivalent to a comma-delimited sequence.) When 12 // Header values are duplicated by other fields in this struct (e.g., 13 // ContentLength, TransferEncoding, Trailer), the field values are 14 // authoritative. 15 // 16 // Keys in the map are canonicalized (see CanonicalHeaderKey). 17 Header Header 18 19 // Body represents the response body. 20 // 21 // The response body is streamed on demand as the Body field 22 // is read. If the network connection fails or the server 23 // terminates the response, Body.Read calls return an error. 24 // 25 // The http Client and Transport guarantee that Body is always 26 // non-nil, even on responses without a body or responses with 27 // a zero-length body. It is the caller's responsibility to 28 // close Body. The default HTTP client's Transport may not 29 // reuse HTTP/1.x "keep-alive" TCP connections if the Body is 30 // not read to completion and closed. 31 // 32 // The Body is automatically dechunked if the server replied 33 // with a "chunked" Transfer-Encoding. 34 // 35 // As of Go 1.12, the Body will be also implement io.Writer 36 // on a successful "101 Switching Protocols" responses, 37 // as used by WebSockets and HTTP/2's "h2c" mode. 38 Body io.ReadCloser 39 40 // ContentLength records the length of the associated content. The 41 // value -1 indicates that the length is unknown. Unless Request.Method 42 // is "HEAD", values >= 0 indicate that the given number of bytes may 43 // be read from Body. 44 ContentLength int64 45 46 // Contains transfer encodings from outer-most to inner-most. Value is 47 // nil, means that "identity" encoding is used. 48 TransferEncoding []string 49 50 // Close records whether the header directed that the connection be 51 // closed after reading Body. The value is advice for clients: neither 52 // ReadResponse nor Response.Write ever closes a connection. 53 Close bool 54 55 // Uncompressed reports whether the response was sent compressed but 56 // was decompressed by the http package. When true, reading from 57 // Body yields the uncompressed content instead of the compressed 58 // content actually set from the server, ContentLength is set to -1, 59 // and the "Content-Length" and "Content-Encoding" fields are deleted 60 // from the responseHeader. To get the original response from 61 // the server, set Transport.DisableCompression to true. 62 Uncompressed bool // Go 1.7 63 64 // Trailer maps trailer keys to values in the same 65 // format as Header. 66 // 67 // The Trailer initially contains only nil values, one for 68 // each key specified in the server's "Trailer" header 69 // value. Those values are not added to Header. 70 // 71 // Trailer must not be accessed concurrently with Read calls 72 // on the Body. 73 // 74 // After Body.Read has returned io.EOF, Trailer will contain 75 // any trailer values sent by the server. 76 Trailer Header 77 78 // Request is the request that was sent to obtain this Response. 79 // Request's Body is nil (having already been consumed). 80 // This is only populated for Client requests. 81 Request *Request 82 83 // TLS contains information about the TLS connection on which the 84 // response was received. It is nil for unencrypted responses. 85 // The pointer is shared between responses and should not be 86 // modified. 87 TLS *tls.ConnectionState // Go 1.3 88 }
http.StatusContinue = 100 http.StatusOK = 200 http.StatusFound = 302 http.StatusBadRequest = 400 http.StatusUnauthorized = 401 http.StatusForbidden = 403 http.StatusNotFound = 404 http.StatusInternalServerError = 500 (3)表单处理 1 package main 2 import ( 3 "io" 4 "net/http" 5 ) 6 7 const form = `<html><body><form action="#" method="post" name="bar"> 8 <input type="text" name="in"/> 9 <input type="text" name="in"/> 10 <input type="submit" value="Submit"/> 11 </form></html></body>` 12 13 func SimpleServer(w http.ResponseWriter, request *http.Request) { 14 io.WriteString(w, "<h1>hello, world</h1>") 15 } 16 17 func FormServer(w http.ResponseWriter, request *http.Request) { 18 w.Header().Set("Content-Type", "text/html") 19 switch request.Method { 20 case "GET": 21 io.WriteString(w, form) 22 case "POST": 23 request.ParseForm() 24 io.WriteString(w, request.Form["in"][0]) 25 io.WriteString(w, "\n") 26 io.WriteString(w, request.FormValue("in")) 27 } 28 } 29 func main() { 30 http.HandleFunc("/test1", SimpleServer) 31 http.HandleFunc("/test2", FormServer) 32 if err := http.ListenAndServe(":8088", nil); err != nil { 33 } 34 } 执行结果: url: test1
url: test2(第一次请求是GET,第二次是POST请求) GET请求:
POST请求: (4)模板 1)替换 {{.字段名}} 模板中的点(.)为结构体中的p 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "text/template" 7 ) 8 9 type Person struct { 10 Name string 11 Age string 12 Title string 13 } 14 15 func main() { 16 t, err := template.ParseFiles("./index.html") 17 if err != nil { 18 fmt.Println("parse file err:", err) 19 return 20 } 21 p := Person{Name: "Mary", Age: "31", Title:"My blog"} 22 if err := t.Execute(os.Stdout, p); err != nil { 23 fmt.Println("There was an error:", err.Error()) 24 } 25 } 1 <html> 2 <head> 3 <title>{{.Title}}</title> 4 </head> 5 <body> 6 <p> hello, {{.Name}}</p> 7 <p> {{.}}</p> 8 </body> 9 </html> 2)if判断 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "text/template" 7 ) 8 9 type Person struct { 10 Name string 11 Age int 12 Title string 13 } 14 15 func main() { 16 t, err := template.ParseFiles("./index2.html") 17 if err != nil { 18 fmt.Println("parse file err:", err) 19 return 20 } 21 p := Person{Name: "Mary", Age: 17, Title:"My blog"} 22 if err := t.Execute(os.Stdout, p); err != nil { 23 fmt.Println( 全部评论
|
请发表评论