0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-23 22:27:38 -05:00
caddy/caddyhttp/root/root_test.go
Alex Harrington 55bded68c2 fixing panic when root is symlink (#1429)
* fixing panic when root is symlink
checking root path is a symlink before os.Stat which panics

* fixing formatting

* adding test to verify symlink root path check

* fixing typo
2017-02-15 22:02:51 -07:00

142 lines
3.9 KiB
Go

package root
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
func TestRoot(t *testing.T) {
// Predefined error substrings
parseErrContent := "Parse error:"
unableToAccessErrContent := "Unable to access root path"
existingDirPath, err := getTempDirPath()
if err != nil {
t.Fatalf("BeforeTest: Failed to find an existing directory for testing! Error was: %v", err)
}
nonExistingDir := filepath.Join(existingDirPath, "highly_unlikely_to_exist_dir")
existingFile, err := ioutil.TempFile("", "root_test")
if err != nil {
t.Fatalf("BeforeTest: Failed to create temp file for testing! Error was: %v", err)
}
defer func() {
existingFile.Close()
os.Remove(existingFile.Name())
}()
inaccessiblePath := getInaccessiblePath(existingFile.Name())
tests := []struct {
input string
shouldErr bool
expectedRoot string // expected root, set to the controller. Empty for negative cases.
expectedErrContent string // substring from the expected error. Empty for positive cases.
}{
// positive
{
fmt.Sprintf(`root %s`, nonExistingDir), false, nonExistingDir, "",
},
{
fmt.Sprintf(`root %s`, existingDirPath), false, existingDirPath, "",
},
// negative
{
`root `, true, "", parseErrContent,
},
{
`root /a /b`, true, "", parseErrContent,
},
{
fmt.Sprintf(`root %s`, inaccessiblePath), true, "", unableToAccessErrContent,
},
{
fmt.Sprintf(`root {
%s
}`, existingDirPath), true, "", parseErrContent,
},
}
for i, test := range tests {
c := caddy.NewTestController("http", test.input)
err := setupRoot(c)
cfg := httpserver.GetConfig(c)
if test.shouldErr && err == nil {
t.Errorf("Test %d: Expected error but got nil for input '%s'", i, test.input)
}
if err != nil {
if !test.shouldErr {
t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err)
}
if !strings.Contains(err.Error(), test.expectedErrContent) {
t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input)
}
}
// check root only if we are in a positive test.
if !test.shouldErr && test.expectedRoot != cfg.Root {
t.Errorf("Root not correctly set for input %s. Expected: %s, actual: %s", test.input, test.expectedRoot, cfg.Root)
}
}
}
// getTempDirPath returns the path to the system temp directory. If it does not exists - an error is returned.
func getTempDirPath() (string, error) {
tempDir := os.TempDir()
_, err := os.Stat(tempDir)
if err != nil {
return "", err
}
return tempDir, nil
}
func getInaccessiblePath(file string) string {
return filepath.Join("C:", "file\x00name") // null byte in filename is not allowed on Windows AND unix
}
func TestSymlinkRoot(t *testing.T) {
origDir, err := ioutil.TempDir("", "root_test")
if err != nil {
t.Fatalf("BeforeTest: Failed to create temp dir for testing! Error was: %v", err)
}
defer func() {
os.Remove(origDir)
}()
tempDir, err := getTempDirPath()
if err != nil {
t.Fatalf("BeforeTest: Failed to find an existing directory for testing! Error was: %v", err)
}
symlinkDir := filepath.Join(tempDir, "symlink")
err = os.Symlink(origDir, symlinkDir)
if err != nil {
if strings.Contains(err.Error(), "A required privilege is not held by the client") {
t.Skip("BeforeTest: A required privilege is not held by the client and is required to create a symlink to run this test.")
}
t.Fatalf("BeforeTest: Cannot create symlink! Error was: %v", err)
}
defer func() {
os.Remove(symlinkDir)
}()
input := fmt.Sprintf(`root %s`, symlinkDir)
c := caddy.NewTestController("http", input)
err = setupRoot(c)
_ = httpserver.GetConfig(c)
if err != nil {
t.Errorf("Test Symlink Root: Expected no error but found one for input %s. Error was: %v", input, err)
}
}