Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions qiita_pet/handlers/cloud_handlers/file_transfer_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from tornado.web import HTTPError, RequestHandler
from tornado.gen import coroutine

from qiita_core.util import execute_as_transaction
from qiita_core.util import execute_as_transaction, is_test_environment
from qiita_db.handlers.oauth2 import authenticate_oauth
from qiita_core.qiita_settings import qiita_config

Expand Down Expand Up @@ -37,20 +37,35 @@ def get(self, requested_filepath):
raise HTTPError(403, reason=(
"The requested file is not present in Qiita's BASE_DATA_DIR!"))

# delivery of the file via nginx requires replacing the basedatadir
# with the prefix defined in the nginx configuration for the
# base_data_dir, '/protected/' by default
protected_filepath = filepath.replace(basedatadir, '/protected')

self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Transfer-Encoding', 'binary')
self.set_header('X-Accel-Redirect', protected_filepath)
self.set_header('Content-Description', 'File Transfer')
self.set_header('Expires', '0')
self.set_header('Cache-Control', 'no-cache')
self.set_header('Content-Disposition',
'attachment; filename=%s' % os.path.basename(
protected_filepath))

# We here need to differentiate a request that comes directly to the
# qiita instance (happens in testing) or was redirected through nginx
# (should be the default). If nginx, we can use nginx' fast file
# delivery mechanisms, otherwise, we need to send via slower tornado.
# We indirectly infer this by looking for the "X-Forwarded-For" header,
# which should only exists when redirectred through nginx.
if self.request.headers.get('X-Forwarded-For') is None:
self.set_header(
'Content-Disposition',
'attachment; filename=%s' % os.path.basename(filepath))
with open(filepath, "rb") as f:
self.write(f.read())
else:
# delivery of the file via nginx requires replacing the basedatadir
# with the prefix defined in the nginx configuration for the
# base_data_dir, '/protected/' by default
protected_filepath = filepath.replace(basedatadir, '/protected')
self.set_header('X-Accel-Redirect', protected_filepath)
self.set_header(
'Content-Disposition',
'attachment; filename=%s' % os.path.basename(
protected_filepath))

self.finish()


Expand All @@ -77,7 +92,8 @@ def post(self):
filepath = filepath[len(os.sep):]
filepath = os.path.abspath(os.path.join(basedatadir, filepath))

if os.path.exists(filepath):
# prevent overwriting existing files, except in test mode
if os.path.exists(filepath) and (not is_test_environment()):
raise HTTPError(403, reason=(
"The requested file is already "
"present in Qiita's BASE_DATA_DIR!"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from qiita_db.handlers.tests.oauthbase import OauthTestingBase
import qiita_db as qdb
from qiita_db.sql_connection import TRN


class FetchFileFromCentralHandlerTests(OauthTestingBase):
Expand Down Expand Up @@ -70,7 +71,15 @@ def test_post(self):

# check if error is raised, if file already exists
with open(fp_source, 'rb') as fh:
# we need to let qiita thinks for this test, to NOT be in test mode
with TRN:
TRN.add("UPDATE settings SET test = False")
TRN.execute()
obs = self.post_authed(endpoint, files={'bar/': fh})
# reset test mode to true
with TRN:
TRN.add("UPDATE settings SET test = True")
TRN.execute()
self.assertIn("already present in Qiita's BASE_DATA_DIR!",
obs.reason)

Expand Down
Loading