2017-09-20 16 views
0

私はGoを使用してWebサイトで作業しています。サーバーの制約により、CGIを使用する必要があります。 http.ListenAndServe()(以下にコメントアウト)を使用して次のコードをローカルでテストすると、要求されたアドレスに応じてさまざまなハンドラが正しく呼び出されます。しかし、代わりにcgi.Serve()を使用すると、デフォルトのルータがすべてのアドレスに対して実行されます(つまり、 "/"のハンドラは常に実行されます)。問題を解決する方法についての手がかりをいただければ幸いです。Webアドレスルーティングはhttp.ListenAndServeで正常に動作しますが、cgi.Serve()で失敗します

EDITは:========

// ============= SIMPLIFIED CODE:ここで私は、問題を示すことを考えることができる最も簡単なテストケースであります======== //

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

あなたはcasクライアントミドルウェアの使用を削除しようとしましたか?おそらくclient.HandleFuncやcas.xxx呼び出しを使わずに、最も簡単なハンドラで試してみてください。あなたは/にリダイレクトされているかもしれません。 –

+0

はい。投稿を編集して、私が考えることができる最も簡単なテストケースを追加します。 – Brent

答えて

1

CGIプログラムでは、リクエストを作成するためにいくつかの変数が設定されていると想定しています。

おそらく、変数が正しく設定されていないか正しく指定されていないWebサーバーの設定に問題があります。この確認するに

cgi.Serveを呼び出す前にこれを追加し、あなたが

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

2)otherHandler(右ハンドラが呼び出された方法を見ていきます)

1)mainの先頭にこれを追加します。

fmt.Println(os.Environ()) 

この出力では、CGIメタ変数dを探しますスペックでefined:そのページ内の「要求のメタ変数」のための

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

見て、あなたはおそらくSCRIPT_NAMEまたはPATH_INFO変数を探しています。あなたは以下の貼り付けられた変数の値から

EDIT

、問題はREQUEST_URIが追加のパスコンポーネントが含まれていることであるようだ。

REQUEST_URI=/main.cgi/other 

あなたがマップするので、最も簡単な修正は次のようになりそれに応じてルート:

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

助けてくれてありがとう。私はここでやっている、非常にわからないんだけど、ここでは一つの試みからのプリントアウトです: REQUEST_SCHEME = HTTP CONTEXT_PREFIX = CONTEXT_DOCUMENT_ROOT = /ホーム/ user1の/ public_htmlの [email protected]は、 SCRIPT_FILENAME =/home/user1/public_html/main。CGI REMOTE_PORT = 45516 GATEWAY_INTERFACE = CGI/1.1 SERVER_PROTOCOL = HTTP/1.1 REQUEST_METHOD = GET QUERY_STRING = REQUEST_URI =/main.cgi /その他 SCRIPT_NAME = /その他 PATH_INFO = /その他 PATH_TRANSLATED = /ホーム/ user1の/ public_html/other – Brent

+0

Goがどのようにそれらのヴァールに基づいてリクエストを作成するのかを見てみましょう:https://golang.org/src/net/http/cgi/child.go?#L94 – eugenioy

+0

@Brent:私の編集を参照してくださいあなたが貼り付けたものに基づいて答えで – eugenioy

関連する問題