request-interfaces.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package sftp
  2. import (
  3. "io"
  4. "os"
  5. )
  6. // WriterAtReaderAt defines the interface to return when a file is to
  7. // be opened for reading and writing
  8. type WriterAtReaderAt interface {
  9. io.WriterAt
  10. io.ReaderAt
  11. }
  12. // Interfaces are differentiated based on required returned values.
  13. // All input arguments are to be pulled from Request (the only arg).
  14. // The Handler interfaces all take the Request object as its only argument.
  15. // All the data you should need to handle the call are in the Request object.
  16. // The request.Method attribute is initially the most important one as it
  17. // determines which Handler gets called.
  18. // FileReader should return an io.ReaderAt for the filepath
  19. // Note in cases of an error, the error text will be sent to the client.
  20. // Called for Methods: Get
  21. type FileReader interface {
  22. Fileread(*Request) (io.ReaderAt, error)
  23. }
  24. // FileWriter should return an io.WriterAt for the filepath.
  25. //
  26. // The request server code will call Close() on the returned io.WriterAt
  27. // ojbect if an io.Closer type assertion succeeds.
  28. // Note in cases of an error, the error text will be sent to the client.
  29. // Note when receiving an Append flag it is important to not open files using
  30. // O_APPEND if you plan to use WriteAt, as they conflict.
  31. // Called for Methods: Put, Open
  32. type FileWriter interface {
  33. Filewrite(*Request) (io.WriterAt, error)
  34. }
  35. // OpenFileWriter is a FileWriter that implements the generic OpenFile method.
  36. // You need to implement this optional interface if you want to be able
  37. // to read and write from/to the same handle.
  38. // Called for Methods: Open
  39. type OpenFileWriter interface {
  40. FileWriter
  41. OpenFile(*Request) (WriterAtReaderAt, error)
  42. }
  43. // FileCmder should return an error
  44. // Note in cases of an error, the error text will be sent to the client.
  45. // Called for Methods: Setstat, Rename, Rmdir, Mkdir, Link, Symlink, Remove
  46. type FileCmder interface {
  47. Filecmd(*Request) error
  48. }
  49. // PosixRenameFileCmder is a FileCmder that implements the PosixRename method.
  50. // If this interface is implemented PosixRename requests will call it
  51. // otherwise they will be handled in the same way as Rename
  52. type PosixRenameFileCmder interface {
  53. FileCmder
  54. PosixRename(*Request) error
  55. }
  56. // StatVFSFileCmder is a FileCmder that implements the StatVFS method.
  57. // You need to implement this interface if you want to handle statvfs requests.
  58. // Please also be sure that the statvfs@openssh.com extension is enabled
  59. type StatVFSFileCmder interface {
  60. FileCmder
  61. StatVFS(*Request) (*StatVFS, error)
  62. }
  63. // FileLister should return an object that fulfils the ListerAt interface
  64. // Note in cases of an error, the error text will be sent to the client.
  65. // Called for Methods: List, Stat, Readlink
  66. //
  67. // Since Filelist returns an os.FileInfo, this can make it non-ideal for implementing Readlink.
  68. // This is because the Name receiver method defined by that interface defines that it should only return the base name.
  69. // However, Readlink is required to be capable of returning essentially any arbitrary valid path relative or absolute.
  70. // In order to implement this more expressive requirement, implement [ReadlinkFileLister] which will then be used instead.
  71. type FileLister interface {
  72. Filelist(*Request) (ListerAt, error)
  73. }
  74. // LstatFileLister is a FileLister that implements the Lstat method.
  75. // If this interface is implemented Lstat requests will call it
  76. // otherwise they will be handled in the same way as Stat
  77. type LstatFileLister interface {
  78. FileLister
  79. Lstat(*Request) (ListerAt, error)
  80. }
  81. // RealPathFileLister is a FileLister that implements the Realpath method.
  82. // The built-in RealPath implementation does not resolve symbolic links.
  83. // By implementing this interface you can customize the returned path
  84. // and, for example, resolve symbolinc links if needed for your use case.
  85. // You have to return an absolute POSIX path.
  86. //
  87. // Up to v1.13.5 the signature for the RealPath method was:
  88. //
  89. // # RealPath(string) string
  90. //
  91. // we have added a legacyRealPathFileLister that implements the old method
  92. // to ensure that your code does not break.
  93. // You should use the new method signature to avoid future issues
  94. type RealPathFileLister interface {
  95. FileLister
  96. RealPath(string) (string, error)
  97. }
  98. // ReadlinkFileLister is a FileLister that implements the Readlink method.
  99. // By implementing the Readlink method, it is possible to return any arbitrary valid path relative or absolute.
  100. // This allows giving a better response than via the default FileLister (which is limited to os.FileInfo, whose Name method should only return the base name of a file)
  101. type ReadlinkFileLister interface {
  102. FileLister
  103. Readlink(string) (string, error)
  104. }
  105. // This interface is here for backward compatibility only
  106. type legacyRealPathFileLister interface {
  107. FileLister
  108. RealPath(string) string
  109. }
  110. // NameLookupFileLister is a FileLister that implmeents the LookupUsername and LookupGroupName methods.
  111. // If this interface is implemented, then longname ls formatting will use these to convert usernames and groupnames.
  112. type NameLookupFileLister interface {
  113. FileLister
  114. LookupUserName(string) string
  115. LookupGroupName(string) string
  116. }
  117. // ListerAt does for file lists what io.ReaderAt does for files, i.e. a []os.FileInfo buffer is passed to the ListAt function
  118. // and the entries that are populated in the buffer will be passed to the client.
  119. //
  120. // ListAt should return the number of entries copied and an io.EOF error if at end of list.
  121. // This is testable by comparing how many you copied to how many could be copied (eg. n < len(ls) below).
  122. // The copy() builtin is best for the copying.
  123. //
  124. // Uid and gid information will on unix systems be retrieved from [os.FileInfo.Sys]
  125. // if this function returns a [syscall.Stat_t] when called on a populated entry.
  126. // Alternatively, if the entry implements [FileInfoUidGid], it will be used for uid and gid information.
  127. //
  128. // If a populated entry implements [FileInfoExtendedData], extended attributes will also be returned to the client.
  129. //
  130. // Note in cases of an error, the error text will be sent to the client.
  131. type ListerAt interface {
  132. ListAt([]os.FileInfo, int64) (int, error)
  133. }
  134. // TransferError is an optional interface that readerAt and writerAt
  135. // can implement to be notified about the error causing Serve() to exit
  136. // with the request still open
  137. type TransferError interface {
  138. TransferError(err error)
  139. }