在同一程序中运行HTTP和HTTPS [英] Run both HTTP and HTTPS in same program

查看:127
本文介绍了在同一程序中运行HTTP和HTTPS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我不能从同一个golang程序中同时运行HTTP和HTTPS?

这是启动两个服务器的代码..首先启动的服务器将运行-第二个服务器将不运行.如果将它们切换到另一个,则另一个将运行,而另一个将不运行. >

运行程序时没有错误返回,但是请求http://www.localhosthttps://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)
    }
}

解决方案

ListenAndServe ListenAndServeTLS 打开侦听套接字,然后循环永远服务的客户端连接.这些函数只会在出错时返回.

主goroutine永远不会进入启动TLS服务器,因为主goroutine忙于等待ListenAndServe中的HTTP连接.

要解决此问题,请在新的goroutine中启动HTTP服务器:

//  Start HTTP
go func() {
    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)
}

Why can't I run both HTTP and HTTPS from the same golang program?

Here is the code where the two servers are initiated.. The server which is initiated first will run - the second won't.. If they are switched arround the other will run and the other won't..

No errors are returned when running the program, but the requests http://www.localhost or https://secure.localhost times out

//  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)
}

Here is the complete code

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)
    }
}

解决方案

ListenAndServe and ListenAndServeTLS open the listening socket and then loop forever serving client connections. These functions only return on an error.

The main goroutine never gets to the starting the TLS server because the main goroutine is busy waiting for HTTP connections in ListenAndServe.

To fix the problem, start the HTTP server in a new goroutine:

//  Start HTTP
go func() {
    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)
}

这篇关于在同一程序中运行HTTP和HTTPS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