Golang中如何将HTTP请求重定向到HTTPS:解决"Client sent an HTTP request to an HTTPS server"错误

Golang中如何将HTTP请求重定向到HTTPS:解决"Client sent an HTTP request to an HTTPS server"错误 如何在这种情况下添加自定义处理程序:客户端向HTTPS服务器发送了HTTP请求 我希望重定向到HTTPS。

6 回复

不愚蠢。不要为学习而道歉。 其他有相同问题的人将从这个帖子中受益。

更多关于Golang中如何将HTTP请求重定向到HTTPS:解决"Client sent an HTTP request to an HTTPS server"错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的……没错……你说得对。是我的错……

但我原本希望这是可行的……因为关于错误协议的信息是通过 HTTP 发送的。

例如,如果我想更改错误信息,让它看起来不一样。 也许在那里抛出一个重定向是可能的……

但这想法很蠢。抱歉。

你好

你不能在同一个端口上同时使用 HTTP 和 HTTPS(至少使用 Go 的 HTTP 库函数不行)。在 Web 服务器上,通常是 HTTP 使用 80 端口,HTTPS 使用 443 端口。所以需要开启两个不同的服务器,并使用

Redirect(w ResponseWriter, r *Request, url string, code int)

将 HTTP 服务器上的所有调用重定向到运行 HTTPS 的那个服务器上。

这不是一个解决方案 我有一个HTTPS服务器和一个开放的端口 https://gist.github.com/denji/12b3a568f092ab951456 示例:

package main

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

func HelloServer(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("This is an example server.\n"))
    // fmt.Fprintf(w, "This is an example server.\n")
    // io.WriteString(w, "This is an example server.\n")
}

func main() {
    http.HandleFunc("/hello", HelloServer)
    err := http.ListenAndServeTLS(":8081", "server.crt", "server.key", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

当我访问:

http://localhost:8081/hello

我需要重定向到:

https://localhost:8081/hello

因为我得到:

客户端向HTTPS服务器发送了HTTP请求。

你好 kamil, 你可以使用 mux,正如我们的朋友 Johandalabacka 所说:

如何修复重定向中的简单问题? Code Review

H. 抱歉。我读得有点太快了。你可以这样做 在一台物理服务器或 VPS 上运行多个 Web 服务器 来拥有两个不同的 servermux,或者对 https 使用默认的,只对 http 使用一个新的,仅包含一个重定向方法。

package main

import (
	"io"
	"net/http"
)

func index1(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello from server 1")
}

func index2(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello from server 2")
}

func main() {

	mux := ht…

在Go中处理HTTP到HTTPS重定向,可以通过以下方式实现自定义处理程序:

package main

import (
    "net/http"
    "strings"
)

func redirectToHTTPS(w http.ResponseWriter, r *http.Request) {
    // 构建HTTPS URL
    host := r.Host
    if strings.Contains(host, ":") {
        host = strings.Split(host, ":")[0]
    }
    
    httpsURL := "https://" + host + ":443" + r.URL.Path
    if r.URL.RawQuery != "" {
        httpsURL += "?" + r.URL.RawQuery
    }
    
    // 执行301永久重定向
    http.Redirect(w, r, httpsURL, http.StatusMovedPermanently)
}

func main() {
    // HTTP服务器监听80端口
    go func() {
        http.HandleFunc("/", redirectToHTTPS)
        http.ListenAndServe(":80", nil)
    }()
    
    // HTTPS服务器监听443端口
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("HTTPS连接成功"))
    })
    
    // 启动HTTPS服务器(需要证书文件)
    http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
}

对于更细粒度的控制,可以使用自定义服务器配置:

package main

import (
    "crypto/tls"
    "net/http"
    "time"
)

func main() {
    // 创建自定义HTTP服务器处理重定向
    httpServer := &http.Server{
        Addr: ":80",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            target := "https://" + r.Host + r.URL.Path
            if r.URL.RawQuery != "" {
                target += "?" + r.URL.RawQuery
            }
            http.Redirect(w, r, target, http.StatusPermanentRedirect)
        }),
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
    }
    
    // 创建HTTPS服务器
    httpsServer := &http.Server{
        Addr: ":443",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("安全连接已建立"))
        }),
        TLSConfig: &tls.Config{
            MinVersion: tls.VersionTLS12,
        },
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
    }
    
    // 启动HTTP重定向服务器
    go httpServer.ListenAndServe()
    
    // 启动HTTPS服务器
    httpsServer.ListenAndServeTLS("server.crt", "server.key")
}

如果需要在单个端口中处理混合协议,可以使用TLS嗅探:

package main

import (
    "bytes"
    "crypto/tls"
    "net"
    "net/http"
)

func handleConn(conn net.Conn) {
    defer conn.Close()
    
    // 读取前几个字节判断是否为TLS握手
    buf := make([]byte, 1)
    conn.Read(buf)
    
    if buf[0] == 0x16 { // TLS握手开始标志
        // 重建连接进行TLS处理
        tlsConn := tls.Server(&bufferedConn{
            Conn:   conn,
            buffer: append(buf, make([]byte, 4095)...),
        }, &tls.Config{
            Certificates: []tls.Certificate{loadCertificate()},
        })
        
        http.Serve(tlsConn, http.HandlerFunc(httpsHandler))
    } else {
        // 处理HTTP重定向
        http.Serve(&bufferedConn{
            Conn:   conn,
            buffer: append(buf, make([]byte, 4095)...),
        }, http.HandlerFunc(redirectHandler))
    }
}

type bufferedConn struct {
    net.Conn
    buffer []byte
    offset int
}

func (bc *bufferedConn) Read(p []byte) (n int, err error) {
    if bc.offset < len(bc.buffer) {
        n = copy(p, bc.buffer[bc.offset:])
        bc.offset += n
        return n, nil
    }
    return bc.Conn.Read(p)
}

func redirectHandler(w http.ResponseWriter, r *http.Request) {
    http.Redirect(w, r, "https://"+r.Host+r.RequestURI, http.StatusMovedPermanently)
}

func httpsHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("安全HTTPS连接"))
}

这些示例展示了在Go中处理"Client sent an HTTP request to an HTTPS server"错误的不同方法,通过重定向HTTP请求到HTTPS端点来解决协议不匹配问题。

回到顶部