golang https服务简单介绍

前端之家收集整理的这篇文章主要介绍了golang https服务简单介绍前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

首先从启动https监听服务开始.

  • 完成Server实例创建.
  • 配置https协议
  • 启动tcp监听

1. 开启server https服务

通过下边的函数,开启https服务,下边函数主要初始化了Server实例,然后通过ListenAndServeTLS开启https服务.

func ListenAndServeTLS(addr,certFile,keyFile string,handler Handler) error {
    server := &Server{Addr: addr,Handler: handler}
    return server.ListenAndServeTLS(certFile,keyFile)
 }
  • Server类,主要是Https服务的参数.下边是这个类的结构体.
type Server struct {
    @H_403_32@// TCP address to listen on,":http" if empty
    @H_403_32@// http监听的地址.
    Addr         string    
    @H_403_32@// handler to invoke,http.DefaultServeMux if nil
    @H_403_32@// 处理客户端http请求的函数
    Handler      Handler    
    @H_403_32@// maximum duration before timing out read of the request
    @H_403_32@// 读取数据超时时间
    ReadTimeout  time.Duration 
    @H_403_32@// maximum duration before timing out write of the response
    @H_403_32@// 写入数据超时时间
    WriteTimeout time.Duration 

    @H_403_32@// optional TLS config,used by ListenAndServeTLS
    @H_403_32@// 安全传输协议配置
    TLSConfig    *tls.Config  

    @H_403_32@// MaxHeaderBytes controls the maximum number of bytes the
    @H_403_32@// server will read parsing the request header's keys and
    @H_403_32@// values,including the request line. It does not limit the
    @H_403_32@// size of the request body.
    @H_403_32@// If zero,DefaultMaxHeaderBytes is used.
    @H_403_32@// 头部最大字节数
    MaxHeaderBytes int

    @H_403_32@// TLSNextProto optionally specifies a function to take over
    @H_403_32@// ownership of the provided TLS connection when an NPN/ALPN
    @H_403_32@// protocol upgrade has occurred. The map key is the protocol
    @H_403_32@// name negotiated. The Handler argument should be used to
    @H_403_32@// handle HTTP requests and will initialize the Request's TLS
    @H_403_32@// and RemoteAddr if not already set. The connection is
    @H_403_32@// automatically closed when the function returns.
    @H_403_32@// If TLSNextProto is nil,HTTP/2 support is enabled automatically.
    TLSNextProto map[string]func(*Server,*tls.Conn,Handler)

    @H_403_32@// ConnState specifies an optional callback function that is
    @H_403_32@// called when a client connection changes state. See the
    @H_403_32@// ConnState type and associated constants for details.
    ConnState func(net.Conn,ConnState)

    @H_403_32@// ErrorLog specifies an optional logger for errors accepting
    @H_403_32@// connections and unexpected behavior from handlers.
    @H_403_32@// If nil,logging goes to os.Stderr via the log package's
    @H_403_32@// standard logger.
    ErrorLog *log.Logger

    disableKeepAlives int32     @H_403_32@// accessed atomically.
    nextProtoOnce     sync.Once @H_403_32@// guards setupHTTP2_* init
    nextProtoErr      error     @H_403_32@// result of http2.ConfigureServer if used
}
  1. ListenAndServeTLS过后,开始监听一个端口.循环等待客户端发起tcp请求.主要函数如下:
func (srv *Server) Serve(l net.Listener) error {
    defer l.Close()
    if fn := testHookServerServe; fn != nil {
        fn(srv,l)
    }
    var tempDelay time.Duration @H_403_32@// how long to sleep on accept failure

    if err := srv.setupHTTP2_Serve(); err != nil {
        return err
    }

    @H_403_32@// TODO: allow changing base context? can't imagine concrete
    @H_403_32@// use cases yet.
    @H_403_32@// 开启监听的时候,初始化了顶层context
    @H_403_32@// 此处是一个空的context,这个context不能被取消.
    baseCtx := context.Background()

    @H_403_32@// 创建一个新的context,并设置value值.
    ctx := context.WithValue(baseCtx,ServerContextKey,srv)
    ctx = context.WithValue(ctx,LocalAddrContextKey,l.Addr())
    for {
        rw,e := l.Accept()
        if e != nil {
            if ne,ok := e.(net.Error); ok && ne.Temporary() {
                if tempDelay == 0 {
                    tempDelay = 5 * time.Millisecond
                } else {
                    tempDelay *= 2
                }
                if max := 1 * time.Second; tempDelay > max {
                    tempDelay = max
                }
                srv.logf("http: Accept error: %v; retrying in %v",e,tempDelay)
                time.Sleep(tempDelay)
                continue
            }
            return e
        }
        tempDelay = 0
        c := srv.newConn(rw)
        c.setState(c.rwc,StateNew) @H_403_32@// before Serve can return
        go c.serve(ctx)
    }
}

上边过程完成了https服务监听程序. 接下来就可以接收客户端发送过来的请求.

2. server接收client请求

客户端发起连接后,创建出一个TCPConn的实例,这个实例组合了conn,而conn就是每一个客户端创建连接时,产生的一个连接成功的对象.通过conn实例,来与客户端进行报文交互. (下边这个类定义在net/http/server.go中)

@H_403_32@// A conn represents the server side of an HTTP connection.
type conn struct {
    @H_403_32@// server is the server on which the connection arrived.
    @H_403_32@// Immutable; never nil.
    server *Server

    @H_403_32@// rwc is the underlying network connection.
    @H_403_32@// This is never wrapped by other types and is the value given out
    @H_403_32@// to CloseNotifier callers. It is usually of type *net.TCPConn or
    @H_403_32@// *tls.Conn.
    rwc net.Conn

    @H_403_32@// remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously
    @H_403_32@// inside the Listener's Accept goroutine,as some implementations block.
    @H_403_32@// It is populated immediately inside the (*conn).serve goroutine.
    @H_403_32@// This is the value of a Handler's (*Request).RemoteAddr.
    remoteAddr string

    @H_403_32@// tlsState is the TLS connection state when using TLS.
    @H_403_32@// nil means not TLS.
    tlsState *tls.ConnectionState

    @H_403_32@// werr is set to the first write error to rwc.
    @H_403_32@// It is set via checkConnErrorWriter{w},where bufw writes.
    werr error

    @H_403_32@// r is bufr's read source. It's a wrapper around rwc that provides
    @H_403_32@// io.LimitedReader-style limiting (while reading request headers)
    @H_403_32@// and functionality to support CloseNotifier. See *connReader docs.
    r *connReader

    @H_403_32@// bufr reads from r.
    @H_403_32@// Users of bufr must hold mu.
    bufr *bufio.Reader

    @H_403_32@// bufw writes to checkConnErrorWriter{c},which populates werr on error.
    bufw *bufio.Writer

    @H_403_32@// lastMethod is the method of the most recent request
    @H_403_32@// on this connection,if any.
    lastMethod string

    @H_403_32@// mu guards hijackedv,use of bufr,(*response).closeNotifyCh.
    mu sync.Mutex

    @H_403_32@// hijackedv is whether this connection has been hijacked
    @H_403_32@// by a Handler with the Hijacker interface.
    @H_403_32@// It is guarded by mu.
    hijackedv bool
}
  • conn类中,引用了net.Conn,他是一个接口,由如下几种方法,net.Conn才是真正与客户端交互的接口.(下边的接口定义在net/net.go包中)
type Conn interface {
    @H_403_32@// Read reads data from the connection.
    @H_403_32@// Read can be made to time out and return a Error with Timeout() == true
    @H_403_32@// after a fixed time limit; see SetDeadline and SetReadDeadline.
    Read(b []byte) (n int,err error)

    @H_403_32@// Write writes data to the connection.
    @H_403_32@// Write can be made to time out and return a Error with Timeout() == true
    @H_403_32@// after a fixed time limit; see SetDeadline and SetWriteDeadline.
    Write(b []byte) (n int,err error)

    @H_403_32@// Close closes the connection.
    @H_403_32@// Any blocked Read or Write operations will be unblocked and return errors.
    Close() error

    @H_403_32@// LocalAddr returns the local network address.
    LocalAddr() Addr

    @H_403_32@// RemoteAddr returns the remote network address.
    RemoteAddr() Addr

    @H_403_32@// SetDeadline sets the read and write deadlines associated
    @H_403_32@// with the connection. It is equivalent to calling both
    @H_403_32@// SetReadDeadline and SetWriteDeadline.
    @H_403_32@//
    @H_403_32@// A deadline is an absolute time after which I/O operations
    @H_403_32@// fail with a timeout (see type Error) instead of
    @H_403_32@// blocking. The deadline applies to all future I/O,not just
    @H_403_32@// the immediately following call to Read or Write.
    @H_403_32@//
    @H_403_32@// An idle timeout can be implemented by repeatedly extending
    @H_403_32@// the deadline after successful Read or Write calls.
    @H_403_32@//
    @H_403_32@// A zero value for t means I/O operations will not time out.
    SetDeadline(t time.Time) error

    @H_403_32@// SetReadDeadline sets the deadline for future Read calls.
    @H_403_32@// A zero value for t means Read will not time out.
    SetReadDeadline(t time.Time) error

    @H_403_32@// SetWriteDeadline sets the deadline for future Write calls.
    @H_403_32@// Even if write times out,it may return n > 0,indicating that
    @H_403_32@// some of the data was successfully written.
    @H_403_32@// A zero value for t means Write will not time out.
    SetWriteDeadline(t time.Time) error
}
  • 通过下边的函数来处理客户端的https请求,用户每发起一个请求,都会创建一个goroutine. 这个新创建的goroutine负责与客户端进行交互. net/http/server.go中定义的conn中使用了net/net.go中的接口来与客户端实现报文通信.
func (c *conn) serve(ctx context.Context) {
    @H_403_32@// 客户端地址.
    c.remoteAddr = c.rwc.RemoteAddr().String()

    @H_403_32@// 异常补货,当一个用户的请求导致服务器异常后,http监听进程不会退出.
    defer func() {
        if err := recover(); err != nil {
            const size = 64 << 10
            buf := make([]byte,size)
            buf = buf[:runtime.Stack(buf,false)]
            c.server.logf("http: panic serving %v: %v\n%s",c.remoteAddr,err,buf)
        }
        if !c.hijacked() {
            c.close()
            c.setState(c.rwc,StateClosed)
        }
    }()

    @H_403_32@// tlsConn 就是实现了net/net.go中conn接口的一个实例.
    if tlsConn,ok := c.rwc.(*tls.Conn); ok {
        if d := c.server.ReadTimeout; d != 0 {
            @H_403_32@// 设置读超时时间
            c.rwc.SetReadDeadline(time.Now().Add(d))
        }
        if d := c.server.WriteTimeout; d != 0 {
            @H_403_32@// 设置写超时时间
            c.rwc.SetWriteDeadline(time.Now().Add(d))
        }
        if err := tlsConn.Handshake(); err != nil {
            c.server.logf("http: TLS handshake error from %s: %v",c.rwc.RemoteAddr(),err)
            return
        }
        c.tlsState = new(tls.ConnectionState)
        *c.tlsState = tlsConn.ConnectionState()
        if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) {
            if fn := c.server.TLSNextProto[proto]; fn != nil {
                h := initNPNRequest{tlsConn,serverHandler{c.server}}
                fn(c.server,tlsConn,h)
            }
            return
        }
    }

    @H_403_32@// HTTP/1.x from here on.

    c.r = &connReader{r: c.rwc}
    c.bufr = newBufioReader(c.r)
    c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)

    ctx,cancelCtx := context.WithCancel(ctx)
    defer cancelCtx()

    for {
        w,err := c.readRequest(ctx)
        if c.r.remain != c.server.initialReadLimitSize() {
            @H_403_32@// If we read any bytes off the wire,we're active.
            c.setState(c.rwc,StateActive)
        }
        if err != nil {
            if err == errTooLarge {
                @H_403_32@// Their HTTP client may or may not be
                @H_403_32@// able to read this if we're
                @H_403_32@// responding to them and hanging up
                @H_403_32@// while they're still writing their
                @H_403_32@// request. Undefined behavior.
                io.WriteString(c.rwc,"HTTP/1.1 431 Request Header Fields Too Large\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n431 Request Header Fields Too Large")
                c.closeWriteAndWait()
                return
            }
            if err == io.EOF {
                return @H_403_32@// don't reply
            }
            if neterr,ok := err.(net.Error); ok && neterr.Timeout() {
                return @H_403_32@// don't reply
            }
            var publicErr string
            if v,ok := err.(badRequestError); ok {
                publicErr = ": " + string(v)
            }
            io.WriteString(c.rwc,"HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n400 Bad Request"+publicErr)
            return
        }

        @H_403_32@// Expect 100 Continue support
        req := w.req
        if req.expectsContinue() {
            if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
                @H_403_32@// Wrap the Body reader with one that replies on the connection
                req.Body = &expectContinueReader{readCloser: req.Body,resp: w}
            }
        } else if req.Header.get("Expect") != "" {
            w.sendExpectationFailed()
            return
        }

        @H_403_32@// HTTP cannot have multiple simultaneous active requests.[*]
        @H_403_32@// Until the server replies to this request,it can't read another,
        @H_403_32@// so we might as well run the handler in this goroutine.
        @H_403_32@// [*] Not strictly true: HTTP pipelining. We could let them all process
        @H_403_32@// in parallel even if their responses need to be serialized.
        serverHandler{c.server}.ServeHTTP(w,w.req)
        w.cancelCtx()
        if c.hijacked() {
            return
        }
        w.finishRequest()
        if !w.shouldReuseConnection() {
            if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
                c.closeWriteAndWait()
            }
            return
        }
        c.setState(c.rwc,StateIdle)
    }
}
  • 通过上边的代码可知request是response中的一部分.第三方路由中,自定义了serverHandler{c.server}.ServeHTTP(w,w.req)部分,从而脱离了SDK默认的路由方式,使用自定义的路由处理规则.
  • 用户若要自定义路由处理函数,需要实现Handler接口.接口定义如下.
type Handler interface {
    ServeHTTP(ResponseWriter,*Request)
}
  • 用户可以自定义一个类,实现Handler接口中的ServeHTTP方法.就可以了.
  • ServeHTTP方法接收ResponseWrite与Request.其中ResponseWrite是一个接口,Response实现了这个接口.其接口定义如下:
