Add MLST command in the form of a Get method (#269)

* Add MLST command in the form of a Get method

The `LIST` and `MLSD` commands are inefficient when the objective
is to retrieve one single `Entry` for a known path, because the only way
to get such an entry is to list the parent directory using a data
connection. The `MLST` fixes this by allowing one single `Entry` to be
returned using the control connection.

The name `Get` was chosen because it is often used in conjunction with
`List` as a mean to get one single entry.

Signed-off-by: Thomas Hallgren <thomas@datawire.io>

* Changes in response to code review:

- Rename `Get` to `GetEntry` (because it returns an `*Entry`)
- Add test-case for multiline response on the control connection
- Fix issues with parsing the multiline response.

Signed-off-by: Thomas Hallgren <thomas@datawire.io>

* Add sample output from MLST to GetEntry comment.

Signed-off-by: Thomas Hallgren <thomas@datawire.io>

* Changes in response to code review:

- Remove unused `time.Time` argument
- Add struct labels to make `govet` happy

Signed-off-by: Thomas Hallgren <thomas@datawire.io>

* Remove time arg when calling parseNextRFC3659ListLine

Signed-off-by: Thomas Hallgren <thomas@datawire.io>

Signed-off-by: Thomas Hallgren <thomas@datawire.io>
This commit is contained in:
Thomas Hallgren
2022-08-21 23:25:29 +02:00
committed by GitHub
parent 4d1d644cf1
commit 0aeb8660a7
4 changed files with 116 additions and 5 deletions

View File

@@ -110,6 +110,40 @@ func testConn(t *testing.T, disableEPSV bool) {
_, err = c.FileSize("not-found")
assert.Error(err)
entry, err := c.GetEntry("magic-file")
if err != nil {
t.Error(err)
}
if entry == nil {
t.Fatal("expected entry, got nil")
}
if entry.Size != 42 {
t.Errorf("entry size %q, expected %q", entry.Size, 42)
}
if entry.Type != EntryTypeFile {
t.Errorf("entry type %q, expected %q", entry.Type, EntryTypeFile)
}
if entry.Name != "magic-file" {
t.Errorf("entry name %q, expected %q", entry.Name, "magic-file")
}
entry, err = c.GetEntry("multiline-dir")
if err != nil {
t.Error(err)
}
if entry == nil {
t.Fatal("expected entry, got nil")
}
if entry.Size != 0 {
t.Errorf("entry size %q, expected %q", entry.Size, 0)
}
if entry.Type != EntryTypeFolder {
t.Errorf("entry type %q, expected %q", entry.Type, EntryTypeFolder)
}
if entry.Name != "multiline-dir" {
t.Errorf("entry name %q, expected %q", entry.Name, "multiline-dir")
}
err = c.Delete("tset")
assert.NoError(err)
@@ -245,7 +279,7 @@ func TestMissingFolderDeleteDirRecur(t *testing.T) {
}
func TestListCurrentDir(t *testing.T) {
mock, c := openConn(t, "127.0.0.1")
mock, c := openConnExt(t, "127.0.0.1", "no-time", DialWithDisabledMLSD(true))
_, err := c.List("")
assert.NoError(t, err)