您好,欢迎访问沃航(武汉)科技有限公司官方网站
使用go语言写的简单的http服务器程序,支持代理https协议
2020-11-26 10:57:57

使用go语言写的简单的http服务器程序,支持https代理以及直连。话不多说,直接上代码。

package main

import (
    "bytes"
    "log"
    "net"
    "io"
    "net/url"
    "runtime"
    "strings"
)

func main() {
    runtime.GOMAXPROCS(1)

    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.Println("version: " + runtime.Version())

    HttpAccept(8888)
}

func HttpAccept (port int) {
    tcpaddr := &net.TCPAddr{
        IP: []byte{0, 0, 0, 0},
        Port: port,
        Zone: "",
    }
    l, err := net.ListenTCP("tcp", tcpaddr)
    if err != nil {
        log.Println(err)
        return
    }
    for {
        client, err := l.AcceptTCP()
        if err != nil {
            log.Println(err)
            l.Close()
            return
        }
        go HttpProxyRequest(client)
    }
}

func HttpProxyRequest (client *net.TCPConn) {
    client.SetReadBuffer(32*1024)
    client.SetWriteBuffer(32*1024)
    b := make([]byte, 32*1024)
    n, err := client.Read(b)
    if err != nil {
        log.Println(err)
        client.Close()
        return
    }
    maddr := bytes.IndexByte(b, ' ')
    method := string(b[:maddr])
    host := string(b[maddr+1:maddr+1+bytes.IndexByte(b[maddr+1:], ' ')])
    if method == "CONNECT" {
        log.Println(host)
        tcpaddr, err := net.ResolveTCPAddr("tcp", host)
        if err != nil {
            log.Println(err)
            client.Close()
            return
        }
        server, err := net.DialTCP("tcp", nil, tcpaddr)
        if err != nil {
            log.Println(err)
            client.Close()
            return
        }
        server.SetReadBuffer(32*1024)
        server.SetWriteBuffer(32*1024)
        _, err = client.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
        if err != nil {
            log.Println(err)
            client.Close()
            server.Close()
            return
        }
        go IoCopy(client, server)
        go IoCopy(server, client)
    } else {
        hostPortURL, err := url.Parse(host)
        if err != nil {
            log.Println(err)
            client.Close()
            return
        }
        address := hostPortURL.Host
        if strings.Index(address, ":") == -1 {
            address = address + ":80"
        }
        log.Println(address)
        tcpaddr, err := net.ResolveTCPAddr("tcp", address)
        if err != nil {
            log.Println(err)
            client.Close()
            return
        }
        server, err := net.DialTCP("tcp", nil, tcpaddr)
        if err != nil {
            log.Println(err)
            client.Close()
            return
        }
        server.SetReadBuffer(32*1024)
        server.SetWriteBuffer(32*1024)
        httpheadlen := bytes.Index(b, []byte("\r\n\r\n"))+4
        httphead := b[:httpheadlen]
        start := bytes.Index(httphead, []byte(hostPortURL.Host)) + len(hostPortURL.Host)
        if start != -1 {
            httphead = append(httphead[:maddr+1], httphead[start:]...)
        }
        start = bytes.Index(httphead, []byte("Proxy-Connection:"))
        if start != -1 {
            httphead = append(httphead[:start], httphead[start+6:]...)
        }
        if httpheadlen < n {
            b = append(httphead, b[httpheadlen:n]...)
        } else {
            b = httphead
        }
        _, err = server.Write(b)
        if err != nil {
            log.Println(err)
            client.Close()
            server.Close()
            return
        }
        go IoCopy(client, server)
        go IoCopy(server, client)
    }
}

func IoCopy(dst *net.TCPConn, src *net.TCPConn) {
    io.Copy(dst, src)
    dst.Close()
}

一共134行,编译后可直接使用。


文章作者:沃航科技

联系我们
地址:
武汉市洪山区蓝晶国际7栋903
QQ:
932773931
电话:
027-59761089-806
手机:
13397158231
邮箱:
jevian_ma@worldflying.cn
×
物联网组态平台
试用账号:123456
试用密码:123456
如需测试更多功能或者有疑问可发送邮件至:jevian_ma@worldflying.cn
×
积木编程平台
试用方式:试用手机号码注册即可使用
如需测试更多功能或者有疑问可发送邮件至:jevian_ma@worldflying.cn