http хост и информация о порте в HandleFunc - PullRequest
0 голосов
/ 08 февраля 2020

Я пытаюсь запустить несколько http-серверов, прослушивающих разные порты в одном пакете. В моей тестовой функции HandleFun c мне нужно напечатать наш хост и порт информации http-сервера, который обслуживал запрос. Как бы я это сделал?

Вот мой пример кода:

package main

import (
    "encoding/json"
    "flag"
    "log"
    "net/http"
    "os"

    "github.com/dineshgowda24/lb/backendserver/config"
)

func main() {
    c := flag.String("c", "config/config.json", "Please specify conf.json")
    flag.Parse()
    file, err := os.Open(*c)
    if err != nil {
        log.Fatal("Unable to open config file")
    }
    defer file.Close()
    decoder := json.NewDecoder(file)
    config := bconfig.BackendConfiguration{}
    err = decoder.Decode(&config)
    if err != nil {
        log.Fatal("Unable to decode conf.json file")
    }
    http.HandleFunc("/", handle)
    for _, s := range config.Servers {
        log.Printf("Started server at : %s : %s ", s.Host, s.Port)
        go func(host, port string) {
            if err := http.ListenAndServe(host+":"+port, nil); err != nil {
                log.Printf("Unable to start server at : %s : %s ", host, port)
            }
        }(s.Host, s.Port)
    }
    select {}
}

//How to get info of the server which served the request ??
func handle(w http.ResponseWriter, r *http.Request) {
    response := "I came from " //need to get server info
    w.Write([]byte(response))
    w.WriteHeader(http.StatusOK)
}

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Используйте http.LocalAddrContextKey , чтобы получить адрес сервера из контекста запроса.

В своем комментарии я предложил использовать ServerContextKey, но поле http.Server.Addr не всегда устанавливается, например, при использовании http.Server.Serve (и по расширению http .Обслуживать). Следующий пример демонстрирует, что LocalAddrContextKey работает как с http.ListenAndServe, так и с http.Serve:

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()

        srvAddr := ctx.Value(http.LocalAddrContextKey).(net.Addr)

        fmt.Println(srvAddr)
    })

    ln, err := net.Listen("tcp", "127.0.0.1:3000")
    if err != nil {
        log.Fatal(err)
    }

    go func() { log.Fatal(http.Serve(ln, nil)) }()
    go func() { log.Fatal(http.ListenAndServe("127.0.0.1:4000", nil)) }()

    resp, err := http.Get("http://localhost:3000")
    if err != nil {
        log.Fatal(err)
    }
    resp.Body.Close()

    resp, err = http.Get("http://localhost:4000")
    if err != nil {
        log.Fatal(err)
    }
    resp.Body.Close()

}

// Output:
// 127.0.0.1:3000
// 127.0.0.1:4000
0 голосов
/ 08 февраля 2020

Вы можете получить его от хоста запроса, используя r.Host. ref: https://golang.org/pkg/net/http/#Request

...