Implementing the Path
This commit is contained in:
parent
9ce435af85
commit
143430ff5f
4 changed files with 188 additions and 6 deletions
|
@ -10,15 +10,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// PATH is the constant which should contain the fixed path where the simpleFTP server will run
|
||||
// This will act like a root cage.
|
||||
const PATH = "/Users/denis/GoglandProjects/golangBook/GoRoutines/"
|
||||
|
||||
// GetFile sends the file to the client and returns true if it succeeds and false otherwise.
|
||||
func GetFile(c net.Conn, path string) (int, error) {
|
||||
fileName := sanitizeFilePath(path)
|
||||
|
||||
file, err := os.Open(PATH + fileName)
|
||||
file, err := os.Open(BasePath + fileName)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return 0, err
|
||||
|
@ -66,7 +62,7 @@ func sanitizeFilePath(path string) string {
|
|||
|
||||
// ListFiles list the files from path and sends them to the connection
|
||||
func ListFiles(c net.Conn) error {
|
||||
files, err := ioutil.ReadDir(PATH)
|
||||
files, err := ioutil.ReadDir(BasePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -37,3 +37,10 @@ var (
|
|||
StackOverflowError = StackError{"StackOverflowError", errors.New("stack capacity exceeded")}
|
||||
StackUnderflowError = StackError{"StackUnderflowError", errors.New("stack is empty")}
|
||||
)
|
||||
|
||||
// PathErrors
|
||||
var (
|
||||
ErrInvalidDirectoryName = errors.New("names should not contain / character")
|
||||
ErrNotADirectory = errors.New("file name is not a valid directory")
|
||||
ErrAlreadyAtBaseDirectory = errors.New("can't go past beyond root directory")
|
||||
)
|
||||
|
|
85
server/server/path.go
Normal file
85
server/server/path.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package server
|
||||
|
||||
// The Path module should work with the stack by providing functions that update the stack
|
||||
// with information that helps keeping track of the directories that the clients use.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
)
|
||||
|
||||
func containsSlash(dir string) bool {
|
||||
for _, c := range dir {
|
||||
if c == '/' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PATH is the constant which should contain the fixed path where the simpleFTP server will run
|
||||
// This will act like a root cage.
|
||||
var BasePath = "/Users/denis/GoglandProjects/golangBook/"
|
||||
|
||||
// GetPath will return the complete path
|
||||
func GetPath(stack *StringStack) string {
|
||||
if stack.IsEmpty() {
|
||||
return BasePath
|
||||
}
|
||||
|
||||
return BasePath
|
||||
}
|
||||
|
||||
// MakePathFromStringStack gets a StringStack and makes a path.
|
||||
func MakePathFromStringStack(stack *StringStack) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
buffer.WriteString(BasePath)
|
||||
if BasePath[len(BasePath)-1] != '/' {
|
||||
buffer.WriteString("/")
|
||||
}
|
||||
|
||||
for i := 0; i < stack.Size(); i++ {
|
||||
buffer.WriteString(stack.Items()[i] + "/")
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// ChangeDirectory changes the current working directory with respect to BasePath
|
||||
func ChangeDirectory(stack *StringStack, directory string) error {
|
||||
if containsSlash(directory) == true {
|
||||
return ErrInvalidDirectoryName
|
||||
}
|
||||
stack.Push(directory)
|
||||
|
||||
path := MakePathFromStringStack(stack)
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fileInfo.IsDir() == false {
|
||||
return ErrNotADirectory
|
||||
}
|
||||
|
||||
// The last 9 bits represent the Unix perms format rwxrwxrwx
|
||||
perms := fileInfo.Mode().Perm()
|
||||
|
||||
// The user has permission to view the directory
|
||||
if (perms&1 != 0) && (perms&(1<<2) != 0) || (perms&(1<<6) != 0) && (perms&(1<<8) != 0) {
|
||||
return nil
|
||||
}
|
||||
stack.Pop()
|
||||
return os.ErrPermission
|
||||
}
|
||||
|
||||
// ChangeDirectoryToPrevious changes the current working directory to the previous one,
|
||||
// doesn't go past the BasePath
|
||||
func ChangeDirectoryToPrevious(stack *StringStack) error {
|
||||
if stack.IsEmpty() {
|
||||
return ErrAlreadyAtBaseDirectory
|
||||
}
|
||||
stack.Pop()
|
||||
return nil
|
||||
}
|
94
server/server/path_test.go
Normal file
94
server/server/path_test.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetPath_StackIsEmpty(t *testing.T) {
|
||||
st := MakeStringStack(1)
|
||||
|
||||
path := GetPath(st)
|
||||
|
||||
if path != BasePath {
|
||||
t.Errorf("TestGetPath: Base path is not returned when stack is empty.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakePathFromStringStack(t *testing.T) {
|
||||
st := MakeStringStack(5)
|
||||
|
||||
st.Push("first")
|
||||
st.Push("folder two")
|
||||
st.Push("trinity")
|
||||
|
||||
path := MakePathFromStringStack(st)
|
||||
expected := fmt.Sprintf("%s/%s/%s/%s/", BasePath, "first", "folder two", "trinity")
|
||||
|
||||
if path != expected {
|
||||
t.Errorf("TestMakePathFromStringStack: Returned an invalid path! Want %s Got %s", expected, path)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMakePathFromStringStack_StackIsEmpty(t *testing.T) {
|
||||
st := MakeStringStack(1)
|
||||
path := MakePathFromStringStack(st)
|
||||
|
||||
expected := BasePath
|
||||
if BasePath[len(BasePath)-1] != '/' {
|
||||
expected += "/"
|
||||
}
|
||||
|
||||
if path != expected {
|
||||
t.Errorf("TestMakePathFromStringStack: Returned an invalid path!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeDirectory(t *testing.T) {
|
||||
st := MakeStringStack(1)
|
||||
err := os.Chdir(BasePath)
|
||||
if err != nil {
|
||||
t.Errorf("TestChangeDirectory: Step1: %s", err.Error())
|
||||
}
|
||||
|
||||
dirName := string(rand.Intn(10000))
|
||||
|
||||
err = os.Mkdir(dirName, os.FileMode(0522))
|
||||
if err != nil {
|
||||
t.Errorf("TestChangeDirectory: Step2: %s", err.Error())
|
||||
}
|
||||
|
||||
err = ChangeDirectory(st, dirName)
|
||||
if err != nil {
|
||||
t.Errorf("TestChangeDirectory: Step3: %s", err.Error())
|
||||
}
|
||||
|
||||
err = os.Chdir(BasePath)
|
||||
if err != nil {
|
||||
t.Errorf("TestChangeDirectory: Step4: %s", err.Error())
|
||||
}
|
||||
|
||||
err = os.Remove(dirName)
|
||||
if err != nil {
|
||||
t.Errorf("TestChangeDirectory: Step5: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeDirectory_InvalidDirectoryName(t *testing.T) {
|
||||
st := MakeStringStack(1)
|
||||
err := ChangeDirectory(st, "some/not/cool/directory/")
|
||||
if err != ErrInvalidDirectoryName {
|
||||
t.Error("TestChangeDirectory: Changed directory to something containing the '/' character!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeDirectoryToPrevious_StackIsEmpty(t *testing.T) {
|
||||
st := MakeStringStack(1)
|
||||
err := ChangeDirectoryToPrevious(st)
|
||||
if err != ErrAlreadyAtBaseDirectory {
|
||||
t.Error("TestChangeDirectoryToPrevious: Stack is empty and no error occured!")
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue