爲什麼我無法從同一個golang程序運行HTTP和HTTPS?在同一個程序中運行HTTP和HTTPS
這裏是兩個服務器啓動的代碼..第一個啓動的服務器將運行 - 第二個不會..如果他們切換到另一個將運行,另一個不會..
運行程序時返回沒有錯誤,但請求http://www.localhost
或https://secure.localhost
超時
// Start HTTP
err_http := http.ListenAndServe(fmt.Sprintf(":%d", port), http_r)
if err_http != nil {
log.Fatal("Web server (HTTP): ", err_http)
}
// Start HTTPS
err_https := http.ListenAndServeTLS(fmt.Sprintf(":%d", ssl_port), "D:/Go/src/www/ssl/public.crt", "D:/Go/src/www/ssl/private.key", https_r)
if err_https != nil {
log.Fatal("Web server (HTTPS): ", err_https)
}
下面是完整的代碼
package main
import (
"net/http"
"fmt"
"log"
"os"
"io"
"runtime"
// go get github.com/gorilla/mux
"github.com/gorilla/mux"
)
const (
HOST = "localhost"
)
func Handler_404(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w, "Oops, something went wrong!")
}
func Handler_www(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w, "Hello world :)")
}
func Handler_api(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w, "This is the API")
}
func Handler_secure(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w, "This is Secure")
}
func redirect(r *mux.Router, from string, to string){
r.Host(from).Subrouter().HandleFunc("/", func (w http.ResponseWriter, r *http.Request){
http.Redirect(w, r, to, 301)
})
}
func main(){
port := 9000
ssl_port := 443
runtime.GOMAXPROCS(runtime.NumCPU())
http_r := mux.NewRouter()
https_r := mux.NewRouter()
// HTTP 404
http_r.NotFoundHandler = http.HandlerFunc(Handler_404)
// Redirect "http://HOST" => "http://www.HOST"
redirect(http_r, HOST, fmt.Sprintf("http://www.%s:%d", HOST, port))
// Redirect "http://secure.HOST" => "https://secure.HOST"
redirect(http_r, "secure."+HOST, fmt.Sprintf("https://secure.%s", HOST))
www := http_r.Host("www."+HOST).Subrouter()
www.HandleFunc("/", Handler_www)
api := http_r.Host("api."+HOST).Subrouter()
api.HandleFunc("/", Handler_api)
secure := https_r.Host("secure."+HOST).Subrouter()
secure.HandleFunc("/", Handler_secure)
// Start HTTP
err_http := http.ListenAndServe(fmt.Sprintf(":%d", port), http_r)
if err_http != nil {
log.Fatal("Web server (HTTP): ", err_http)
}
// Start HTTPS
err_https := http.ListenAndServeTLS(fmt.Sprintf(":%d", ssl_port), "D:/Go/src/www/ssl/public.crt", "D:/Go/src/www/ssl/private.key", https_r)
if err_https != nil {
log.Fatal("Web server (HTTPS): ", err_https)
}
}
除幾乎總是用ListenAndServer錯誤完成的* only *事件記錄並退出(如果需要,允許外部機制重新啓動整個服務器/進程)。例如。到底是什麼問題和答案用'log.Fatal()'搶救遇到的第一個遇到的錯誤。如果這是所期望的行爲,那麼除了他們正在做的事情之外的任何事情都會分散注意力。 – 2015-04-06 15:35:02
這是真的戴夫。我通常過於複雜的事情。我總是在代碼級重啓邏輯,而不是像supervisord這樣的東西。如果整個過程都停止,那就是我使用的東西。如果一個人死亡,第二個人死亡,整個腳本將被竊聽。必須承認,我沒有經歷過那麼多的http,但經歷了很多AMQP,其中一個保持不變,第二個失敗並且使整個邏輯被竊聽,因此我需要在內部循環下重新啓動。比我採取的方法,並在我有超過1聽衆大聲笑的地方使用它 – 2015-04-07 14:47:54
@NevioVesić的例子具有一致性的優點。我唯一要添加的是一個關閉沒有錯誤的去程序的通道,特別是如果有人希望在處理錯誤後再次啓動它。 – 2016-05-13 23:18:18