@ -51,17 +51,18 @@ type FileSystemForRemote struct {
// mu guards the below values. Acquire a write lock before updating any of
// mu guards the below values. Acquire a write lock before updating any of
// them, acquire a read lock before reading any of them.
// them, acquire a read lock before reading any of them.
mu sync . RWMutex
mu sync . RWMutex
fileServerAddr string
// fileServerTokenAndAddr is the secretToken|fileserverAddress
shares [ ] * drive . Share
fileServerTokenAndAddr string
children map [ string ] * compositedav . Child
shares [ ] * drive . Share
userServers map [ string ] * userServer
children map [ string ] * compositedav . Child
userServers map [ string ] * userServer
}
}
// SetFileServerAddr implements drive.FileSystemForRemote.
// SetFileServerAddr implements drive.FileSystemForRemote.
func ( s * FileSystemForRemote ) SetFileServerAddr ( addr string ) {
func ( s * FileSystemForRemote ) SetFileServerAddr ( addr string ) {
s . mu . Lock ( )
s . mu . Lock ( )
s . fileServer Addr = addr
s . fileServer TokenAnd Addr = addr
s . mu . Unlock ( )
s . mu . Unlock ( )
}
}
@ -113,11 +114,58 @@ func (s *FileSystemForRemote) SetShares(shares []*drive.Share) {
}
}
func ( s * FileSystemForRemote ) buildChild ( share * drive . Share ) * compositedav . Child {
func ( s * FileSystemForRemote ) buildChild ( share * drive . Share ) * compositedav . Child {
getTokenAndAddr := func ( shareName string ) ( string , string , error ) {
s . mu . RLock ( )
var share * drive . Share
i , shareFound := slices . BinarySearchFunc ( s . shares , shareName , func ( s * drive . Share , name string ) int {
return strings . Compare ( s . Name , name )
} )
if shareFound {
share = s . shares [ i ]
}
userServers := s . userServers
fileServerTokenAndAddr := s . fileServerTokenAndAddr
s . mu . RUnlock ( )
if ! shareFound {
return "" , "" , fmt . Errorf ( "unknown share %v" , shareName )
}
var tokenAndAddr string
if ! drive . AllowShareAs ( ) {
tokenAndAddr = fileServerTokenAndAddr
} else {
userServer , found := userServers [ share . As ]
if found {
userServer . mu . RLock ( )
tokenAndAddr = userServer . tokenAndAddr
userServer . mu . RUnlock ( )
}
}
if tokenAndAddr == "" {
return "" , "" , fmt . Errorf ( "unable to determine address for share %v" , shareName )
}
parts := strings . Split ( tokenAndAddr , "|" )
if len ( parts ) != 2 {
return "" , "" , fmt . Errorf ( "invalid address for share %v" , shareName )
}
return parts [ 0 ] , parts [ 1 ] , nil
}
return & compositedav . Child {
return & compositedav . Child {
Child : & dirfs . Child {
Child : & dirfs . Child {
Name : share . Name ,
Name : share . Name ,
} ,
} ,
BaseURL : fmt . Sprintf ( "http://%v/%v" , hex . EncodeToString ( [ ] byte ( share . Name ) ) , url . PathEscape ( share . Name ) ) ,
BaseURL : func ( ) ( string , error ) {
secretToken , _ , err := getTokenAndAddr ( share . Name )
if err != nil {
return "" , err
}
return fmt . Sprintf ( "http://%s/%s/%s" , hex . EncodeToString ( [ ] byte ( share . Name ) ) , secretToken , url . PathEscape ( share . Name ) ) , nil
} ,
Transport : & http . Transport {
Transport : & http . Transport {
Dial : func ( _ , shareAddr string ) ( net . Conn , error ) {
Dial : func ( _ , shareAddr string ) ( net . Conn , error ) {
shareNameHex , _ , err := net . SplitHostPort ( shareAddr )
shareNameHex , _ , err := net . SplitHostPort ( shareAddr )
@ -132,36 +180,9 @@ func (s *FileSystemForRemote) buildChild(share *drive.Share) *compositedav.Child
}
}
shareName := string ( shareNameBytes )
shareName := string ( shareNameBytes )
s . mu . RLock ( )
_ , addr , err := getTokenAndAddr ( shareName )
var share * drive . Share
if err != nil {
i , shareFound := slices . BinarySearchFunc ( s . shares , shareName , func ( s * drive . Share , name string ) int {
return nil , err
return strings . Compare ( s . Name , name )
} )
if shareFound {
share = s . shares [ i ]
}
userServers := s . userServers
fileServerAddr := s . fileServerAddr
s . mu . RUnlock ( )
if ! shareFound {
return nil , fmt . Errorf ( "unknown share %v" , shareName )
}
var addr string
if ! drive . AllowShareAs ( ) {
addr = fileServerAddr
} else {
userServer , found := userServers [ share . As ]
if found {
userServer . mu . RLock ( )
addr = userServer . addr
userServer . mu . RUnlock ( )
}
}
if addr == "" {
return nil , fmt . Errorf ( "unable to determine address for share %v" , shareName )
}
}
_ , err = netip . ParseAddrPort ( addr )
_ , err = netip . ParseAddrPort ( addr )
@ -253,10 +274,10 @@ type userServer struct {
// mu guards the below values. Acquire a write lock before updating any of
// mu guards the below values. Acquire a write lock before updating any of
// them, acquire a read lock before reading any of them.
// them, acquire a read lock before reading any of them.
mu sync . RWMutex
mu sync . RWMutex
cmd * exec . Cmd
cmd * exec . Cmd
addr string
tokenAndAddr string
closed bool
closed bool
}
}
func ( s * userServer ) Close ( ) error {
func ( s * userServer ) Close ( ) error {
@ -366,7 +387,7 @@ func (s *userServer) run() error {
}
}
} ( )
} ( )
s . mu . Lock ( )
s . mu . Lock ( )
s . a ddr = strings . TrimSpace ( addr )
s . tokenAndA ddr = strings . TrimSpace ( addr )
s . mu . Unlock ( )
s . mu . Unlock ( )
return cmd . Wait ( )
return cmd . Wait ( )
}
}