mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-22 03:20:41 +08:00
feat: support CORS Private Network Access (#350)
This commit is contained in:
@@ -152,6 +152,8 @@ cors:
|
|||||||
# Whether or not CORS configuration should be applied. Default is 'false'.
|
# Whether or not CORS configuration should be applied. Default is 'false'.
|
||||||
enabled: true
|
enabled: true
|
||||||
credentials: true
|
credentials: true
|
||||||
|
# Allow Private Network Access preflight requests. Default is 'false'.
|
||||||
|
allow_private_network: false
|
||||||
# The following are the default CORS settings when it is enabled.
|
# The following are the default CORS settings when it is enabled.
|
||||||
allowed_hosts:
|
allowed_hosts:
|
||||||
- '*'
|
- '*'
|
||||||
@@ -240,7 +242,7 @@ A `regex` rule is matched literally against the path, and gets none of the above
|
|||||||
|
|
||||||
### CORS
|
### CORS
|
||||||
|
|
||||||
The `allowed_*` properties are optional, the default value for each of them will be `*`. `exposed_headers` is optional as well, but is not set if not defined. Setting `credentials` to `true` will allow you to:
|
The `allowed_*` properties are optional, the default value for each of them will be `*`. `exposed_headers` is optional as well, but is not set if not defined. Setting `allow_private_network` to `true` to allow Private-Network-Access preflight requests. Setting `credentials` to `true` will allow you to:
|
||||||
|
|
||||||
1. Use `withCredentials = true` in javascript.
|
1. Use `withCredentials = true` in javascript.
|
||||||
2. Use the `username:password@host` syntax.
|
2. Use the `username:password@host` syntax.
|
||||||
|
|||||||
+7
-6
@@ -383,10 +383,11 @@ type Log struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CORS struct {
|
type CORS struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
Credentials bool
|
Credentials bool
|
||||||
AllowedHeaders []string `mapstructure:"allowed_headers"`
|
AllowPrivateNetwork bool `mapstructure:"allow_private_network"`
|
||||||
AllowedHosts []string `mapstructure:"allowed_hosts"`
|
AllowedHeaders []string `mapstructure:"allowed_headers"`
|
||||||
AllowedMethods []string `mapstructure:"allowed_methods"`
|
AllowedHosts []string `mapstructure:"allowed_hosts"`
|
||||||
ExposedHeaders []string `mapstructure:"exposed_headers"`
|
AllowedMethods []string `mapstructure:"allowed_methods"`
|
||||||
|
ExposedHeaders []string `mapstructure:"exposed_headers"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ func TestConfigDefaults(t *testing.T) {
|
|||||||
require.EqualValues(t, []string{"*"}, cfg.CORS.AllowedHosts)
|
require.EqualValues(t, []string{"*"}, cfg.CORS.AllowedHosts)
|
||||||
require.EqualValues(t, []string{"Authorization", "Content-Type", "Content-Range", "Depth", "Destination", "If", "Lock-Token", "Overwrite", "X-Update-Range"}, cfg.CORS.AllowedHeaders)
|
require.EqualValues(t, []string{"Authorization", "Content-Type", "Content-Range", "Depth", "Destination", "If", "Lock-Token", "Overwrite", "X-Update-Range"}, cfg.CORS.AllowedHeaders)
|
||||||
require.EqualValues(t, []string{"COPY", "DELETE", "GET", "HEAD", "LOCK", "MKCOL", "MOVE", "OPTIONS", "PATCH", "POST", "PROPFIND", "PROPPATCH", "PUT", "UNLOCK"}, cfg.CORS.AllowedMethods)
|
require.EqualValues(t, []string{"COPY", "DELETE", "GET", "HEAD", "LOCK", "MKCOL", "MOVE", "OPTIONS", "PATCH", "POST", "PROPFIND", "PROPPATCH", "PUT", "UNLOCK"}, cfg.CORS.AllowedMethods)
|
||||||
|
require.False(t, cfg.CORS.AllowPrivateNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigCascade(t *testing.T) {
|
func TestConfigCascade(t *testing.T) {
|
||||||
@@ -356,6 +357,7 @@ func TestConfigKeys(t *testing.T) {
|
|||||||
cors:
|
cors:
|
||||||
enabled: true
|
enabled: true
|
||||||
credentials: true
|
credentials: true
|
||||||
|
allow_private_network: true
|
||||||
allowed_headers:
|
allowed_headers:
|
||||||
- Depth
|
- Depth
|
||||||
allowed_hosts:
|
allowed_hosts:
|
||||||
@@ -369,6 +371,7 @@ cors:
|
|||||||
|
|
||||||
require.True(t, cfg.CORS.Enabled)
|
require.True(t, cfg.CORS.Enabled)
|
||||||
require.True(t, cfg.CORS.Credentials)
|
require.True(t, cfg.CORS.Credentials)
|
||||||
|
require.True(t, cfg.CORS.AllowPrivateNetwork)
|
||||||
require.EqualValues(t, []string{"Content-Length", "Content-Range"}, cfg.CORS.ExposedHeaders)
|
require.EqualValues(t, []string{"Content-Length", "Content-Range"}, cfg.CORS.ExposedHeaders)
|
||||||
require.EqualValues(t, []string{"Depth"}, cfg.CORS.AllowedHeaders)
|
require.EqualValues(t, []string{"Depth"}, cfg.CORS.AllowedHeaders)
|
||||||
require.EqualValues(t, []string{"http://localhost:8080"}, cfg.CORS.AllowedHosts)
|
require.EqualValues(t, []string{"http://localhost:8080"}, cfg.CORS.AllowedHosts)
|
||||||
|
|||||||
+7
-6
@@ -48,12 +48,13 @@ func NewHandler(c *Config) (http.Handler, error) {
|
|||||||
|
|
||||||
if c.CORS.Enabled {
|
if c.CORS.Enabled {
|
||||||
return cors.New(cors.Options{
|
return cors.New(cors.Options{
|
||||||
AllowCredentials: c.CORS.Credentials,
|
AllowCredentials: c.CORS.Credentials,
|
||||||
AllowedOrigins: c.CORS.AllowedHosts,
|
AllowPrivateNetwork: c.CORS.AllowPrivateNetwork,
|
||||||
AllowedMethods: c.CORS.AllowedMethods,
|
AllowedOrigins: c.CORS.AllowedHosts,
|
||||||
AllowedHeaders: c.CORS.AllowedHeaders,
|
AllowedMethods: c.CORS.AllowedMethods,
|
||||||
ExposedHeaders: c.CORS.ExposedHeaders,
|
AllowedHeaders: c.CORS.AllowedHeaders,
|
||||||
OptionsPassthrough: false,
|
ExposedHeaders: c.CORS.ExposedHeaders,
|
||||||
|
OptionsPassthrough: false,
|
||||||
}).Handler(h), nil
|
}).Handler(h), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,29 @@ func TestServerDefaults(t *testing.T) {
|
|||||||
require.ErrorContains(t, client.Write("/foo.txt", []byte("hello world 2"), 0666), "403")
|
require.ErrorContains(t, client.Write("/foo.txt", []byte("hello world 2"), 0666), "403")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServerCORSPrivateNetwork(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
srv := makeTestServer(t, `
|
||||||
|
cors:
|
||||||
|
enabled: true
|
||||||
|
allow_private_network: true`)
|
||||||
|
defer srv.Close()
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodOptions, srv.URL, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
req.Header.Set("Origin", "https://example.com")
|
||||||
|
req.Header.Set("Access-Control-Request-Method", http.MethodGet)
|
||||||
|
req.Header.Set("Access-Control-Request-Private-Network", "true")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusNoContent, resp.StatusCode)
|
||||||
|
require.Equal(t, "true", resp.Header.Get("Access-Control-Allow-Private-Network"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestServerPartialUpdateOptions(t *testing.T) {
|
func TestServerPartialUpdateOptions(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user