我正在使用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)
}
}
答案 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_NAME
或PATH_INFO
变量。
修改强>
根据您下面粘贴的变量值,似乎问题是REQUEST_URI包含一个额外的路径组件:
REQUEST_URI=/main.cgi/other
因此,最简单的解决方法是相应地映射路线:
http.HandleFunc("/main.cgi/other", otherHandler)
http.HandleFunc("/", defaultHandler) // or maybe /main.cgi