使用http.ListenAndServe,Web地址路由工作正常,但是cgi.Serve()

时间:2017-09-20 18:39:44

标签: go routing

我正在使用Go工作的网站。服务器约束要求我使用CGI。当我使用http.ListenAndServe()在本地测试以下代码时(下面已注释掉),根据请求的地址正确调用各种处理程序。但是,如果我改为使用cgi.Serve(),则对所有地址执行默认路由器(即,始终执行“/”的处理程序)。我很欣赏有关如何解决问题的任何线索。

编辑:这是我能想到的最简单的测试案例来展示问题:

// =============简化代码================ //

package main

import (
    "fmt"
    "net/http"
    "net/http/cgi"
)

func defaultHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "Default")
}

func otherHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "Other")
}

 func main() {

    http.HandleFunc("/other", otherHandler)

    http.HandleFunc("/", defaultHandler)

    /*
        //Works fine
        err := http.ListenAndServe(":8090", nil)
        if err != nil {
            panic(err)
        }
    */

   //Always fires defaultHandler no matter the address requested
    err := cgi.Serve(nil)

    if err != nil {
        panic(err)
    }
}

// =============来自原始邮件的代码=================== //

package main

import (
    "fmt"
    "net/http"
    "net/http/cgi"
    "net/url"
    "os"

    "github.com/go-cas/cas"
)

func logoutHandler(w http.ResponseWriter, r *http.Request) {
    cas.RedirectToLogout(w, r)
}

func calendarHandler(w http.ResponseWriter, r *http.Request) {
    if !cas.IsAuthenticated(r) {
        cas.RedirectToLogin(w, r)
}

    fmt.Fprintf(w, "Calendar for %s", cas.Username(r))
}

func defaultHandler(w http.ResponseWriter, r *http.Request) {
    if !cas.IsAuthenticated(r) {
        cas.RedirectToLogin(w, r)
    }

    fmt.Fprintf(w, "Hi there %s!", cas.Username(r))
}

func main() {
    u, _ := url.Parse("https://www.examplecasserver.com")

    client := cas.NewClient(&cas.Options{
        URL: u,
    })

    http.Handle("/logout", client.HandleFunc(logoutHandler))

    http.Handle("/calendar", client.HandleFunc(calendarHandler))

    http.Handle("/", client.HandleFunc(defaultHandler))

    /*
        err := http.ListenAndServe(":8080", nil)
        if err != nil {
            log.Fatal("ListenAndServe: ", err)
        }
    */

    err := cgi.Serve(nil)

    if err != nil {
        panic(err)
    }
}

1 个答案:

答案 0 :(得分:1)

CGI程序期望设置一些变量以构建请求。

您的Web服务器配置可能存在一些问题,其中变量未正确设置或未正确命名。

验证这一点:

1)在调用cgi.Serve之前添加此内容,您将看到如何调用正确的处理程序(otherHandler

os.Setenv("REQUEST_METHOD", "get")
os.Setenv("SERVER_PROTOCOL", "HTTP/1.1")
os.Setenv("SCRIPT_NAME", "/other")

2)在main的开头添加它以检查Web服务器如何设置变量:

fmt.Println(os.Environ())

在该输出中,查找规范中定义的CGI元变量:

http://www.ietf.org/rfc/rfc3875

查找" Request Meta-Variables"在该页面中,您可能正在寻找SCRIPT_NAMEPATH_INFO变量。

修改

根据您下面粘贴的变量值,似乎问题是REQUEST_URI包含一个额外的路径组件:

REQUEST_URI=/main.cgi/other

因此,最简单的解决方法是相应地映射路线:

http.HandleFunc("/main.cgi/other", otherHandler)
http.HandleFunc("/", defaultHandler)  // or maybe /main.cgi