2017-04-26 9 views
-1

私はgolangで書かれたrest-fulインターフェイスを持っています。各エンドポイントで認証を行う必要があります。認証が完了したら、それをtcpサーバに転送する必要があります。 私はtcpクライアントを作成しました。チャンネルから来る値はtcp serverに送信されます。チャネルはHTTP要求本体から移入されます。 問題は、curlコマンドを発行すると、クライアントは応答なしで止まってしまうことです。私は間違っているかどうか分からない何か間違ったことをしています。誰かが私の問題が何であるかについての洞察を持っていますか? c <- bodyStringTCPクライアントが正しく動作しないgolang

package main 

      import (
       "bufio" 
       "encoding/json" 
       "flag" 
       "fmt" 
       "io/ioutil" 
       "log" 
       "net" 
       "net/http" 
       "net/http/httputil" 
       "net/url" 
       "os" 
       "strconv" 

       auth "github.com/abbot/go-http-auth" 
      ) 

      type Configuration struct { 
       Server  string 
       Port   int64 
       UserName  string 
       Pwd   string 
       Realm   string 
       ProxyPort  int64 
       Edeserver  string 

      } 

      var (
       Config *Configuration 
       logp = flag.Bool("log", false, "enable logging") 
      ) 

      func ReadConfiguration() { 
       file, _ := os.Open("Config.json") 
       decoder := json.NewDecoder(file) 
       Config = &Configuration{} 
       err := decoder.Decode(&Config) 
       if err != nil { 
        fmt.Println("error:", err) 
       } 

      } 

      func Secret(user, realm string) string { 
       if user == Config.UserName { 
        // password is "hello" 
        return Config.Pwd 
       } 
       return "" 
      } 

      func reverseProxyTows(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) { 
       req := &authenticatedRequest.Request 

       if *logp { 
        log.Println(" Authenticated Username ", authenticatedRequest.Username) 
        log.Println(" Authenticated URL ", req.URL.RequestURI()) 
       } 

       destinationURL := fmt.Sprintf("http://%s:%d", Config.Server, Config.Port) 
       u, err := url.Parse(destinationURL) 
       if err != nil { 
        log.Fatal(err) 
       } 

       if *logp { 
        log.Println("reverse_proxy", u) 
       } 

       reverseProxy := httputil.NewSingleHostReverseProxy(u) 

       reverseProxy.ServeHTTP(w, req) 
      } 

      func openConnectionTotcp(edechannel chan string) { 
       conn, _ := net.Dial("tcp", Config.Edeserver) 
       text := <-edechannel 
       fmt.Fprintf(conn, text+"\n") 
       message, _ := bufio.NewReader(conn).ReadString('\n') 
       fmt.Print("Message from server: " + message) 
      } 


      func main() { 
       ReadConfiguration() 
       flag.Parse() 
       c := make(chan string) 
       go openConnectionTotcp(c) 

       fmt.Printf("Started proxy to destination server %v:%d and is listening on %d ", Config.Server, Config.Port, Config.ProxyPort) 

       authenticator := auth.NewBasicAuthenticator(Config.Realm, Secret) 
       http.HandleFunc("/", authenticator.Wrap(reverseProxyTows)) 
       http.HandleFunc("/tyrion/1", authenticator.Wrap(func(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) { 
        req := &authenticatedRequest.Request 
        bodyBytes, err2 := ioutil.ReadAll(req.Body) 
        if err2 != nil { 
         log.Fatal(err2) 
        } 
        bodyString := string(bodyBytes) 
        c <- bodyString 
        fmt.Fprintf(w, "success") 
       })) 
       http.ListenAndServe(":"+strconv.FormatInt(Config.ProxyPort, 10), nil) 
      } 
+1

"c < - bodyString"で実行フローがブロックされているようです。チャネルのコンシューマーが存在しない場合に発生する可能性があります。ここでエラーがないことを確認してください "conn、_:= net.Dial(" tcp "、Config.Edeserver)" –

+0

開始するには、 'net.Dial'または'ReadString'では、tcp接続をクローズしていないので、複数のメッセージを読んでみると、バッファされたデータを持っているかもしれない' bufio.Reader'を投げ捨ててしまいます。また、 'tcp.Dial'を一度呼び出してからgoroutineを終了するだけで、動作しても非常に最初のhttp要求にしか使えません。 – JimB

答えて

0

あなたのコードの実行ブロックは何もそのバッファリングされていないチャンネルからの読み込みされるように表示されませんので。その行は、別のルーチンがチャネルから読み込むまで実行を一時停止します。

+0

は真ではありません。openConnectionTotcpはchan引数を持ち、そのルーチンはそれから読み取ります。 '' 'func openConnectionTotcp(edechannel chan string){ conn、_:= net.Dial(" tcp "、Config.Edeserver) text: = "-edechannel" fmt.Fprintf(conn、text + "\ n") メッセージ、_:= bufio.NewReader(conn).ReadString( '\ n') fmt.Print( "サーバーからのメッセージ:" +メッセージ) } '' ' – harry

+0

このルーチンは1つのメッセージを消費してから復帰し、その後チャネルへの書き込みは永遠にブロックされます。また、tcp.Dialからエラーを捨てるので、そのルーチンで何が起こっているのかを知ることができます。 – Adrian

+0

ローカルのtcpサーバを実行しているときにtcpダイヤルが動作し、tcpサーバ側でメッセージが表示されます。カール要求を行うクライアントがハングアップしています。どのようにそのルーチンが単一のメッセージを消費した後に戻る、私は最初にチャンネルを閉じていないので戻ります – harry

関連する問題