[Go]基於Go語言的Web路由轉發,多個網站共享一個端口(存在問題,已經拋棄,新解決方案請看新博客)

服務器上跑了不少的Web服務,但都是基於Golang本身寫的,不能像IIS或者Apache同樣共享端口和綁定域名,不少端口號本身又記不住git

因此呢,我就利用端口轉發技術,製做了這樣一個Web路由github

其主要原理就是將全部流量集中在一個端口,而後再將其經過域名轉發至真正WebServer工做的端口json

從而實現了域名指向一處服務器,而服務器又能夠經過域名鏈接至與其對應的Web服務服務器

其實在個人測試中,這個Web路由也能夠進行網站鏡像之類的服務,或者說直接將流量轉發至其餘服務器tcp

下面是在我服務器上的測試,已經投入使用,暫時沒用什麼問題測試

這裏是代碼,其實也很少,就一百來行網站

package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
    "log"
    "net"
    "strings"
    "regexp"
    "io/ioutil"
    "encoding/json"
)
type Rule struct{
    Domain string `json:Domain`
    Address string `json:Address`
}
type Config struct{
    MainPort string `json:MainPort`
    Rules []Rule `json:Rules`
}
var myConfig Config
func InitConfig(){
    var Data,err = ioutil.ReadFile("config.json")
    if err != nil{
        log.Println("Read Config File Error!")
        os.Exit(0)
        return
    }
    err = json.Unmarshal(Data,&myConfig)
    if err != nil{
        log.Println("Read Config JSON Error!Please Check!")
        os.Exit(0)
        return
    }
    fmt.Println("Main Port:"+myConfig.MainPort)
    for i:=0;i<len(myConfig.Rules);i++{
        fmt.Println("Domain: "+myConfig.Rules[i].Domain+" <----> "+myConfig.Rules[i].Address)
    }
}
func handleClientRequest(client net.Conn) {
    if client == nil {
        return
    }
    defer client.Close()
    var b [1024]byte
    n, err := client.Read(b[:])
    if err != nil {
        log.Println(err)
        return
    }
    var method, url, HTTPv, address string
    fmt.Sscanf(string(b[:bytes.IndexByte(b[:], '\n')]), "%s%s%s", &method, &url, &HTTPv)
    address = GetAddress(string(b[:]))
    if address == "nil"{
        fmt.Println("Unknow Domain")
        return
    }
    server, err := net.Dial("tcp", address)
    if err != nil {
        log.Println(err)
        return
    }
    if method == "CONNECT" {
        fmt.Fprint(client, "HTTP/1.1 200 Connection established\r\n\r\n")
    } else {
        server.Write(b[:n])
    }
    go io.Copy(server, client)
    io.Copy(client, server)
}
func GetAddress(HTTPData string) string{
    Lines := strings.Split(HTTPData,"\r\n")
    for i:=0;i<len(Lines);i++{
        line := Lines[i]
        temp := strings.Split(line,": ")
        if strings.Compare(temp[0],"Host")==0{
            for i:=0;i<len(myConfig.Rules);i++{
                if strings.Compare(myConfig.Rules[i].Domain,temp[1])==0{
                    return myConfig.Rules[i].Address
                }
            }
        }
    }
    return "nil"
}
func compressStr(str string) string {
    if str == "" {
        return ""
    }
    reg := regexp.MustCompile("\\s+")
    return reg.ReplaceAllString(str, "")
}
func main() {
    log.SetFlags(log.LstdFlags|log.Lshortfile)
    InitConfig()
    l, err := net.Listen("tcp", ":"+myConfig.MainPort)
    if err != nil {
        log.Panic(err)
    }
    for {
        client, err := l.Accept()
        if err != nil {
            log.Panic(err)
        }
        go handleClientRequest(client)
    }
}

 

下面是GitHub地址:https://github.com/leeli73/WebRouterurl

Config規則和幾個Release都在該項目中spa

相關文章
相關標籤/搜索