c6e9c5e37f62c90dd15aeb232d0960460ab0d5d6
2 # Copyright 2016 RIFT.IO Inc
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Taken from http://stackoverflow.com/a/27786580
22 from urllib
.parse
import urlparse
25 class LocalFileAdapter(requests
.adapters
.BaseAdapter
):
26 """Protocol Adapter to allow Requests to GET file:// URLs
28 @todo: Properly handle non-empty hostname portions.
32 def _chkpath(method
, path
):
33 """Return an HTTP status for the given filesystem path."""
34 if method
.lower() in ('put', 'delete'):
35 return 501, "Not Implemented" # TODO
36 elif method
.lower() not in ('get', 'head'):
37 return 405, "Method Not Allowed"
38 elif os
.path
.isdir(path
):
39 return 400, "Path Not A File"
40 elif not os
.path
.isfile(path
):
41 return 404, "File Not Found"
42 elif not os
.access(path
, os
.R_OK
):
43 return 403, "Access Denied"
47 def send(self
, req
, **kwargs
): # pylint: disable=unused-argument
48 """Return the file specified by the given request
50 @type req: C{PreparedRequest}
51 @todo: Should I bother filling `response.headers` and processing
52 If-Modified-Since and friends using `os.stat`?
55 log
= logging
.getLogger('rw-mano-log')
56 log
.debug("Request: {}".format(req
))
58 url
= urlparse(req
.path_url
)
59 path
= os
.path
.normcase(os
.path
.normpath(url
.path
))
60 response
= requests
.Response()
62 response
.status_code
, response
.reason
= self
._chkpath
(req
.method
, path
)
63 log
.debug("Response {}: {}".format(response
.status_code
, response
.reason
))
64 if response
.status_code
== 200 and req
.method
.lower() != 'head':
66 response
.raw
= open(path
, 'rb')
67 except (OSError, IOError) as err
:
68 response
.status_code
= 500
69 response
.reason
= str(err
)
71 if isinstance(req
.url
, bytes
):
72 response
.url
= req
.url
.decode('utf-8')
74 response
.url
= req
.url
76 response
.request
= req
77 response
.connection
= self
80 log
.debug("Response {}: {}".format(response
.status_code
, response
))