dquv73115
2017-01-25 14:42
浏览 139
已采纳

在GoLang中,如何获取HandleFunc()函数以将json解析为该函数外部可访问的变量

I am trying to create a service using golang that will listen on a port for a post request containing json and would like to parse out the username and password fields of the json and save those as variables to be used outside of the function to authenticate to Active Directory. I am using the HandleFunc() fucntion, but cannot ficure out how to access the variables outside of the function. I tried creating a return, but it wouldn't build. How do I properly create the variables and then use them outside of the function?

 package main

 import (
         "gopkg.in/ldap.v2"
         "fmt"
         "net/http"
         "os"
         "encoding/json"
         "log"
         "crypto/tls"
         "html"

 )

 type Message struct {
     User string 
     Password string 
 }

 func main() {
     const SERVICE_PORT = "8080"


     var uname string
     var pwd string

     LDAP_SERVER_DOMAIN := os.Getenv("LDAP_DOM")
     if LDAP_SERVER_DOMAIN == "" {
        LDAP_SERVER_DOMAIN = "192.168.10.0" 
     }


     //Handle Http request and parse json
     http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
            var m Message

            if request.Body == nil {
            http.Error(w, "Please send a request body", 400)                
            return
            }

            err := json.NewDecoder(request.Body).Decode(&m)
            if err != nil {
                http.Error(w, err.Error(), 400)
                return
            }
            // Not sure what to do here
            uname = m.User
            pwd = m.Password
        })

     log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))

     connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)

     if connected == true {
        fmt.Println("Connected is", connected)
     }


 }


// Connects to the ldap server and returns true if successful
 func ldapConn(dom, user, pass string) bool {
    // For testing go insecure
    tlsConfig := &tls.Config{InsecureSkipVerify: true}

    conn, err := ldap.DialTLS("tcp", dom, tlsConfig)
    if err != nil {
        // error in connection
        log.Println("ldap.DialTLS ERROR:", err)

        //debug
        fmt.Println("Error", err)

        return false
    }
    defer conn.Close()
    err = conn.Bind(user, pass)
    if err != nil {
        // error in ldap bind
        log.Println(err)

        //debug
        log.Println("conn.Bind ERROR:", err)

        return false
    }
    return true
}
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • doulu1914 2017-01-26 09:42
    已采纳

    You can't access the variables not because Go namespaces not allow it but because ListenAndServe is blocking and ldapConn could be called only if the server is stopped.

     log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
     // Blocked until the server is listening and serving.
    
     connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)
    

    A more correct approach is to call ldapConn inside http.HandleFunc callback.

     http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
            var m Message
    
            if request.Body == nil {
                http.Error(w, "Please send a request body", 400)                
                return
            }
    
            err := json.NewDecoder(request.Body).Decode(&m)
            if err != nil {
                http.Error(w, err.Error(), 400)
                return
            }
    
            connected := ldapConn(LDAP_SERVER_DOMAIN, m.User, m.Password)
            if connected == true {
                fmt.Println("Connected is", connected)
            }
     })
    
     log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dr5779 2017-01-25 15:07

    How do I get the HandleFunc() function to parse a json into variables accesible outside of the function?

    from your question I don't think you can return the json value here. Instead you could pass the struct to a function and call them inside it. for example :

    //Handle Http request and parse json
         http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
                var m Message
    
                if request.Body == nil {
                http.Error(w, "Please send a request body", 400)                
                return
                }
    
                err := json.NewDecoder(request.Body).Decode(&m)
                if err != nil {
                    http.Error(w, err.Error(), 400)
                    return
                }
                // Not sure what to do here
                // pass the variable to your function
                uname = m.User
                pwd = m.Password
    
                // passed your struct to a function here and do your logic there.
                yourFunction(m)
            })
    

    and you can write yourFunction(m Message) in another package or the same package as you define your handler. for example writing yourFunction() would be :

    func yourFunction(m Message){
       // do your logic here
    }
    

    if function is in another package

    //call your package where your struct is defined.
    func yourFunction(m main.Message){
       // do your logic here
    }
    

    as JimB said. You're calling your ldapConn after ListenAndServe those lines would never be executed since it is blocked.

    and if you like to print your app is started or failed. I think this code will help you :

        log.Println("App started on port = ", port)
        err := http.ListenAndServe(":"+port, nil)
        if err != nil {
            log.Panic("App Failed to start on = ", port, " Error : ", err.Error())
        }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题