MCPcopy
hub / github.com/syncthing/syncthing / Request

Method Request

lib/model/model.go:1964–2089  ·  view source on GitHub ↗

Request returns the specified data segment by reading it from local disk. Implements the protocol.Model interface.

(conn protocol.Connection, req *protocol.Request)

Source from the content-addressed store, hash-verified

1962// Request returns the specified data segment by reading it from local disk.
1963// Implements the protocol.Model interface.
1964func (m *model) Request(conn protocol.Connection, req *protocol.Request) (out protocol.RequestResponse, err error) {
1965 if req.Size < 0 || req.Offset < 0 {
1966 return nil, protocol.ErrInvalid
1967 }
1968
1969 deviceID := conn.DeviceID()
1970
1971 m.mut.RLock()
1972 folderCfg, ok := m.folderCfgs[req.Folder]
1973 folderIgnores := m.folderIgnores[req.Folder]
1974 m.mut.RUnlock()
1975 if !ok {
1976 // The folder might be already unpaused in the config, but not yet
1977 // in the model.
1978 l.Debugf("Request from %s for file %s in unstarted folder %q", deviceID.Short(), req.Name, req.Folder)
1979 return nil, protocol.ErrGeneric
1980 }
1981
1982 if !folderCfg.SharedWith(deviceID) {
1983 slog.Warn("Request for file in unshared folder", slog.String("folder", req.Folder), deviceID.LogAttr(), slogutil.FilePath(req.Name))
1984 return nil, protocol.ErrGeneric
1985 }
1986 if folderCfg.Paused {
1987 l.Debugf("Request from %s for file %s in paused folder %q", deviceID.Short(), req.Name, req.Folder)
1988 return nil, protocol.ErrGeneric
1989 }
1990
1991 // Make sure the path is valid and in canonical form
1992 if name, err := fs.Canonicalize(req.Name); err != nil {
1993 l.Debugf("Request from %s in folder %q for invalid filename %s", deviceID.Short(), req.Folder, req.Name)
1994 return nil, protocol.ErrGeneric
1995 } else {
1996 req.Name = name
1997 }
1998
1999 if deviceID != protocol.LocalDeviceID {
2000 l.Debugf("%v REQ(in): %s: %q / %q o=%d s=%d t=%v", m, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size, req.FromTemporary)
2001 }
2002
2003 if fs.IsInternal(req.Name) {
2004 l.Debugf("%v REQ(in) for internal file: %s: %q / %q o=%d s=%d", m, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
2005 return nil, protocol.ErrInvalid
2006 }
2007
2008 if folderIgnores.Match(req.Name).IsIgnored() {
2009 l.Debugf("%v REQ(in) for ignored file: %s: %q / %q o=%d s=%d", m, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
2010 return nil, protocol.ErrInvalid
2011 }
2012
2013 // Restrict parallel requests by connection/device
2014
2015 m.mut.RLock()
2016 limiter := m.connRequestLimiters[deviceID]
2017 m.mut.RUnlock()
2018
2019 // The requestResponse releases the bytes to the buffer pool and the
2020 // limiters when its Close method is called.
2021 res := newLimitedRequestResponse(req.Size, limiter, m.globalRequestLimiter)

Callers

nothing calls this directly

Calls 15

recheckFileMethod · 0.95
FilePathFunction · 0.92
CanonicalizeFunction · 0.92
IsInternalFunction · 0.92
TraversesSymlinkFunction · 0.92
TempNameFunction · 0.92
ValidateFunction · 0.92
IsNotExistFunction · 0.92
readOffsetIntoBufFunction · 0.85
DebugfMethod · 0.80
ShortMethod · 0.80

Tested by

no test coverage detected