go http 包练习

栏目: IT技术 · 发布时间: 3年前

内容简介:几个官方的例子,拿来练习一下,wc, 体会到了 go http 包的强大之处:

参见:

下载包 设置代理

妈的,下载包有时能下,有时候就卡住。

手动安装包

Go 的 http 包详解

https://golang.org/pkg/net/http/

几个官方的例子,拿来练习一下,wc, 体会到了 go http 包的强大之处:

下面是一些例子,来主要讲解下面的几个函数

FileServer

FileServer (DotFileHiding)

FileServer (StripPrefix)

Get

Handle

HandleFunc

Hijacker

ListenAndServe

ListenAndServeTLS

NotFoundHandler

ResponseWriter (Trailers)

ServeMux.Handle

Server.Shutdown

主体结构是:

func main(){
    FileServer()
        ...
}

我把每个函数的例子,封装为一个函数 然后放在 main 函数里面执行一下。main 都是重复的,所以就不贴代码了。(联系 采用 subline,炒鸡方便)

  • FileServer

func FileServer(root FileSystem) Handler

这个函数也是很牛逼, 主要是可以把文件路径映射为 url 路由。

https://golang.org/pkg/net/http/#FileServer

实现原理:

https://shockerli.net/post/golang-pkg-http-file-server/

使用 FileSystem 接口 root 提供文件访问服务的 HTTP 处理器。可以方便的实现静态文件服务器

func FileServer(){
    http.ListenAndServe(":8081", http.FileServer(http.Dir("F:/go/")))

}

运行效果:

go http 包练习

注意多次运行,可能需要更改端口号

go http 包练习

点击 go_practice 链接(文件夹)

go http 包练习

点击 http_pkg.go

上面是个简单的 可以展示文件目录的功能,go 底层,帮我们实现了 文件读取和展示。

支持子目录路径

只是比上面多了个 自定义路由前缀

http.StripPrefix() 方法配合 http.Handle() 或 http.HandleFunc() 可以实现带路由前缀的文件服务。

func FileServer(){
    // 
    // http.ListenAndServe(":8081", http.FileServer(http.Dir("F:/go/")))
    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("F:/go/"))))

    http.ListenAndServe(":8082", nil)
}

运行效果:

go http 包练习

会比第一个程序多一个 tmpfiles 路径前缀

  • Handle

func Handle(pattern string, handler Handler)

路由匹配处理函数, 要实现 Handler 接口的 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法

package main

import (
    "fmt"
    "log"
    "net/http"
    "sync"
)

type countHandler struct {
    mu sync.Mutex // guards n
    n  int
}

func (h *countHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.mu.Lock()
    defer h.mu.Unlock()
    h.n++
    fmt.Fprintf(w, "count is %d\n", h.n)
}

func main() {
    http.Handle("/count", new(countHandler))
    log.Fatal(http.ListenAndServe(":8080", nil))
}
  • HandleFunc

func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

和 Handle 几乎一样,唯一不同的是参数不一样,这个是自己定义一个

xx(w http.ResponseWriter, r *http.Request) 这样的函数,儿不必叫 ServeHTTP 名字,因为 HandleFunc 函数第二个参数是 直接一个函数类型,二不是 有ServeHTTP 函数的 Handler 接口类型

func simple_server(){

    http.HandleFunc("/my_name", name_haddler)

    http.HandleFunc("/url", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello, %q</h1>", html.EscapeString(r.URL.Path))
    })

    http.ListenAndServe(":8080", nil)
}

func name_haddler(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "<h1>hello yxl</h1>")
}
  • ListenAndServe

func ListenAndServe(addr string, handler Handler) error

第二个参数通常为 nil, 在这种情况下,使用DefaultServeMux。

func simple_server(){

    http.HandleFunc("/my_name", name_haddler)

    http.HandleFunc("/url", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello, %q</h1>", html.EscapeString(r.URL.Path))
    })

    http.ListenAndServe(":8080", nil)
}

func name_haddler(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "<h1>hello yxl</h1>")
}
  • ListenAndServeTLS

func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error

ListenAndServe HTTPS 版本

  • NotFoundHandler

404 对应的处理

func NotFoundHandler() Handler
func NotFoundHandler(){
    // 404 对应的处理
    mux.Handle("/resources", http.NotFoundHandler())

}
  • ResponseWriter

一个接口

定义源码如下:

