2017-01-25 11 views
-2

Я пытаюсь создать службу с помощью golang, которая будет прослушивать порт для запроса почты, содержащего json, и хотела бы проанализируйте поля имени пользователя и пароля json и сохраните их как переменные, которые будут использоваться вне функции для аутентификации в Active Directory. Я использую функцию HandleFunc(), но не могу определить, как получить доступ к переменным вне функции. Я попытался создать возврат, но он не будет построен. Как правильно создать переменные, а затем использовать их вне функции?В GoLang Как получить функцию HandleFunc() для синтаксического анализа json в переменных, доступных вне функции

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 
} 
+1

Это не имеет смысла по нескольким причинам. Функция 'ldapConn' будет вызвана до вашего обработчика, поэтому эти переменные не будут установлены. Это также не пытается учесть, что происходит с одновременными вызовами обработчика. Просто объявите переменные и вызовите функцию auth в обработчике. У вас также нет http-сервера, поэтому ничто не может вызвать вашего обработчика, и ваша программа просто выйдет. – JimB

+0

Я просто слушаю Localhost. Когда я скручиваю локальный хост с помощью json, мой обработчик просто подбирает его. Кажется, я не могу вызвать какие-либо функции внутри обработчика. Когда я пытаюсь простую fmt.PrintLn, я ничего не получаю в консоли. – antman1p

+0

Извините, я пропустил ListenAndServe, поэтому у вас есть http-сервер, поэтому вы никогда не добираетесь до вызова 'ldapConn', потому что вы блокируете его. вызовы функций работают точно так же в обработчике, как и везде, вам нужно показать пример того, что не работает для вас. – JimB

ответ

1

Вы не можете получить доступ к переменным не потому, что Go Пространства имен не позволяют, а потому ListenAndServe блокирует и ldapConn можно назвать только тогда, когда сервер остановлен.

log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil)) 
// Blocked until the server is listening and serving. 

connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd) 

Более правильный подход заключается в вызове ldapConn внутри http.HandleFunc обратного вызова.

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)) 
0

Как получить функцию HandleFunc() для разбора JSON в переменные вне доступного для функции?

с вашего вопроса Я не думаю, что вы можете вернуть значение json здесь. Вместо этого вы можете передать структуру функции и вызвать ее внутри нее. , например:

//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) 
     }) 

и вы можете написать yourFunction(m Message) в другой упаковке или же пакете, вы определяете обработчик. например, написание yourFunction() будет:

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

если функция находится в другом пакете

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

, как JimB сказал. Вы вызываете свой ldapConn после ListenAndServe, эти строки никогда не будут выполнены, так как они заблокированы.

и если вы хотите распечатать приложение, оно запущено или не выполнено. Я думаю, что этот код поможет вам:

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()) 
    } 
+0

Все обработчики HTTP по своей сути являются параллельными. Вы не можете получить доступ к глобальным переменным без синхронизации из обработчика http. – JimB

+0

@JimB вы правы –

+0

@JimB извините, я отредактировал свой ответ, так как было очень поздно для меня, поэтому у меня не так много времени, чтобы отредактировать его. да, это была ошибка –