summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/caddyhttp.go75
-rw-r--r--modules/caddyhttp/caddyhttp_test.go80
2 files changed, 151 insertions, 4 deletions
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go
index 296e28f..99efef0 100644
--- a/modules/caddyhttp/caddyhttp.go
+++ b/modules/caddyhttp/caddyhttp.go
@@ -1,7 +1,13 @@
package caddyhttp
import (
+ "fmt"
"log"
+ "net"
+ "net/http"
+ "strconv"
+ "strings"
+ "time"
"bitbucket.org/lightcodelabs/caddy2"
)
@@ -9,7 +15,7 @@ import (
func init() {
err := caddy2.RegisterModule(caddy2.Module{
Name: "http",
- New: func() (interface{}, error) { return httpModuleConfig{}, nil },
+ New: func() (interface{}, error) { return new(httpModuleConfig), nil },
})
if err != nil {
log.Fatal(err)
@@ -20,8 +26,69 @@ type httpModuleConfig struct {
Servers map[string]httpServerConfig `json:"servers"`
}
+func (hc *httpModuleConfig) Run() error {
+ fmt.Printf("RUNNING: %#v\n", hc)
+
+ for _, srv := range hc.Servers {
+ s := http.Server{
+ ReadTimeout: time.Duration(srv.ReadTimeout),
+ ReadHeaderTimeout: time.Duration(srv.ReadHeaderTimeout),
+ }
+
+ for _, lnAddr := range srv.Listen {
+ proto, addrs, err := parseListenAddr(lnAddr)
+ if err != nil {
+ return fmt.Errorf("parsing listen address '%s': %v", lnAddr, err)
+ }
+ for _, addr := range addrs {
+ ln, err := caddy2.Listen(proto, addr)
+ if err != nil {
+ return fmt.Errorf("%s: listening on %s: %v", proto, addr, err)
+ }
+ go s.Serve(ln)
+ }
+ }
+ }
+
+ return nil
+}
+
+func parseListenAddr(a string) (proto string, addrs []string, err error) {
+ proto = "tcp"
+ if idx := strings.Index(a, ":::"); idx >= 0 {
+ proto = strings.ToLower(strings.TrimSpace(a[:idx]))
+ a = a[idx+3:]
+ }
+ var host, port string
+ host, port, err = net.SplitHostPort(a)
+ if err != nil {
+ return
+ }
+ ports := strings.SplitN(port, "-", 2)
+ if len(ports) == 1 {
+ ports = append(ports, ports[0])
+ }
+ var start, end int
+ start, err = strconv.Atoi(ports[0])
+ if err != nil {
+ return
+ }
+ end, err = strconv.Atoi(ports[1])
+ if err != nil {
+ return
+ }
+ if end < start {
+ err = fmt.Errorf("end port must be greater than start port")
+ return
+ }
+ for p := start; p <= end; p++ {
+ addrs = append(addrs, net.JoinHostPort(host, fmt.Sprintf("%d", p)))
+ }
+ return
+}
+
type httpServerConfig struct {
- Listen []string `json:"listen"`
- ReadTimeout string `json:"read_timeout"`
- ReadHeaderTimeout string `json:"read_header_timeout"`
+ Listen []string `json:"listen"`
+ ReadTimeout caddy2.Duration `json:"read_timeout"`
+ ReadHeaderTimeout caddy2.Duration `json:"read_header_timeout"`
}
diff --git a/modules/caddyhttp/caddyhttp_test.go b/modules/caddyhttp/caddyhttp_test.go
new file mode 100644
index 0000000..c65a9a2
--- /dev/null
+++ b/modules/caddyhttp/caddyhttp_test.go
@@ -0,0 +1,80 @@
+package caddyhttp
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestParseListenerAddr(t *testing.T) {
+ for i, tc := range []struct {
+ input string
+ expectProto string
+ expectAddrs []string
+ expectErr bool
+ }{
+ {
+ input: "",
+ expectProto: "tcp",
+ expectErr: true,
+ },
+ {
+ input: ":",
+ expectProto: "tcp",
+ expectErr: true,
+ },
+ {
+ input: ":1234",
+ expectProto: "tcp",
+ expectAddrs: []string{":1234"},
+ },
+ {
+ input: "tcp::::1234",
+ expectProto: "tcp",
+ expectAddrs: []string{":1234"},
+ },
+ {
+ input: "tcp6::::1234",
+ expectProto: "tcp6",
+ expectAddrs: []string{":1234"},
+ },
+ {
+ input: "tcp4:::localhost:1234",
+ expectProto: "tcp4",
+ expectAddrs: []string{"localhost:1234"},
+ },
+ {
+ input: "unix:::localhost:1234-1236",
+ expectProto: "unix",
+ expectAddrs: []string{"localhost:1234", "localhost:1235", "localhost:1236"},
+ },
+ {
+ input: "localhost:1234-1234",
+ expectProto: "tcp",
+ expectAddrs: []string{"localhost:1234"},
+ },
+ {
+ input: "localhost:2-1",
+ expectProto: "tcp",
+ expectErr: true,
+ },
+ {
+ input: "localhost:0",
+ expectProto: "tcp",
+ expectAddrs: []string{"localhost:0"},
+ },
+ } {
+ actualProto, actualAddrs, err := parseListenAddr(tc.input)
+ if tc.expectErr && err == nil {
+ t.Errorf("Test %d: Expected error but got: %v", i, err)
+ }
+ if !tc.expectErr && err != nil {
+ t.Errorf("Test %d: Expected no error but got: %v", i, err)
+ }
+ if actualProto != tc.expectProto {
+ t.Errorf("Test %d: Expeceted protocol '%s' but got '%s'", i, tc.expectProto, actualProto)
+ }
+ if !reflect.DeepEqual(tc.expectAddrs, actualAddrs) {
+ t.Errorf("Test %d: Expected addresses %v but got %v", i, tc.expectAddrs, actualAddrs)
+ }
+ }
+}