golang http 编程-1(服务器编程)
2017-08-10 15:32
197 查看
http 编程
http常见请求方法
1. Get 请求,请求一个页面或者信息
2. Post 请求, 提交一个表单给服务器使用
3. Put 请求,创建一个资源,一般上传文件使用该方法
4. Delete请求,删除一个信息使用该方法
5. Head 请求,只请求http header,一般监测网站状态使用该方法
6. OPTIONS 请求,一般监测网站支持的http方法列表
7. TRACE 请求(不常用),一般使用监测使用
8. LOCK 请求(不常用),允许用户锁定资源,比如可以再编辑某个资源时将其锁定,以防别人同时对其进行编辑。
9. MKCOL 请求(不常用), 允许用户创建资源
10. COPY 请求(不常用), 便于用户在服务器上复制资源
11. MOVE 请求(不常用),在服务器上移动资源
http常见状态码
状态码 | http方法 | 描述 |
---|---|---|
100 | http.StatusContinue = 100 | 一般文件上传的时候使用 |
200 | http.StatusOK = 200 | 服务器状态正常 |
302 | http.StatusFound = 302 | 跳转 |
400 | http.StatusBadRequest = 400 | 非法请求构造协议包无法解析,服务器无法解析处理 |
401 | http.StatusUnauthorized = 401 | 权限未通过 |
403 | http.StatusForbidden = 403 | 不让访问该资源 |
404 | http.StatusNotFound = 404 | 页面不存在,资源未找到 |
500 | http.StatusInternalServerError = 500 | 服务器内部错误,无法处理请求, |
502 | php | nginx请求php, php无响应nginx 返回502 |
简单的http server
http.HandleFunc 定义url路由http.stenAndServe 启动server服务
package main import ( "fmt" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { fmt.Println("index hello") fmt.Fprintf(w, "<h1>index hello</h1>") } func login(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "user login") } func main() { http.HandleFunc("/", hello) http.HandleFunc("/user/login", login) err := http.ListenAndServe("0.0.0.0:8000", nil) if err != nil { fmt.Println("server failed, err:", err) } }
编译并运行
$ go build go_dev/day10/example/http_server $ sudo ./http_server
打开浏览器验证路径
/,
/user/login
http client (Get方法)
http.Get 来获取一个url的request的对象,request.BoBy 是网页信息(html)package main import ( "fmt" "io/ioutil" "net/http" ) func main() { res, err := http.Get("http://localhost:8000") if err != nil { fmt.Println("get err:", err) return } data, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println("read data err:", err) return } fmt.Printf("data: %s", string(data)) fmt.Printf("data: %v\n", data) }
运行:
%v是打印原始信息,很显然获取过来的信息是一个ASCII码表的数字对应的信息
例如index ASCII表:[105 110 100 101 120 10], 10是换行符
\n
$ .\2-http-client.exe data: <h1>index</h1> data: [60 104 49 62 105 110 100 101 120 60 47 104 49 62 10]
检测http server 状态(Head 方法)
检测http服务器状态使用http方法 Head, 只获取头部信息package main import ( "fmt" "net/http" ) var url = []string{ "http://www.baidu.com", "http://taobao.com", "http://google.com", } func main() { for _, v := range url { c := http.Client{} res, err := http.Head(v) if err != nil { fmt.Println("get head failed, err:", err) continue } fmt.Printf("head success , status:%v\n", res.Status) } }
编译并运行
$ go build go_dev/day10/example/http_head $ ./http_head head success , status:200 OK head success , status:200 OK get head failed, err: Head http://google.com: dial tcp 216.58.200.46:80: i/o timeout
发现超时时间过长,调整超时时间方法
一般检测一个网站,一秒钟没有返回就认为改网站故障
调整代码(带超时时间的http请求)
调整在net底层设置超时时间,这个设置比较底层
package main import ( "fmt" "net" "net/http" "time" ) var url = []string{ "http://www.baidu.com", "http://google.com", "http://taobao.com", } func timeout(network, addr string) (net.Conn, error) { timeout := time.Second return net.DialTimeout(network, addr, timeout) } func main() { for _, v := range url { c := http.Client{ Transport: &http.Transport{ Dial: timeout, }, } fmt.Println() fmt.Println(time.Now()) res, err := c.Head(v) if err != nil { fmt.Println("get head failed, err:", err) continue } fmt.Printf("head success , status:%v\n", res.Status) } }
更简单方法调整超时时间
在
http.Client结构体设置超时时间,这个更简单
package main import ( "fmt" "net/http" "time" ) var url = []string{ "http://www.baidu.com", "http://www.google.com.hk", "http://www.jd.com", } func main() { client := http.Client{ Timeout: time.Duration(time.Second), } for _, v := range url { fmt.Println() fmt.Println(time.Now()) resp, err := client.Head(v) if err != nil { fmt.Printf("head %s failed, err:%v\n", v, err) continue } fmt.Printf("%s head success, status:%v\n", v, resp.Status) } }
编译并运行
$ go build go_dev/day10/example/http_head $ ./http_head 2017-08-08 23:18:35.329123548 +0800 CST head success , status:200 OK 2017-08-08 23:18:35.339484242 +0800 CST get head failed, err: Head http://google.com: dial tcp [2404:6800:4008:802::200e]:80: i/o timeout 2017-08-08 23:18:36.343658858 +0800 CST head success , status:200 OK
网站检测超时时间1秒
http 表单处理
http.Request.ParseFrom(), 解析from表单
http.Request.From, 返回一个数组,获取里面的值需要通过下标来获取:
request.Form["username"][0]
http.Request.FromValue(name), 获取一个标签为name的值
package main import ( "fmt" "io" "net/http" ) const from = ` <html> <body> <form action="#" method="POST" name="bar"> <input type="text" name="username" /> <input type="text" name="password" /> <input type="submit" value="Submit" /> </form> </body> </html> ` func simpleServer(w http.ResponseWriter, p *http.Request) { io.WriteString(w, "<h1>hello world</h1>") } func fromServer(w http.ResponseWriter, request *http.Request) { w.Header().Set("Content-Type", "text/html") switch request.Method { case "GET": io.WriteString(w, from) case "POST": // 解析form request.ParseForm() // request.From[username] 返回一个数组,必须要写具体的那个下标的元素 io.WriteString(w, request.Form["username"][0]) io.WriteString(w, "\n") // request.FromValue 获取一个指定的 name="password"的标签的值 io.WriteString(w, request.FormValue("password")) } } func main() { http.HandleFunc("/test", simpleServer) http.HandleFunc("/from", fromServer) err := http.ListenAndServe("0.0.0.0:8000", nil) if err != nil { fmt.Println("http server failed...") return } }
编译并运行
$ go build go_dev/day10/exercises/3-http-from $ ./3-http-from
打开浏览器测试是否提交的表单又重新写到了返回的页面了
http panic 处理
适合场景- 其中一个页面出现异常,不会引起整个web服务器的异常退出
- 类似python的装饰器等功能都可以使用这个
主要实现是在执行url函数前添加了一个异常捕捉的函数
package main import ( "fmt" "net/http" ) func index(writer http.ResponseWriter, request *http.Request) { fmt.Println("page --> index") fmt.Fprintln(writer, "<h1>welcome index</h1>") } func login(writer http.ResponseWriter, request *http.Request) { panic("user logiun page panic...") } func logPanic(handle http.HandlerFunc) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { defer func() { if x := recover(); x != nil { fmt.Printf("[%v] caught panic: %v\n", request.RemoteAddr, x) } }() handle(writer, request) } } func main() { http.HandleFunc("/", logPanic(index)) http.HandleFunc("/login", logPanic(login)) err := http.ListenAndServe("0.0.0.0:8000", nil) if err != nil { fmt.Println("server failed ...") return } }
编译并测试(访问
/login异常,但访问
/正常返回)
$ go build go_dev/day10/exercises/4-http-panic $ .\4-http-panic.exe
相关文章推荐
- golang http 编程-2(模版渲染)
- Linux网络编程【三】:TCP服务器多进程和多线程(http访问)版本
- golang 建立web服务器 http包源码详解
- Android网络编程之Http请求服务器数据(GET方式)
- Linux网络编程【六】:TCP协议高性能服务器(http)模型之I/O多路转接epoll
- Android网络客户端编程,HttpGet类和HttpPost类使用详解,连接php-mysql服务器
- Android网络编程之URLConnection和HttpClient访问服务器
- 使用Golang 搭建http web服务器
- Android网络编程之Http请求服务器数据(POST方式)
- 最先進的HTTP编程模式:服务器API模式
- java网络编程之HTTP服务器的实现
- Android网络编程之Http请求服务器数据(POST方式)
- golang 建立web服务器 http包源码详解
- Linux网络编程一步一步学-编写一个HTTP协议的目录浏览和文件下载服务器
- HTTP学习与Web服务器编程
- 基于HTTP的客户端与服务器交互编程
- Golang http 建立Web服务器
- 【go】用Golang的 http 包建立 Web 服务器
- Golang:使用 httprouter 构建 API 服务器
- 基于golang http包实现的文件服务器