diff options
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/format/idxfile/idxfile.go | 79 | ||||
-rw-r--r-- | plumbing/transport/ssh/common.go | 27 | ||||
-rw-r--r-- | plumbing/transport/ssh/proxy_test.go | 36 |
3 files changed, 90 insertions, 52 deletions
diff --git a/plumbing/format/idxfile/idxfile.go b/plumbing/format/idxfile/idxfile.go index 26cca59..14b5860 100644 --- a/plumbing/format/idxfile/idxfile.go +++ b/plumbing/format/idxfile/idxfile.go @@ -5,8 +5,9 @@ import ( "io" "sort" + encbin "encoding/binary" + "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/utils/binary" ) const ( @@ -122,41 +123,32 @@ func (idx *MemoryIndex) FindOffset(h plumbing.Hash) (int64, error) { return 0, plumbing.ErrObjectNotFound } - offset, err := idx.getOffset(k, i) + offset := idx.getOffset(k, i) if !idx.offsetHashIsFull { // Save the offset for reverse lookup if idx.offsetHash == nil { idx.offsetHash = make(map[int64]plumbing.Hash) } - idx.offsetHash[offset] = h + idx.offsetHash[int64(offset)] = h } - return offset, err + return int64(offset), nil } const isO64Mask = uint64(1) << 31 -func (idx *MemoryIndex) getOffset(firstLevel, secondLevel int) (int64, error) { +func (idx *MemoryIndex) getOffset(firstLevel, secondLevel int) uint64 { offset := secondLevel << 2 - buf := bytes.NewBuffer(idx.Offset32[firstLevel][offset : offset+4]) - ofs, err := binary.ReadUint32(buf) - if err != nil { - return -1, err - } + ofs := encbin.BigEndian.Uint32(idx.Offset32[firstLevel][offset : offset+4]) if (uint64(ofs) & isO64Mask) != 0 { offset := 8 * (uint64(ofs) & ^isO64Mask) - buf := bytes.NewBuffer(idx.Offset64[offset : offset+8]) - n, err := binary.ReadUint64(buf) - if err != nil { - return -1, err - } - - return int64(n), nil + n := encbin.BigEndian.Uint64(idx.Offset64[offset : offset+8]) + return n } - return int64(ofs), nil + return uint64(ofs) } // FindCRC32 implements the Index interface. @@ -167,13 +159,12 @@ func (idx *MemoryIndex) FindCRC32(h plumbing.Hash) (uint32, error) { return 0, plumbing.ErrObjectNotFound } - return idx.getCRC32(k, i) + return idx.getCRC32(k, i), nil } -func (idx *MemoryIndex) getCRC32(firstLevel, secondLevel int) (uint32, error) { +func (idx *MemoryIndex) getCRC32(firstLevel, secondLevel int) uint32 { offset := secondLevel << 2 - buf := bytes.NewBuffer(idx.CRC32[firstLevel][offset : offset+4]) - return binary.ReadUint32(buf) + return encbin.BigEndian.Uint32(idx.CRC32[firstLevel][offset : offset+4]) } // FindHash implements the Index interface. @@ -213,22 +204,19 @@ func (idx *MemoryIndex) genOffsetHash() error { idx.offsetHash = make(map[int64]plumbing.Hash, count) idx.offsetHashIsFull = true - iter, err := idx.Entries() - if err != nil { - return err - } - - for { - entry, err := iter.Next() - if err != nil { - if err == io.EOF { - return nil - } - return err + var hash plumbing.Hash + i := uint32(0) + for firstLevel, fanoutValue := range idx.Fanout { + mappedFirstLevel := idx.FanoutMapping[firstLevel] + for secondLevel := uint32(0); i < fanoutValue; i++ { + copy(hash[:], idx.Names[mappedFirstLevel][secondLevel*objectIDLength:]) + offset := int64(idx.getOffset(mappedFirstLevel, int(secondLevel))) + idx.offsetHash[offset] = hash + secondLevel++ } - - idx.offsetHash[int64(entry.Offset)] = entry.Hash } + + return nil } // Count implements the Index interface. @@ -297,22 +285,11 @@ func (i *idxfileEntryIter) Next() (*Entry, error) { continue } + mappedFirstLevel := i.idx.FanoutMapping[i.firstLevel] entry := new(Entry) - ofs := i.secondLevel * objectIDLength - copy(entry.Hash[:], i.idx.Names[i.idx.FanoutMapping[i.firstLevel]][ofs:]) - - pos := i.idx.FanoutMapping[entry.Hash[0]] - - offset, err := i.idx.getOffset(pos, i.secondLevel) - if err != nil { - return nil, err - } - entry.Offset = uint64(offset) - - entry.CRC32, err = i.idx.getCRC32(pos, i.secondLevel) - if err != nil { - return nil, err - } + copy(entry.Hash[:], i.idx.Names[mappedFirstLevel][i.secondLevel*objectIDLength:]) + entry.Offset = i.idx.getOffset(mappedFirstLevel, i.secondLevel) + entry.CRC32 = i.idx.getCRC32(mappedFirstLevel, i.secondLevel) i.secondLevel++ i.total++ diff --git a/plumbing/transport/ssh/common.go b/plumbing/transport/ssh/common.go index e4a3d18..d320d43 100644 --- a/plumbing/transport/ssh/common.go +++ b/plumbing/transport/ssh/common.go @@ -2,6 +2,7 @@ package ssh import ( + "context" "fmt" "reflect" "strconv" @@ -11,6 +12,7 @@ import ( "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" + "golang.org/x/net/proxy" ) // DefaultClient is the default SSH client. @@ -115,7 +117,7 @@ func (c *command) connect() error { overrideConfig(c.config, config) - c.client, err = ssh.Dial("tcp", c.getHostWithPort(), config) + c.client, err = dial("tcp", c.getHostWithPort(), config) if err != nil { return err } @@ -130,6 +132,29 @@ func (c *command) connect() error { return nil } +func dial(network, addr string, config *ssh.ClientConfig) (*ssh.Client, error) { + var ( + ctx = context.Background() + cancel context.CancelFunc + ) + if config.Timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, config.Timeout) + } else { + ctx, cancel = context.WithCancel(ctx) + } + defer cancel() + + conn, err := proxy.Dial(ctx, network, addr) + if err != nil { + return nil, err + } + c, chans, reqs, err := ssh.NewClientConn(conn, addr, config) + if err != nil { + return nil, err + } + return ssh.NewClient(c, chans, reqs), nil +} + func (c *command) getHostWithPort() string { if addr, found := c.doGetHostWithPortFromSSHConfig(); found { return addr diff --git a/plumbing/transport/ssh/proxy_test.go b/plumbing/transport/ssh/proxy_test.go new file mode 100644 index 0000000..3caf1ff --- /dev/null +++ b/plumbing/transport/ssh/proxy_test.go @@ -0,0 +1,36 @@ +package ssh + +import ( + "fmt" + "log" + "net" + "os" + + "github.com/armon/go-socks5" + . "gopkg.in/check.v1" +) + +type ProxySuite struct { + UploadPackSuite +} + +var _ = Suite(&ProxySuite{}) + +func (s *ProxySuite) SetUpSuite(c *C) { + s.UploadPackSuite.SetUpSuite(c) + + l, err := net.Listen("tcp", "localhost:0") + c.Assert(err, IsNil) + + server, err := socks5.New(&socks5.Config{}) + c.Assert(err, IsNil) + + port := l.Addr().(*net.TCPAddr).Port + + err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://localhost:%d", port)) + c.Assert(err, IsNil) + + go func() { + log.Fatal(server.Serve(l)) + }() +} |