func getPublicObject(rw http.ResponseWriter, req *http.Request) { lumber.Info("GETPUBLICOBJECT!!") obj, err := models.GetPublicObject(parsePublicPath(req)) if err != nil { lumber.Error("Get Object: PublicGet: %s", err.Error()) rw.WriteHeader(422) return } if obj.Size == 0 { lumber.Info("object size is 0", obj.Size) rw.WriteHeader(422) rw.Write([]byte("incomplete file")) return } rc, err := obj.ReadCloser() if err != nil { lumber.Error("Get Object: Get ReadCloser :%s", err.Error()) rw.WriteHeader(http.StatusInternalServerError) return } defer rc.Close() rw.Header().Set("Content-Type", "application/octet-stream") _, err = io.Copy(rw, rc) if err != nil { lumber.Error("Get Object: Copy :%s", err.Error()) rw.WriteHeader(http.StatusInternalServerError) return } }
// Listen starts the pulse tcp socket api (stats) func Listen(address string, publisher Publisher) error { if publisher == nil { return MissingPublisher } publish = publisher serverSocket, err := net.Listen("tcp", address) if err != nil { return err } lumber.Info("[PULSE :: SERVER] Listening at %s...", address) go func() { defer serverSocket.Close() // Continually listen for any incoming connections. for { conn, err := serverSocket.Accept() if err != nil { // if the connection stops working we should // panic so we never are in a state where we thing // its accepting and it isnt panic(err) } // handle each connection individually (non-blocking) go handleConnection(conn) } }() return nil }
// start sets the state of the package if the config has all the necessary data for the api // and starts the default api server; routing web requests and handling all the routes func Start() error { routes, err := registerRoutes() if err != nil { return err } nanoauth.DefaultAuth.Header = "X-AUTH-TOKEN" // blocking... if viper.GetBool("insecure") { lumber.Info("[PULSE :: API] Listening at 'http://%s'...\n", viper.GetString("http-listen-address")) return nanoauth.ListenAndServe(viper.GetString("http-listen-address"), viper.GetString("token"), routes) } lumber.Info("[PULSE :: API] Listening at 'https://%s'...\n", viper.GetString("http-listen-address")) return nanoauth.ListenAndServeTLS(viper.GetString("http-listen-address"), viper.GetString("token"), routes) }
// StartTCP starts a tcp server listening on the specified address (default 127.0.0.1:1445) // and then continually reads from the server handling any incoming connections func StartTCP(uri string, errChan chan<- error) { // start a TCP listener ln, err := net.Listen("tcp", uri) if err != nil { errChan <- fmt.Errorf("Failed to start tcp listener - %v", err.Error()) return } lumber.Info("TCP server listening at '%s'...", uri) // start continually listening for any incoming tcp connections (non-blocking) go func() { for { // accept connections conn, err := ln.Accept() if err != nil { errChan <- fmt.Errorf("Failed to accept TCP connection %v", err.Error()) return } // handle each connection individually (non-blocking) go handleConnection(conn, errChan) } }() }
// handleRequest func handleRequest(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { lumber.Info(` Request: -------------------------------------------------------------------------------- %+v `, req) // fn(rw, req) lumber.Info(` Response: -------------------------------------------------------------------------------- %+v `, rw) } }
// Start starts the api listener func Start() error { uri, err := url.Parse(viper.GetString("listen-addr")) if err != nil { return fmt.Errorf("Failed to parse 'listen-addr' - %v", err) } // blocking... nanoauth.DefaultAuth.Header = "X-AUTH-TOKEN" // listen http (with auth support) if uri.Scheme == "http" { lumber.Info("Starting hoarder server at 'http://%s'...", uri.Host) return nanoauth.ListenAndServe(uri.Host, viper.GetString("token"), routes(), "/ping") } // listen https lumber.Info("Starting secure hoarder server at 'https://%s'...", uri.Host) return nanoauth.ListenAndServeTLS(uri.Host, viper.GetString("token"), routes(), "/ping") }
// runLoop handles communication from the server func (relay *Relay) runLoop(reader *bufio.Reader) { for { // when implementing relay, set `lumber.Level(lumber.LvlInt("TRACE"))` in client to view logs line, err := reader.ReadString('\n') if err != nil { lumber.Error("[PULSE :: RELAY] Disconnected from host %v!", relay.hostAddr) // retry indefinitely for { if reader, err = relay.establishConnection(); err == nil { lumber.Info("[PULSE :: RELAY] Reconnected to host %v!", relay.hostAddr) break } lumber.Debug("[PULSE :: RELAY] Reconnecting to host %v... Fail!", relay.hostAddr) <-time.After(5 * time.Second) } // we won't have anything in 'line' so continue continue } line = strings.TrimSuffix(line, "\n") split := strings.SplitN(line, " ", 2) cmd := split[0] switch cmd { case "ok": lumber.Trace("[PULSE :: RELAY] OK: %v", split) // just an ack case "get": lumber.Trace("[PULSE :: RELAY] GET: %v", split) if len(split) != 2 { continue } stats := strings.Split(split[1], ",") results := make([]string, 0) for _, stat := range stats { tagCollector, ok := relay.collectors[stat] if !ok { continue } for name, value := range tagCollector.collector.Collect() { formatted := strconv.FormatFloat(value, 'f', 4, 64) if name == "" { name = stat } results = append(results, fmt.Sprintf("%s-%s:%s", stat, name, formatted)) } } response := fmt.Sprintf("got %s\n", strings.Join(results, ",")) relay.conn.Write([]byte(response)) default: lumber.Trace("[PULSE :: RELAY] BAD: %v", split) relay.conn.Write([]byte("unknown command\n")) } } }
func setLogLevel() { switch level { case "TRACE": lumber.Level(0) case "DEBUG": lumber.Level(1) case "INFO": lumber.Level(2) case "WARN": lumber.Level(3) case "ERROR": lumber.Level(4) case "FATAL": lumber.Level(5) default: lumber.Info("the log level provided (" + level + ") is not available, defaulting to INFO") } }
func (c *Client) Connect(server, origin string) error { log.Trace("connect") var err error if c.ws, err = websocket.Dial(server, WAMP_SUBPROTOCOL_ID, origin); err != nil { return fmt.Errorf("Error connecting to websocket server: %s", err) } // Receive welcome message if err = c.ReceiveWelcome(); err != nil { return err } log.Info("Connected to server: %s", server) go c.Listen() go c.Send() return nil }
// Start attempts to individually start mist servers from a list of provided // listeners; the listeners provided is a comma delimited list of uri strings // (scheme:[//[user:pass@]host[:port]][/]path[?query][#fragment]) func Start(uris []string, token string) error { // BUG: https://github.com/spf13/viper/issues/112 // due to the above issue with cobra/viper (pflag) when --listeners are provided // we have to parse this string slice manually and then split it into the slice // of string schemes it should have been in the first place; one day this bug // will get fixed and this will probably break... at that point this should be // removed if viper.GetString("config") == "" { r := strings.NewReplacer("[", "", "]", "") uris = strings.Split(r.Replace(uris[0]), ",") } // check to see if a token is provided; an authenticator cannot work without // a token and so it should error here informing that. if auth.DefaultAuth != nil && token == "" { return fmt.Errorf("An authenticator has been specified but no token provided!\n") } // set the authtoken authtoken = token // this chan is given to each individual server start as a way for them to // communcate back their startup status errChan := make(chan error, len(uris)) // iterate over each of the provided listener uris attempting to start them // individually; if one isn't supported it gets skipped for i := range uris { // parse the uri string into a url object url, err := url.Parse(uris[i]) if err != nil { return err } // check to see if the scheme is supported; if not, indicate as such and // continue server, ok := servers[url.Scheme] if !ok { lumber.Error("Unsupported scheme '%v'", url.Scheme) continue } // attempt to start the server lumber.Info("Starting '%v' server...", url.Scheme) go server(url.Host, errChan) } // handle errors that happen during startup by reading off errChan and returning // on any error received. If no errors are received after 1 second per server // assume successful starts. select { case err := <-errChan: lumber.Error("Failed to start - %v", err) return err case <-time.After(time.Second * time.Duration(len(uris))): // no errors } // handle errors that happen after initial start; if any errors are received they // are logged and the servers just try to keep running for err := range errChan { // log these errors and continue lumber.Error("Server error - %v", err) } return nil }
func newHTTP(address string) error { lumber.Info("HTTP server listening at '%s'...\n", address) // blocking... return http.ListenAndServe(address, routes()) }