From 5e7266f75e99712d20c19b43f58e42cadf3ff922 Mon Sep 17 00:00:00 2001
From: Pascal Bleser
Date: Fri, 12 Sep 2025 11:31:01 +0200
Subject: [PATCH] jmap: modify GetBlob -> GetBlobMetadata
* fix(jmap): fix bug where CommandBlobUpload was used instead of
CommandBlobGet in GetBlob (now GetBlobMetadata)
* we currently don't need a variant of BlobGetCommand that also
retrieves the content of the blob, instead we only use it for
retrieving metadata about it
---
pkg/jmap/jmap_api_blob.go | 13 ++++++------
pkg/jmap/jmap_model.go | 44 ++++++++++++++++++++++++++++++++++-----
2 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/pkg/jmap/jmap_api_blob.go b/pkg/jmap/jmap_api_blob.go
index cf91f8861f..788a8ca009 100644
--- a/pkg/jmap/jmap_api_blob.go
+++ b/pkg/jmap/jmap_api_blob.go
@@ -11,15 +11,16 @@ import (
type BlobResponse struct {
Blob *Blob `json:"blob,omitempty"`
- State State `json:"state"`
+ State State `json:"state,omitempty"`
}
-func (j *Client) GetBlob(accountId string, session *Session, ctx context.Context, logger *log.Logger, id string) (BlobResponse, SessionState, Error) {
+func (j *Client) GetBlobMetadata(accountId string, session *Session, ctx context.Context, logger *log.Logger, id string) (BlobResponse, SessionState, Error) {
cmd, jerr := j.request(session, logger,
- invocation(CommandBlobUpload, BlobGetCommand{
- AccountId: accountId,
- Ids: []string{id},
- Properties: []string{BlobPropertyData, BlobPropertyDigestSha512, BlobPropertySize},
+ invocation(CommandBlobGet, BlobGetCommand{
+ AccountId: accountId,
+ Ids: []string{id},
+ // add BlobPropertyData to retrieve the data
+ Properties: []string{BlobPropertyDigestSha256, BlobPropertyDigestSha512, BlobPropertySize},
}, "0"),
)
if jerr != nil {
diff --git a/pkg/jmap/jmap_model.go b/pkg/jmap/jmap_model.go
index 48dbd50746..bbbf224a6f 100644
--- a/pkg/jmap/jmap_model.go
+++ b/pkg/jmap/jmap_model.go
@@ -2590,8 +2590,9 @@ type BlobUploadResponse struct {
const (
BlobPropertyDataAsText = "data:asText"
BlobPropertyDataAsBase64 = "data:asBase64"
- BlobPropertyData = "data"
- BlobPropertySize = "size"
+ // Returns data:asText if the selected octets are valid UTF-8 or data:asBase64.
+ BlobPropertyData = "data"
+ BlobPropertySize = "size"
// https://www.iana.org/assignments/http-digest-hash-alg/http-digest-hash-alg.xhtml
BlobPropertyDigestSha256 = "digest:sha256"
// https://www.iana.org/assignments/http-digest-hash-alg/http-digest-hash-alg.xhtml
@@ -2633,6 +2634,16 @@ type Blob struct {
DigestSha512 string `json:"digest:sha512,omitempty"`
// If an encoding problem occured.
+ //
+ // The data fields contain a representation of the octets within the selected range
+ // that are present in the blob.
+ //
+ // If the octets selected are not valid UTF-8 (including truncating in the middle of a
+ // multi-octet sequence) and data or data:asText was requested, then the key isEncodingProblem
+ // MUST be set to true, and the data:asText response value MUST be null.
+ //
+ // In the case where data was requested and the data is not valid UTF-8, then data:asBase64
+ // MUST be returned.
IsEncodingProblem bool `json:"isEncodingProblem,omitzero"`
// When requesting a range: the isTruncated property in the result MUST be
@@ -2655,10 +2666,33 @@ func (b *Blob) Digest() string {
}
type BlobGetResponse struct {
+ // The id of the account used for the call.
AccountId string `json:"accountId"`
- State State `json:"state,omitempty"`
- List []Blob `json:"list,omitempty"`
- NotFound []any `json:"notFound,omitempty"`
+
+ // A string representing the state on the server for all the data of this type in the
+ // account (not just the objects returned in this call).
+ //
+ // If the data changes, this string MUST change. If the Blob data is unchanged, servers
+ // SHOULD return the same state string on subsequent requests for this data type.
+ //
+ // When a client receives a response with a different state string to a previous call,
+ // it MUST either throw away all currently cached objects for the type or call
+ // Blob/changes to get the exact changes.
+ State State `json:"state,omitempty"`
+
+ // An array of the Blob objects requested.
+ //
+ // This is the empty array if no objects were found or if the ids argument passed in
+ // was also an empty array. The results MAY be in a different order to the ids in the
+ // request arguments. If an identical id is included more than once in the request,
+ // the server MUST only include it once in either the list or the notFound argument of the response.
+ List []Blob `json:"list,omitempty"`
+
+ // This array contains the ids passed to the method for records that do not exist.
+ //
+ // The array is empty if all requested ids were found or if the ids argument passed
+ // in was either null or an empty array.
+ NotFound []any `json:"notFound,omitempty"`
}
type BlobDownload struct {