-
-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
453 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<meta charset='utf-8'> | ||
<meta http-equiv='X-UA-Compatible' content='IE=edge'> | ||
<title>WsgiDAV CORS Test</title> | ||
<meta name='viewport' content='width=device-width, initial-scale=1'> | ||
<link rel='stylesheet' type='text/css' media='screen' href='main.css'> | ||
<script defer src='main.js'></script> | ||
<!-- <script defer src='///localhost:5000/main.js'></script> --> | ||
</head> | ||
|
||
<body> | ||
<p> | ||
<ul> | ||
<li>Load ./main.js</li> | ||
<li>Load ./main.js from :5000</li> | ||
<li>Local image: <img src="logo.png"></li> | ||
<li>image on :5000: <img src="///localhost:5000/logo.png"></li> | ||
<li>Edit docx locally: | ||
<a href="Lotosblütenstengel (蓮花莖).docx">Lotosblütenstengel (蓮花莖).docx</a> | ||
</li> | ||
<li>Edit docx on :5000: | ||
<a href="///localhost:5000/Lotosblütenstengel (蓮花莖).docx">Lotosblütenstengel (蓮花莖).docx :5000</a> | ||
</li> | ||
</ul> | ||
</p> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"value": "foo", | ||
"values": [1, 2, 3] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
body { | ||
background-color: antiquewhite; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
(function () { | ||
console.log("main.js loaded."); | ||
console.log("Loading 'data.json'...", window.origin, window.location); | ||
fetch("data.json") | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
.then((data) => { | ||
console.log("Loading 'data.json': ", data); | ||
}); | ||
|
||
// Calling a cross-origin target with a non-tandrad header should trigger a | ||
// preflight request: | ||
fetch("//localhost:5000/data.json", { | ||
headers: { "X-PINGOTHER": "pingpong" }, | ||
}) | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
.then((data) => { | ||
console.log("Loading 'data.json' from :5000: ", data); | ||
}); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# -*- coding: utf-8 -*- | ||
# (c) 2009-2021 Martin Wendt and contributors; see WsgiDAV https://github.com/mar10/wsgidav | ||
# Licensed under the MIT license: | ||
# http://www.opensource.org/licenses/mit-license.php | ||
""" | ||
WSGI middleware used for CORS support (optional). | ||
Respond to CORS preflight OPTIONS request and inject CORS headers. | ||
""" | ||
from wsgidav import util | ||
from wsgidav.mw.base_mw import BaseMiddleware | ||
|
||
__docformat__ = "reStructuredText" | ||
|
||
_logger = util.get_module_logger(__name__) | ||
|
||
|
||
class Cors(BaseMiddleware): | ||
def __init__(self, wsgidav_app, next_app, config): | ||
super().__init__(wsgidav_app, next_app, config) | ||
opts = config.get("cors", None) | ||
if opts is None: | ||
opts = {} | ||
|
||
allow_origins = opts.get("allow_origin") | ||
if type(allow_origins) is str: | ||
allow_origins = allow_origins.strip() | ||
if allow_origins != "*": | ||
allow_origins = [allow_origins] | ||
elif allow_origins: | ||
allow_origins = [ao.strip() for ao in allow_origins] | ||
|
||
allow_headers = ",".join(util.to_set(opts.get("allow_headers"))) | ||
allow_methods = ",".join(util.to_set(opts.get("allow_methods"))) | ||
expose_headers = ",".join(util.to_set(opts.get("expose_headers"))) | ||
allow_credentials = opts.get("allow_credentials", False) | ||
max_age = opts.get("max_age") | ||
always_headers = opts.get("add_always") | ||
|
||
add_always = [] | ||
if allow_credentials: | ||
add_always.append(("Access-Control-Allow-Credentials", "true")) | ||
if always_headers: | ||
if type(always_headers) is not dict: | ||
raise ValueError( | ||
f"cors.add_always must be a list a dict: {always_headers}" | ||
) | ||
for n, v in always_headers.items(): | ||
add_always.append((n, v)) | ||
|
||
add_non_preflight = add_always[:] | ||
if expose_headers: | ||
add_always.append(("Access-Control-Expose-Headers", expose_headers)) | ||
|
||
add_preflight = add_always[:] | ||
if allow_headers: | ||
add_preflight.append(("Access-Control-Allow-Headers", allow_headers)) | ||
if allow_methods: | ||
add_preflight.append(("Access-Control-Allow-Methods", allow_methods)) | ||
if max_age: | ||
add_preflight.append(("Access-Control-Max-Age", str(int(max_age)))) | ||
|
||
self.non_preflight_headers = add_non_preflight | ||
self.preflight_headers = add_preflight | ||
#: Either '*' or al list of origins | ||
self.allow_origins = allow_origins | ||
|
||
def __repr__(self): | ||
allow_origin = self.get_config("cors.allow_origin", None) | ||
return f"{self.__module__}.{self.__class__.__name__}({allow_origin})" | ||
|
||
def is_disabled(self): | ||
"""Optionally return True to skip this module on startup.""" | ||
return not self.get_config("cors.allow_origin", False) | ||
|
||
def __call__(self, environ, start_response): | ||
method = environ["REQUEST_METHOD"].upper() | ||
origin = environ.get("HTTP_ORIGIN") | ||
ac_req_meth = environ.get("HTTP_ACCESS_CONTROL_REQUEST_METHOD") | ||
ac_req_headers = environ.get("HTTP_ACCESS_CONTROL_REQUEST_HEADERS") | ||
|
||
acao_headers = None | ||
if self.allow_origins == "*": | ||
acao_headers = [("Access-Control-Allow-Origin", "*")] | ||
elif origin in self.allow_origins: | ||
acao_headers = [ | ||
("Access-Control-Allow-Origin", origin), | ||
("Vary", "Origin"), | ||
] | ||
|
||
if acao_headers: | ||
_logger.debug( | ||
f"Granted CORS {method} {environ['PATH_INFO']!r} " | ||
f"{ac_req_meth!r}, headers: {ac_req_headers}, origin: {origin!r}" | ||
) | ||
else: | ||
# Deny (still return 200 on preflight) | ||
_logger.warning( | ||
f"Denied CORS {method} {environ['PATH_INFO']!r} " | ||
f"{ac_req_meth!r}, headers: {ac_req_headers}, origin: {origin!r}" | ||
) | ||
|
||
is_preflight = method == "OPTIONS" and ac_req_meth is not None | ||
|
||
# Handle preflight request | ||
if is_preflight: | ||
# Always return 2xx, but only add Access-Control-Allow-Origin etc. | ||
# if Origin is allowed | ||
resp_headers = [ | ||
("Content-Length", "0"), | ||
("Date", util.get_rfc1123_time()), | ||
] | ||
if acao_headers: | ||
resp_headers += acao_headers + self.preflight_headers | ||
|
||
start_response("204 No Content", resp_headers) | ||
return [b""] | ||
|
||
# non_preflight CORS request | ||
def wrapped_start_response(status, headers, exc_info=None): | ||
if acao_headers: | ||
util.update_headers_in_place( | ||
headers, | ||
acao_headers + self.non_preflight_headers, | ||
) | ||
start_response(status, headers, exc_info) | ||
|
||
return self.next_app(environ, wrapped_start_response) |
Oops, something went wrong.