Exemple #1
0
func getObject(rw http.ResponseWriter, req *http.Request) {
	obj, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("Get Object: Get :%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
	}
}
Exemple #2
0
func deleteObject(rw http.ResponseWriter, req *http.Request) {
	obj, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("Delete Object: Get :%s", err.Error())
		rw.WriteHeader(http.StatusAccepted)
		return
	}

	err = obj.Remove()
	if err != nil && !strings.Contains(err.Error(), "no such file") {
		lumber.Error("Delete Object: Remove :%s", err.Error())
		// if i cant remove it im assuming it was already gone
		// we will probably need to check on this sometime soon
		// to confirm we are not leaving cruft
		if obj.Size != 0 {
			// if the object size is 0 dont worry about a failed remove
			// chances are the object didnt have any data in it.
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	err = models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
	if err != nil {
		lumber.Error("Delete Object: Delete :%s", err.Error())
		rw.WriteHeader(http.StatusAccepted)
		return
	}

	rw.WriteHeader(http.StatusAccepted)
}
Exemple #3
0
func setObjectPublic(rw http.ResponseWriter, req *http.Request) {
	obj, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("SetObjectPublic: Get :%s", err.Error())
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	obj.Public = true
	err = models.SaveObject(obj)
	if err != nil {
		lumber.Error("SetObjectPublic: Save :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	bytes, err := json.Marshal(obj)
	if err != nil {
		lumber.Error("SetObjectPublic: Json Marshal :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	rw.Write(bytes)
}
Exemple #4
0
func adminAccess(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
	return func(rw http.ResponseWriter, req *http.Request) {
		userId := req.Header.Get("Userid")
		userKey := req.Header.Get("Key")

		if userId == "" || userKey == "" {
			lumber.Error("no userid or key given")
			rw.WriteHeader(http.StatusNotFound)
			return
		}

		// get a user and return it
		user, err := models.GetUser(userId)
		if err != nil {
			lumber.Error("get user: %s", err.Error())
		}
		if user == nil || user.Key != userKey || user.Admin == false {
			lumber.Error("User not authorized %+v", user)
			rw.WriteHeader(http.StatusNotFound)
			return
		}

		fn(rw, req)
	}
}
Exemple #5
0
func main() {

	setLogLevel()

	runtime.GOMAXPROCS(runtime.NumCPU())

	var be models.Storage

	switch selectedBackend {
	case "local":
		be = backends.NewLocalStorage(backendCredentials)
	default:
		be = backends.NewLocalStorage(backendCredentials)
	}

	err := models.Initialize(dbCredentials, be)
	if err != nil {
		panic(err)
	}

	models.CleanEmptyObjects()

	err = api.Start(port)
	lumber.Error(err.Error())

}
Exemple #6
0
func startHoarder(ccmd *cobra.Command, args []string) error {
	// convert the log level
	logLvl := lumber.LvlInt(viper.GetString("log-level"))

	// configure the logger
	lumber.Prefix("[hoader]")
	lumber.Level(logLvl)

	// enable/start garbage collection if age config was changed
	if ccmd.Flag("clean-after").Changed {
		lumber.Debug("Starting garbage collector (data older than %vs)...\n", ccmd.Flag("clean-after").Value)

		// start garbage collector
		go collector.Start()
	}

	// set, and initialize, the backend driver
	if err := backends.Initialize(); err != nil {
		lumber.Error("Failed to initialize backend - %v", err)
		return err
	}

	// start the API
	if err := api.Start(); err != nil {
		lumber.Fatal("Failed to start API: ", err.Error())
		return err
	}

	return nil
}
Exemple #7
0
func (c *Client) Send() {
	for msg := range c.messages {
		log.Trace("Sending message: %s", msg)
		if err := websocket.Message.Send(c.ws, msg); err != nil {
			log.Error("Error sending message: %s", err)
		}
	}
}
Exemple #8
0
func listBuckets(rw http.ResponseWriter, req *http.Request) {
	bucks, err := models.ListBuckets(userId(req), userKey(req))
	if err != nil {
		lumber.Error("List Bucket :%s", err.Error())
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	b, err := json.Marshal(bucks)
	if err != nil {
		lumber.Error("List Bucket: Parse Json :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	rw.Write(b)
}
Exemple #9
0
func listObjects(rw http.ResponseWriter, req *http.Request) {
	objs, err := models.ListObjects(userId(req), userKey(req), bucketId(req))
	if err != nil {
		lumber.Error("List Object: Get :%s", err.Error())
		rw.WriteHeader(422)
		return
	}

	b, err := json.Marshal(objs)
	if err != nil {
		lumber.Error("List Object: Json Marshal :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	rw.Write(b)
}
Exemple #10
0
// PublishAfter sends a message after [delay]
func (p *Proxy) PublishAfter(tags []string, data string, delay time.Duration) {
	go func() {
		<-time.After(delay)
		if err := publish(p.id, tags, data); err != nil {
			// log this error and continue
			lumber.Error("Proxy failed to PublishAfter - %v", err)
		}
	}()
}
Exemple #11
0
func listUsers(rw http.ResponseWriter, req *http.Request) {
	users, err := models.ListUsers()
	if err != nil {
		lumber.Error("List User: Get :%s", err.Error())
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	b, err := json.Marshal(users)
	if err != nil {
		lumber.Error("List User: Json Marshel :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	rw.Write(b)
}
Exemple #12
0
// parseBody parses the json body into v
func parseBody(req *http.Request, v interface{}) error {

	// read the body
	b, err := ioutil.ReadAll(req.Body)
	if err != nil {
		lumber.Error(err.Error())
		return BodyReadFail
	}
	defer req.Body.Close()

	// parse body and store in v
	err = json.Unmarshal(b, v)
	if err != nil {
		lumber.Error(err.Error())
		return BadJson
	}

	return nil
}
Exemple #13
0
func (t *Server) handlePrefix(id string, msg PrefixMsg) {
	log.Trace("Handling prefix message")
	if _, ok := t.prefixes[id]; !ok {
		t.prefixes[id] = make(PrefixMap)
	}
	if err := t.prefixes[id].RegisterPrefix(msg.Prefix, msg.URI); err != nil {
		log.Error("Error registering prefix: %s", err)
	}
	log.Debug("Client %s registered prefix '%s' for URI: %s", id, msg.Prefix, msg.URI)
}
Exemple #14
0
func deleteBucket(rw http.ResponseWriter, req *http.Request) {
	err := models.DeleteBucket(userId(req), userKey(req), bucketId(req))
	if err != nil {
		lumber.Error("Delete Bucket :%s", err.Error())
		rw.WriteHeader(http.StatusNotAcceptable)
		return
	}

	rw.WriteHeader(http.StatusAccepted)
}
Exemple #15
0
// 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"))
		}
	}
}
Exemple #16
0
// PublishAfter publishes to ALL subscribers. Usefull in client applications
// who reuse the publish connection for subscribing
func PublishAfter(tags []string, data string, delay time.Duration) error {
	go func() {
		<-time.After(delay)
		if err := Publish(tags, data); err != nil {
			// log this error and continue?
			lumber.Error("Failed to PublishAfter - %v", err)
		}
	}()

	return nil
}
Exemple #17
0
func deleteUser(rw http.ResponseWriter, req *http.Request) {
	id := req.URL.Query().Get(":id")
	err := models.DeleteUser(id)
	if err != nil {
		lumber.Error("Delete User: Delete :%s", err.Error())
		rw.WriteHeader(http.StatusNotAcceptable)
		return
	}

	rw.WriteHeader(http.StatusAccepted)
}
Exemple #18
0
func createBucket(rw http.ResponseWriter, req *http.Request) {
	buck, err := models.CreateBucket(userId(req), userKey(req), bucketId(req))
	if err != nil {
		lumber.Error("New Bucket :%s", err.Error())
		rw.WriteHeader(422)
		return
	}
	b, _ := json.Marshal(buck)

	rw.WriteHeader(http.StatusCreated)
	rw.Header().Set("Content-Type", "application/json")
	rw.Write(b)
}
Exemple #19
0
func createUser(rw http.ResponseWriter, req *http.Request) {
	s := sizeLimit(req)
	newUser, err := models.CreateUser(s)
	if err != nil {
		lumber.Error("Create User: Create :%s", err.Error())
		rw.WriteHeader(422)
		return
	}

	b, _ := json.Marshal(newUser)
	rw.WriteHeader(http.StatusCreated)
	rw.Header().Set("Content-Type", "application/json")
	rw.Write(b)
}
Exemple #20
0
func getObjectInfo(rw http.ResponseWriter, req *http.Request) {
	obj, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("Get Object Info: Get :%s", err.Error())
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	rw.Header().Set("Object-Alias", obj.Alias)
	rw.Header().Set("Object-Size", strconv.FormatInt(obj.Size, 10))
	rw.Header().Set("Object-Checksum", obj.CheckSum)

	if req.Method == "GET" {
		bytes, err := json.Marshal(obj)
		if err != nil {
			lumber.Error("Get Object Info: Json Marshal :%s", err.Error())
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}

		rw.Header().Set("Content-Type", "application/json")
		rw.Write(bytes)
	}
}
Exemple #21
0
func (c *Client) Listen() {
	for {
		var rec string
		err := websocket.Message.Receive(c.ws, &rec)
		if err != nil {
			if err != io.EOF {
				log.Error("Error receiving message, aborting connection: %s", err)
			}
			break
		}
		log.Trace("Message received: %s", rec)

		data := []byte(rec)

		switch typ := ParseType(rec); typ {
		case CALLRESULT:
			var msg CallResultMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling call result message: %s", err)
			}
			c.handleCallResult(msg)
		case CALLERROR:
			var msg CallErrorMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling call error message: %s", err)
			}
			c.handleCallError(msg)
		case EVENT:
			var msg EventMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling event message: %s", err)
			}
			c.handleEvent(msg)
		case PREFIX, CALL, SUBSCRIBE, UNSUBSCRIBE, PUBLISH:
			log.Error("Client -> server message received, ignored: %s", TypeString(typ))
		case WELCOME:
			log.Error("Received extraneous welcome message, ignored")
		default:
			log.Error("Invalid message format, message dropped: %s", data)
		}
	}
}
Exemple #22
0
// connect dials the remote mist server and handles any incoming responses back
// from mist
func (c *TCP) connect() error {

	// attempt to connect to the server
	conn, err := net.Dial("tcp", c.host)
	if err != nil {
		return fmt.Errorf("Failed to dial '%v' - %v", c.host, err)
	}

	// set the connection for the client
	c.conn = conn

	// create a new json encoder for the clients connection
	c.encoder = json.NewEncoder(c.conn)

	// if the client was created with a token, authentication is needed
	if c.token != "" {
		err = c.encoder.Encode(&mist.Message{Command: "auth", Data: c.token})
		if err != nil {
			return fmt.Errorf("Failed to send auth - %v", err)
		}
	}

	// ensure we are authorized/still connected (unauthorized clients get disconnected)
	c.Ping()
	decoder := json.NewDecoder(conn)
	msg := mist.Message{}
	if err := decoder.Decode(&msg); err != nil {
		conn.Close()
		close(c.messages)
		return fmt.Errorf("Ping failed, possibly bad token, or can't read from mist")
	}

	// connection loop (blocking); continually read off the connection. Once something
	// is read, check to see if it's a message the client understands to be one of
	// its commands. If so attempt to execute the command.
	go func() {

		for {
			msg := mist.Message{}

			// decode an array value (Message)
			if err := decoder.Decode(&msg); err != nil {
				switch err {
				case io.EOF:
					lumber.Debug("[mist client] Mist terminated connection")
				case io.ErrUnexpectedEOF:
					lumber.Debug("[mist client] Mist terminated connection unexpedtedly")
				default:
					lumber.Error("[mist client] Failed to get message from mist - %s", err.Error())
				}
				conn.Close()
				close(c.messages)
				return
			}
			c.messages <- msg // read from this using the .Messages() function
			lumber.Trace("[mist client] Received message - %#v", msg)
		}
	}()

	return nil
}
Exemple #23
0
func createObject(rw http.ResponseWriter, req *http.Request) {
	_, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	// If the object already exists replace it
	if err == nil {
		replaceObject(rw, req)
		return
	}

	obj, err := models.CreateObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("Create Object: Create :%s", err.Error())
		rw.WriteHeader(422)
		return
	}

	w, err := obj.WriteCloser()
	if err != nil {
		lumber.Error("Create Object: Get writecloser :%s", err.Error())
		models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	defer w.Close()
	defer req.Body.Close()

	hash := md5.New()
	multiWriter := io.MultiWriter(hash, w)

	size, err := io.Copy(multiWriter, req.Body)
	if err != nil {
		lumber.Error("Create Object: Copy :%s", err.Error())
		if err = obj.Remove(); err == nil {
			models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		}
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	//
	obj.Size = int64(size)
	obj.Public = req.Header.Get("Public") == "true"
	obj.CheckSum = fmt.Sprintf("%x", hash.Sum(nil))
	err = models.SaveObject(obj)
	if err != nil {
		lumber.Error("Create Object: Save :%s", err.Error())
		if err = obj.Remove(); err == nil {
			models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		}
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	if !obj.Exists() {
		lumber.Error("Create Object: Confirm file: File didnt exist on the file system")
		models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	// get the user and make sure we are still in the limit
	usr, err := models.GetUser(userId(req))
	if err == nil && usr.LimitExceeded() {
		lumber.Error("Create Object: LimitExceeded")
		if err = obj.Remove(); err == nil {
			models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		}
		rw.WriteHeader(http.StatusNotAcceptable)
		return
	}

	f, _ := json.Marshal(obj)

	rw.WriteHeader(http.StatusCreated)
	rw.Header().Set("Content-Type", "application/json")
	rw.Write(f)
}
Exemple #24
0
func replaceObject(rw http.ResponseWriter, req *http.Request) {
	obj, err := models.GetObject(userId(req), userKey(req), bucketId(req), objectId(req))
	if err != nil {
		lumber.Error("Replace Object: Get Existing :%s", err.Error())
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	// create a new temporary file
	// the new file has an alias that is the id of the old object
	tmpObj, err := models.CreateObject(userId(req), userKey(req), obj.BucketID, obj.ID)
	if err != nil {
		lumber.Error("Replace Object: New Object :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	// write to the tmp file
	w, err := tmpObj.WriteCloser()
	if err != nil {
		lumber.Error("Replace Object: Write to tmp :%s", err.Error())
		models.DeleteObject(userId(req), userKey(req), tmpObj.BucketID, tmpObj.ID)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer w.Close()
	defer req.Body.Close()

	hash := md5.New()
	multiWriter := io.MultiWriter(hash, w)

	size, err := io.Copy(multiWriter, req.Body)
	if err != nil {
		lumber.Error("Replace Object: Copy to tmp :%s", err.Error())
		if err = tmpObj.Remove(); err == nil {
			models.DeleteObject(userId(req), userKey(req), tmpObj.BucketID, tmpObj.ID)
		}
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	// before we move lets make sure the existing object exists on the system
	old, err := obj.WriteCloser()
	if err != nil {
		lumber.Error("Replace Object: Create old if not exists :%s", err.Error())
		models.DeleteObject(userId(req), userKey(req), tmpObj.BucketID, tmpObj.ID)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	old.Close()

	// move the tmp object to the existing one
	err = tmpObj.Move(obj.ID)
	if err != nil {
		lumber.Error("Replace Object: Move Tmp :%s", err.Error())
		if err = tmpObj.Remove(); err == nil {
			models.DeleteObject(userId(req), userKey(req), tmpObj.BucketID, tmpObj.ID)
		}
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	// I have no need for the db record anymore
	models.DeleteObject(userId(req), userKey(req), tmpObj.BucketID, tmpObj.ID)

	// set size of replaced object
	obj.Size = int64(size)
	obj.Public = req.Header.Get("Public") == "true"
	obj.CheckSum = fmt.Sprintf("%x", hash.Sum(nil))
	err = models.SaveObject(obj)
	if err != nil {
		lumber.Error("Replace Object: Save Existing :%s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	if !obj.Exists() {
		lumber.Error("Replace Object: Confirm file: File didnt exist on the file system")
		models.DeleteObject(userId(req), userKey(req), obj.BucketID, obj.ID)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	f, _ := json.Marshal(obj)

	rw.WriteHeader(http.StatusCreated)
	rw.Header().Set("Content-Type", "application/json")
	rw.Write(f)
}
Exemple #25
0
func (t *Server) HandleWebsocket(conn *websocket.Conn) {
	defer conn.Close()

	log.Debug("Received websocket connection")

	tid, err := uuid.NewV4()
	if err != nil {
		log.Error("Could not create unique id, refusing client connection")
		return
	}
	id := tid.String()

	arr, err := CreateWelcome(id, TURNPIKE_SERVER_IDENT)
	if err != nil {
		log.Error("Error encoding welcome message")
		return
	}
	log.Debug("Sending welcome message: %s", arr)
	err = websocket.Message.Send(conn, string(arr))
	if err != nil {
		log.Error("Error sending welcome message, aborting connection: %s", err)
		return
	}

	c := make(chan string, serverBacklog)
	t.clients[id] = c

	go func() {
		for msg := range c {
			log.Trace("Sending message: %s", msg)
			err := websocket.Message.Send(conn, string(msg))
			if err != nil {
				log.Error("Error sending message: %s", err)
			}
		}
	}()

	for {
		var rec string
		err := websocket.Message.Receive(conn, &rec)
		if err != nil {
			if err != io.EOF {
				log.Error("Error receiving message, aborting connection: %s", err)
			}
			break
		}
		log.Trace("Message received: %s", rec)

		data := []byte(rec)

		switch typ := ParseType(rec); typ {
		case PREFIX:
			var msg PrefixMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling prefix message: %s", err)
			}
			t.handlePrefix(id, msg)
		case CALL:
			var msg CallMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling call message: %s", err)
			}
			t.handleCall(id, msg)
		case SUBSCRIBE:
			var msg SubscribeMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling subscribe message: %s", err)
			}
			t.handleSubscribe(id, msg)
		case UNSUBSCRIBE:
			var msg UnsubscribeMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling unsubscribe message: %s", err)
			}
			t.handleUnsubscribe(id, msg)
		case PUBLISH:
			var msg PublishMsg
			err := json.Unmarshal(data, &msg)
			if err != nil {
				log.Error("Error unmarshalling publish message: %s", err)
			}
			t.handlePublish(id, msg)
		case WELCOME, CALLRESULT, CALLERROR, EVENT:
			log.Error("Server -> client message received, ignored: %s", TypeString(typ))
		default:
			log.Error("Invalid message format, message dropped: %s", data)
		}
	}

	delete(t.clients, id)
	close(c)
}
Exemple #26
0
func (t *Server) handlePublish(id string, msg PublishMsg) {
	log.Trace("Handling publish message")
	topic := CheckCurie(t.prefixes[id], msg.TopicURI)
	lm, ok := t.subscriptions[topic]
	if !ok {
		return
	}

	out, err := CreateEvent(topic, msg.Event)
	if err != nil {
		log.Error("Error creating event message: %s", err)
		return
	}

	var sendTo []string
	if len(msg.ExcludeList) > 0 || len(msg.EligibleList) > 0 {
		// this is super ugly, but I couldn't think of a better way...
		for tid := range lm {
			include := true
			for _, _tid := range msg.ExcludeList {
				if tid == _tid {
					include = false
					break
				}
			}
			if include {
				sendTo = append(sendTo, tid)
			}
		}

		for _, tid := range msg.EligibleList {
			include := true
			for _, _tid := range sendTo {
				if _tid == tid {
					include = false
					break
				}
			}
			if include {
				sendTo = append(sendTo, tid)
			}
		}
	} else {
		for tid := range lm {
			if tid == id && msg.ExcludeMe {
				continue
			}
			sendTo = append(sendTo, tid)
		}
	}

	log.Debug("Sending event messages")
	for _, tid := range sendTo {
		// we're not locking anything, so we need
		// to make sure the client didn't disconnecct in the
		// last few nanoseconds...
		if client, ok := t.clients[tid]; ok {
			client <- string(out)
		}
	}
}
Exemple #27
0
func main() {
	var db DB
	var err error
	switch dbType {
	case "fs":
		db, err = NewFileStore("file_store")
	case "couchdb":
		db, err = NewCouchDB("localhost:5984", "test", "", "")
	default:
		err = fmt.Errorf("Unsupported database type: %s", dbType)
	}

	if err != nil {
		log.Error("Error initializing database: %s", err)
		os.Exit(1)
		return
	}

	m := martini.Classic()
	m.Use(martini.Static("build/web"))
	m.Get("/projects", func() (string, int) {
		projs, err := db.GetProjects()
		if err != nil {
			return err.Error(), 500
		}
		b, _ := json.Marshal(projs)
		return string(b), 200
	})

	m.Get("/projects/:project/tests", func(params martini.Params) (string, int) {
		tests, err := db.GetTests(params["project"])
		if err != nil {
			return err.Error(), 500
		}
		b, _ := json.Marshal(tests)
		return string(b), 200
	})

	m.Post("/projects/:project/tests", func(params martini.Params, r *http.Request) (string, int) {
		id := time.Now().Format(time.RFC3339)
		s, err := stein.Parse(r.Body)
		if err != nil {
			return err.Error(), 500
		}

		err = db.Save(params["project"], id, s)
		if err != nil {
			return err.Error(), 500
		}
		return id, 200
	})
	m.Get("/projects/:project/tests/:test", func(params martini.Params) (string, int) {
		s, err := db.GetTest(params["project"], params["test"])
		if err != nil {
			return err.Error(), 500
		}
		b, _ := json.Marshal(s)
		return string(b), 200
	})
	m.Run()
}
Exemple #28
0
// 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
}