ronantakizawa/codereview-bench huggingface dataset:
Repository: rclone/rclone
File: backend/box/box.go (Go)

Code before:
				streamPosition, err = f.changeNotifyRunner(ctx, notifyFunc, streamPosition)
				if err != nil {
					fs.Infof(f, "Change notify listener failure: %s", err)
				}
			}
		}
	}()
}

func (f *Fs) changeNotifyStreamPosition(ctx context.Context) (streamPosition string, err error) {
	opts := rest.Opts{
		Method:     "GET",
		Path:       "/events",
		Parameters: fieldsValue(),
	}
	opts.Parameters.Set("stream_position", "now")
	opts.Parameters.Set("stream_type", "changes")

	var result api.Events
	var resp *http.Response
	err = f.pacer.Call(func() (bool, error) {
		resp, err = f.srv.CallJSON(ctx, &opts, nil, &result)
		return shouldRetry(ctx, resp, err)
	})
	if err != nil {
		return "", fmt.Errorf("%w", err)
	}

	return strconv.FormatInt(result.NextStreamPosition, 10), nil
}

func (f *Fs) changeNotifyRunner(ctx context.Context, notifyFunc func(string, fs.EntryType), streamPosition string) (nextStreamPosition string, err error) {
	nextStreamPosition = streamPosition

	// box can send duplicate Event IDs; filter any in a single notify run
	processedEventIds := make(map[string]bool)

	for {
		limit := f.opt.ListChunk

		// box only allows a max of 500 events
		if limit > 500 {
			limit = 500
		}

		opts := rest.Opts{
			Method:     "GET",
			Path:       "/events",
			Parameters: fieldsValue(),
		}
		opts.Parameters.Set("stream_position", nextStreamPosition)

Review comment (suggestion):
This can just be `return "", err` if you aren't going to annotate the error.

Code after:
						ticker.Stop()
					}
					return
				}
				if ticker != nil {
					ticker.Stop()
					ticker, tickerC = nil, nil
				}
				if pollInterval != 0 {
					ticker = time.NewTicker(pollInterval)
					tickerC = ticker.C
				}
			case <-tickerC:
				if streamPosition == "" {
					streamPosition, err = f.changeNotifyStreamPosition(ctx)
					if err != nil {
						fs.Infof(f, "Failed to get StreamPosition: %s", err)
						continue
					}
				}
				streamPosition, err = f.changeNotifyRunner(ctx, notifyFunc, streamPosition)
				if err != nil {
					fs.Infof(f, "Change notify listener failure: %s", err)
				}
			}
		}
	}()
}

func (f *Fs) changeNotifyStreamPosition(ctx context.Context) (streamPosition string, err error) {
	opts := rest.Opts{
		Method:     "GET",
		Path:       "/events",
		Parameters: fieldsValue(),
	}
	opts.Parameters.Set("stream_position", "now")
	opts.Parameters.Set("stream_type", "changes")

	var result api.Events
	var resp *http.Response
	err = f.pacer.Call(func() (bool, error) {
		resp, err = f.srv.CallJSON(ctx, &opts, nil, &result)
		return shouldRetry(ctx, resp, err)
	})
	if err != nil {
		return "", err
	}

	return strconv.FormatInt(result.NextStreamPosition, 10), nil
}
Repository: rclone/rclone
File: fs/operations/rc.go (Go)

Code before:
					return nil, nil
				}
				if err != nil {
					return nil, err
				}
				if p.FileName() != "" {
					obj, err := Rcat(ctx, f, path.Join(remote, p.FileName()), p, time.Now(), nil)
					if err != nil {
						return nil, err
					}
					fs.Debugf(obj, "Upload Succeeded")
				}
			}
		}
		return nil, nil
	case "cleanup":
		return nil, CleanUp(ctx, f)
	case "settier":
		if !f.Features().SetTier {
			return nil, fmt.Errorf("remote %s does not support settier", f.Name())
		}
		tier, err := in.GetString("tier")
		if err != nil {
			return nil, err
		}
		fsrc, err := fs.NewFs(ctx, path.Join(f.Name()+":", remote))
		if err != nil && err != fs.ErrorIsFile {
			return nil, err
		}
		return nil, SetTier(ctx, fsrc, tier)
	}
	panic("unknown rcSingleCommand type")
}