<pre>type ResponseWriter interface {
    // Header returns the header map that will be sent by
    // WriteHeader. The Header map also is the mechanism with which
    // Handlers can set HTTP trailers.
    //
    // Changing the header map after a call to WriteHeader (or
    // Write) has no effect unless the modified headers are
    // trailers.
    //
    // There are two ways to set Trailers. The preferred way is to
    // predeclare in the headers which trailers you will later
    // send by setting the "Trailer" header to the names of the
    // trailer keys which will come later. In this case, those
    // keys of the Header map are treated as if they were
    // trailers. See the example. The second way, for trailer
    // keys not known to the Handler until after the first Write,
    // is to prefix the Header map keys with the TrailerPrefix
    // constant value. See TrailerPrefix.
    //
    // To suppress automatic response headers (such as "Date"), set
    // their value to nil.
    Header() [Header](https://golang.org/pkg/net/http/#Header)

    // Write writes the data to the connection as part of an HTTP reply.
    //
    // If WriteHeader has not yet been called, Write calls
    // WriteHeader(http.StatusOK) before writing the data. If the Header
    // does not contain a Content-Type line, Write adds a Content-Type set
    // to the result of passing the initial 512 bytes of written data to
    // DetectContentType. Additionally, if the total size of all written
    // data is under a few KB and there are no Flush calls, the
    // Content-Length header is added automatically.
    //
    // Depending on the HTTP protocol version and the client, calling
    // Write or WriteHeader may prevent future reads on the
    // Request.Body. For HTTP/1.x requests, handlers should read any
    // needed request body data before writing the response. Once the
    // headers have been flushed (due to either an explicit Flusher.Flush
    // call or writing enough data to trigger a flush), the request body
    // may be unavailable. For HTTP/2 requests, the Go HTTP server permits
    // handlers to continue to read the request body while concurrently
    // writing the response. However, such behavior may not be supported
    // by all HTTP/2 clients. Handlers should read before writing if
    // possible to maximize compatibility.
    Write([][byte](https://golang.org/pkg/builtin/#byte)) ([int](https://golang.org/pkg/builtin/#int), [error](https://golang.org/pkg/builtin/#error))

    // WriteHeader sends an HTTP response header with the provided
    // status code.
    //
    // If WriteHeader is not called explicitly, the first call to Write
    // will trigger an implicit WriteHeader(http.StatusOK).
    // Thus explicit calls to WriteHeader are mainly used to
    // send error codes.
    //
    // The provided code must be a valid HTTP 1xx-5xx status code.
    // Only one header may be written. Go does not currently
    // support sending user-defined 1xx informational headers,
    // with the exception of 100-continue response header that the
    // Server sends automatically when the Request.Body is read.
    WriteHeader(statusCode [int](https://golang.org/pkg/builtin/#int))
}</pre>

其他的暂时就不讲了,太难了,老铁

完整总结的代码(其实和上面一样的):

package main 
/* http 包的练习 */
import (
    "fmt"
    "net/http"
    "io/ioutil"
    "html"
    _ "log"
)

func easy_test(url string){
    resp, err := http.Get(url)
    if err != nil{
        fmt.Printf("%v", err)
        return 
    }
    defer resp.Body.Close()  // 入站是当前内存区域的 执行, 和主函数分开的,每个块内存都可以有自己的 压栈
    defer fmt.Printf("请求函数执行结束")
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf("%s", body)
    return 
}

func simple_server(){

    http.HandleFunc("/my_name", name_haddler)

    http.HandleFunc("/url", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello, %q</h1>", html.EscapeString(r.URL.Path))
    })

    http.ListenAndServe(":8080", nil)
}

func name_haddler(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "<h1>hello yxl</h1>")
}


// 事例
// FileServer
// FileServer (DotFileHiding)
// FileServer (StripPrefix)
// Get
// Handle
// HandleFunc
// Hijacker
// ListenAndServe
// ListenAndServeTLS
// NotFoundHandler
// ResponseWriter (Trailers)
// ServeMux.Handle
// Server.Shutdown
// StripPrefix

// FileServer  func FileServer(root FileSystem) Handler
func FileServer(){
    
    http.ListenAndServe(":8081", http.FileServer(http.Dir("F:/go/")))
    
}

// FileServer (DotFileHiding)  
func FileServer_DotFileHiding(){
    // 这个看不懂啊

}

// FileServer (StripPrefix)  
func FileServer_StripPrefix(){
    // 这个就是子在 FileServer 基础上加了一个前缀路由地址
    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("F:/go/"))))
    http.ListenAndServe(":8082", nil)
}

// Get func Get(url string) (resp *Response, err error)
func get(){
    // 请求一个地址, 如果状态码是 30x  x 是12378之一 就自动重定向,最多 10 次
    // 参见 11 行 easy_test

}

// Handle  func Handle(pattern string, handler Handler)
func handle(){
    // 就是添加路由,匹配对应一个函数酱紫
    // 这个就暂时补贴代码了
    // 路由匹配处理函数(结构体类型), 要实现 Handler 接口的 ServeHTTP(w http.ResponseWriter, r *http.Request)  方法 


}

// HandleFunc  func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func HandleFunc(){
    // 和 Handle 几乎一样,唯一不同的是参数不一样,这个是自己定义一个 
    // xx(w http.ResponseWriter, r *http.Request) 这样的函数,儿不必叫 ServeHTTP 名字,因为 HandleFunc 函数第二个参数是 直接一个函数类型,二不是  有ServeHTTP 函数的 Handler  接口类型
    // 参见 simple_server  24-37 行

}

// ListenAndServe  func ListenAndServe(addr string, handler Handler) error 
func ListenAndServe(){
    // 参见 

}


// ListenAndServeTLS  func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error
func ListenAndServeTLS(){
    // ListenAndServe  HTTPS 版本

}

// NotFoundHandler  func NotFoundHandler() Handler
func NotFoundHandler(){
    // 404 对应的处理
    mux.Handle("/resources", http.NotFoundHandler())

}

// ResponseWriter   interface 
func ResponseWriter(){
    // 上面所有的 处理函数,都直接或者间接实现这个 函数了
    // 如: func(w http.ResponseWriter, r *http.Request)
    // 还有 Handler 接口定义的 ServeHTTP(ResponseWriter, *Request) 函数(同包就省略了 http.)


}

// func (*ServeMux) ServeMux      func (mux *ServeMux) Handle(pattern string, handler Handler)
func ServeMux_ServeMux(){
    // 这个不太懂

}

// func (*Server) Shutdown    func (srv *Server) Shutdown(ctx context.Context) error
func Server_Shutdown(){
    // 这个也不会


}

// StripPrefix   func StripPrefix(prefix string, h Handler) Handler
func StripPrefix(){
    // 删除请求的特定前缀 
    // 参见:  FileServer_StripPrefix  70 行

}


func main(){
    // easy_test("https://sunrain.xyz")
    // simple_server()
    FileServer()
}

欢迎关注我们的微信公众号,每天学习 Go 知识

go http 包练习

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Machine Learning in Action

Machine Learning in Action

Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99

It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换