@@ -1828,7 +1828,7 @@ def name(self):
1828
1828
async def handle (self , request , environ , app ):
1829
1829
raise NotImplementedError (self .handle )
1830
1830
1831
- def allow (self , request ):
1831
+ async def allow (self , request , environ , app ):
1832
1832
"""Is this method allowed considering the specified request?"""
1833
1833
return True
1834
1834
@@ -1851,14 +1851,23 @@ async def handle(self, request, environ, app):
1851
1851
1852
1852
1853
1853
class PostMethod (Method ):
1854
+ async def allow (self , request , environ , app ):
1855
+ """POST is only allowed on collections (for RFC5995 add-member)."""
1856
+ unused_href , path , r = app ._get_resource_from_environ (request , environ )
1857
+ if r is None :
1858
+ return False
1859
+ return COLLECTION_RESOURCE_TYPE in r .resource_types
1860
+
1854
1861
async def handle (self , request , environ , app ):
1855
1862
# see RFC5995
1856
1863
new_contents = await _readBody (request )
1857
1864
unused_href , path , r = app ._get_resource_from_environ (request , environ )
1858
1865
if r is None :
1859
1866
return _send_not_found (request )
1860
1867
if COLLECTION_RESOURCE_TYPE not in r .resource_types :
1861
- return _send_method_not_allowed (app ._get_allowed_methods (request ))
1868
+ return _send_method_not_allowed (
1869
+ await app ._get_allowed_methods (request , environ )
1870
+ )
1862
1871
content_type , params = parse_type (request .content_type )
1863
1872
try :
1864
1873
(name , etag ) = await r .create_member (
@@ -1912,7 +1921,9 @@ async def handle(self, request, environ, app):
1912
1921
description = e .description ,
1913
1922
)
1914
1923
except NotImplementedError :
1915
- return _send_method_not_allowed (app ._get_allowed_methods (request ))
1924
+ return _send_method_not_allowed (
1925
+ await app ._get_allowed_methods (request , environ )
1926
+ )
1916
1927
else :
1917
1928
return Response (status = "204 No Content" , headers = [("ETag" , new_etag )])
1918
1929
content_type = request .content_type
@@ -1922,7 +1933,9 @@ async def handle(self, request, environ, app):
1922
1933
# RFC 4918 Section 9.7.1: Return 409 Conflict when intermediate collection is missing
1923
1934
return Response (status = 409 , reason = "Conflict" )
1924
1935
if COLLECTION_RESOURCE_TYPE not in r .resource_types :
1925
- return _send_method_not_allowed (app ._get_allowed_methods (request ))
1936
+ return _send_method_not_allowed (
1937
+ await app ._get_allowed_methods (request , environ )
1938
+ )
1926
1939
try :
1927
1940
(new_name , new_etag ) = await r .create_member (
1928
1941
name ,
@@ -2466,7 +2479,9 @@ async def handle(self, request, environ, app):
2466
2479
raise UnsupportedMediaType (base_content_type )
2467
2480
href , path , resource = app ._get_resource_from_environ (request , environ )
2468
2481
if resource is not None :
2469
- return _send_method_not_allowed (app ._get_allowed_methods (request ))
2482
+ return _send_method_not_allowed (
2483
+ await app ._get_allowed_methods (request , environ )
2484
+ )
2470
2485
try :
2471
2486
resource = app .backend .create_collection (path )
2472
2487
except FileNotFoundError :
@@ -2506,7 +2521,7 @@ async def handle(self, request, environ, app):
2506
2521
return _send_not_found (request )
2507
2522
dav_features = app ._get_dav_features (r )
2508
2523
headers .append (("DAV" , ", " .join (dav_features )))
2509
- allowed_methods = app ._get_allowed_methods (request )
2524
+ allowed_methods = await app ._get_allowed_methods (request , environ )
2510
2525
headers .append (("Allow" , ", " .join (allowed_methods )))
2511
2526
2512
2527
# RFC7231 requires that if there is no response body,
@@ -2690,19 +2705,21 @@ def _get_dav_features(self, resource):
2690
2705
"quota" ,
2691
2706
]
2692
2707
2693
- def _get_allowed_methods (self , request ):
2708
+ async def _get_allowed_methods (self , request , environ ):
2694
2709
"""List of supported methods on this endpoint."""
2695
2710
ret = []
2696
2711
for name in sorted (self .methods .keys ()):
2697
- if self .methods [name ].allow (request ):
2712
+ if await self .methods [name ].allow (request , environ , self ):
2698
2713
ret .append (name )
2699
2714
return ret
2700
2715
2701
2716
async def _handle_request (self , request , environ , start_response = None ):
2702
2717
try :
2703
2718
do = self .methods [request .method ]
2704
2719
except KeyError :
2705
- return _send_method_not_allowed (self ._get_allowed_methods (request ))
2720
+ return _send_method_not_allowed (
2721
+ await self ._get_allowed_methods (request , environ )
2722
+ )
2706
2723
try :
2707
2724
return await do .handle (request , environ , self )
2708
2725
except BadRequestError as e :
0 commit comments