func init() {
	rc.Add(rc.Call{
		Path:         "operations/size",
		AuthRequired: true,
		Fn:           rcSize,
		Title:        "Count the number of bytes and files in remote",
		Help: `This takes the following parameters:

- fs - a remote name string e.g. "drive:path/to/dir"

Returns:

- count - number of files
- bytes - number of bytes in those files

See the [size](/commands/rclone_size/) command for more information on the above.
`,

Review comment (suggestion):
You shouldn't call `fs.NewFs` here - you have an `Fs` and a `remote` here already.

Note that `operations.SetTier` sets everything under a path so you don't need a remote here either.

So set `noRemote: true` above then just call `SetTier(ctx, f, tier)`

That would be a direct translation of the `rclone settier` command. This means you can set a single object or a tree of objects.






Code after:
				if err == io.EOF {
					return nil, nil
				}
				if err != nil {
					return nil, err
				}
				if p.FileName() != "" {
					obj, err := Rcat(ctx, f, path.Join(remote, p.FileName()), p, time.Now(), nil)
					if err != nil {
						return nil, err
					}
					fs.Debugf(obj, "Upload Succeeded")
				}
			}
		}
		return nil, nil
	case "cleanup":
		return nil, CleanUp(ctx, f)
	case "settier":
		if !f.Features().SetTier {
			return nil, fmt.Errorf("remote %s does not support settier", f.Name())
		}
		tier, err := in.GetString("tier")
		if err != nil {
			return nil, err
		}
		return nil, SetTier(ctx, f, tier)
	case "settierfile":
		if !f.Features().SetTier {
			return nil, fmt.Errorf("remote %s does not support settier", f.Name())
		}
		tier, err := in.GetString("tier")
		if err != nil {
			return nil, err
		}
		o, err := f.NewObject(ctx, remote)
		if err != nil {
			return nil, err
		}
		return nil, SetTierFile(ctx, o, tier)
	}
	panic("unknown rcSingleCommand type")
}

