Initial
This commit is contained in:
31
server/dir.go
Normal file
31
server/dir.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func isDir(path string) bool {
|
||||
stat, err := os.Stat(path)
|
||||
return err == nil && stat.IsDir()
|
||||
}
|
||||
|
||||
func notesDir(path string, w http.ResponseWriter, r *http.Request) {
|
||||
dirs, files := lsDir(path)
|
||||
log.Println(dirs)
|
||||
log.Println(files)
|
||||
}
|
||||
|
||||
func lsDir(p string) ([]Path, []Path) {
|
||||
dirs := newDirs()
|
||||
files := newFiles()
|
||||
|
||||
found, _ := ioutil.ReadDir(p)
|
||||
for _, f := range found {
|
||||
dirs.Push(p, f)
|
||||
files.Push(p, f)
|
||||
}
|
||||
return *dirs, *files
|
||||
}
|
||||
29
server/dir_test.go
Normal file
29
server/dir_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsDir(t *testing.T) {
|
||||
if ok := isDir("/tmp"); !ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
if ok := isDir("/dev/null"); ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
if ok := isDir("/proc/not/real/tho"); ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLsDir(t *testing.T) {
|
||||
dirs, files := lsDir("/usr/local")
|
||||
if len(dirs) == 0 {
|
||||
t.Fatal(len(dirs))
|
||||
}
|
||||
if len(files) == 0 {
|
||||
t.Fatal(len(files))
|
||||
}
|
||||
t.Log(dirs)
|
||||
t.Log(files)
|
||||
}
|
||||
21
server/dirs.go
Normal file
21
server/dirs.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type Dirs []Path
|
||||
|
||||
func newDirs() *Dirs {
|
||||
d := Dirs([]Path{})
|
||||
return &d
|
||||
}
|
||||
|
||||
func (d *Dirs) Push(p string, f os.FileInfo) {
|
||||
if f.IsDir() {
|
||||
*d = append(*d, Path{
|
||||
dir: p,
|
||||
base: f.Name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
1
server/dirs_test.go
Normal file
1
server/dirs_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package server
|
||||
14
server/file.go
Normal file
14
server/file.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func isFile(path string) bool {
|
||||
stat, err := os.Stat(path)
|
||||
return err == nil && !stat.IsDir()
|
||||
}
|
||||
|
||||
func notesFile(path string, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
17
server/file_test.go
Normal file
17
server/file_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsFile(t *testing.T) {
|
||||
if ok := isFile("/tmp"); ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
if ok := isFile("/dev/null"); !ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
if ok := isFile("/proc/not/real/tho"); ok {
|
||||
t.Fatal(ok)
|
||||
}
|
||||
}
|
||||
21
server/files.go
Normal file
21
server/files.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type Files []Path
|
||||
|
||||
func newFiles() *Files {
|
||||
d := Files([]Path{})
|
||||
return &d
|
||||
}
|
||||
|
||||
func (d *Files) Push(p string, f os.FileInfo) {
|
||||
if !f.IsDir() {
|
||||
*d = append(*d, Path{
|
||||
dir: p,
|
||||
base: f.Name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
1
server/files_test.go
Normal file
1
server/files_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package server
|
||||
29
server/notes.go
Normal file
29
server/notes.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"local/notes-server/config"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (s *Server) notes(w http.ResponseWriter, r *http.Request) {
|
||||
path := resolvePath(r.URL.Path)
|
||||
if isDir(path) {
|
||||
head(w, r)
|
||||
notesDir(path, w, r)
|
||||
foot(w, r)
|
||||
} else if isFile(path) {
|
||||
head(w, r)
|
||||
notesFile(path, w, r)
|
||||
foot(w, r)
|
||||
} else {
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func resolvePath(p string) string {
|
||||
p = strings.TrimPrefix(p, "/notes/")
|
||||
p = path.Join(config.Root, p)
|
||||
return p
|
||||
}
|
||||
13
server/notes_test.go
Normal file
13
server/notes_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"local/notes-server/config"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResolvePath(t *testing.T) {
|
||||
config.Root = "ROOT"
|
||||
if p := resolvePath("/notes/a/b/c"); p != "ROOT/a/b/c" {
|
||||
t.Fatal(p)
|
||||
}
|
||||
}
|
||||
12
server/path.go
Normal file
12
server/path.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package server
|
||||
|
||||
import "path"
|
||||
|
||||
type Path struct {
|
||||
dir string
|
||||
base string
|
||||
}
|
||||
|
||||
func (p Path) String() string {
|
||||
return path.Join(p.dir, p.base)
|
||||
}
|
||||
1
server/path_test.go
Normal file
1
server/path_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package server
|
||||
27
server/routes.go
Normal file
27
server/routes.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"local/router"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (s *Server) Routes() error {
|
||||
wildcard := router.Wildcard
|
||||
endpoints := []struct {
|
||||
path string
|
||||
handler http.HandlerFunc
|
||||
}{
|
||||
{
|
||||
path: fmt.Sprintf("notes/%s%s", wildcard, wildcard),
|
||||
handler: s.notes,
|
||||
},
|
||||
}
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
if err := s.Add(endpoint.path, endpoint.handler); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
38
server/routes_test.go
Normal file
38
server/routes_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServerRoutes(t *testing.T) {
|
||||
s := New()
|
||||
err := s.Routes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerNotes(t *testing.T) {
|
||||
s := New()
|
||||
w := httptest.NewRecorder()
|
||||
r := &http.Request{
|
||||
URL: &url.URL{
|
||||
Path: "/",
|
||||
},
|
||||
}
|
||||
s.notes(w, r)
|
||||
t.Logf("serve %s: %s", r.URL.Path, w.Body.Bytes())
|
||||
|
||||
w.Body.Reset()
|
||||
r.URL.Path = "/serve/"
|
||||
s.notes(w, r)
|
||||
t.Logf("serve %s: %s", r.URL.Path, w.Body.Bytes())
|
||||
|
||||
w.Body.Reset()
|
||||
r.URL.Path = "/serve/test"
|
||||
s.notes(w, r)
|
||||
t.Logf("serve %s: %s", r.URL.Path, w.Body.Bytes())
|
||||
}
|
||||
25
server/server.go
Normal file
25
server/server.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"local/notes-server/config"
|
||||
"local/router"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
*router.Router
|
||||
}
|
||||
|
||||
func New() *Server {
|
||||
return &Server{
|
||||
Router: router.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func head(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(config.Head + "\n"))
|
||||
}
|
||||
|
||||
func foot(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(config.Foot + "\n"))
|
||||
}
|
||||
26
server/server_test.go
Normal file
26
server/server_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"local/notes-server/config"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHead(t *testing.T) {
|
||||
config.Head = "A"
|
||||
w := httptest.NewRecorder()
|
||||
head(w, nil)
|
||||
if s := strings.TrimSpace(string(w.Body.Bytes())); s != config.Head {
|
||||
t.Fatal(s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFoot(t *testing.T) {
|
||||
config.Foot = "A"
|
||||
w := httptest.NewRecorder()
|
||||
foot(w, nil)
|
||||
if s := strings.TrimSpace(string(w.Body.Bytes())); s != config.Foot {
|
||||
t.Fatal(s)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user