func (up *Uploader) UploadMap(m schema.Map) (*client.PutResult, error) { json, err := m.JSON() if err != nil { return nil, err } return up.uploadString(json) }
// fileMapFromDuplicate queries the server's search interface for an // existing file with an entire contents of sum (a blobref string). // If the server has it, it's validated, and then fileMap (which must // already be partially populated) has its "parts" field populated, // and then fileMap is uploaded (if necessary) and its blobref is // returned. If there's any problem, or a dup doesn't exist, ok is // false. func (up *Uploader) fileMapFromDuplicate(bs blobserver.StatReceiver, fileMap schema.Map, sum string) (fileSchema *blobref.BlobRef, ok bool) { _, err := up.Client.SearchRoot() if err != nil { return } dupFileRef, err := up.Client.SearchExistingFileSchema(blobref.MustParse(sum)) if err != nil { log.Printf("Warning: error searching for already-uploaded copy of %s: %v", sum, err) return nil, false } if dupFileRef == nil { return nil, false } if *flagVerbose { log.Printf("Found dup of contents %s in file schema %s", sum, dupFileRef) } dupMap, err := up.Client.FetchMap(dupFileRef) if err != nil { log.Printf("Warning: error fetching %v: %v", dupFileRef, err) return nil, false } parts, ok := dupMap["parts"].([]interface{}) if !ok { return nil, false } fileMap["parts"] = parts // safe, since dupMap never escapes, so sharing parts is okay // Hack: convert all the parts' float64 to int64, so they encode as e.g. "1000035" // and not "1.000035e+06". Perhaps we should work in *schema.SuperSets here, and not // JSON maps. // TODO(bradfitz): clean up? for _, p := range parts { pm := p.(map[string]interface{}) pm["size"] = int64(pm["size"].(float64)) } json, err := fileMap.JSON() if err != nil { return nil, false } uh := client.NewUploadHandleFromString(json) if uh.BlobRef.Equal(dupFileRef) { // Unchanged (same filename, modtime, JSON serialization, etc) return dupFileRef, true } pr, err := up.uploadHandle(uh) if err != nil { log.Printf("Warning: error uploading file map after finding server dup of %v: %v", sum, err) return nil, false } return pr.BlobRef, true }
func (h *Handler) SignMap(m schema.Map) (string, error) { m["camliSigner"] = h.pubKeyBlobRef.String() unsigned, err := m.JSON() if err != nil { return "", err } sreq := &jsonsign.SignRequest{ UnsignedJSON: unsigned, Fetcher: h.pubKeyFetcher, ServerMode: true, SecretKeyringPath: h.secretRing, } return sreq.Sign() }
// sigTime optionally specifies the signature time. // If zero, the current time is used. func (up *Uploader) SignMap(m schema.Map, sigTime time.Time) (string, error) { camliSigBlobref := up.Client.SignerPublicKeyBlobref() if camliSigBlobref == nil { // TODO: more helpful error message return "", errors.New("No public key configured.") } m["camliSigner"] = camliSigBlobref.String() unsigned, err := m.JSON() if err != nil { return "", err } sr := &jsonsign.SignRequest{ UnsignedJSON: unsigned, Fetcher: up.Client.GetBlobFetcher(), EntityFetcher: up.entityFetcher, SignatureTime: sigTime, } return sr.Sign() }
func (id *IndexDeps) uploadAndSignMap(m schema.Map) *blobref.BlobRef { m["camliSigner"] = id.SignerBlobRef unsigned, err := m.JSON() if err != nil { id.Fatalf("uploadAndSignMap: " + err.Error()) } sr := &jsonsign.SignRequest{ UnsignedJSON: unsigned, Fetcher: id.PublicKeyFetcher, EntityFetcher: id.EntityFetcher, SignatureTime: id.now, } signed, err := sr.Sign() if err != nil { id.Fatalf("problem signing: " + err.Error()) } tb := &test.Blob{Contents: signed} _, err = id.Index.ReceiveBlob(tb.BlobRef(), tb.Reader()) if err != nil { id.Fatalf("problem indexing blob: %v\nblob was:\n%s", err, signed) } return tb.BlobRef() }