func init() {
	rc.Add(rc.Call{
		Path:         "operations/size",
		AuthRequired: true,
		Fn:           rcSize,
		Title:        "Count the number of bytes and files in remote",
		Help: `This takes the following parameters:
Repository: rclone/rclone
File: fs/operations/rc_test.go (Go)

Code before:
		assert.Equal(t, false, stat.IsDir)
	})

	t.Run("Subdir", func(t *testing.T) {
		stat := fetch(t, "subdir")
		assert.Equal(t, "subdir", stat.Path)
		assert.Equal(t, "subdir", stat.Name)
		assert.Equal(t, int64(-1), stat.Size)
		assert.Equal(t, "inode/directory", stat.MimeType)
		assert.Equal(t, true, stat.IsDir)
	})

	t.Run("NotFound", func(t *testing.T) {
		stat := fetch(t, "notfound")
		assert.Nil(t, stat)
	})
}

// operations/settier: Set the storage tier of a file
func TestRcSettier(t *testing.T) {
	// ctx := context.Background()
	r, call := rcNewRun(t, "operations/settier")
	file1 := r.WriteObject(context.Background(), "file1", "file1 contents", t1)
	r.CheckRemoteItems(t, file1)

	if r.Fremote.Features().SetTier {
		in := rc.Params{
			"fs":     r.FremoteName,
			"remote": "file1",
			"tier":   "Cold",
		}
		out, err := call.Fn(context.Background(), in)
		require.NoError(t, err)
		assert.Equal(t, rc.Params(nil), out)
	}

}

// operations/mkdir: Make a destination directory or container
func TestRcMkdir(t *testing.T) {
	ctx := context.Background()
	r, call := rcNewRun(t, "operations/mkdir")
	r.Mkdir(context.Background(), r.Fremote)

	fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{}, []string{}, fs.GetModifyWindow(ctx, r.Fremote))

	in := rc.Params{
		"fs":     r.FremoteName,
		"remote": "subdir",
	}
	out, err := call.Fn(context.Background(), in)

Review comment (suggestion):
This should say something like
```
if !r.Fremote.Features().SetTier {
    t.Skip("settier not supported")
}
```

Code after:
		assert.Equal(t, false, stat.IsDir)
	})

	t.Run("Subdir", func(t *testing.T) {
		stat := fetch(t, "subdir")
		assert.Equal(t, "subdir", stat.Path)
		assert.Equal(t, "subdir", stat.Name)
		assert.Equal(t, int64(-1), stat.Size)
		assert.Equal(t, "inode/directory", stat.MimeType)
		assert.Equal(t, true, stat.IsDir)
	})

	t.Run("NotFound", func(t *testing.T) {
		stat := fetch(t, "notfound")
		assert.Nil(t, stat)
	})
}

// operations/settier: Set the storage tier of a fs
func TestRcSetTier(t *testing.T) {
	ctx := context.Background()
	r, call := rcNewRun(t, "operations/settier")
	if !r.Fremote.Features().SetTier {
		t.Skip("settier not supported")
	}
	file1 := r.WriteObject(context.Background(), "file1", "file1 contents", t1)
	r.CheckRemoteItems(t, file1)

	// Because we don't know what the current tier options here are, let's
	// just get the current tier, and re-use that
	o, err := r.Fremote.NewObject(ctx, file1.Path)
	require.NoError(t, err)
	trr, ok := o.(fs.GetTierer)
	require.True(t, ok)
	ctier := trr.GetTier()
	in := rc.Params{
		"fs":   r.FremoteName,
		"tier": ctier,
	}
	out, err := call.Fn(context.Background(), in)
	require.NoError(t, err)
	assert.Equal(t, rc.Params(nil), out)

}

// operations/settier: Set the storage tier of a file
func TestRcSetTierFile(t *testing.T) {
	ctx := context.Background()
	r, call := rcNewRun(t, "operations/settierfile")
	if !r.Fremote.Features().SetTier {
		t.Skip("settier not supported")
Repository: rclone/rclone
File: fs/operations/operations.go (Go)

Code before:
		tr.Done(ctx, err)
	}()
	newDst = dst
	if SkipDestructive(ctx, src, "copy") {
		in := tr.Account(ctx, nil)
		in.DryRun(src.Size())
		return newDst, nil
	}
	maxTries := ci.LowLevelRetries
	tries := 0
	doUpdate := dst != nil
	hashType, hashOption := CommonHash(ctx, f, src.Fs())

	if dst != nil {
		remote = dst.Remote()
	}

	var (
		inplace       = true
		remotePartial = remote
	)
	if !ci.Inplace && f.Features().Move != nil && f.Features().PartialUploads && !strings.HasSuffix(remote, ".rclonelink") {
		// Avoid making the leaf name longer if it's already lengthy to avoid
		// trouble with file name length limits.
		ext := strings.TrimSpace(ci.PartialUploadExtension)
		if len(ext) == 0 {
			ext = fs.GetConfig(context.Background()).PartialUploadExtension
		}

		suffix := "." + random.String(8) + "." + ext
		base := path.Base(remotePartial)
		if len(base) > 100 {
			limit := len(base) - len(suffix)

			if len(suffix) > len(base) {
				limit = 1
			}

			remotePartial = remotePartial[:len(remotePartial)-len(base)+limit] + suffix
		} else {
			remotePartial += suffix
		}
		inplace = false
	}

	var actionTaken string
	for {
		// Try server-side copy first - if has optional interface and
		// is same underlying remote
		actionTaken = "Copied (server-side copy)"
		if ci.MaxTransfer >= 0 {

Review comment (suggestion):
I don't think you need this `if len(ext) == 0 { ... }` clause do you as the context.Background() Config wasn't what the user asked for here.

Code after:
		tr.Done(ctx, err)
	}()
	newDst = dst
	if SkipDestructive(ctx, src, "copy") {
		in := tr.Account(ctx, nil)
		in.DryRun(src.Size())
		return newDst, nil
	}
	maxTries := ci.LowLevelRetries
	tries := 0
	doUpdate := dst != nil
	hashType, hashOption := CommonHash(ctx, f, src.Fs())

	if dst != nil {
		remote = dst.Remote()
	}

	var (
		inplace       = true
		remotePartial = remote
	)
	if !ci.Inplace && f.Features().Move != nil && f.Features().PartialUploads && !strings.HasSuffix(remote, ".rclonelink") {
		if len(ci.PartialSuffix) > 16 {
			return nil, fmt.Errorf("expecting length of --partial-suffix to be not greater than %d but got %d", 16, len(ci.PartialSuffix))
		}

		// Avoid making the leaf name longer if it's already lengthy to avoid
		// trouble with file name length limits.
		suffix := "." + random.String(8) + ci.PartialSuffix
		base := path.Base(remotePartial)
		if len(base) > 100 {
			remotePartial = remotePartial[:len(remotePartial)-len(suffix)] + suffix
		} else {
			remotePartial += suffix
		}
		inplace = false
	}

	var actionTaken string
	for {
		// Try server-side copy first - if has optional interface and
		// is same underlying remote
		actionTaken = "Copied (server-side copy)"
		if ci.MaxTransfer >= 0 {
			var bytesSoFar int64
			if ci.CutoffMode == fs.CutoffModeCautious {
				bytesSoFar = accounting.Stats(ctx).GetBytesWithPending() + src.Size()
			} else {
				bytesSoFar = accounting.Stats(ctx).GetBytes()
			}
			if bytesSoFar >= int64(ci.MaxTransfer) {
Repository: rclone/rclone
File: fs/operations/operations.go (Go)

Code before:
	defer func() {
		tr.Done(ctx, err)
	}()
	newDst = dst
	if SkipDestructive(ctx, src, "copy") {
		in := tr.Account(ctx, nil)
		in.DryRun(src.Size())
		return newDst, nil
	}
	maxTries := ci.LowLevelRetries
	tries := 0
	doUpdate := dst != nil
	hashType, hashOption := CommonHash(ctx, f, src.Fs())

	if dst != nil {
		remote = dst.Remote()
	}

	var (
		inplace       = true
		remotePartial = remote
	)
	if !ci.Inplace && f.Features().Move != nil && f.Features().PartialUploads && !strings.HasSuffix(remote, ".rclonelink") {
		// Avoid making the leaf name longer if it's already lengthy to avoid
		// trouble with file name length limits.
		ext := strings.TrimSpace(ci.PartialUploadExtension)
		if len(ext) == 0 {
			ext = fs.GetConfig(context.Background()).PartialUploadExtension
		}

		suffix := "." + random.String(8) + "." + ext
		base := path.Base(remotePartial)
		if len(base) > 100 {
			limit := len(base) - len(suffix)

			if len(suffix) > len(base) {
				limit = 1
			}

			remotePartial = remotePartial[:len(remotePartial)-len(base)+limit] + suffix
		} else {
			remotePartial += suffix
		}
		inplace = false
	}

	var actionTaken string
	for {
		// Try server-side copy first - if has optional interface and
		// is same underlying remote
		actionTaken = "Copied (server-side copy)"

Review comment (suggestion):
No need for `TrimSpace` - if the user wants spaces, they shall have spaces!

Code after:
	defer func() {
		tr.Done(ctx, err)
	}()
	newDst = dst
	if SkipDestructive(ctx, src, "copy") {
		in := tr.Account(ctx, nil)
		in.DryRun(src.Size())
		return newDst, nil
	}
	maxTries := ci.LowLevelRetries
	tries := 0
	doUpdate := dst != nil
	hashType, hashOption := CommonHash(ctx, f, src.Fs())

	if dst != nil {
		remote = dst.Remote()
	}

	var (
		inplace       = true
		remotePartial = remote
	)
	if !ci.Inplace && f.Features().Move != nil && f.Features().PartialUploads && !strings.HasSuffix(remote, ".rclonelink") {
		if len(ci.PartialSuffix) > 16 {
			return nil, fmt.Errorf("expecting length of --partial-suffix to be not greater than %d but got %d", 16, len(ci.PartialSuffix))
		}

		// Avoid making the leaf name longer if it's already lengthy to avoid
		// trouble with file name length limits.
		suffix := "." + random.String(8) + ci.PartialSuffix
		base := path.Base(remotePartial)
		if len(base) > 100 {
			remotePartial = remotePartial[:len(remotePartial)-len(suffix)] + suffix
		} else {
			remotePartial += suffix
		}
		inplace = false
	}

	var actionTaken string
	for {
		// Try server-side copy first - if has optional interface and
		// is same underlying remote
		actionTaken = "Copied (server-side copy)"
		if ci.MaxTransfer >= 0 {
			var bytesSoFar int64
			if ci.CutoffMode == fs.CutoffModeCautious {
				bytesSoFar = accounting.Stats(ctx).GetBytesWithPending() + src.Size()
			} else {
				bytesSoFar = accounting.Stats(ctx).GetBytes()
			}
Repository: rclone/rclone
File: backend/s3/s3.go (Go)

Code before:
		c.Handlers.Sign.Clear()
		c.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
		c.Handlers.Sign.PushBack(signer)
	}
	return c, ses, nil
}

func checkUploadChunkSize(cs fs.SizeSuffix) error {
	if cs < minChunkSize {
		return fmt.Errorf("%s is less than %s", cs, minChunkSize)
	}
	return nil
}

func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	err = checkUploadChunkSize(cs)
	if err == nil {
		old, f.opt.ChunkSize = f.opt.ChunkSize, cs
	}
	return
}

func checkCopyCutoff(cs fs.SizeSuffix) error {
	minCopySize := fs.SizeSuffixBase
	if cs < minCopySize {
		return fmt.Errorf("%s is less than %s", cs, minCopySize)
	}
	return nil
}

func checkUploadCutoff(cs fs.SizeSuffix) error {
	if cs > maxUploadCutoff {
		return fmt.Errorf("%s is greater than %s", cs, maxUploadCutoff)
	}
	return nil
}

func (f *Fs) setUploadCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	if f.opt.Provider != "Rclone" {
		err = checkUploadCutoff(cs)
	}
	if err == nil {
		old, f.opt.UploadCutoff = f.opt.UploadCutoff, cs
	}
	return
}

func (f *Fs) setCopyCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	err = checkUploadChunkSize(cs)
	if err == nil {
		old, f.opt.CopyCutoff = f.opt.CopyCutoff, cs

Review comment (suggestion):
Can you say what is out of range in the error? Also use %d/%v is preferred, so something like

    return fmt.Errorf("--s3-copy-cutoff is too small (%d is less than %d) ", cs, minCopySize)

Code after:
		c.Handlers.Sign.Clear()
		c.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
		c.Handlers.Sign.PushBack(signer)
	}
	return c, ses, nil
}

func checkUploadChunkSize(cs fs.SizeSuffix) error {
	if cs < minChunkSize {
		return fmt.Errorf("%s is less than %s", cs, minChunkSize)
	}
	return nil
}

func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	err = checkUploadChunkSize(cs)
	if err == nil {
		old, f.opt.ChunkSize = f.opt.ChunkSize, cs
	}
	return
}

func checkCopyCutoff(cs fs.SizeSuffix) error {
	minCopySize := fs.SizeSuffixBase
	if cs < minCopySize {
		return fmt.Errorf("value is too small (%v is less than %v)", cs, minCopySize)
	}
	return nil
}

func checkUploadCutoff(cs fs.SizeSuffix) error {
	if cs > maxUploadCutoff {
		return fmt.Errorf("%s is greater than %s", cs, maxUploadCutoff)
	}
	return nil
}

func (f *Fs) setUploadCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	if f.opt.Provider != "Rclone" {
		err = checkUploadCutoff(cs)
	}
	if err == nil {
		old, f.opt.UploadCutoff = f.opt.UploadCutoff, cs
	}
	return
}

func (f *Fs) setCopyCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
	err = checkUploadChunkSize(cs)
	if err == nil {
		old, f.opt.CopyCutoff = f.opt.CopyCutoff, cs
Repository: rclone/rclone
File: backend/webdav/webdav.go (Go)

Code before:
		Description: "WebDAV",
		NewFs:       NewFs,
		Options: []fs.Option{{
			Name:     "url",
			Help:     "URL of http host to connect to.\n\nE.g. https://example.com.",
			Required: true,
		}, {
			Name: "vendor",
			Help: "Name of the WebDAV site/service/software you are using.",
			Examples: []fs.OptionExample{{
				Value: "fastmail",
				Help:  "Fastmail Files",
			}, {
				Value: "nextcloud",
				Help:  "Nextcloud",
			}, {
				Value: "owncloud",
				Help:  "Owncloud",
			}, {
				Value: "sharepoint",
				Help:  "Sharepoint Online, authenticated by Microsoft account",
			}, {
				Value: "sharepoint-ntlm",
				Help:  "Sharepoint with NTLM authentication, usually self-hosted or on-premises",
			}, {
				Value: "rclone-serve",
				Help:  "rclone WebDAV server to serve a remote over HTTP via the WebDAV protocol",
			}, {
				Value: "other",
				Help:  "Other site/service or software",
			}},
		}, {
			Name:      "user",
			Help:      "User name.\n\nIn case NTLM authentication is used, the username should be in the format 'Domain\\User'.",
			Sensitive: true,
		}, {
			Name:       "pass",
			Help:       "Password.",
			IsPassword: true,
		}, {
			Name:      "bearer_token",
			Help:      "Bearer token instead of user/pass (e.g. a Macaroon).",
			Sensitive: true,
		}, {
			Name:     "bearer_token_command",
			Help:     "Command to run to get a bearer token.",
			Advanced: true,
		}, {
			Name:     config.ConfigEncoding,
			Help:     configEncodingHelp,
			Advanced: true,

Review comment (suggestion):
I think just call this `rclone` instead of `rclone-serve`.

Code after:
		Description: "WebDAV",
		NewFs:       NewFs,
		Options: []fs.Option{{
			Name:     "url",
			Help:     "URL of http host to connect to.\n\nE.g. https://example.com.",
			Required: true,
		}, {
			Name: "vendor",
			Help: "Name of the WebDAV site/service/software you are using.",
			Examples: []fs.OptionExample{{
				Value: "fastmail",
				Help:  "Fastmail Files",
			}, {
				Value: "nextcloud",
				Help:  "Nextcloud",
			}, {
				Value: "owncloud",
				Help:  "Owncloud",
			}, {
				Value: "sharepoint",
				Help:  "Sharepoint Online, authenticated by Microsoft account",
			}, {
				Value: "sharepoint-ntlm",
				Help:  "Sharepoint with NTLM authentication, usually self-hosted or on-premises",
			}, {
				Value: "rclone",
				Help:  "rclone WebDAV server to serve a remote over HTTP via the WebDAV protocol",
			}, {
				Value: "other",
				Help:  "Other site/service or software",
			}},
		}, {
			Name:      "user",
			Help:      "User name.\n\nIn case NTLM authentication is used, the username should be in the format 'Domain\\User'.",
			Sensitive: true,
		}, {
			Name:       "pass",
			Help:       "Password.",
			IsPassword: true,
		}, {
			Name:      "bearer_token",
			Help:      "Bearer token instead of user/pass (e.g. a Macaroon).",
			Sensitive: true,
		}, {
			Name:     "bearer_token_command",
			Help:     "Command to run to get a bearer token.",
			Advanced: true,
		}, {
			Name:     config.ConfigEncoding,
			Help:     configEncodingHelp,
			Advanced: true,
Repository: rclone/rclone
File: cmd/serve/dlna/cds.go (Go)

Code before:
	return
}

// Returns all the upnpav objects in a directory.
func (cds *contentDirectoryService) readContainer(o object, host string) (ret []interface{}, err error) {
	node, err := cds.vfs.Stat(o.Path)
	if err != nil {
		return
	}

	if !node.IsDir() {
		err = errors.New("not a directory")
		return
	}

	dir := node.(*vfs.Dir)
	dirEntries, err := dir.ReadDirAll()
	if err != nil {
		err = errors.New("failed to list directory")
		return
	}

	// if there's a "Subs" child directory, add its children to the list as well,
	// so mediaWithResources is able to find them.
	for _, node := range dirEntries {
		if node.Name() == "Subs" && node.IsDir() {
			subtitleDir := node.(*vfs.Dir)
			subtitleEntries, err := subtitleDir.ReadDirAll()
			if err != nil {
				err = errors.New("failed to list subtitle directory")
				return nil, err
			}
			dirEntries = append(dirEntries, subtitleEntries...)
		}
	}

	dirEntries, mediaResources := mediaWithResources(dirEntries)
	for _, de := range dirEntries {
		child := object{
			path.Join(o.Path, de.Name()),
		}
		obj, err := cds.cdsObjectToUpnpavObject(child, de, mediaResources[de], host)
		if err != nil {
			fs.Errorf(cds, "error with %s: %s", child.FilePath(), err)
			continue
		}
		if obj == nil {
			fs.Debugf(cds, "unrecognized file type: %s", de)
			continue
		}
		ret = append(ret, obj)

Review comment (security):
This should probably be a case insensitive compare so `strings.EqualFold`

Code after:
			// try getting it from the file name
			if mimeType == "application/octet-stream" {
				mimeType = fs.MimeTypeFromName(resource.Name())
			}
		} else {
			mimeType = fs.MimeTypeFromName(resource.Name())
		}

		item.Res = append(item.Res, upnpav.Resource{
			URL:          subtitleURL,
			ProtocolInfo: fmt.Sprintf("http-get:*:%s:*", mimeType),
		})
	}

	ret = item
	return
}

// Returns all the upnpav objects in a directory.
func (cds *contentDirectoryService) readContainer(o object, host string) (ret []interface{}, err error) {
	node, err := cds.vfs.Stat(o.Path)
	if err != nil {
		return
	}

	if !node.IsDir() {
		err = errors.New("not a directory")
		return
	}

	dir := node.(*vfs.Dir)
	dirEntries, err := dir.ReadDirAll()
	if err != nil {
		err = errors.New("failed to list directory")
		return
	}

	// if there's a "Subs" child directory, add its children to the list as well,
	// so mediaWithResources is able to find them.
	for _, node := range dirEntries {
		if strings.EqualFold(node.Name(), "Subs") && node.IsDir() {
			subtitleDir := node.(*vfs.Dir)
			subtitleEntries, err := subtitleDir.ReadDirAll()
			if err != nil {
				err = errors.New("failed to list subtitle directory")
				return nil, err
			}
			dirEntries = append(dirEntries, subtitleEntries...)
		}
	}