Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
flaskdav
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
flaskdav
Commits
5ef4c869
Commit
5ef4c869
authored
Dec 09, 2015
by
iv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add possibility to specify the local file system directory + fix uri2local/local2uri.
parent
819484e1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
47 additions
and
38 deletions
+47
-38
flaskdav.py
flaskdav.py
+27
-18
utils.py
utils.py
+20
-20
No files found.
flaskdav.py
View file @
5ef4c869
...
@@ -10,8 +10,6 @@ import os
...
@@ -10,8 +10,6 @@ import os
app
=
Flask
(
__name__
.
split
(
'.'
)[
0
])
app
=
Flask
(
__name__
.
split
(
'.'
)[
0
])
app
.
config
.
from_object
(
__name__
)
app
.
config
.
from_object
(
__name__
)
FS_PATH
=
'/tmp/couscous'
ALLOWED_METHODS
=
[
'GET'
,
'PUT'
,
'PROPFIND'
,
'PROPPATCH'
,
'MKCOL'
,
'DELETE'
,
ALLOWED_METHODS
=
[
'GET'
,
'PUT'
,
'PROPFIND'
,
'PROPPATCH'
,
'MKCOL'
,
'DELETE'
,
'COPY'
,
'MOVE'
,
'OPTIONS'
]
'COPY'
,
'MOVE'
,
'OPTIONS'
]
...
@@ -73,7 +71,6 @@ def is_authorized(cookies_list):
...
@@ -73,7 +71,6 @@ def is_authorized(cookies_list):
return
True
return
True
return
verify_cookie
(
base64_encode
(
origin
))
return
verify_cookie
(
base64_encode
(
origin
))
FS_HANDLER
=
utils
.
FilesystemHandler
(
FS_PATH
,
URI_BEGINNING_PATH
[
'webdav'
])
@
app
.
before_request
@
app
.
before_request
def
before_request
():
def
before_request
():
...
@@ -106,7 +103,6 @@ def before_request():
...
@@ -106,7 +103,6 @@ def before_request():
# tells the world we do CORS when authorized
# tells the world we do CORS when authorized
debug
(
'OPTIONS request special header: '
+
specific_header
)
debug
(
'OPTIONS request special header: '
+
specific_header
)
headers
[
'Access-Control-Request-Headers'
]
=
specific_header
headers
[
'Access-Control-Request-Headers'
]
=
specific_header
headers
[
'Access-Control-Allow-Origin'
]
=
origin
headers
[
'Access-Control-Allow-Methods'
]
=
', '
.
join
(
ALLOWED_METHODS
)
headers
[
'Access-Control-Allow-Methods'
]
=
', '
.
join
(
ALLOWED_METHODS
)
response
=
make_response
(
content
,
200
)
response
=
make_response
(
content
,
200
)
response
.
headers
=
headers
response
.
headers
=
headers
...
@@ -132,9 +128,18 @@ class WebDAV(MethodView):
...
@@ -132,9 +128,18 @@ class WebDAV(MethodView):
self
.
baseuri
=
URI_BEGINNING_PATH
[
'webdav'
]
self
.
baseuri
=
URI_BEGINNING_PATH
[
'webdav'
]
def
get_body
(
self
):
def
get_body
(
self
):
""" get the request's body """
"""
get the request's body
"""
request_data
=
request
.
data
request_data
=
request
.
data
if
not
request_data
and
int
(
request
.
headers
[
'Content-length'
]):
try
:
length
=
int
(
request
.
headers
.
get
(
'Content-length'
))
except
ValueError
:
length
=
0
if
not
request_data
and
length
:
try
:
try
:
request_data
=
request
.
form
.
items
()[
0
][
0
]
request_data
=
request
.
form
.
items
()[
0
][
0
]
except
IndexError
:
except
IndexError
:
...
@@ -147,15 +152,15 @@ class WebDAV(MethodView):
...
@@ -147,15 +152,15 @@ class WebDAV(MethodView):
return headers + body (resource content or list of resources)
return headers + body (resource content or list of resources)
"""
"""
response
=
g
.
response
response
=
g
.
response
localpath
=
FS_HANDLER
.
uri2local
(
pathname
)
localpath
=
app
.
fs_handler
.
uri2local
(
request
.
path
)
# TODO if into a collection => list of the ressources
# TODO if into a collection => list of the ressources
data
=
''
data
=
''
if
os
.
path
.
isdir
(
localpath
):
if
os
.
path
.
isdir
(
localpath
):
data
=
"
\
n
"
.
join
(
FS_HANDLER
.
get_children
(
pathname
))
data
=
"
\
n
"
.
join
(
app
.
fs_handler
.
get_children
(
request
.
path
))
elif
os
.
path
.
isfile
(
localpath
):
elif
os
.
path
.
isfile
(
localpath
):
try
:
try
:
data_resource
=
FS_HANDLER
.
get_data
(
pathname
)
data_resource
=
app
.
fs_handler
.
get_data
(
request
.
path
)
# TODO send large response by chunks would be nice for big
# TODO send large response by chunks would be nice for big
# files... http://flask.pocoo.org/docs/0.10/patterns/streaming/
# files... http://flask.pocoo.org/docs/0.10/patterns/streaming/
data
=
data_resource
.
read
()
data
=
data_resource
.
read
()
...
@@ -177,7 +182,7 @@ class WebDAV(MethodView):
...
@@ -177,7 +182,7 @@ class WebDAV(MethodView):
response
=
g
.
response
response
=
g
.
response
localpath
=
FS_HANDLER
.
uri2local
(
pathname
)
localpath
=
app
.
fs_handler
.
uri2local
(
request
.
path
)
# TODO: get large request chunk by chunk...
# TODO: get large request chunk by chunk...
request_body
=
self
.
get_body
()
request_body
=
self
.
get_body
()
if
request_body
is
None
:
if
request_body
is
None
:
...
@@ -185,7 +190,7 @@ class WebDAV(MethodView):
...
@@ -185,7 +190,7 @@ class WebDAV(MethodView):
elif
os
.
path
.
isdir
(
localpath
):
elif
os
.
path
.
isdir
(
localpath
):
response
.
status
=
'405'
response
.
status
=
'405'
else
:
else
:
response
.
status
=
str
(
FS_HANDLER
.
put
(
pathname
,
request_body
))
response
.
status
=
str
(
app
.
fs_handler
.
put
(
request
.
path
,
request_body
))
return
response
return
response
...
@@ -214,7 +219,7 @@ class WebDAV(MethodView):
...
@@ -214,7 +219,7 @@ class WebDAV(MethodView):
response
=
g
.
response
response
=
g
.
response
response
.
status
=
str
(
FS_HANDLER
.
mkcol
(
pathname
))
response
.
status
=
str
(
app
.
fs_handler
.
mkcol
(
request
.
path
))
return
response
return
response
def
delete
(
self
,
pathname
):
def
delete
(
self
,
pathname
):
...
@@ -225,7 +230,7 @@ class WebDAV(MethodView):
...
@@ -225,7 +230,7 @@ class WebDAV(MethodView):
response
=
g
.
response
response
=
g
.
response
localpath
=
FS_HANDLER
.
uri2local
(
pathname
)
localpath
=
app
.
fs_handler
.
uri2local
(
request
.
path
)
if
not
os
.
path
.
exists
(
localpath
):
if
not
os
.
path
.
exists
(
localpath
):
response
.
status
=
'404'
response
.
status
=
'404'
if
os
.
path
.
isdir
(
localpath
):
if
os
.
path
.
isdir
(
localpath
):
...
@@ -250,11 +255,11 @@ class WebDAV(MethodView):
...
@@ -250,11 +255,11 @@ class WebDAV(MethodView):
response
=
g
.
response
response
=
g
.
response
localpath
=
FS_HANDLER
.
uri2local
(
pathname
)
localpath
=
app
.
fs_handler
.
uri2local
(
request
.
path
)
destination
=
request
.
headers
[
'Destination'
]
destination
=
request
.
headers
[
'Destination'
]
host
=
request
.
headers
[
'Host'
]
host
=
request
.
headers
[
'Host'
]
destination
=
destination
.
split
(
host
+
URI_BEGINNING_PATH
[
'webdav'
],
1
)[
-
1
]
destination
=
destination
.
split
(
host
+
URI_BEGINNING_PATH
[
'webdav'
],
1
)[
-
1
]
destination_path
=
FS_HANDLER
.
uri2local
(
destination
)
destination_path
=
app
.
fs_handler
.
uri2local
(
destination
)
debug
(
'COPY: %s -> %s'
%
(
localpath
,
destination_path
))
debug
(
'COPY: %s -> %s'
%
(
localpath
,
destination_path
))
if
not
os
.
path
.
exists
(
localpath
):
if
not
os
.
path
.
exists
(
localpath
):
...
@@ -290,10 +295,10 @@ class WebDAV(MethodView):
...
@@ -290,10 +295,10 @@ class WebDAV(MethodView):
response
=
g
.
response
response
=
g
.
response
copy_response
=
self
.
copy
(
pathname
)
copy_response
=
self
.
copy
(
request
.
path
)
response
.
status
=
copy_response
.
status
response
.
status
=
copy_response
.
status
if
copy_response
.
status
==
'201'
or
copy_response
.
status
==
'204'
:
if
copy_response
.
status
==
'201'
or
copy_response
.
status
==
'204'
:
delete_response
=
self
.
delete
(
pathname
)
delete_response
=
self
.
delete
(
request
.
path
)
if
delete_response
.
status
!=
'204'
:
if
delete_response
.
status
!=
'204'
:
response
.
status
=
'424'
response
.
status
=
'424'
return
response
return
response
...
@@ -370,11 +375,12 @@ def links():
...
@@ -370,11 +375,12 @@ def links():
return
'TODO: nice set of links to useful local pages: %s <br> + HOWTO'
%
the_links
return
'TODO: nice set of links to useful local pages: %s <br> + HOWTO'
%
the_links
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
import
argparse
import
argparse
parser
=
argparse
.
ArgumentParser
(
description
=
'Run a local webdav/HTTP server.'
)
parser
=
argparse
.
ArgumentParser
(
description
=
'Run a local webdav/HTTP server.'
)
parser
.
add_argument
(
'-d'
,
'--debug'
,
action
=
'store_true'
,
parser
.
add_argument
(
'-d'
,
'--debug'
,
action
=
'store_true'
,
help
=
'Run flask app in debug mode (not recommended for use in production).'
)
help
=
'Run flask app in debug mode (not recommended for use in production).'
)
parser
.
add_argument
(
'-p'
,
'--path'
,
action
=
'store'
,
help
=
'Run flask app in debug mode (not recommended for use in production).'
)
https
=
parser
.
add_argument_group
(
'HTTPS'
,
'Arguments required for HTTPS support.'
)
https
=
parser
.
add_argument_group
(
'HTTPS'
,
'Arguments required for HTTPS support.'
)
https
.
add_argument
(
'--key'
,
type
=
str
,
action
=
'store'
,
default
=
None
,
https
.
add_argument
(
'--key'
,
type
=
str
,
action
=
'store'
,
default
=
None
,
help
=
'SSL/TLS private key. Required for HTTPS support.'
)
help
=
'SSL/TLS private key. Required for HTTPS support.'
)
...
@@ -384,6 +390,9 @@ if __name__ == '__main__':
...
@@ -384,6 +390,9 @@ if __name__ == '__main__':
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
app
.
debug
=
args
.
debug
app
.
debug
=
args
.
debug
app
.
fs_path
=
'/tmp/'
if
not
args
.
path
else
args
.
path
app
.
fs_handler
=
utils
.
FilesystemHandler
(
app
.
fs_path
,
URI_BEGINNING_PATH
[
'webdav'
])
context
=
None
context
=
None
if
args
.
key
and
args
.
cert
and
os
.
path
.
isfile
(
args
.
key
)
and
os
.
path
.
isfile
(
args
.
cert
):
if
args
.
key
and
args
.
cert
and
os
.
path
.
isfile
(
args
.
key
)
and
os
.
path
.
isfile
(
args
.
cert
):
from
OpenSSL
import
SSL
from
OpenSSL
import
SSL
...
...
utils.py
View file @
5ef4c869
...
@@ -58,9 +58,9 @@ class FilesystemHandler():
...
@@ -58,9 +58,9 @@ class FilesystemHandler():
""" Sets the directory """
""" Sets the directory """
if
not
os
.
path
.
isdir
(
path
):
if
not
os
.
path
.
isdir
(
path
):
raise
Exception
,
'%s
not
must be a directory!'
%
path
raise
Exception
,
'%s must be a directory!'
%
path
self
.
directory
=
path
self
.
directory
=
os
.
path
.
normpath
(
path
)
def
setBaseURI
(
self
,
uri
):
def
setBaseURI
(
self
,
uri
):
""" Sets the base uri """
""" Sets the base uri """
...
@@ -73,21 +73,21 @@ class FilesystemHandler():
...
@@ -73,21 +73,21 @@ class FilesystemHandler():
def
uri2local
(
self
,
uri
):
def
uri2local
(
self
,
uri
):
""" map uri in baseuri and local part """
""" map uri in baseuri and local part """
path
=
urlparse
.
urlparse
(
uri
).
path
.
strip
(
'/'
)
path
=
os
.
path
.
normpath
(
uri
)
fileloc
=
path
if
path
.
startswith
(
self
.
baseuri
):
filename
=
os
.
path
.
join
(
self
.
directory
,
fileloc
)
path
=
path
[
len
(
self
.
baseuri
):]
file
name
=
os
.
path
.
normpath
(
filename
)
file
path
=
os
.
path
.
join
(
self
.
directory
,
path
)
print
(
'uri2local: %s -> %s'
%
(
uri
,
filename
)
)
filepath
=
os
.
path
.
normpath
(
filepath
)
return
filename
#print('uri2local: %s -> %s' % (uri, filepath))
return
filepath
def
local2uri
(
self
,
filename
):
""" map local filename to self.baseuri """
def
local2uri
(
self
,
filepath
):
""" map local path to file to self.baseuri """
pnum
=
len
(
split
(
self
.
directory
.
replace
(
"
\
\
"
,
"/"
),
"/"
)
)
filepath
=
os
.
path
.
normpath
(
filepath
)
parts
=
split
(
filename
.
replace
(
"
\
\
"
,
"/"
),
"/"
)[
pnum
:]
if
filepath
.
startswith
(
self
.
directory
):
sparts
=
joinfields
(
parts
,
"/"
)
uri
=
filepath
[
len
(
self
.
directory
):]
uri
=
urlparse
.
urljoin
(
self
.
baseuri
,
sparts
)
uri
=
os
.
path
.
normpath
(
self
.
baseuri
+
uri
)
print
(
'local2uri: %s -> %s'
%
(
filename
,
uri
))
#print('local2uri: %s -> %s' % (filepath
, uri))
return
uri
return
uri
def
get_children
(
self
,
uri
,
filter
=
None
):
def
get_children
(
self
,
uri
,
filter
=
None
):
...
@@ -100,8 +100,8 @@ class FilesystemHandler():
...
@@ -100,8 +100,8 @@ class FilesystemHandler():
if
os
.
path
.
isdir
(
fileloc
):
if
os
.
path
.
isdir
(
fileloc
):
try
:
try
:
files
=
os
.
listdir
(
fileloc
)
files
=
os
.
listdir
(
fileloc
)
except
:
except
Exception
:
raise
404
raise
ValueError
for
file
in
files
:
for
file
in
files
:
newloc
=
os
.
path
.
join
(
fileloc
,
file
)
newloc
=
os
.
path
.
join
(
fileloc
,
file
)
...
@@ -165,7 +165,7 @@ class FilesystemHandler():
...
@@ -165,7 +165,7 @@ class FilesystemHandler():
fp
.
close
()
fp
.
close
()
status
=
201
status
=
201
except
:
except
:
status
=
4
09
status
=
4
24
return
status
return
status
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment