- http状态码
- 全局定量
- 包方法
- Variables
- ProtocolError">type ProtocolError
- Header">type Header
- Cookie">type Cookie
- CookieJar">type CookieJar
- Flusher">type Flusher
- Request">type Request
- Response">type Response
- ResponseWriter">type ResponseWriter
- RoundTripper">type RoundTripper
- Transport">type Transport
- Client">type Client
- Handler">type Handler
- HandlerFunc">type HandlerFunc
- Server">type Server
- ServeMux">type ServeMux
- File">type File
- FileSystem">type FileSystem
- FileServer">func FileServer
- Dir">type Dir
- 路由
http包提供了HTTP客户端和服务端的实现。
Get、Head、Post和PostForm函数发出HTTP/ HTTPS请求。
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{"key": {"Value"}, "id": {"123"}})
程序在使用完回复后必须关闭回复的主体。
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...
要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...
要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
Client和Transport类型都可以安全的被多个go程同时使用。出于效率考虑,应该一次建立、尽量重用。
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
要管理服务端的行为,可以创建一个自定义的Server:
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
http状态码
const (
StatusContinue = 100
StatusSwitchingProtocols = 101
StatusOK = 200
StatusCreated = 201
StatusAccepted = 202
StatusNonAuthoritativeInfo = 203
StatusNoContent = 204
StatusResetContent = 205
StatusPartialContent = 206
StatusMultipleChoices = 300
StatusMovedPermanently = 301
StatusFound = 302
StatusSeeOther = 303
StatusNotModified = 304
StatusUseProxy = 305
StatusTemporaryRedirect = 307
StatusBadRequest = 400
StatusUnauthorized = 401
StatusPaymentRequired = 402
StatusForbidden = 403
StatusNotFound = 404
StatusMethodNotAllowed = 405
StatusNotAcceptable = 406
StatusProxyAuthRequired = 407
StatusRequestTimeout = 408
StatusConflict = 409
StatusGone = 410
StatusLengthRequired = 411
StatusPreconditionFailed = 412
StatusRequestEntityTooLarge = 413
StatusRequestURITooLong = 414
StatusUnsupportedMediaType = 415
StatusRequestedRangeNotSatisfiable = 416
StatusExpectationFailed = 417
StatusTeapot = 418
StatusInternalServerError = 500
StatusNotImplemented = 501
StatusBadGateway = 502
StatusServiceUnavailable = 503
StatusGatewayTimeout = 504
StatusHTTPVersionNotSupported = 505
)
全局定量
DefaultMaxHeaderBytes是HTTP请求的头域最大允许长度。
可以通过设置Server.MaxHeaderBytes字段来覆盖
const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
DefaultMaxIdleConnsPerHost是Transport的MaxIdleConnsPerHost的默认值。
const DefaultMaxIdleConnsPerHost = 2
TimeFormat是当解析或生产HTTP头域中的时间时,用与time.Parse或time.Format函数的时间格式。
const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
包方法
func Handle(pattern string, handler Handler) 新增Handle
func HandleFunc(pattern string, handler func(ResponseWriter, Request))
func ProxyURL(fixedURL url.URL) func(Request) (url.URL, error) 返回一个代理函数(用于Transport类型),该函数总是返回同一个
func Redirect(w ResponseWriter, r Request, urlStr string, code int) 重定向
func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser 限制请求体大小
func NotFound(w ResponseWriter, r Request) 返回404
func Error(w ResponseWriter, error string, code int) 使用指定错误信息与状态码返回
func StatusText(code int) string 返回HTTP状态代码的文本。如果代码未知,则返回空字符串
func ServeFile(w ResponseWriter, r *Request, name string) 回复请求name指定的文件或者目录的内容
func Serve(l net.Listener, handler Handler) error
- Serve会接手监听器l收到的每一个连接,并为每一个连接创建一个新的服务go程。handler参数一般会设为nil,此时会使用DefaultServeMux。
func ListenAndServe(addr string, handler Handler) error
- ListenAndServe监听TCP地址addr,并且会使用handler参数调用Serve函数处理接收到的连接。handler参数一般会设为nil,此时会使用DefaultServeMux。
package main
import (
"io"
"net/http"
"log"
)
// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main() {
http.HandleFunc("/hello", HelloServer)
err := http.ListenAndServe(":12345", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error
- ListenAndServeTLS函数和ListenAndServe函数的行为基本一致,除了它期望HTTPS连接之外。此外,必须提供证书文件和对应的私钥文件,handler参数一般会设为nil,此时会使用DefaultServeMux。
import (
"log"
"net/http"
)
func handler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.\n"))
}
func main() {
http.HandleFunc("/", handler)
err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
if err != nil {
log.Fatal(err)
}
}
Variables
HTTP请求的解析错误
var (
ErrHeaderTooLong = &ProtocolError{"header too long"}
ErrShortBody = &ProtocolError{"entity body too short"}
ErrNotSupported = &ProtocolError{"feature not supported"}
ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
)
会被HTTP服务端返回的错误
var (
ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
ErrHijacked = errors.New("Conn has been hijacked")
ErrContentLength = errors.New("Conn.Write wrote more than the declared Content-Length")
)
var DefaultClient = &Client{} //用于包函数Get、Head和Post的默认Client
var DefaultServeMux = NewServeMux() //用于Serve的默认ServeMux
//在Resquest或Response的Body字段已经关闭后,试图从中读取时,就会返回ErrBodyReadAfterClose
var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
//在处理器超时以后调用ResponseWriter接口的Write方法,就会返回ErrHandlerTimeout
var ErrHandlerTimeout = errors.New("http: Handler timeout")
var ErrLineTooLong = errors.New("header line too long")
var ErrMissingFile = errors.New("http: no such file")
var ErrNoCookie = errors.New("http: named cookie not present")
var ErrNoLocation = errors.New("http: no Location header in response")
type ProtocolError
type ProtocolError struct {
ErrorString string
}
func (err *ProtocolError) Error() string
type Header
type Header map[string][]string
func (h Header) Get(key string) string:查
func (h Header) Set(key, value string):增/改
func (h Header) Add(key, value string):增,追加
func (h Header) Del(key string):删
type Cookie
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
// MaxAge=0表示未设置Max-Age属性
// MaxAge<0表示立刻删除该cookie,等价于"Max-Age: 0"
// MaxAge>0表示存在Max-Age属性,单位是秒
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string // 未解析的“属性-值”对的原始文本
}
type CookieJar
type CookieJar interface {
// SetCookies管理从u的回复中收到的cookie
// 根据其策略和实现,它可以选择是否存储cookie
SetCookies(u *url.URL, cookies []*Cookie)
// Cookies返回发送请求到u时应使用的cookie
// 本方法有责任遵守RFC 6265规定的标准cookie限制
Cookies(u *url.URL) []*Cookie
}
type Flusher
HTTP处理器ResponseWriter接口参数的下层如果实现了Flusher接口,可以让HTTP处理器将缓冲中的数据发送到客户端。
type Flusher interface {
// Flush将缓冲中的所有数据发送到客户端
Flush()
}
type Request
type Request struct {
Method string
URL *url.URL
// 接收到的请求的协议版本。本包生产的Request总是使用HTTP/1.1
Proto string // "HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
// Header字段用来表示HTTP请求的头域。如果头域(多行键值对格式)为:
// accept-encoding: gzip, deflate
// Accept-Language: en-us
// Connection: keep-alive
// 则:
// Header = map[string][]string{
// "Accept-Encoding": {"gzip, deflate"},
// "Accept-Language": {"en-us"},
// "Connection": {"keep-alive"},
// }
Header Header
Body io.ReadCloser
// ContentLength记录相关内容的长度。
// 如果为-1,表示长度未知,如果>=0,表示可以从Body字段读取ContentLength字节数据。
// 在客户端,如果Body非nil而该字段为0,表示不知道Body的长度。
ContentLength int64
// TransferEncoding按从最外到最里的顺序列出传输编码,空切片表示"identity"编码。
// 本字段一般会被忽略。当发送或接受请求时,会自动添加或移除"chunked"传输编码。
TransferEncoding []string
// Close在服务端指定是否在回复请求后关闭连接,在客户端指定是否在发送请求后关闭连接。
Close bool
// 在服务端,Host指定URL会在其上寻找资源的主机。
// 根据RFC 2616,该值可以是Host头的值,或者URL自身提供的主机名。
// Host的格式可以是"host:port"。
//
// 在客户端,请求的Host字段(可选地)用来重写请求的Host头。
// 如过该字段为"",Request.Write方法会使用URL字段的Host。
Host string
// Form是解析好的表单数据,包括URL字段的query参数和POST或PUT的表单数据。
// 本字段只有在调用ParseForm后才有效。在客户端,会忽略请求中的本字段而使用Body替代。
Form url.Values
// PostForm是解析好的POST或PUT的表单数据。
// 本字段只有在调用ParseForm后才有效。在客户端,会忽略请求中的本字段而使用Body替代。
PostForm url.Values
// MultipartForm是解析好的多部件表单,包括上传的文件。
// 本字段只有在调用ParseMultipartForm后才有效。
// 在客户端,会忽略请求中的本字段而使用Body替代。
MultipartForm *multipart.Form
// Trailer指定了会在请求主体之后发送的额外的头域。
Trailer Header
RemoteAddr string
RequestURI string
// TLS字段允许HTTP服务器和其他软件记录接收到该请求的TLS连接的信息
// 本字段不是ReadRequest函数填写的。
// 对启用了TLS的连接,本包的HTTP服务器会在调用处理器之前设置TLS字段,否则将设TLS为nil。
// 客户端会忽略请求中的TLS字段。
TLS *tls.ConnectionState
}
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
- 使用指定的方法、网址和可选的主题创建并返回一个新的*Request
func ReadRequest(b bufio.Reader) (req Request, err error)
- ReadRequest从b读取并解析出一个HTTP请求
func (r Request) UserAgent() string
func (r Request) Referer() string
func (r Request) AddCookie(c Cookie)
func (r Request) Write(w io.Writer) error:Host、URL、Method等
func (r Request) WriteProxy(w io.Writer) error
func (r Request) Cookies() []Cookie
func (r Request) Cookie(name string) (Cookie, error)
func (r Request) ParseForm() error
func (r Request) ParseMultipartForm(maxMemory int64) error
func (r Request) FormValue(key string) string
func (r Request) PostFormValue(key string) string
func (r Request) FormFile(key string) (multipart.File, multipart.FileHeader, error)
func (r Request) MultipartReader() (multipart.Reader, error)
type Response
type Response struct {
Status string // 例如"200 OK"
StatusCode int // 例如200
Proto string // 例如"HTTP/1.0"
ProtoMajor int // 例如1
ProtoMinor int // 例如0
Header Header
// Body代表回复的主体。
// Client类型和Transport类型会保证Body字段总是非nil的,即使回复没有主体或主体长度为0。
// 关闭主体是调用者的责任。
// 如果服务端采用"chunked"传输编码发送的回复,Body字段会自动进行解码。
Body io.ReadCloser
// ContentLength记录相关内容的长度。
// 其值为-1表示长度未知(采用chunked传输编码)
// 除非对应的Request.Method是"HEAD",其值>=0表示可以从Body读取的字节数
ContentLength int64
// TransferEncoding按从最外到最里的顺序列出传输编码,空切片表示"identity"编码。
TransferEncoding []string
// Close记录头域是否指定应在读取完主体后关闭连接。(即Connection头)
// 该值是给客户端的建议,Response.Write方法的ReadResponse函数都不会关闭连接。
Close bool
// Trailer字段保存和头域相同格式的trailer键值对,和Header字段相同类型
Trailer Header
// Request是用来获取此回复的请求
// Request的Body字段是nil(因为已经被用掉了)
// 这个字段是被Client类型发出请求并获得回复后填充的
Request *Request
// TLS包含接收到该回复的TLS连接的信息。 对未加密的回复,本字段为nil。
// 返回的指针是被(同一TLS连接接收到的)回复共享的,不应被修改。
TLS *tls.ConnectionState
}
func ReadResponse(r bufio.Reader, req Request) (*Response, error)
- 从r读取并返回一个HTTP 回复。req参数是可选的,指定该回复对应的请求(即是对该请求的回复)。如果是nil,将假设请求是GET请求。客户端必须在结束resp.Body的读取后关闭它。
func (r Response) Cookies() []Cookie:回该回复中的Set-Cookie头设置的cookie
func (r Response) Write(w io.Writer) error
func (r Response) Location() (*url.URL, error)
- Location返回该回复的Location头设置的URL。相对地址的重定向会相对于该回复对应的请求来确定绝对地址。如果回复中没有Location头,会返回nil, ErrNoLocation。
type ResponseWriter
type ResponseWriter interface {
// Header返回一个Header类型值,该值会被WriteHeader方法发送。
// 在调用WriteHeader或Write方法后再改变该对象是没有意义的。
Header() Header
// WriteHeader该方法发送HTTP回复的头域和状态码。
// 如果没有被显式调用,第一次调用Write时会触发隐式调用WriteHeader(http.StatusOK)
// WriterHeader的显式调用主要用于发送错误码。
WriteHeader(int)
// Write向连接中写入作为HTTP的一部分回复的数据。
// 如果被调用时还未调用WriteHeader,本方法会先调用WriteHeader(http.StatusOK)
// 如果Header中没有"Content-Type"键,
// 本方法会使用包函数DetectContentType检查数据的前512字节,将返回值作为该键的值。
Write([]byte) (int, error)
}
type RoundTripper
RoundTripper接口是具有执行单次HTTP事务的能力(接收指定请求的回复)的接口。
RoundTripper接口的类型必须可以安全的被多线程同时使用。
type RoundTripper interface {
// RoundTrip执行单次HTTP事务,接收并发挥请求req的回复。
// RoundTrip不应试图解析/修改得到的回复。
// 尤其要注意,只要RoundTrip获得了一个回复,不管该回复的HTTP状态码如何,
// 它必须将返回值err设置为nil。
// 非nil的返回值err应该留给获取回复失败的情况。
// 类似的,RoundTrip不能试图管理高层次的细节,如重定向、认证、cookie。
//
// 除了从请求的主体读取并关闭主体之外,RoundTrip不应修改请求,包括(请求的)错误。
// RoundTrip函数接收的请求的URL和Header字段可以保证是(被)初始化了的。
RoundTrip(*Request) (*Response, error)
}
type Transport
Transport类型实现了RoundTripper接口,支持http、https和http/https代理。Transport类型可以缓存连接以在未来重用。
type Transport struct {
// Proxy指定一个对给定请求返回代理的函数。
// 如果该函数返回了非nil的错误值,请求的执行就会中断并返回该错误。
// 如果Proxy为nil或返回nil的*URL置,将不使用代理。
Proxy func(*Request) (*url.URL, error)
// Dial指定创建TCP连接的拨号函数。如果Dial为nil,会使用net.Dial。
Dial func(network, addr string) (net.Conn, error)
// TLSClientConfig指定用于tls.Client的TLS配置信息。
// 如果该字段为nil,会使用默认的配置信息。
TLSClientConfig *tls.Config
// TLSHandshakeTimeout指定等待TLS握手完成的最长时间。零值表示不设置超时。
TLSHandshakeTimeout time.Duration
// 如果DisableKeepAlives为真,会禁止不同HTTP请求之间TCP连接的重用。
DisableKeepAlives bool
// 如果DisableCompression为真,会禁止Transport在请求中没有Accept-Encoding头时,
// 主动添加"Accept-Encoding: gzip"头,以获取压缩数据。
// 如果Transport自己请求gzip并得到了压缩后的回复,它会主动解压缩回复的主体。
// 但如果用户显式的请求gzip压缩数据,Transport是不会主动解压缩的。
DisableCompression bool
// 如果MaxIdleConnsPerHost!=0,会控制每个主机下的最大闲置连接。
// 如果MaxIdleConnsPerHost==0,会使用DefaultMaxIdleConnsPerHost。
MaxIdleConnsPerHost int
// ResponseHeaderTimeout指定在发送完请求(包括其可能的主体)之后,
// 等待接收服务端的回复的头域的最大时间。零值表示不设置超时。
// 该时间不包括获取回复主体的时间。
ResponseHeaderTimeout time.Duration
// 内含隐藏或非导出字段
}
Transport类型实现了RoundTripper接口,支持http、https和http/https代理。Transport类型可以缓存连接以在未来重用。
var DefaultTransport RoundTripper = &Transport{
Proxy: ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
}
DefaultTransport是被包变量DefaultClient使用的默认RoundTripper接口。它会根据需要创建网络连接,并缓存以便在之后的请求中重用这些连接。它使用环境变量$HTTP_PROXY和$NO_PROXY(或$http_proxy和$no_proxy)指定的HTTP代理。
func (t Transport) RoundTrip(req Request) (resp Response, err error) 实现了RoundTripper接口
func (t Transport) CloseIdleConnections() 关闭之前请求建立但目前处于闲置的连接。不会中断正在使用的连接
func (t Transport) CancelRequest(req Request) 通过关闭请求所在的连接取消一个执行中的请求
type Client
type Client struct {
// Transport指定执行独立、单次HTTP请求的机制。
// 如果Transport为nil,则使用DefaultTransport。
Transport RoundTripper
// CheckRedirect指定处理重定向的策略。
// 如果CheckRedirect不为nil,客户端会在执行重定向之前调用本函数字段。
// 如果CheckRedirect为nil,会采用默认策略:连续10此请求后停止。
CheckRedirect func(req *Request, via []*Request) error
// Jar指定cookie管理器。
// 如果Jar为nil,请求中不会发送cookie,回复中的cookie会被忽略。
Jar CookieJar
// Timeout指定本类型的值执行请求的时间限制。
// Timeout为零值表示不设置超时。
Timeout time.Duration
}
func (c Client) Do(req Request) (resp Response, err error)
func (c Client) Head(url string) (resp Response, err error)
func (c Client) Get(url string) (resp Response, err error)
func (c Client) Post(url string, bodyType string, body io.Reader) (resp Response, err error)
func (c Client) PostForm(url string, data url.Values) (resp *Response, err error)
type Handler
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
func NotFoundHandler() Handler 404
func RedirectHandler(url string, code int) Handler 重定向
func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler 超时,返回503
func StripPrefix(prefix string, h Handler) Handler
- 处理器会将请求的URL.Path字段中给定前缀prefix去除后再交由h处理
- StripPrefix会向URL.Path字段中没有给定前缀的请求回复404
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/tmp"))))
type HandlerFunc
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)
- HandleFunc注册一个处理器函数handler和对应的模式pattern(注册到DefaultServeMux)。ServeMux的文档解释了模式的匹配机制。
type Server
type Server struct {
Addr string // 监听的TCP地址,如果为空字符串会使用":http"
Handler Handler // 调用的处理器,如为nil会调用http.DefaultServeMux
ReadTimeout time.Duration // 请求的读取操作在超时前的最大持续时间
WriteTimeout time.Duration // 回复的写入操作在超时前的最大持续时间
MaxHeaderBytes int // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
TLSConfig *tls.Config // 可选的TLS配置,用于ListenAndServeTLS方法
// TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
// 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
// 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
// 连接在函数返回时会自动关闭。
TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
// ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
// 参见ConnState类型和相关常数获取细节。
ConnState func(net.Conn, ConnState)
// ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
// 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
ErrorLog *log.Logger
// 内含隐藏或非导出字段
}
func (s *Server) SetKeepAlivesEnabled(v bool)
- 控制是否允许HTTP闲置连接重用(keep-alive)功能。默认该功能总是被启用的。只有资源非常紧张的环境或者服务端在关闭进程中时,才应该关闭该功能。
func (srv *Server) Serve(l net.Listener) error
- Serve会接手监听器l收到的每一个连接,并为每一个连接创建一个新的服务go程。该go程会读取请求,然后调用srv.Handler回复请求。
func (srv *Server) ListenAndServe() error
- ListenAndServe监听srv.Addr指定的TCP地址,并且会调用Serve方法接收到的连接。如果srv.Addr为空字符串,会使用”:http”
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error
- ListenAndServeTLS监听srv.Addr确定的TCP地址,并且会调用Serve方法处理接收到的连接。必须提供证书文件和对应的私钥文件。如果证书是由权威机构签发的,certFile参数必须是顺序串联的服务端证书和CA证书。如果srv.Addr为空字符串,会使用”:https”。
type ServeMux
type ServeMux struct {
// 内含隐藏或非导出字段
}
ServeMux类型是HTTP请求的多路转接器。它会将每一个接收的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的处理器。
模式是固定的、由根开始的路径,如”/favicon.ico”,或由根开始的子树,如”/images/“(注意结尾的斜杠)。较长的模式优先于较短的模式,因此如果模式”/images/“和”/images/thumbnails/“都注册了处理器,后一个处理器会用于路径以”/images/thumbnails/“开始的请求,前一个处理器会接收到其余的路径在”/images/“子树下的请求。
注意,因为以斜杠结尾的模式代表一个由根开始的子树,模式”/“会匹配所有的未被其他注册的模式匹配的路径,而不仅仅是路径”/“。
模式也能(可选地)以主机名开始,表示只匹配该主机上的路径。指定主机的模式优先于一般的模式,因此一个注册了两个模式”/codesearch”和”codesearch.google.com/“的处理器不会接管目标为”http://www.google.com/“的请求。
ServeMux还会注意到请求的URL路径的无害化,将任何路径中包含”.”或”..”元素的请求重定向到等价的没有这两种元素的URL。(参见path.Clean函数)
func NewServeMux() ServeMux
func (mux ServeMux) Handle(pattern string, handler Handler)
func (mux ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, Request))
func (mux ServeMux) Handler(r Request) (h Handler, pattern string)
- Handler根据r.Method、r.Host和r.URL.Path等数据,返回将用于处理该请求的HTTP处理器。
type File
type File interface {
io.Closer
io.Reader
Readdir(count int) ([]os.FileInfo, error)
Seek(offset int64, whence int) (int64, error)
Stat() (os.FileInfo, error)
}
File是被FileSystem接口的Open方法返回的接口类型,可以被FileServer等函数用于文件访问服务。
该接口的方法的行为应该和*os.File类型的同名方法相同。
type FileSystem
type FileSystem interface {
Open(name string) (File, error)
}
func FS(fsys fs.FS) FileSystem FS将fsys转换为文件系统实现,用于FileServer和NewFileTransport
func FileServer
FileServer返回一个处理程序,该处理程序以根文件系统的内容为HTTP请求提供服务。 作为一个特例,返回的文件服务器将任何以“/index.html”结尾的请求重定向到相同的路径,而不是最终的“index.html”。
func FileServer(root FileSystem) Handler
http.Handle("/", http.FileServer(http.Dir("/tmp")))
http.Handle("/", http.FileServer(http.FS(fsys)))
type Dir
type Dir string
Dir使用限制到指定目录树的本地文件系统实现了http.FileSystem接口。空Dir被视为”.”,即代表当前目录。
func (d Dir) Open(name string) (File,error)
路由
基本
main.go
package main
import (
"log"
"net/http"
"test/webservice/test1/route"
)
func main() {
route.Route()
err := http.ListenAndServe(":12345", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
route.go
import (
"io"
"net/http"
)
// hello world, the web server
func HelloServer1(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello\n")
}
// hello world, the web server
func HelloServer2(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "world\n")
}
func Route() {
http.HandleFunc("/hello", HelloServer1)
http.HandleFunc("/world", HelloServer2)
}
ServeMux
main.go
package main
import (
"log"
"net/http"
"test/webservice/test1/route"
)
func main() {
mux := http.NewServeMux()
route.Route(mux)
http.DefaultServeMux = mux
err := http.ListenAndServe(":12345", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
route.go
package route
import (
"io"
"net/http"
)
// hello world, the web server
func HelloServer1(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello\n")
}
// hello world, the web server
func HelloServer2(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "world\n")
}
func Route(mux *http.ServeMux) {
mux.HandleFunc("/hello", HelloServer1)
mux.HandleFunc("/world", HelloServer2)
}