Go pkg學與練 - http

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。Go http package 包含了http client 和 http server 的實現。主要檔案有:~~~client.gocookie.goheader.gohttp.gomethod.gorequest.goresponse.goserver.gotransport.go~~~Server.go:---------我們先從一個簡單的http server開始。建立一個http服務需要有三個步驟:* 建立ServerMux:將預定義的url列表與Hanlder相關聯。* 建立Handler:負責對http請求進行處理,返回http響應。* 監聽給定的地址及連接埠提供http服務。~~~package mainimport ("fmt""html""log""net/http")func fooHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))}func main() {mux := http.NewServeMux()handler := http.HandlerFunc(fooHandler)mux.Handle("/foo", handler)log.Fatal(http.ListenAndServe(":8080", mux))}~~~ServeMux:~~~// ServeMux 結構type ServeMux struct {mu sync.RWMutex// 這個map用於存放http url entries, 而每個erntry 包含了一個Handler// 對應上面的例子:m = {"/foo":fooHandler(ResponseWriter, *Request)}m map[string]muxEntryhosts bool // whether any patterns contain hostnames}type muxEntry struct {explicit boolh Handlerpattern string}func NewServeMux() *ServeMux { return new(ServeMux) }func (mux *ServeMux) match(path string) (h Handler, pattern string) {// 根據request找出對應的Handlerfunc (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {// 將request 分發給Handler處理func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {// 註冊Handlerfunc (mux *ServeMux) Handle(pattern string, handler Handler) {func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {~~~DefaultServeMux:~~~var DefaultServeMux = &defaultServeMuxvar defaultServeMux ServeMuxfunc Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {// 上面的例子用defaultServeMux,可以簡化為:func main() {handler := http.HandlerFunc(fooHandler)http.Handle("/foo", handler)log.Fatal(http.ListenAndServe(":8080", nil))}或者func main() {http.HandleFunc("/foo", fooHandler)log.Fatal(http.ListenAndServe(":8080", nil))}~~~Handler:~~~type Handler interface {ServeHTTP(ResponseWriter, *Request)}// f 實現介面 Handler ServeHTTPtype HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r)}// 已定義好的一些處理器func NotFoundHandler() Handler { return HandlerFunc(NotFound) }func RedirectHandler(url string, code int) Handler {func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {~~~ListenAndServe:~~~// server 結構type Server struct {Addr string // TCP address to listen on, ":http" if emptyHandler Handler // handler to invoke, http.DefaultServeMux if nilTLSConfig *tls.Config // optional TLS config, used by ServeTLS and ListenAndServeTLSReadTimeout time.DurationReadHeaderTimeout time.DurationWriteTimeout time.DurationIdleTimeout time.DurationMaxHeaderBytes intTLSNextProto map[string]func(*Server, *tls.Conn, Handler)ConnState func(net.Conn, ConnState)ErrorLog *log.LoggerdisableKeepAlives int32 // accessed atomically.inShutdown int32 // accessed atomically (non-zero means we're in Shutdown)nextProtoOnce sync.Once // guards setupHTTP2_* initnextProtoErr error // result of http2.ConfigureServer if usedmu sync.Mutexlisteners map[net.Listener]struct{}activeConn map[*conn]struct{}doneChan chan struct{}onShutdown []func()}// 建立Server,調用ListenAndServefunc ListenAndServe(addr string, handler Handler) error {server := &Server{Addr: addr, Handler: handler}return server.ListenAndServe()}func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {server := &Server{Addr: addr, Handler: handler}return server.ListenAndServeTLS(certFile, keyFile)}// 調用net.Listen()進行監聽func (srv *Server) ListenAndServe() error {func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {// 接著調用server.Serve負責處理請求func (srv *Server) Serve(l net.Listener) error {func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {// Serve()調用Accept擷取串連資料, 並建立conn, go c.serve()處理請求func (srv *Server) newConn(rwc net.Conn) *conn {/* conn 結構type conn struct {server *ServercancelCtx context.CancelFuncrwc net.ConnremoteAddr stringtlsState *tls.ConnectionStatewerr errorr *connReaderbufr *bufio.Readerbufw *bufio.WriterlastMethod stringcurReq atomic.Value // of *response (which has a Request in it)curState atomic.Value // of ConnStatemu sync.Mutexhijackedv bool}*/// c.readRequest()讀取請求, 調用Handler ServeHTTP()func (c *conn) serve(ctx context.Context) {Server中其他methods:func (srv *Server) maxHeaderBytes() int {func (srv *Server) initialReadLimitSize() int64 {func (srv *Server) Close() error {func (srv *Server) Shutdown(ctx context.Context) error {func (srv *Server) RegisterOnShutdown(f func()) {func (srv *Server) shouldConfigureHTTP2ForServe() bool {func (srv *Server) SetKeepAlivesEnabled(v bool) {func (srv *Server) setupHTTP2_ServeTLS() error {func (srv *Server) setupHTTP2_Serve() error {func (srv *Server) onceSetNextProtoDefaults_Serve() {func (srv *Server) onceSetNextProtoDefaults() {Conn中其他methods:func (c *conn) hijacked() bool {func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {func (c *conn) readRequest(ctx context.Context) (w *response, err error) {func (c *conn) finalFlush() {func (c *conn) close() {func (c *conn) closeWriteAndWait() {func (c *conn) setState(nc net.Conn, state ConnState) {func (c *conn) serve(ctx context.Context) {~~~ResponseWrite:~~~type ResponseWriter interface {Header() HeaderWrite([]byte) (int, error)WriteHeader(int)}// response struct 實現 http.ResponseWritertype response struct {conn *connreq *Request // request for this responsereqBody io.ReadClosercancelCtx context.CancelFunc // when ServeHTTP exitswroteHeader bool // reply header has been (logically) writtenwroteContinue bool // 100 Continue response was writtenwants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive"wantsClose bool // HTTP request has Connection "close"// 例子中的字串“hello ...”會寫在w中w *bufio.Writer // buffers output in chunks to chunkWritercw chunkWriterhandlerHeader HeadercalledHeader bool // handler accessed handlerHeader via Header// 對應字串長度written int64 // number of bytes written in bodycontentLength int64 // explicitly-declared Content-Length; or -1 // 狀態代碼status int // status code passed to WriteHeadercloseAfterReply boolrequestBodyLimitHit booltrailers []stringhandlerDone atomicBool // set true when the handler exitsdateBuf [len(TimeFormat)]byteclenBuf [10]bytestatusBuf [3]bytecloseNotifyCh chan booldidCloseNotify int32 // atomic (only 0->1 winner should send)}func (w *response) Header() Header {func (w *response) Write(data []byte) (n int, err error) {func (w *response) WriteHeader(code int) {~~~Client.go:---------用戶端可以直接使用http.Get, http.Post等,樣本如下:~~~package mainimport "net/http"import "fmt"import "io/ioutil"func main() {resp, err := http.Get("http://www.163.com")if err != nil {fmt.Println(err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)fmt.Println(string(body))}~~~~~~func Get(url string) (resp *Response, err error) {func Post(url string, contentType string, body io.Reader) (resp *Response, err error) {func PostForm(url string, data url.Values) (resp *Response, err error) {func Head(url string) (resp *Response, err error) {func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {// 可以通過建立Client來做某些控制type Client struct {Transport RoundTripperCheckRedirect func(req *Request, via []*Request) errorJar CookieJarTimeout time.Duration}func (c *Client) Get(url string) (resp *Response, err error) {func (c *Client) Post(url string, contentType string, body io.Reader) (resp *Response, err error) {func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {func (c *Client) Head(url string) (resp *Response, err error) {func (c *Client) Do(req *Request) (*Response, error) {func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {~~~Request.go----------~~~type Request struct {Method stringURL *url.URLProto string // "HTTP/1.0"ProtoMajor int // 1ProtoMinor int // 0Header HeaderBody io.ReadCloserGetBody func() (io.ReadCloser, error)ContentLength int64TransferEncoding []stringClose boolHost stringForm url.ValuesPostForm url.ValuesMultipartForm *multipart.FormTrailer HeaderRemoteAddr stringRequestURI stringTLS *tls.ConnectionStateCancel <-chan struct{}Response *Responsectx context.Context}func NewRequest(method, url string, body io.Reader) (*Request, error) {func (r *Request) Context() context.Context {func (r *Request) WithContext(ctx context.Context) *Request {func (r *Request) ProtoAtLeast(major, minor int) bool {func (r *Request) UserAgent() string {func (r *Request) Cookies() []*Cookie {func (r *Request) Cookie(name string) (*Cookie, error) {func (r *Request) AddCookie(c *Cookie) {func (r *Request) Referer() string {func (r *Request) MultipartReader() (*multipart.Reader, error) {func (r *Request) multipartReader() (*multipart.Reader, error) {func (r *Request) isH2Upgrade() bool {func (r *Request) Write(w io.Writer) error {func (r *Request) WriteProxy(w io.Writer) error {func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {func (r *Request) BasicAuth() (username, password string, ok bool) {func (r *Request) SetBasicAuth(username, password string) {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) expectsContinue() bool {func (r *Request) wantsHttp10KeepAlive() bool {func (r *Request) wantsClose() bool {func (r *Request) closeBody() {func (r *Request) isReplayable() bool {func (r *Request) outgoingLength() int64 {~~~Response.go-----------~~~type Response struct {Status string // e.g. "200 OK"StatusCode int // e.g. 200Proto string // e.g. "HTTP/1.0"ProtoMajor int // e.g. 1ProtoMinor int // e.g. 0Header HeaderBody io.ReadCloserContentLength int64TransferEncoding []stringClose boolUncompressed boolTrailer HeaderRequest *RequestTLS *tls.ConnectionState}func (r *Response) Cookies() []*Cookie {func (r *Response) Location() (*url.URL, error) {func (r *Response) ProtoAtLeast(major, minor int) bool {func (r *Response) Write(w io.Writer) error {func (r *Response) closeBody() {func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {~~~263 次點擊  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.