Merge pull request #213 from vansante/master

Add PosixRename method which uses the posix-rename@openssh.com extension (without server support)
diff --git a/request-server.go b/request-server.go
index a6e5513..6cefddd 100644
--- a/request-server.go
+++ b/request-server.go
@@ -3,9 +3,9 @@
 import (
 	"encoding"
 	"io"
+	"path"
 	"path/filepath"
 	"strconv"
-	"strings"
 	"sync"
 	"syscall"
 
@@ -197,12 +197,13 @@
 	}
 }
 
-func cleanPath(path string) string {
-	cleanSlashPath := filepath.ToSlash(filepath.Clean(path))
-	if !strings.HasPrefix(cleanSlashPath, "/") {
-		return "/" + cleanSlashPath
+// Makes sure we have a clean POSIX (/) absolute path to work with
+func cleanPath(p string) string {
+	p = filepath.ToSlash(p)
+	if !path.IsAbs(p) {
+		p = "/" + p
 	}
-	return cleanSlashPath
+	return path.Clean(p)
 }
 
 // Wrap underlying connection methods to use packetManager
diff --git a/request-server_test.go b/request-server_test.go
index 0c25ecf..40f6bba 100644
--- a/request-server_test.go
+++ b/request-server_test.go
@@ -331,17 +331,25 @@
 
 func TestCleanPath(t *testing.T) {
 	assert.Equal(t, "/", cleanPath("/"))
+	assert.Equal(t, "/", cleanPath("."))
+	assert.Equal(t, "/", cleanPath("/."))
+	assert.Equal(t, "/", cleanPath("/a/.."))
+	assert.Equal(t, "/a/c", cleanPath("/a/b/../c"))
+	assert.Equal(t, "/a/c", cleanPath("/a/b/../c/"))
+	assert.Equal(t, "/a", cleanPath("/a/b/.."))
+	assert.Equal(t, "/a/b/c", cleanPath("/a/b/c"))
 	assert.Equal(t, "/", cleanPath("//"))
 	assert.Equal(t, "/a", cleanPath("/a/"))
 	assert.Equal(t, "/a", cleanPath("a/"))
 	assert.Equal(t, "/a/b/c", cleanPath("/a//b//c/"))
 
-	// filepath.ToSlash does not touch \ as char on unix systems, so os.PathSeparator is used for windows compatible tests
+	// filepath.ToSlash does not touch \ as char on unix systems
+	// so os.PathSeparator is used for windows compatible tests
 	bslash := string(os.PathSeparator)
 	assert.Equal(t, "/", cleanPath(bslash))
 	assert.Equal(t, "/", cleanPath(bslash+bslash))
 	assert.Equal(t, "/a", cleanPath(bslash+"a"+bslash))
 	assert.Equal(t, "/a", cleanPath("a"+bslash))
-	assert.Equal(t, "/a/b/c", cleanPath(bslash+"a"+bslash+bslash+"b"+bslash+bslash+"c"+bslash))
-
+	assert.Equal(t, "/a/b/c",
+		cleanPath(bslash+"a"+bslash+bslash+"b"+bslash+bslash+"c"+bslash))
 }