type response struct {
    conn             *conn
    req              *Request @H_403_32@// request for this response
    reqBody          io.ReadCloser
    cancelCtx        context.CancelFunc @H_403_32@// when ServeHTTP exits
    wroteHeader      bool               @H_403_32@// reply header has been (logically) written
    wroteContinue    bool               @H_403_32@// 100 Continue response was written
    wants10KeepAlive bool               @H_403_32@// HTTP/1.0 w/ Connection "keep-alive"
    wantsClose       bool               @H_403_32@// HTTP request has Connection "close"

    w  *bufio.Writer @H_403_32@// buffers output in chunks to chunkWriter
    cw chunkWriter

    @H_403_32@// handlerHeader is the Header that Handlers get access to,
    @H_403_32@// which may be retained and mutated even after WriteHeader.
    @H_403_32@// handlerHeader is copied into cw.header at WriteHeader
    @H_403_32@// time,and privately mutated thereafter.
    handlerHeader Header
    calledHeader  bool @H_403_32@// handler accessed handlerHeader via Header

    written       int64 @H_403_32@// number of bytes written in body
    contentLength int64 @H_403_32@// explicitly-declared Content-Length; or -1
    status        int   @H_403_32@// status code passed to WriteHeader

    @H_403_32@// close connection after this reply. set on request and
    @H_403_32@// updated after response from handler if there's a
    @H_403_32@// "Connection: keep-alive" response header and a
    @H_403_32@// Content-Length.
    closeAfterReply bool

    @H_403_32@// requestBodyLimitHit is set by requestTooLarge when
    @H_403_32@// maxBytesReader hits its max size. It is checked in
    @H_403_32@// WriteHeader,to make sure we don't consume the
    @H_403_32@// remaining request body to try to advance to the next HTTP
    @H_403_32@// request. Instead,when this is set,we stop reading
    @H_403_32@// subsequent requests on this connection and stop reading
    @H_403_32@// input from it.
    requestBodyLimitHit bool

    @H_403_32@// trailers are the headers to be sent after the handler
    @H_403_32@// finishes writing the body. This field is initialized from
    @H_403_32@// the Trailer response header when the response header is
    @H_403_32@// written.
    trailers []string

    handlerDone atomicBool @H_403_32@// set true when the handler exits

    @H_403_32@// Buffers for Date and Content-Length
    dateBuf [len(TimeFormat)]byte
    clenBuf [10]byte

    @H_403_32@// closeNotifyCh is non-nil once CloseNotify is called.
    @H_403_32@// Guarded by conn.mu
    closeNotifyCh <-chan bool
}

Response中可以获取到Request. Request定义如下:

