Skip to content

Commit

Permalink
dserve 2.0: Major refactor
Browse files Browse the repository at this point in the history
- Change directory structure: cli in cmd/dserve
- Refactor application code to be usable as package
  • Loading branch information
peteretelej committed Oct 5, 2016
1 parent b8c2918 commit f737abd
Show file tree
Hide file tree
Showing 20 changed files with 132 additions and 2,212 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
index.html
releases
secure/
12 changes: 0 additions & 12 deletions Godeps/Godeps.json

This file was deleted.

5 changes: 0 additions & 5 deletions Godeps/Readme

This file was deleted.

64 changes: 37 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,54 +23,64 @@ cd ~/myProject
dserve
```

Or from any directory

serve a directory
```
dserve -d ~/myProject
dserve --dir ~/myProject
```

- Specifying custom directory and listen address
serve current directory on a specific address
```
dserve -d /home/chief/mystaticwebsite -l 8011
# Note: serving on port 80 requires root
dserve --port 8011
```

- `dserve --help` for cli usage help
- `-l`, `--listen-addr` - custom listen address
- `-d`, `--directory` - custom directory to serve

## dserve go package

Get the package: `package github.com/peteretelej/dserve/dserve`
serve current directory on localhost
```
dserve --local
```

serve current directory as well as a basic_auth secured directory secure/static
```
go get github.com/peteretelej/dserve/dserve
dserve --secure
```

Import into your code

- Specifying custom directory and listen address, on localhost
```
import "github.com/peteretelej/dserve/dserve"
dserve --dir /home/chief/mystaticwebsite --port 8011 --local
# Note: serving on port 80 requires admin rights
```

Launch the server with `dserve.Serve(directory,listenAddress)` where _directory_ is a string path to the folder to serve, and _listenAddress_ is the address to listen on.
`dserve --help` for cli usage help

Example
- `--port` - custom port to listen on, default is 9011
- `--dir` - custom directory to serve, default is the directory dserve is run from
- `--local` - only serve on localhost
- `--secure` - serve a HTTP basic_auth secured directory at secure/static


## dserve go package
Get: `go get github.com/peteretelej/dserve`

Usage Example:
```
package main
import "github.com/peteretelej/dserve/dserve"
import "github.com/peteretelej/dserve"
func main() {
// Serving contents of current folder on port 80
dserve.Serve(".",":80")
// Serving contents of current folder on port 8011
dserve.Serve(".",":8011")
}
```

## Secure directory
The secure directory (served at secure) uses `http basic authentication`. Files are served from the `secure/static` directory onto `/secure/`
The secure directory (served at secure if the `--secure` flag is used) uses __http basic authentication__. Files are served from the `secure/static` directory (relative to current directory `--dir`) and server on `/secure/`

Configuration:
A sample configuration file is the secure folder (`securepass.json.sample`). Copy the sample file and rename to `securepass.json` and edit the credentials as required.
- secure/securepass.json.sample - a sample username and password
- secure/securepass.json - your username and password ( create this file , both username and password in plain text)

Files:
- secure/securepass.json.sample - a sample username and password
- secure/securepass.json - your username and password ( create this file )
Changing of the configuration file (e.g password) does not require restart to pick ne crendentials.

Note:
- Though the `secure/securepass.json` password is not served/ visible, it is stored in plaintext
- Dserve does not need to be restart to pick new credenctions
15 changes: 7 additions & 8 deletions dserve/basichttpauth.go → basichttpauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"strings"
)

const securedir = "secure/static"

// AuthCreds defines the http basic authentication credentials for /secure
// Note: Though the password is not served, it is stored in plaintext
type AuthCreds struct {
Expand All @@ -19,16 +21,12 @@ type AuthCreds struct {
Password string `json:"password"`
}

var securedir string

// authInit initializes the secure directory
func authInit() {
// files served on /secure (secure/static)
securedir = basedir + "/secure/static"
func authInit() error {
if _, err := os.Stat(securedir); err != nil {
err := os.MkdirAll(securedir, 0700)
if err != nil {
log.Fatal(err.Error())
return err
}
}
// get creds
Expand All @@ -44,8 +42,9 @@ func authInit() {
if err != nil {
log.Fatal(err.Error())
}
err = ioutil.WriteFile(basedir+"/secure/securepass.json.sample", d, 0644)
return ioutil.WriteFile("secure/securepass.json.sample", d, 0644)
}
return nil
}

// validBasicAuth checks the authentication credentials to access /secure files
Expand All @@ -72,7 +71,7 @@ func validBasicAuth(r *http.Request) bool {
// getCreds gets the current http basic credentials
func getCreds() (*AuthCreds, error) {
creds := &AuthCreds{}
sp, err := ioutil.ReadFile(basedir + "/secure/securepass.json")
sp, err := ioutil.ReadFile("/secure/securepass.json")
if err != nil {
return creds, err
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/dserve/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
index.html
secure/
releases/
File renamed without changes.
43 changes: 43 additions & 0 deletions cmd/dserve/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"time"

"github.com/peteretelej/dserve"
)

var (
dir = flag.String("dir", "./", "the directory to serve, defaults to current directory")
port = flag.Int("port", 9011, "the port to serve at, defaults 9011")
local = flag.Bool("local", false, "whether to serve on all address or on localhost, default all addresses")
secure = flag.Bool("secure", false, "whether to create a basic_auth secured secure/ directory, default false")
)

func main() {
flag.Parse()

if err := os.Chdir(*dir); err != nil {
handleFatal(err)
return
}
var addr string
if *local {
addr = "localhost"
}
listenAddr := fmt.Sprintf("%s:%d", addr, *port)

log.Printf("Launching dserve: serving %s on %s", *dir, listenAddr)
if err := dserve.Serve(listenAddr, *secure); err != nil {
handleFatal(err)
return
}
}

func handleFatal(err error) {
log.Print("dserve fatal error: %v", err)
time.Sleep(5 * time.Second)
}
42 changes: 42 additions & 0 deletions dserve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dserve

import (
"fmt"
"net/http"
"time"
)

func Serve(listenAddr string, secureDir bool) error {
mux := http.NewServeMux()

fs := http.FileServer(http.Dir("."))
mux.Handle("/", fs)

if secureDir {
if err := authInit(); err != nil {
return fmt.Errorf("failed to initialize secure/ dir: %v", err)
}
mux.HandleFunc("/secure/", handleSecure)
}

svr := &http.Server{
Addr: listenAddr,
Handler: mux,
ReadTimeout: 15 * time.Second,
WriteTimeout: 30 * time.Second,
MaxHeaderBytes: 1 << 20,
}
return svr.ListenAndServe()
}

func handleSecure(w http.ResponseWriter, r *http.Request) {
if validBasicAuth(r) {
fs := http.FileServer(http.Dir("secure/static"))
h := http.StripPrefix("/secure/", fs)
h.ServeHTTP(w, r)
return
}
w.Header().Set("WWW-Authenticate", `Basic realm="Dserve secure/ Basic Authentication"`)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("401 Unauthorized\n"))
}
54 changes: 0 additions & 54 deletions dserve/serve.go

This file was deleted.

42 changes: 0 additions & 42 deletions main.go

This file was deleted.

13 changes: 0 additions & 13 deletions vendor/github.com/codegangsta/cli/.travis.yml

This file was deleted.

21 changes: 0 additions & 21 deletions vendor/github.com/codegangsta/cli/LICENSE

This file was deleted.

Loading

0 comments on commit f737abd

Please sign in to comment.