您的位置:首页 > 理论基础 > 计算机网络

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方法描述
100http.StatusContinue = 100一般文件上传的时候使用
200http.StatusOK = 200服务器状态正常
302http.StatusFound = 302跳转
400http.StatusBadRequest = 400非法请求构造协议包无法解析,服务器无法解析处理
401http.StatusUnauthorized = 401权限未通过
403http.StatusForbidden = 403不让访问该资源
404http.StatusNotFound = 404页面不存在,资源未找到
500http.StatusInternalServerError = 500服务器内部错误,无法处理请求,
502phpnginx请求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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程 服务器