Skip to content

Commit 87b05a8

Browse files
nonrationalPezmc
andauthored
add no-serve-public-paths flag (#262)
* allow config to ignore static paths inside /public, upgrade ci add static files to try to resolve but ignore add configuration for linux and macos add field broken impl. clean up bad impl if request path should be ignored by the static server, don't serve it forgotten flag rename slightly better description upgrades * Add logging of no-serve-public-paths and add -install support for it (#263) * Add logging of no-serve-public-paths settings * Add the NoServePublicPaths settings to the plist template * Fix missing , causing test failures Co-authored-by: Pez Cuckow <[email protected]>
1 parent 458cc5c commit 87b05a8

File tree

12 files changed

+95
-26
lines changed

12 files changed

+95
-26
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ jobs:
1212
strategy:
1313
matrix:
1414
os: [macos-latest, ubuntu-latest]
15-
go-version: [1.13.x, 1.14.x]
16-
ruby-version: [2.5]
15+
go-version: [1.14, 1.15]
16+
ruby-version: [2.7]
1717

1818
name: ${{ matrix.os }} / go-${{ matrix.go-version }}
1919
steps:

Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ release:
2525
test:
2626
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
2727

28+
clean-test:
29+
rm -rf ~/.gotest-macos-puma-dev
30+
31+
test-macos-filesystem-setup:
32+
sudo mkdir -p /etc/resolver;
33+
sudo chmod 0775 /etc/resolver;
34+
sudo chown :staff /etc/resolver;
35+
2836
coverage: test
2937
go tool cover -html=coverage.out -o coverage.html
3038

@@ -50,4 +58,4 @@ test-macos-manual-setup-install: clean build
5058
test -f "$$HOME/Library/Logs/puma-dev.log"
5159
test 'Hi Puma!' == "$$(curl -s https://rack-hi-puma.puma)" && echo "PASS"
5260

53-
.PHONY: all release
61+
.PHONY: release

cmd/puma-dev/main_darwin.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ var (
2525
fPow = flag.Bool("pow", false, "Mimic pow's settings")
2626
fLaunch = flag.Bool("launchd", false, "Use socket from launchd")
2727

28+
fNoServePublicPaths = flag.String("no-serve-public-paths", "", "Disable static file server for specific paths under /public")
29+
2830
fSetup = flag.Bool("setup", false, "Run system setup")
2931
fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
3032

@@ -78,6 +80,7 @@ func main() {
7880
LogfilePath: LogFilePath,
7981
Timeout: (*fTimeout).String(),
8082
TlsPort: *fInstallTLS,
83+
NoServePublicPaths: *fNoServePublicPaths,
8184
})
8285

8386
if err != nil {
@@ -176,6 +179,10 @@ func main() {
176179
http.Pool = &pool
177180
http.Debug = *fDebug
178181
http.Events = &events
182+
if len(*fNoServePublicPaths) > 0 {
183+
http.IgnoredStaticPaths = strings.Split(*fNoServePublicPaths, ":")
184+
fmt.Printf("* Ignoring files under: public{%s}\n", strings.Join(http.IgnoredStaticPaths, ", "))
185+
}
179186

180187
http.Setup()
181188

cmd/puma-dev/main_darwin_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ func TestMainPumaDev_Darwin(t *testing.T) {
2424
defer linkAllTestApps(t, appLinkDir)()
2525

2626
serveErr := configureAndBootPumaDevServer(t, map[string]string{
27-
"d": "test:puma",
28-
"dir": appLinkDir,
29-
"dns-port": "65053",
30-
"http-port": "65080",
31-
"https-port": "65443",
27+
"d": "test:puma",
28+
"dir": appLinkDir,
29+
"dns-port": "65053",
30+
"http-port": "65080",
31+
"https-port": "65443",
32+
"no-serve-public-paths": "/packs:/config.json",
3233
})
3334

3435
assert.NoError(t, serveErr)

cmd/puma-dev/main_linux.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ import (
1515
)
1616

1717
var (
18-
fDebug = flag.Bool("debug", false, "enable debug output")
19-
fDomains = flag.String("d", "test", "domains to handle, separate with :, defaults to test")
20-
fHTTPPort = flag.Int("http-port", 9280, "port to listen on http for")
21-
fTLSPort = flag.Int("https-port", 9283, "port to listen on https for")
22-
fSysBind = flag.Bool("sysbind", false, "bind to ports 80 and 443")
23-
fDir = flag.String("dir", "~/.puma-dev", "directory to watch for apps")
24-
fTimeout = flag.Duration("timeout", 15*60*time.Second, "how long to let an app idle for")
25-
fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
18+
fDebug = flag.Bool("debug", false, "enable debug output")
19+
fDir = flag.String("dir", "~/.puma-dev", "directory to watch for apps")
20+
fDomains = flag.String("d", "test", "domains to handle, separate with :, defaults to test")
21+
fHTTPPort = flag.Int("http-port", 9280, "port to listen on http for")
22+
fNoServePublicPaths = flag.String("no-serve-public-paths", "", "Disable static file server for specific paths under /public")
23+
fStop = flag.Bool("stop", false, "Stop all puma-dev servers")
24+
fSysBind = flag.Bool("sysbind", false, "bind to ports 80 and 443")
25+
fTimeout = flag.Duration("timeout", 15*60*time.Second, "how long to let an app idle for")
26+
fTLSPort = flag.Int("https-port", 9283, "port to listen on https for")
2627
)
2728

2829
func main() {
@@ -99,6 +100,10 @@ func main() {
99100
http.Pool = &pool
100101
http.Debug = *fDebug
101102
http.Events = &events
103+
if len(*fNoServePublicPaths) > 0 {
104+
http.IgnoredStaticPaths = strings.Split(*fNoServePublicPaths, ":")
105+
fmt.Printf("* Ignoring files under: public{%s}\n", strings.Join(http.IgnoredStaticPaths, ", "))
106+
}
102107

103108
http.Setup()
104109

cmd/puma-dev/main_linux_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ func TestMainPumaDev_Linux(t *testing.T) {
1212
defer linkAllTestApps(t, appLinkDir)()
1313

1414
configureAndBootPumaDevServer(t, map[string]string{
15-
"dir": appLinkDir,
16-
"http-port": "65080",
17-
"https-port": "65443",
15+
"dir": appLinkDir,
16+
"http-port": "65080",
17+
"https-port": "65443",
18+
"no-serve-public-paths": "/packs:/config",
1819
})
1920

2021
runPlatformAgnosticTestScenarios(t)

cmd/puma-dev/main_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,18 @@ func runPlatformAgnosticTestScenarios(t *testing.T) {
296296

297297
assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
298298
})
299+
300+
t.Run("static-site ignore packs", func(t *testing.T) {
301+
reqURL := fmt.Sprintf("http://localhost:%d/packs/site.js", *fHTTPPort)
302+
statusHost := "static-site"
303+
304+
assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
305+
})
306+
307+
t.Run("static-site ignore config", func(t *testing.T) {
308+
reqURL := fmt.Sprintf("http://localhost:%d/config.json", *fHTTPPort)
309+
statusHost := "static-site"
310+
311+
assert.Equal(t, "rack wuz here", getURLWithHost(t, reqURL, statusHost))
312+
})
299313
}

dev/http.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ import (
1818
)
1919

2020
type HTTPServer struct {
21-
Address string
22-
TLSAddress string
23-
Pool *AppPool
24-
Debug bool
25-
Events *Events
21+
Address string
22+
TLSAddress string
23+
Pool *AppPool
24+
Debug bool
25+
Events *Events
26+
IgnoredStaticPaths []string
2627

2728
mux *pat.PatternServeMux
2829
transport *httpu.Transport
@@ -147,7 +148,7 @@ func (h *HTTPServer) proxyReq(w http.ResponseWriter, req *http.Request) error {
147148
return err
148149
}
149150

150-
if app.Public && req.URL.Path != "/" {
151+
if h.shouldServePublicPathForApp(app, req) {
151152
safeURLPath := path.Clean(req.URL.Path)
152153
path := filepath.Join(app.dir, "public", safeURLPath)
153154

@@ -178,6 +179,29 @@ func (h *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
178179
}
179180
}
180181

182+
func (h *HTTPServer) shouldServePublicPathForApp(a *App, req *http.Request) bool {
183+
reqPath := path.Clean(req.URL.Path)
184+
185+
if !a.Public {
186+
return false
187+
}
188+
189+
if reqPath == "/" {
190+
return false
191+
}
192+
193+
for _, ignoredPath := range h.IgnoredStaticPaths {
194+
if strings.HasPrefix(reqPath, ignoredPath) {
195+
if h.Debug {
196+
fmt.Fprintf(os.Stdout, "Not serving '%s' as it matches a path in no-serve-public-paths\n", reqPath)
197+
}
198+
return false
199+
}
200+
}
201+
202+
return true
203+
}
204+
181205
func (h *HTTPServer) status(w http.ResponseWriter, req *http.Request) {
182206
type appStatus struct {
183207
Scheme string `json:"scheme"`

dev/setup_darwin.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ type InstallIntoSystemArgs struct {
103103
LaunchAgentDirPath string
104104
Domains string
105105
Timeout string
106+
NoServePublicPaths string
106107
}
107108

108109
func InstallIntoSystem(config *InstallIntoSystemArgs) error {
@@ -138,6 +139,8 @@ func InstallIntoSystem(config *InstallIntoSystemArgs) error {
138139
<string>%s</string>
139140
<string>-timeout</string>
140141
<string>%s</string>
142+
<string>-no-serve-public-paths</string>
143+
<string>%s</string>
141144
</array>
142145
<key>KeepAlive</key>
143146
<true/>
@@ -181,7 +184,7 @@ func InstallIntoSystem(config *InstallIntoSystemArgs) error {
181184

182185
err = ioutil.WriteFile(
183186
plist,
184-
[]byte(fmt.Sprintf(userTemplate, binPath, dir, config.Domains, config.Timeout, config.ListenPort, config.TlsPort, logPath, logPath)),
187+
[]byte(fmt.Sprintf(userTemplate, binPath, dir, config.Domains, config.Timeout, config.NoServePublicPaths, config.ListenPort, config.TlsPort, logPath, logPath)),
185188
0644,
186189
)
187190

dev/setup_darwin_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func TestInstallIntoSystem_FailsAsSuperuser(t *testing.T) {
4949
TlsPort: 10443,
5050
Domains: "test:localhost",
5151
Timeout: "5s",
52+
NoServePublicPaths: "",
5253
ApplinkDirPath: "/tmp/gotest-dummy-applinkdir",
5354
LaunchAgentDirPath: "/tmp/gotest-dummy-launchagent",
5455
LogfilePath: "/tmp/gotest-dummy-logs/dummy.log",
@@ -80,6 +81,7 @@ func installIntoTestContext(t *testing.T) (string, string, func()) {
8081
TlsPort: 10443,
8182
Domains: "test:localhost",
8283
Timeout: "5s",
84+
NoServePublicPaths: "",
8385
ApplinkDirPath: appLinkDir,
8486
LaunchAgentDirPath: launchAgentDir,
8587
LogfilePath: logFilePath,

0 commit comments

Comments
 (0)