type Request struct {
    @H_403_32@// Method specifies the HTTP method (GET,POST,PUT,etc.).
    @H_403_32@// For client requests an empty string means GET.
    Method string

    @H_403_32@// URL specifies either the URI being requested (for server
    @H_403_32@// requests) or the URL to access (for client requests).
    @H_403_32@//
    @H_403_32@// For server requests the URL is parsed from the URI
    @H_403_32@// supplied on the Request-Line as stored in RequestURI. For
    @H_403_32@// most requests,fields other than Path and RawQuery will be
    @H_403_32@// empty. (See RFC 2616,Section 5.1.2)
    @H_403_32@//
    @H_403_32@// For client requests,the URL's Host specifies the server to
    @H_403_32@// connect to,while the Request's Host field optionally
    @H_403_32@// specifies the Host header value to send in the HTTP
    @H_403_32@// request.
    URL *url.URL

    @H_403_32@// The protocol version for incoming server requests.
    @H_403_32@//
    @H_403_32@// For client requests these fields are ignored. The HTTP
    @H_403_32@// client code always uses either HTTP/1.1 or HTTP/2.
    @H_403_32@// See the docs on Transport for details.
    Proto      string @H_403_32@// "HTTP/1.0"
    ProtoMajor int    @H_403_32@// 1
    ProtoMinor int    @H_403_32@// 0

    @H_403_32@// Header contains the request header fields either received
    @H_403_32@// by the server or to be sent by the client.
    @H_403_32@//
    @H_403_32@// If a server received a request with header lines,
    @H_403_32@//
    @H_403_32@// Host: example.com
    @H_403_32@// accept-encoding: gzip,deflate
    @H_403_32@// Accept-Language: en-us
    @H_403_32@// fOO: Bar
    @H_403_32@// foo: two
    @H_403_32@//
    @H_403_32@// then
    @H_403_32@//
    @H_403_32@// Header = map[string][]string{
    @H_403_32@// "Accept-Encoding": {"gzip,deflate"},
    @H_403_32@// "Accept-Language": {"en-us"},
    @H_403_32@// "Foo": {"Bar","two"},
    @H_403_32@// }
    @H_403_32@//
    @H_403_32@// For incoming requests,the Host header is promoted to the
    @H_403_32@// Request.Host field and removed from the Header map.
    @H_403_32@//
    @H_403_32@// HTTP defines that header names are case-insensitive. The
    @H_403_32@// request parser implements this by using CanonicalHeaderKey,
    @H_403_32@// making the first character and any characters following a
    @H_403_32@// hyphen uppercase and the rest lowercase.
    @H_403_32@//
    @H_403_32@// For client requests,certain headers such as Content-Length
    @H_403_32@// and Connection are automatically written when needed and
    @H_403_32@// values in Header may be ignored. See the documentation
    @H_403_32@// for the Request.Write method.
    Header Header

    @H_403_32@// Body is the request's body.
    @H_403_32@//
    @H_403_32@// For client requests a nil body means the request has no
    @H_403_32@// body,such as a GET request. The HTTP Client's Transport
    @H_403_32@// is responsible for calling the Close method.
    @H_403_32@//
    @H_403_32@// For server requests the Request Body is always non-nil
    @H_403_32@// but will return EOF immediately when no body is present.
    @H_403_32@// The Server will close the request body. The ServeHTTP
    @H_403_32@// Handler does not need to.
    Body io.ReadCloser

    @H_403_32@// ContentLength records the length of the associated content.
    @H_403_32@// The value -1 indicates that the length is unknown.
    @H_403_32@// Values >= 0 indicate that the given number of bytes may
    @H_403_32@// be read from Body.
    @H_403_32@// For client requests,a value of 0 means unknown if Body is not nil.
    ContentLength int64

    @H_403_32@// TransferEncoding lists the transfer encodings from outermost to
    @H_403_32@// innermost. An empty list denotes the "identity" encoding.
    @H_403_32@// TransferEncoding can usually be ignored; chunked encoding is
    @H_403_32@// automatically added and removed as necessary when sending and
    @H_403_32@// receiving requests.
    TransferEncoding []string

    @H_403_32@// Close indicates whether to close the connection after
    @H_403_32@// replying to this request (for servers) or after sending this
    @H_403_32@// request and reading its response (for clients).
    @H_403_32@//
    @H_403_32@// For server requests,the HTTP server handles this automatically
    @H_403_32@// and this field is not needed by Handlers.
    @H_403_32@//
    @H_403_32@// For client requests,setting this field prevents re-use of
    @H_403_32@// TCP connections between requests to the same hosts,as if
    @H_403_32@// Transport.DisableKeepAlives were set.
    Close bool

    @H_403_32@// For server requests Host specifies the host on which the
    @H_403_32@// URL is sought. Per RFC 2616,this is either the value of
    @H_403_32@// the "Host" header or the host name given in the URL itself.
    @H_403_32@// It may be of the form "host:port".
    @H_403_32@//
    @H_403_32@// For client requests Host optionally overrides the Host
    @H_403_32@// header to send. If empty,the Request.Write method uses
    @H_403_32@// the value of URL.Host.
    Host string

    @H_403_32@// Form contains the parsed form data,including both the URL
    @H_403_32@// field's query parameters and the POST or PUT form data.
    @H_403_32@// This field is only available after ParseForm is called.
    @H_403_32@// The HTTP client ignores Form and uses Body instead.
    Form url.Values

    @H_403_32@// PostForm contains the parsed form data from POST,PATCH,
    @H_403_32@// or PUT body parameters.
    @H_403_32@//
    @H_403_32@// This field is only available after ParseForm is called.
    @H_403_32@// The HTTP client ignores PostForm and uses Body instead.
    PostForm url.Values

    @H_403_32@// MultipartForm is the parsed multipart form,including file uploads.
    @H_403_32@// This field is only available after ParseMultipartForm is called.
    @H_403_32@// The HTTP client ignores MultipartForm and uses Body instead.
    MultipartForm *multipart.Form

    @H_403_32@// Trailer specifies additional headers that are sent after the request
    @H_403_32@// body.
    @H_403_32@//
    @H_403_32@// For server requests the Trailer map initially contains only the
    @H_403_32@// trailer keys,with nil values. (The client declares which trailers it
    @H_403_32@// will later send.) While the handler is reading from Body,it must
    @H_403_32@// not reference Trailer. After reading from Body returns EOF,Trailer
    @H_403_32@// can be read again and will contain non-nil values,if they were sent
    @H_403_32@// by the client.
    @H_403_32@//
    @H_403_32@// For client requests Trailer must be initialized to a map containing
    @H_403_32@// the trailer keys to later send. The values may be nil or their final
    @H_403_32@// values. The ContentLength must be 0 or -1,to send a chunked request.
    @H_403_32@// After the HTTP request is sent the map values can be updated while
    @H_403_32@// the request body is read. Once the body returns EOF,the caller must
    @H_403_32@// not mutate Trailer.
    @H_403_32@//
    @H_403_32@// Few HTTP clients,servers,or proxies support HTTP trailers.
    Trailer Header

    @H_403_32@// RemoteAddr allows HTTP servers and other software to record
    @H_403_32@// the network address that sent the request,usually for
    @H_403_32@// logging. This field is not filled in by ReadRequest and
    @H_403_32@// has no defined format. The HTTP server in this package
    @H_403_32@// sets RemoteAddr to an "IP:port" address before invoking a
    @H_403_32@// handler.
    @H_403_32@// This field is ignored by the HTTP client.
    RemoteAddr string

    @H_403_32@// RequestURI is the unmodified Request-URI of the
    @H_403_32@// Request-Line (RFC 2616,Section 5.1) as sent by the client
    @H_403_32@// to a server. Usually the URL field should be used instead.
    @H_403_32@// It is an error to set this field in an HTTP client request.
    RequestURI string

    @H_403_32@// TLS allows HTTP servers and other software to record
    @H_403_32@// information about the TLS connection on which the request
    @H_403_32@// was received. This field is not filled in by ReadRequest.
    @H_403_32@// The HTTP server in this package sets the field for
    @H_403_32@// TLS-enabled connections before invoking a handler;
    @H_403_32@// otherwise it leaves the field nil.
    @H_403_32@// This field is ignored by the HTTP client.
    TLS *tls.ConnectionState

    @H_403_32@// Cancel is an optional channel whose closure indicates that the client
    @H_403_32@// request should be regarded as canceled. Not all implementations of
    @H_403_32@// RoundTripper may support Cancel.
    @H_403_32@//
    @H_403_32@// For server requests,this field is not applicable.
    @H_403_32@//
    @H_403_32@// Deprecated: Use the Context and WithContext methods
    @H_403_32@// instead. If a Request's Cancel field and context are both
    @H_403_32@// set,it is undefined whether Cancel is respected.
    Cancel <-chan struct{}

    @H_403_32@// Response is the redirect response which caused this request
    @H_403_32@// to be created. This field is only populated during client
    @H_403_32@// redirects.
    Response *Response

    @H_403_32@// ctx is either the client or server context. It should only
    @H_403_32@// be modified via copying the whole Request using WithContext.
    @H_403_32@// It is unexported to prevent people from using Context wrong
    @H_403_32@// and mutating the contexts held by callers of the same request.
    ctx context.Context
}
  • 在Response与Request中可以获取到客户端与服务端的参数信息.所以,在自定义的路由处理函数中,通过这两个变量,可以轻松的完成client与server之间的通信处理.
  • 在这个地方插入中间件,可以实现附加的功能处理.

总结:

golang sdk http服务支持自定义的路由处理函数. 这也是很多中间件注入的地方.通过中间件可以完成很多系统需要的附加功能.如权限认证,缓存处理,负载均衡等等

猜你在找的Go相关文章