in images/coturn-web/main.go [46:117]
func main() {
externalIP := popVarFromEnv("EXTERNAL_IP", true, "")
turnPort := popVarFromEnv("TURN_PORT", false, "3478")
sharedSecret := popVarFromEnv("TURN_SHARED_SECRET", true, "")
listenPort := popVarFromEnv("PORT", false, "8080")
authHeaderName := popVarFromEnv("AUTH_HEADER_NAME", false, "x-auth-user")
// Env vars for running in aggregator mode.
discoveryDNSName := popVarFromEnv("DISCOVERY_DNS_NAME", false, "")
discoveryPortName := popVarFromEnv("DISCOVERY_PORT_NAME", false, "turn")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Get user from auth header.
user := r.Header.Get(authHeaderName)
if len(user) == 0 {
writeStatusResponse(w, http.StatusUnauthorized, fmt.Sprintf("Missing or invalid %s header", authHeaderName))
return
}
// IAP uses a prefix of accounts.google.com:email, remove this to just get the email
userToks := strings.Split(user, ":")
user = userToks[len(userToks)-1]
ips := make([]string, 0)
if len(discoveryDNSName) == 0 {
// Standard mode, use external IP to return single server.
ips = []string{externalIP}
resp, err := makeRTCConfig(ips, turnPort, user, sharedSecret)
if err != nil {
writeStatusResponse(w, http.StatusInternalServerError, "Internal server error")
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(resp)
} else {
// Aggregator mode, use DNS SRV records to build RTC config.
// Fetch all service host and ports using SRV record of headless discovery service.
// NOTE: The SRV record returns resolvable aliases to the endpoints, so do another lookup should return the IP.
_, srvs, err := net.LookupSRV(discoveryPortName, "tcp", discoveryDNSName)
if err != nil {
log.Printf("ERROR: failed to query SRV record from %v %v: %v", discoveryDNSName, discoveryPortName, err)
writeStatusResponse(w, http.StatusInternalServerError, "Internal server error")
return
}
for _, srv := range srvs {
addrs, err := net.LookupHost(srv.Target)
if err != nil {
log.Printf("ERROR: failed to query A record from %v: %v", srv.Target, err)
writeStatusResponse(w, http.StatusInternalServerError, "Internal server error")
return
}
ips = append(ips, addrs[0])
}
}
resp, err := makeRTCConfig(ips, turnPort, user, sharedSecret)
if err != nil {
log.Printf("ERROR: failed to make RTC config: %v", err)
writeStatusResponse(w, http.StatusInternalServerError, "Internal server error")
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(resp)
})
log.Println(fmt.Sprintf("Listening on port %s", listenPort))
http.ListenAndServe(fmt.Sprintf("0.0.0.0:%s", listenPort), nil)
}