在实现Web服务器实现,我们需要了解HTTP 协议
- HTTP 报文分为 响应报文 与 请求报文
//报文头 GET /index.html HTTP/1.1 //说明请求类型 GET POST PUT DELETE .... 页面为index.html Host: hackr.jp // 在主机hackr.jp 上 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/2010010 //浏览器请求头 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*//*; q=0 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: keep-alive If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT If-None-Match: "45bae1-16a-46d776ac" Cache-Control: max-age=0 ``
响应报文
HTTP/1.1 304 Not Modified //状态码
Date: Thu, 07 Jun 2012 07:21:36 GMT //响应时间
Server: Apache //服务器
Connection: close // 是否与服务器链接
Etag: "45bae1-16a-46d776ac" //请求资源的Etag
效果


实现
- main.go
package main
import (
"sync"
)
var wg sync.WaitGroup
func main() {
go Accpect()
wg.Add(1)
wg.Wait()
}
- WebServer .go
package main
import (
"fmt"
"io"
"net"
"os"
"regexp"
"strings"
)
var (
address string = "127.0.1:5678"
)
func Accpect() {
conn, err := net.Listen("tcp", address)
if err != nil {
fmt.Print(err)
return
}
defer conn.Close()
client, err := conn.Accept()
if err != nil {
fmt.Print(err)
return
}
buff := make([]byte, 2048)
client.Read(buff)
Response(client, buff)
}
func Resolving(header []byte) map[string]string {
//用户保存解析后的报文信息
ResponseArray := make(map[string]string, 8)
for index, v := range strings.Split(string(header), "\n") {
if len(v) == 1 || v == "" {
continue
}
if index == 0 {
Compiles := regexp.MustCompile(`([A-Z]{3}) /([A-Za-z0-9 .]*) HTTP/1.1`)
result := Compiles.FindStringSubmatch(v)
ResponseArray["Method"] = result[1]
ResponseArray["page"] = result[2]
} else {
splitArray := strings.Split(v, ":")
if len(splitArray) == 1 {
continue
}
ResponseArray[splitArray[0]] = strings.Replace(splitArray[1], " ", "", -1)
}
}
return ResponseArray
}
func ReadFile(path string) string {
Html := ""
buff := make([]byte, 1024)
File, err := os.Open(path)
if err != nil {
return "找不到该路径"
} else {
for {
_, readerr := File.Read(buff)
if readerr == io.EOF {
break
}
Html += string(buff)
}
return Html
}
}
//对请求进行响应
func Response(conn net.Conn, buff []byte) {
defer conn.Close()
ResoArray := make(map[string]string, 8)
ResoArray = Resolving(buff)
ResponseHead := "HTTP/1.1 200 OK"
ResponseHead += "\n"
ResponseHead += "Date: Thu, 07 Jun 2012 07:21:36 GMT"
ResponseHead += "\n"
ResponseHead += "Content-Type: text/html"
ResponseHead += "\n"
ResponseHead += "Server:yhWebServer"
ResponseHead += "\n"
ResponseHead += "Connection: close"
ResponseHead += "\n \n\n\n"
paths := fmt.Sprintf("/home/yh/vpnDemo/web/%s/%s", ResoArray["Host"], ResoArray["page"])
ResponseHead += ReadFile(paths)
ResponseHead += "\n"
//fmt.Print(ResponseHead)
conn.Write([]byte(ResponseHead))
}
``
// go run main.go WebServer.go 运行
版权声明:本文为qq_45535340原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。