func TestPut(t *testing.T) { mb1, err := mailbox.Create("put1") if err != nil { t.Fatal(err) } mb2, err := mailbox.Create("put2") if err != nil { t.Fatal(err) } accessKey := mailbox.AccessKey{FullAccess: true} accessKey.Create() req := api.PutMessageRequest{ Mailboxes: []string{ mb1.Id, mb2.Id, }, Body: "TEST", } req.Sign(accessKey.Name, accessKey.Secret) var resp api.PutMessageResponse code := doRequest(t, req, &resp, "put") count, err := mb1.MessageCount() if err != nil { t.Fatal(err) } if count == 0 { t.Fatal("Message not added to mailbox") } count, err = mb2.MessageCount() if err != nil { t.Fatal(err) } if count == 0 { t.Fatal("Message not added to mailbox") } if code != 200 { t.Fatal("Server responded with", code) } message1, err := mb1.GetMessage() if err != nil { t.Fatal(err) } message2, err := mb2.GetMessage() if err != nil { t.Fatal(err) } if message1 == nil || message2 == nil { t.Fatal("Message is nil") } if message1.Body != "TEST" { t.Fatal("Incorrect message1 body", message1.Body) } if message2.Body != "TEST" { t.Fatal("Incorrect message2 body", message2.Body) } }
func TestPutBadToken(t *testing.T) { mb, _ := mailbox.Create("puttest.badtoken") accessKey := mailbox.AccessKey{MailboxId: mb.Id} accessKey.Create() req := api.PutMessageRequest{ Mailboxes: []string{mb.Id}, Body: "TEST MESSAGE", } req.Sign(accessKey.Name, accessKey.Secret) var resp api.PutMessageResponse code := doRequest(t, req, &resp, "put") if code == 200 { t.Fatal("Bad token should return error") } }
func TestPutByPattern(t *testing.T) { mb, _ := mailbox.Create("PATTERN") accessKey := mailbox.AccessKey{FullAccess: true} accessKey.Create() req := api.PutMessageRequest{Pattern: "P*"} req.Sign(accessKey.Name, accessKey.Secret) var resp api.PutMessageResponse code := doRequest(t, req, &resp, "put") count, err := mb.MessageCount() if err != nil { t.Fatal(err) } if count == 0 { t.Fatal("Message not added to mailbox") } if code != 200 { t.Fatal("Server responded with", code) } }
// Put sends a message to a series of mailboxes. An array of mailboxes can be // provided, as well as a pattern using '*' as wildcards. The message will by // sent to all matching mailboxes. func (client *Client) Put(mbxs []string, pattern string, msg string, deploymentName string, asset string) (*api.PutMessageResponse, error) { md5, _ := client.hashFile(asset) if asset != "" { exists, err := client.CheckRemoteFile(md5) if err != nil { return nil, err } if exists == true { log.Info("File exists on server, skipping upload") } else { _, err := client.Upload(asset) if err != nil { log.Debug(err.Error()) return nil, errors.New("Could not upload asset") } } } request := api.PutMessageRequest{ Mailboxes: mbxs, Body: msg, Pattern: pattern, DeploymentName: deploymentName, Asset: md5, } request.Sign(client.AccessKeyName, client.AccessKey) var response api.PutMessageResponse err := client.request("put", request, &response) if err != nil { return nil, err } if !response.Validate(client.AccessKey) { return nil, errors.New("Server responded with an invalid signature") } return &response, nil }
// putMessage is used to deploy messages to mailboxes, etiher by a list of // mailboxes or a pattern. Messages are organized into a deployment and // persisted to the database. If any receiptients are currently polling the // message will be forwarded to that session. func putMessage(w http.ResponseWriter, r *http.Request) { var request api.PutMessageRequest err := readRequest(r, &request) if err != nil { sendError(w, "Could not parse request") } mailboxes := []mailbox.Mailbox{} if request.Pattern != "" { results, err := mailbox.Search(request.Pattern) if err != nil { sendError(w, err.Error()) return } for _, mb := range results { mailboxes = append(mailboxes, mb) } } for _, mbId := range request.Mailboxes { mb, err := mailbox.Find(mbId) if err != nil { sendError(w, err.Error()) } if mb == nil { sendError(w, fmt.Sprintf("Mailbox not found (%s)", mbId)) return } mailboxes = append(mailboxes, *mb) } if len(mailboxes) == 0 { sendError(w, "No mailboxes specified") return } if request.Asset != "" { assetPath := filepath.Join(filesPath(), request.Asset) if _, err := os.Stat(assetPath); os.IsNotExist(err) { sendError(w, "Asset does not exist on server") return } } mbList := []string{} // dep, err := mailbox.CreateDeployment(request.DeploymentName, request.Token, // request.Body) dep := mailbox.Deployment{ Name: request.DeploymentName, DeployedBy: request.AccessKeyName, MessageBody: request.Body, Asset: request.Asset, } err = dep.Create() if err != nil { sendError(w, err.Error()) return } accessKey, err := mailbox.FindKeyByName(request.AccessKeyName) if err != nil || accessKey == nil { sendError(w, "Access key is invalid") return } if !request.Validate(accessKey.Secret) { sendError(w, "Signature not valid") return } for _, mb := range mailboxes { if !accessKey.CanPut(&mb) { sendError(w, "Not allowed to send messages to "+mb.Id) return } var msg *mailbox.Message msg, err = dep.Deploy(&mb) mbList = append(mbList, mb.Id) if err != nil { sendError(w, err.Error()) return } if pollChannel, ok := pollingChannels[mb.Id]; ok { time.Sleep(50 * time.Millisecond) pollChannel <- msg } } resp := api.PutMessageResponse{ MessageSize: r.ContentLength, Mailboxes: mbList, Deployment: dep.Id, } resp.Sign(accessKey.Name, accessKey.Secret) log.Infof("Message received for %d mailboxes from %s", len(mbList), dep.DeployedBy) writeResponse(&w, resp) }