diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1f89e90d..16168136 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,8 +12,8 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
- go-version: [1.13.x, 1.14.x]
- ruby-version: [2.5]
+ go-version: [1.14, 1.15]
+ ruby-version: [2.7]
name: ${{ matrix.os }} / go-${{ matrix.go-version }}
steps:
diff --git a/Makefile b/Makefile
index fd1cdcbe..79f26754 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,14 @@ release:
test:
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
+clean-test:
+ rm -rf ~/.gotest-macos-puma-dev
+
+test-macos-filesystem-setup:
+ sudo mkdir -p /etc/resolver;
+ sudo chmod 0775 /etc/resolver;
+ sudo chown :staff /etc/resolver;
+
coverage: test
go tool cover -html=coverage.out -o coverage.html
@@ -50,4 +58,4 @@ test-macos-manual-setup-install: clean build
test -f "$$HOME/Library/Logs/puma-dev.log"
test 'Hi Puma!' == "$$(curl -s https://rack-hi-puma.puma)" && echo "PASS"
-.PHONY: all release
+.PHONY: release
diff --git a/cmd/puma-dev/main_darwin.go b/cmd/puma-dev/main_darwin.go
index 6a75e1a2..1d730ee3 100644
--- a/cmd/puma-dev/main_darwin.go
+++ b/cmd/puma-dev/main_darwin.go
@@ -25,6 +25,8 @@ var (
fPow = flag.Bool("pow", false, "Mimic pow's settings")
fLaunch = flag.Bool("launchd", false, "Use socket from launchd")
+ fNoServePublicPaths = flag.String("no-serve-public-paths", "", "Disable static file server for specific paths under /public")
+
fSetup = flag.Bool("setup", false, "Run system setup")
fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
@@ -78,6 +80,7 @@ func main() {
LogfilePath: LogFilePath,
Timeout: (*fTimeout).String(),
TlsPort: *fInstallTLS,
+ NoServePublicPaths: *fNoServePublicPaths,
})
if err != nil {
@@ -176,6 +179,10 @@ func main() {
http.Pool = &pool
http.Debug = *fDebug
http.Events = &events
+ if len(*fNoServePublicPaths) > 0 {
+ http.IgnoredStaticPaths = strings.Split(*fNoServePublicPaths, ":")
+ fmt.Printf("* Ignoring files under: public{%s}\n", strings.Join(http.IgnoredStaticPaths, ", "))
+ }
http.Setup()
diff --git a/cmd/puma-dev/main_darwin_test.go b/cmd/puma-dev/main_darwin_test.go
index 0146401b..7d023a5c 100644
--- a/cmd/puma-dev/main_darwin_test.go
+++ b/cmd/puma-dev/main_darwin_test.go
@@ -24,11 +24,12 @@ func TestMainPumaDev_Darwin(t *testing.T) {
defer linkAllTestApps(t, appLinkDir)()
serveErr := configureAndBootPumaDevServer(t, map[string]string{
- "d": "test:puma",
- "dir": appLinkDir,
- "dns-port": "65053",
- "http-port": "65080",
- "https-port": "65443",
+ "d": "test:puma",
+ "dir": appLinkDir,
+ "dns-port": "65053",
+ "http-port": "65080",
+ "https-port": "65443",
+ "no-serve-public-paths": "/packs:/config.json",
})
assert.NoError(t, serveErr)
diff --git a/cmd/puma-dev/main_linux.go b/cmd/puma-dev/main_linux.go
index 7d183be8..1c1e5be9 100644
--- a/cmd/puma-dev/main_linux.go
+++ b/cmd/puma-dev/main_linux.go
@@ -15,14 +15,15 @@ import (
)
var (
- fDebug = flag.Bool("debug", false, "enable debug output")
- fDomains = flag.String("d", "test", "domains to handle, separate with :, defaults to test")
- fHTTPPort = flag.Int("http-port", 9280, "port to listen on http for")
- fTLSPort = flag.Int("https-port", 9283, "port to listen on https for")
- fSysBind = flag.Bool("sysbind", false, "bind to ports 80 and 443")
- fDir = flag.String("dir", "~/.puma-dev", "directory to watch for apps")
- fTimeout = flag.Duration("timeout", 15*60*time.Second, "how long to let an app idle for")
- fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
+ fDebug = flag.Bool("debug", false, "enable debug output")
+ fDir = flag.String("dir", "~/.puma-dev", "directory to watch for apps")
+ fDomains = flag.String("d", "test", "domains to handle, separate with :, defaults to test")
+ fHTTPPort = flag.Int("http-port", 9280, "port to listen on http for")
+ fNoServePublicPaths = flag.String("no-serve-public-paths", "", "Disable static file server for specific paths under /public")
+ fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
+ fSysBind = flag.Bool("sysbind", false, "bind to ports 80 and 443")
+ fTimeout = flag.Duration("timeout", 15*60*time.Second, "how long to let an app idle for")
+ fTLSPort = flag.Int("https-port", 9283, "port to listen on https for")
)
func main() {
@@ -99,6 +100,10 @@ func main() {
http.Pool = &pool
http.Debug = *fDebug
http.Events = &events
+ if len(*fNoServePublicPaths) > 0 {
+ http.IgnoredStaticPaths = strings.Split(*fNoServePublicPaths, ":")
+ fmt.Printf("* Ignoring files under: public{%s}\n", strings.Join(http.IgnoredStaticPaths, ", "))
+ }
http.Setup()
diff --git a/cmd/puma-dev/main_linux_test.go b/cmd/puma-dev/main_linux_test.go
index 96410747..dd288a08 100644
--- a/cmd/puma-dev/main_linux_test.go
+++ b/cmd/puma-dev/main_linux_test.go
@@ -12,9 +12,10 @@ func TestMainPumaDev_Linux(t *testing.T) {
defer linkAllTestApps(t, appLinkDir)()
configureAndBootPumaDevServer(t, map[string]string{
- "dir": appLinkDir,
- "http-port": "65080",
- "https-port": "65443",
+ "dir": appLinkDir,
+ "http-port": "65080",
+ "https-port": "65443",
+ "no-serve-public-paths": "/packs:/config",
})
runPlatformAgnosticTestScenarios(t)
diff --git a/cmd/puma-dev/main_test.go b/cmd/puma-dev/main_test.go
index 4854e37e..2cab7460 100644
--- a/cmd/puma-dev/main_test.go
+++ b/cmd/puma-dev/main_test.go
@@ -296,4 +296,18 @@ func runPlatformAgnosticTestScenarios(t *testing.T) {
assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
})
+
+ t.Run("static-site ignore packs", func(t *testing.T) {
+ reqURL := fmt.Sprintf("http://localhost:%d/packs/site.js", *fHTTPPort)
+ statusHost := "static-site"
+
+ assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
+ })
+
+ t.Run("static-site ignore config", func(t *testing.T) {
+ reqURL := fmt.Sprintf("http://localhost:%d/config.json", *fHTTPPort)
+ statusHost := "static-site"
+
+ assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
+ })
}
diff --git a/dev/http.go b/dev/http.go
index 40509431..7446f6c3 100644
--- a/dev/http.go
+++ b/dev/http.go
@@ -18,11 +18,12 @@ import (
)
type HTTPServer struct {
- Address string
- TLSAddress string
- Pool *AppPool
- Debug bool
- Events *Events
+ Address string
+ TLSAddress string
+ Pool *AppPool
+ Debug bool
+ Events *Events
+ IgnoredStaticPaths []string
mux *pat.PatternServeMux
transport *httpu.Transport
@@ -147,7 +148,7 @@ func (h *HTTPServer) proxyReq(w http.ResponseWriter, req *http.Request) error {
return err
}
- if app.Public && req.URL.Path != "/" {
+ if h.shouldServePublicPathForApp(app, req) {
safeURLPath := path.Clean(req.URL.Path)
path := filepath.Join(app.dir, "public", safeURLPath)
@@ -178,6 +179,29 @@ func (h *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
}
+func (h *HTTPServer) shouldServePublicPathForApp(a *App, req *http.Request) bool {
+ reqPath := path.Clean(req.URL.Path)
+
+ if !a.Public {
+ return false
+ }
+
+ if reqPath == "/" {
+ return false
+ }
+
+ for _, ignoredPath := range h.IgnoredStaticPaths {
+ if strings.HasPrefix(reqPath, ignoredPath) {
+ if h.Debug {
+ fmt.Fprintf(os.Stdout, "Not serving '%s' as it matches a path in no-serve-public-paths\n", reqPath)
+ }
+ return false
+ }
+ }
+
+ return true
+}
+
func (h *HTTPServer) status(w http.ResponseWriter, req *http.Request) {
type appStatus struct {
Scheme string `json:"scheme"`
diff --git a/dev/setup_darwin.go b/dev/setup_darwin.go
index 62ef2ccb..63f7e539 100644
--- a/dev/setup_darwin.go
+++ b/dev/setup_darwin.go
@@ -103,6 +103,7 @@ type InstallIntoSystemArgs struct {
LaunchAgentDirPath string
Domains string
Timeout string
+ NoServePublicPaths string
}
func InstallIntoSystem(config *InstallIntoSystemArgs) error {
@@ -138,6 +139,8 @@ func InstallIntoSystem(config *InstallIntoSystemArgs) error {
%s
-timeout
%s
+ -no-serve-public-paths
+ %s
KeepAlive
@@ -181,7 +184,7 @@ func InstallIntoSystem(config *InstallIntoSystemArgs) error {
err = ioutil.WriteFile(
plist,
- []byte(fmt.Sprintf(userTemplate, binPath, dir, config.Domains, config.Timeout, config.ListenPort, config.TlsPort, logPath, logPath)),
+ []byte(fmt.Sprintf(userTemplate, binPath, dir, config.Domains, config.Timeout, config.NoServePublicPaths, config.ListenPort, config.TlsPort, logPath, logPath)),
0644,
)
diff --git a/dev/setup_darwin_test.go b/dev/setup_darwin_test.go
index 82b242a5..5c7885be 100644
--- a/dev/setup_darwin_test.go
+++ b/dev/setup_darwin_test.go
@@ -49,6 +49,7 @@ func TestInstallIntoSystem_FailsAsSuperuser(t *testing.T) {
TlsPort: 10443,
Domains: "test:localhost",
Timeout: "5s",
+ NoServePublicPaths: "",
ApplinkDirPath: "/tmp/gotest-dummy-applinkdir",
LaunchAgentDirPath: "/tmp/gotest-dummy-launchagent",
LogfilePath: "/tmp/gotest-dummy-logs/dummy.log",
@@ -80,6 +81,7 @@ func installIntoTestContext(t *testing.T) (string, string, func()) {
TlsPort: 10443,
Domains: "test:localhost",
Timeout: "5s",
+ NoServePublicPaths: "",
ApplinkDirPath: appLinkDir,
LaunchAgentDirPath: launchAgentDir,
LogfilePath: logFilePath,
diff --git a/etc/static-hi-puma/public/config.json b/etc/static-hi-puma/public/config.json
new file mode 100644
index 00000000..5df5e437
--- /dev/null
+++ b/etc/static-hi-puma/public/config.json
@@ -0,0 +1,3 @@
+{
+ "path": "/public/config.json"
+}
diff --git a/etc/static-hi-puma/public/packs/site.js b/etc/static-hi-puma/public/packs/site.js
new file mode 100644
index 00000000..3f3ca0e0
--- /dev/null
+++ b/etc/static-hi-puma/public/packs/site.js
@@ -0,0 +1 @@
+/* /public/packs/site.js */