Created
September 17, 2018 03:01
-
-
Save RitterHou/e77b38acdd30d30ee3b9f19004940d3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# 可以通过命令 go env 获取当前的环境变量 | |
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o http_echo_linux | |
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o http_echo_windows.exe | |
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o http_echo_mac |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"log" | |
"net" | |
"os" | |
"regexp" | |
"strconv" | |
"strings" | |
) | |
var p = flag.Int("p", 6728, "port") | |
const ( | |
frame = 256 | |
crLf2 = "\r\n\r\n" | |
) | |
var contentLengthReg = regexp.MustCompile(`content-length: *(\d+)\r\n`) | |
func getContentLength(request string) (length int) { | |
request = strings.ToLower(request) | |
params := contentLengthReg.FindStringSubmatch(request) | |
if params != nil { | |
value, err := strconv.Atoi(params[1]) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
length = value | |
} | |
return | |
} | |
func handleRequest(conn net.Conn) { | |
// 不断地接受HTTP请求 | |
for { | |
var contentLength int | |
data := make([]byte, 0, frame*4) | |
tmp := make([]byte, frame) | |
// 读取HTTP请求报文 | |
for { | |
length, err := conn.Read(tmp) | |
// 连接断开 | |
if length == 0 { | |
log.Println("Remove", conn.RemoteAddr().String()) | |
return | |
} | |
if err != nil { | |
log.Fatalln("Error reading:", err) | |
} | |
data = append(data, tmp[:length]...) | |
request := string(data) | |
if strings.Contains(request, crLf2) { | |
if contentLength == 0 { | |
contentLength = getContentLength(request) | |
if contentLength == 0 { | |
break | |
} | |
} | |
body := strings.Split(request, crLf2)[1] | |
if len([]byte(body)) == contentLength { | |
break | |
} | |
} | |
} | |
log.Println(string(data)) | |
head := []byte("HTTP/1.1 200 OK\r\n") | |
head = append(head, []byte("content-length: "+strconv.Itoa(len(data))+"\r\n")...) | |
head = append(head, []byte("content-type: text/plain"+crLf2)...) | |
data = append(head, data...) | |
conn.Write(data) | |
} | |
} | |
func main() { | |
log.SetOutput(os.Stdout) | |
flag.Parse() | |
port := strconv.Itoa(*p) | |
listener, err := net.Listen("tcp", "0.0.0.0:"+port) | |
if err != nil { | |
log.Fatalln("Error listening:", err) | |
} | |
log.Println("Listening 0.0.0.0:" + port) | |
defer listener.Close() | |
for { | |
conn, err := listener.Accept() | |
if err != nil { | |
log.Fatalln("Error accepting:", err) | |
} | |
log.Println("Accept", conn.RemoteAddr().String()) | |
go handleRequest(conn) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment