| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 | 
							- // Copyright (C) 2014 The Syncthing Authors.
 
- //
 
- // This Source Code Form is subject to the terms of the Mozilla Public
 
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
 
- // You can obtain one at https://mozilla.org/MPL/2.0/.
 
- package model
 
- import (
 
- 	"bytes"
 
- 	"context"
 
- 	"net"
 
- 	"sync"
 
- 	"time"
 
- 	"github.com/syncthing/syncthing/lib/connections"
 
- 	"github.com/syncthing/syncthing/lib/protocol"
 
- 	"github.com/syncthing/syncthing/lib/scanner"
 
- )
 
- type downloadProgressMessage struct {
 
- 	folder  string
 
- 	updates []protocol.FileDownloadProgressUpdate
 
- }
 
- type fakeConnection struct {
 
- 	fakeUnderlyingConn
 
- 	id                       protocol.DeviceID
 
- 	downloadProgressMessages []downloadProgressMessage
 
- 	closed                   bool
 
- 	files                    []protocol.FileInfo
 
- 	fileData                 map[string][]byte
 
- 	folder                   string
 
- 	model                    *model
 
- 	indexFn                  func(context.Context, string, []protocol.FileInfo)
 
- 	requestFn                func(ctx context.Context, folder, name string, offset int64, size int, hash []byte, fromTemporary bool) ([]byte, error)
 
- 	closeFn                  func(error)
 
- 	mut                      sync.Mutex
 
- }
 
- func (f *fakeConnection) Close(err error) {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	if f.closeFn != nil {
 
- 		f.closeFn(err)
 
- 		return
 
- 	}
 
- 	f.closed = true
 
- 	f.model.Closed(f, err)
 
- }
 
- func (f *fakeConnection) Start() {
 
- }
 
- func (f *fakeConnection) ID() protocol.DeviceID {
 
- 	return f.id
 
- }
 
- func (f *fakeConnection) Name() string {
 
- 	return ""
 
- }
 
- func (f *fakeConnection) Option(string) string {
 
- 	return ""
 
- }
 
- func (f *fakeConnection) Index(ctx context.Context, folder string, fs []protocol.FileInfo) error {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	if f.indexFn != nil {
 
- 		f.indexFn(ctx, folder, fs)
 
- 	}
 
- 	return nil
 
- }
 
- func (f *fakeConnection) IndexUpdate(ctx context.Context, folder string, fs []protocol.FileInfo) error {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	if f.indexFn != nil {
 
- 		f.indexFn(ctx, folder, fs)
 
- 	}
 
- 	return nil
 
- }
 
- func (f *fakeConnection) Request(ctx context.Context, folder, name string, offset int64, size int, hash []byte, weakHash uint32, fromTemporary bool) ([]byte, error) {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	if f.requestFn != nil {
 
- 		return f.requestFn(ctx, folder, name, offset, size, hash, fromTemporary)
 
- 	}
 
- 	return f.fileData[name], nil
 
- }
 
- func (f *fakeConnection) ClusterConfig(protocol.ClusterConfig) {}
 
- func (f *fakeConnection) Ping() bool {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	return f.closed
 
- }
 
- func (f *fakeConnection) Closed() bool {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	return f.closed
 
- }
 
- func (f *fakeConnection) Statistics() protocol.Statistics {
 
- 	return protocol.Statistics{}
 
- }
 
- func (f *fakeConnection) DownloadProgress(_ context.Context, folder string, updates []protocol.FileDownloadProgressUpdate) {
 
- 	f.downloadProgressMessages = append(f.downloadProgressMessages, downloadProgressMessage{
 
- 		folder:  folder,
 
- 		updates: updates,
 
- 	})
 
- }
 
- func (f *fakeConnection) addFileLocked(name string, flags uint32, ftype protocol.FileInfoType, data []byte, version protocol.Vector) {
 
- 	blockSize := protocol.BlockSize(int64(len(data)))
 
- 	blocks, _ := scanner.Blocks(context.TODO(), bytes.NewReader(data), blockSize, int64(len(data)), nil, true)
 
- 	if ftype == protocol.FileInfoTypeFile || ftype == protocol.FileInfoTypeDirectory {
 
- 		f.files = append(f.files, protocol.FileInfo{
 
- 			Name:         name,
 
- 			Type:         ftype,
 
- 			Size:         int64(len(data)),
 
- 			ModifiedS:    time.Now().Unix(),
 
- 			Permissions:  flags,
 
- 			Version:      version,
 
- 			Sequence:     time.Now().UnixNano(),
 
- 			RawBlockSize: int32(blockSize),
 
- 			Blocks:       blocks,
 
- 		})
 
- 	} else {
 
- 		// Symlink
 
- 		f.files = append(f.files, protocol.FileInfo{
 
- 			Name:          name,
 
- 			Type:          ftype,
 
- 			Version:       version,
 
- 			Sequence:      time.Now().UnixNano(),
 
- 			SymlinkTarget: string(data),
 
- 			NoPermissions: true,
 
- 		})
 
- 	}
 
- 	if f.fileData == nil {
 
- 		f.fileData = make(map[string][]byte)
 
- 	}
 
- 	f.fileData[name] = data
 
- }
 
- func (f *fakeConnection) addFile(name string, flags uint32, ftype protocol.FileInfoType, data []byte) {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	var version protocol.Vector
 
- 	version = version.Update(f.id.Short())
 
- 	f.addFileLocked(name, flags, ftype, data, version)
 
- }
 
- func (f *fakeConnection) updateFile(name string, flags uint32, ftype protocol.FileInfoType, data []byte) {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	for i, fi := range f.files {
 
- 		if fi.Name == name {
 
- 			f.files = append(f.files[:i], f.files[i+1:]...)
 
- 			f.addFileLocked(name, flags, ftype, data, fi.Version.Update(f.id.Short()))
 
- 			return
 
- 		}
 
- 	}
 
- }
 
- func (f *fakeConnection) deleteFile(name string) {
 
- 	f.mut.Lock()
 
- 	defer f.mut.Unlock()
 
- 	for i, fi := range f.files {
 
- 		if fi.Name == name {
 
- 			fi.Deleted = true
 
- 			fi.ModifiedS = time.Now().Unix()
 
- 			fi.Version = fi.Version.Update(f.id.Short())
 
- 			fi.Sequence = time.Now().UnixNano()
 
- 			fi.Blocks = nil
 
- 			f.files = append(append(f.files[:i], f.files[i+1:]...), fi)
 
- 			return
 
- 		}
 
- 	}
 
- }
 
- func (f *fakeConnection) sendIndexUpdate() {
 
- 	f.model.IndexUpdate(f.id, f.folder, f.files)
 
- }
 
- func addFakeConn(m *model, dev protocol.DeviceID) *fakeConnection {
 
- 	fc := &fakeConnection{id: dev, model: m}
 
- 	m.AddConnection(fc, protocol.HelloResult{})
 
- 	m.ClusterConfig(dev, protocol.ClusterConfig{
 
- 		Folders: []protocol.Folder{
 
- 			{
 
- 				ID: "default",
 
- 				Devices: []protocol.Device{
 
- 					{ID: myID},
 
- 					{ID: device1},
 
- 				},
 
- 			},
 
- 		},
 
- 	})
 
- 	return fc
 
- }
 
- type fakeProtoConn struct {
 
- 	protocol.Connection
 
- 	fakeUnderlyingConn
 
- }
 
- func newFakeProtoConn(protoConn protocol.Connection) connections.Connection {
 
- 	return &fakeProtoConn{Connection: protoConn}
 
- }
 
- // fakeUnderlyingConn implements the methods of connections.Connection that are
 
- // not implemented by protocol.Connection
 
- type fakeUnderlyingConn struct{}
 
- func (f *fakeUnderlyingConn) RemoteAddr() net.Addr {
 
- 	return &fakeAddr{}
 
- }
 
- func (f *fakeUnderlyingConn) Type() string {
 
- 	return "fake"
 
- }
 
- func (f *fakeUnderlyingConn) Crypto() string {
 
- 	return "fake"
 
- }
 
- func (f *fakeUnderlyingConn) Transport() string {
 
- 	return "fake"
 
- }
 
- func (f *fakeUnderlyingConn) Priority() int {
 
- 	return 9000
 
- }
 
- func (f *fakeUnderlyingConn) String() string {
 
- 	return ""
 
- }
 
- type fakeAddr struct{}
 
- func (fakeAddr) Network() string {
 
- 	return "network"
 
- }
 
- func (fakeAddr) String() string {
 
- 	return "address"
 
- }
 
 
  |