Compare commits

..

3 Commits

Author SHA1 Message Date
Sebastian Lohff 2b138446d4 Change shebang to /usr/bin/env python
Using /usr/bin/python might have side-effects, such as the system
python being used even when the script is called from within a
python virtual env. env python should give us the right interpreter.
As we are both python2 and python3 compatible this should cause no
problems.
2020-01-15 00:48:06 +01:00
Sebastian Lohff ccd01e8b6e Fix -4/-6 crash caused by broken filter statement
In python3 filter returns a generator instead of a list. When -4 or
-6 is used or if the host system has either of those address
families disabled len() gets called onto this filter expression
which results into a crash. This commit makes a filter expression
out of this statement and also adds a test for ipv4-only downloading.
2020-01-15 00:48:06 +01:00
MasterofJOKers 907013522c Make `targetDir` absolute by default
When serving a `../` as directory (with `-l`), servefile creates an
endless 301-redirect loop. Having an absolute path fixes this. Since
this error might come up any time again, we're setting `targetDir` to
its absolute path right from the beginning and never have to worry about
it later on.
2020-01-15 00:07:07 +01:00
2 changed files with 52 additions and 6 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Licensed under GNU General Public License v3 or later
@ -312,7 +312,7 @@ class DirListingHandler(FileBaseHandler):
path = self.getCleanPath()
# check if path is in current serving directory
currBaseDir = os.path.abspath(self.targetDir) + os.path.sep
currBaseDir = self.targetDir + os.path.sep
requestPath = os.path.normpath(os.path.join(currBaseDir, path)) + os.path.sep
if not requestPath.startswith(currBaseDir):
self.send_response(301)
@ -849,9 +849,9 @@ class ServeFile():
# filter out ips we are not listening on
if not self.listenIPv6:
ips = filter(lambda ip: ":" not in ip, ips)
ips = [ip for ip in ips if '.' in ip]
if not self.listenIPv4:
ips = filter(lambda ip: "." not in ip, ips)
ips = [ip for ip in ips if ':' in ip]
return ips
return None
@ -1041,7 +1041,7 @@ class ServeFile():
raise ServeFileException("Error: Could not create directory '%s' for uploads, %r" % (self.target, str(e)))
else:
raise ServeFileException("Error: Upload directory already exists and is a file.")
FilePutter.targetDir = self.target
FilePutter.targetDir = os.path.abspath(self.target)
FilePutter.maxUploadSize = self.maxUploadSize
handler = FilePutter
elif self.serveMode == self.MODE_LISTDIR:
@ -1050,7 +1050,7 @@ class ServeFile():
if not os.path.isdir(self.target):
raise ServeFileException("Error: '%s' is not a directory." % (self.target,))
handler = DirListingHandler
handler.targetDir = self.target
handler.targetDir = os.path.abspath(self.target)
if self.auth:
# do authentication

View File

@ -2,6 +2,7 @@ import io
import os
import pytest
import requests
import socket
import subprocess
import tarfile
import time
@ -9,6 +10,12 @@ import urllib3
# crudly written to learn more about pytest and to have a base for refactoring
try:
ConnectionRefusedError
connrefused_exc = ConnectionRefusedError
except NameError:
connrefused_exc = socket.error
@pytest.fixture
def run_servefile():
@ -118,6 +125,18 @@ def test_specify_port(run_servefile, datadir):
check_download(data, fname='testfile', port=8081)
def test_ipv4_only(run_servefile, datadir):
data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile'
run_servefile([str(p), '-4'])
check_download(data, fname='testfile', host='127.0.0.1')
sock = socket.socket(socket.AF_INET6)
with pytest.raises(connrefused_exc):
sock.connect(("::1", 8080))
def test_big_download(run_servefile, datadir):
# test with about 10 mb of data
data = "x" * (10 * 1024 ** 2)
@ -167,6 +186,33 @@ def test_serve_directory(run_servefile, datadir):
check_download('jup!', '/bar/thisisaverylongfilenamefortestingthatthisstillworksproperly')
def test_serve_relative_directory(run_servefile, datadir):
d = {
'foo': {'kratzbaum': 'cat', 'I like Cats!': 'kitteh', '&&&&&&&': 'wheee'},
'bar': {'thisisaverylongfilenamefortestingthatthisstillworksproperly': 'jup!'},
'noot': 'still data in here',
'bigfile': 'x' * (10 * 1024 ** 2),
}
p = datadir(d)
run_servefile(['../', '-l'], cwd=os.path.join(str(p), 'foo'))
# check if all files are in directory listing
# (could be made more sophisticated with beautifulsoup)
for path in '/', '/../':
r = make_request(path)
for k in d:
assert k in r.text
for fname, content in d['foo'].items():
check_download(content, '/foo/' + fname)
r = make_request('/unknown')
assert r.status_code == 404
# download
check_download('jup!', '/bar/thisisaverylongfilenamefortestingthatthisstillworksproperly')
def test_upload(run_servefile, tmp_path):
data = ('this is my live now\n'
'uploading strings to servers\n'