【go语言 socket编程系列】Response数据类型及http.Head方法获取头部信息

 【Response数据类型】

Response定义在response.go中,源码如下

// Response represents the response from an HTTP request.
//
// The Client and Transport return Responses from servers once
// the response headers have been received. The response body
// is streamed on demand as the Body field is read.
type Response struct {
	Status     string // e.g. "200 OK"
	StatusCode int    // e.g. 200
	Proto      string // e.g. "HTTP/1.0"
	ProtoMajor int    // e.g. 1
	ProtoMinor int    // e.g. 0

	// Header maps header keys to values. If the response had multiple
	// headers with the same key, they may be concatenated, with comma
	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
	// be semantically equivalent to a comma-delimited sequence.) When
	// Header values are duplicated by other fields in this struct (e.g.,
	// ContentLength, TransferEncoding, Trailer), the field values are
	// authoritative.
	//
	// Keys in the map are canonicalized (see CanonicalHeaderKey).
	Header Header

	// Body represents the response body.
	//
	// The response body is streamed on demand as the Body field
	// is read. If the network connection fails or the server
	// terminates the response, Body.Read calls return an error.
	//
	// The http Client and Transport guarantee that Body is always
	// non-nil, even on responses without a body or responses with
	// a zero-length body. It is the caller's responsibility to
	// close Body. The default HTTP client's Transport may not
	// reuse HTTP/1.x "keep-alive" TCP connections if the Body is
	// not read to completion and closed.
	//
	// The Body is automatically dechunked if the server replied
	// with a "chunked" Transfer-Encoding.
	Body io.ReadCloser

	// ContentLength records the length of the associated content. The
	// value -1 indicates that the length is unknown. Unless Request.Method
	// is "HEAD", values >= 0 indicate that the given number of bytes may
	// be read from Body.
	ContentLength int64

	// Contains transfer encodings from outer-most to inner-most. Value is
	// nil, means that "identity" encoding is used.
	TransferEncoding []string

	// Close records whether the header directed that the connection be
	// closed after reading Body. The value is advice for clients: neither
	// ReadResponse nor Response.Write ever closes a connection.
	Close bool

	// Uncompressed reports whether the response was sent compressed but
	// was decompressed by the http package. When true, reading from
	// Body yields the uncompressed content instead of the compressed
	// content actually set from the server, ContentLength is set to -1,
	// and the "Content-Length" and "Content-Encoding" fields are deleted
	// from the responseHeader. To get the original response from
	// the server, set Transport.DisableCompression to true.
	Uncompressed bool

	// Trailer maps trailer keys to values in the same
	// format as Header.
	//
	// The Trailer initially contains only nil values, one for
	// each key specified in the server's "Trailer" header
	// value. Those values are not added to Header.
	//
	// Trailer must not be accessed concurrently with Read calls
	// on the Body.
	//
	// After Body.Read has returned io.EOF, Trailer will contain
	// any trailer values sent by the server.
	Trailer Header

	// Request is the request that was sent to obtain this Response.
	// Request's Body is nil (having already been consumed).
	// This is only populated for Client requests.
	Request *Request

	// TLS contains information about the TLS connection on which the
	// response was received. It is nil for unencrypted responses.
	// The pointer is shared between responses and should not be
	// modified.
	TLS *tls.ConnectionState
}

StatusCode大概分5类,如下,详细返回码可以网上找下

  1. 消息:1开头,代表请求已被接受,需要继续处理
  2. 成功:2开头,代表请求已成功被服务器接收、理解、并接受
  3. 重定向:3开头,用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明
  4. 请求错误:4开头,代表了客户端看起来可能发生了错误,妨碍了服务器的处理
  5. 服务器错误:5/6开头,代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理

Header 类型的数据定义在header.go文件中,原始定义如下

 // A Header represents the key-value pairs in an HTTP header.
 type Header map[string][]string

Body 为io.ReadCloser 类型的数据,ReadCloser为接口类型,定义在io.go文件中,如下

// ReadCloser is the interface that groups the basic Read and Close methods.
type ReadCloser interface {
        Reader
        Closer
}

其中Reader接口的定义如下,封装了一个读取数据的方法

type Reader interface {
         Read(p []byte) (n int, err error)
 }

    Request *Request ,Request类型的后续展开讲解。

通过具体的例子了解Respinse数据结构,较简单的方法是向服务端发送Head请求。

【http.Head方法】

http.Head方法定义在client.go中,原型如下

// Head is a wrapper around DefaultClient.Head
func Head(url string) (resp *Response, err error) {
        return DefaultClient.Head(url)
}

其中 DefaultClient是默认的客户端,函数返回实现了Client类型的Head方法。其源码如下

func (c *Client) Head(url string) (resp *Response, err error) {
        req, err := NewRequest("HEAD", url, nil)
        if err != nil {
                return nil, err 
        }   
        return c.Do(req)
}

上面代码中用了2个函数,NewRequest()和Do(),其函数原型如下

          func NewRequest(method, url string, body io.Reader) (*Request, error)

          func (c *Client) Do(req *Request) (*Response, error)

结合原型可知,http.Head请求会把参数url传递给 http.NewRequest  来生成一个Request类型的数据

并通过Client.Do 函数发送给服务器,返回服务器的响应数据Response。

从上面可以看到在HTTP交互中,客户端及服务端是 通过 Request 和Response交互的。

【http.Head 代码调用demo】

func Head(url string),参数url 可以通过字符串“http://www.baidu.com”代替

package main

import (
	"fmt"
	"net/http"
	"os"
)

func main() {
	//if len(os.Args) != 2 {
	//	fmt.Println("Usage:", os.Args[0], "host:port")
	//	os.Exit(1)
	//}
	//myurl := os.Args[1]
	myurl := "http://www.baidu.com"
	response, err := http.Head(myurl) //通过http.Head直接调用

	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}

	fmt.Println(response.Status)
	for k, v := range response.Header {  //Header 类型为map,通过range循环打印出来
		fmt.Println(k+":", v) //+为输出顺序

	}
	
	os.Exit(0)

}

执行结果如下

200 OK
Etag: ["575e1f80-115"]
Last-Modified: [Mon, 13 Jun 2016 02:50:40 GMT]
Pragma: [no-cache]
Accept-Ranges: [bytes]
Cache-Control: [private, no-cache, no-store, proxy-revalidate, no-transform]
Connection: [Keep-Alive]
Server: [bfe/1.0.8.18]
Content-Length: [277]
Content-Type: [text/html]
Date: [Mon, 22 Oct 2018 06:43:29 GMT]

猜你喜欢

转载自blog.csdn.net/natpan/article/details/83273062