Repository: rclone/rclone
File: backend/internetarchive/internetarchive.go (Go)

Code before:
	size := src.Size()
	updateTracker := random.String(32)

	// Set the mtime in the metadata
	// internetarchive backend builds at header level as IAS3 has extension outside X-Amz-
	headers := map[string]string{
		// https://github.com/jjjake/internetarchive/blob/2456376533251df9d05e0a14d796ec1ced4959f5/internetarchive/iarequest.py#L158
		"x-amz-filemeta-rclone-mtime":        modTime.Format(time.RFC3339Nano),
		"x-amz-filemeta-rclone-update-track": updateTracker,

		// we add some more headers for intuitive actions
		"x-amz-auto-make-bucket":     "1",    // create an item if does not exist, do nothing if already
		"x-archive-auto-make-bucket": "1",    // same as above in IAS3 original way
		"x-archive-keep-old-version": "0",    // do not keep old versions (a.k.a. trashes in other clouds)
		"x-archive-meta-mediatype":   "data", // mark media type of the uploading file as "data"
		"x-archive-queue-derive":     "0",    // skip derivation process (e.g. encoding to smaller files, OCR on PDFs)
		"x-archive-cascade-delete":   "1",    // enable "cascate delete" (delete all derived files in addition to the file itself)
	}

	if size >= 0 {
		headers["Content-Length"] = fmt.Sprintf("%d", size)
		headers["x-archive-size-hint"] = fmt.Sprintf("%d", size)
	}

	for _, v := range o.fs.opt.Metadata {
		// Split the metadata key and value
		parts := strings.SplitN(v, "=", 2)
		if len(parts) != 2 {
			return errors.New("metadata key=value should be in the form key=value")
		}

		// Add the metadata to the headers (potentially overwriting the defaults)
		headers[fmt.Sprintf("x-archive-meta-%s", parts[0])] = parts[1]
	}

	var mdata fs.Metadata
	mdata, err = fs.GetMetadataOptions(ctx, o.fs, src, options)
	if err == nil && mdata != nil {
		for mk, mv := range mdata {
			mk = strings.ToLower(mk)
			if strings.HasPrefix(mk, "rclone-") {
				fs.LogPrintf(fs.LogLevelWarning, o, "reserved metadata key %s is about to set", mk)
			} else if _, ok := roMetadataKey[mk]; ok {
				fs.LogPrintf(fs.LogLevelWarning, o, "setting or modifying read-only key %s is requested, skipping", mk)
				continue
			} else if mk == "mtime" {
				// redirect to make it work
				mk = "rclone-mtime"
			}
			headers[fmt.Sprintf("x-amz-filemeta-%s", mk)] = mv
		}

Review comment (suggestion):
If you could just note that this is the item metadata in this comment then that will save confusion later!

Code after:
		return nil, err
	}
	return resp.Body, nil
}

// Update the Object from in with modTime and size
func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) {
	bucket, bucketPath := o.split()
	modTime := src.ModTime(ctx)
	size := src.Size()
	updateTracker := random.String(32)

	// Set the mtime in the metadata
	// internetarchive backend builds at header level as IAS3 has extension outside X-Amz-
	headers := map[string]string{
		// https://github.com/jjjake/internetarchive/blob/2456376533251df9d05e0a14d796ec1ced4959f5/internetarchive/iarequest.py#L158
		"x-amz-filemeta-rclone-mtime":        modTime.Format(time.RFC3339Nano),
		"x-amz-filemeta-rclone-update-track": updateTracker,

		// we add some more headers for intuitive actions
		"x-amz-auto-make-bucket":     "1", // create an item if does not exist, do nothing if already
		"x-archive-auto-make-bucket": "1", // same as above in IAS3 original way
		"x-archive-keep-old-version": "0", // do not keep old versions (a.k.a. trashes in other clouds)
		"x-archive-cascade-delete":   "1", // enable "cascate delete" (delete all derived files in addition to the file itself)
	}

	if size >= 0 {
		headers["Content-Length"] = fmt.Sprintf("%d", size)
		headers["x-archive-size-hint"] = fmt.Sprintf("%d", size)
	}

	// This is IA's ITEM metadata, not file metadata
	headers, err = o.appendItemMetadataHeaders(headers, o.fs.opt)
	if err != nil {
		return err
	}

	var mdata fs.Metadata
	mdata, err = fs.GetMetadataOptions(ctx, o.fs, src, options)
	if err == nil && mdata != nil {
		for mk, mv := range mdata {
			mk = strings.ToLower(mk)
			if strings.HasPrefix(mk, "rclone-") {
				fs.LogPrintf(fs.LogLevelWarning, o, "reserved metadata key %s is about to set", mk)
			} else if _, ok := roMetadataKey[mk]; ok {
				fs.LogPrintf(fs.LogLevelWarning, o, "setting or modifying read-only key %s is requested, skipping", mk)
				continue
			} else if mk == "mtime" {
				// redirect to make it work
				mk = "rclone-mtime"
			}