Skip to content

Commit

Permalink
Important improvement to the way how we forward data; now it is corre…
Browse files Browse the repository at this point in the history
…ct - before it was stupid :)
  • Loading branch information
romanchyla committed Dec 22, 2018
1 parent b85a143 commit 6ea3799
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 13 deletions.
26 changes: 14 additions & 12 deletions adsws/api/discoverer/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ def __init__(self, endpoint, service_uri, deploy_path, route):
@staticmethod
def get_body_data(request):
"""
Returns the correct payload data coming from the flask.Request object
Returns the correct payload data coming from the flask.Request object.
The correctness of this methods depends on the before_request hook to be
called before any other module (such as oauthlib); basically - data stream
must be cached before something parses it; because during parsing the
stream gets consumed and is gone.
Also, NOTHING should modify Content-Length and Type headers!!!
"""
if request.content_length < 5242880: # 1024 * 1024 * 5
request.input_stream.seek(0)
return request.input_stream.read()
else:
raise Exception('Request too large')

return request.get_data()



def dispatcher(self, **kwargs):
Expand Down Expand Up @@ -99,8 +104,7 @@ def post(self, ep, request):
"""
Proxy to remote POST endpoint, should be invoked via self.dispatcher()
"""
if not isinstance(request.data, basestring):
request.data = json.dumps(request.data)

try:
return self.session.post(ep, data=ProxyView.get_body_data(request), headers=request.headers, timeout=self.default_request_timeout)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
Expand All @@ -110,8 +114,7 @@ def put(self, ep, request):
"""
Proxy to remote PUT endpoint, should be invoked via self.dispatcher()
"""
if not isinstance(request.data, basestring):
request.data = json.dumps(request.data)

try:
return self.session.put(ep, data=ProxyView.get_body_data(request), headers=request.headers, timeout=self.default_request_timeout)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
Expand All @@ -121,8 +124,7 @@ def delete(self, ep, request):
"""
Proxy to remote PUT endpoint, should be invoked via self.dispatcher()
"""
if not isinstance(request.data, basestring):
request.data = json.dumps(request.data)

try:
return self.session.delete(ep, data=ProxyView.get_body_data(request), headers=request.headers, timeout=self.default_request_timeout)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
Expand Down
23 changes: 23 additions & 0 deletions adsws/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def create_app(app_name=None, instance_path=None, static_path=None,

app.before_request(set_translations)
app.before_request(make_session_permanent)
app.before_request(cache_data_stream)

if app.config.get('PRODUCTION', False):
app.wsgi_app = ProxyFix(
Expand Down Expand Up @@ -248,6 +249,28 @@ def _(s, **kwargs):
g._ = _


def cache_data_stream():
"""Workaround for remembering the input stream data (i.e. input stream
will be saved/cached and can be retrieved.
The problem is following:
- request.attributes are initialized the first time they are used
- flask_oauthlib is the first one to call request
request.form.to_dict()
- but stream is *only* cached if request.get_data() was
called first
- if you call request.form, the stream is read and it can
never be retrieved again (it is a socked)
Important detail: always set MAX_CONTENT_LENGTH
"""
cl = request.content_length
ml = current_app.config.get('MAX_CONTENT_LENGTH', 1024*1024*5)
if ml is None or ml > cl:
request.get_data(cache=True, as_text=False, parse_form_data=False)


def register_secret_key(app):
"""
Register sercret key in application configuration., and warns that it
Expand Down
12 changes: 12 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,17 @@ def generate_secret_key():
key = "'{0}{1}'".format(os.urandom(15), os.urandom(15))
print "\nSECRET_KEY = '{0}'\n".format(key.encode('hex'))


@manager.shell
def make_shell_context():
from wsgi import application, API, ACCOUNTS
app = application.app
context = app.app_context()
flask._app_ctx_stack.push(context)


return dict(app=app, api=API, accounts=ACCOUNTS,
context=context)

if __name__ == "__main__":
manager.run()
3 changes: 2 additions & 1 deletion scripts/generate_oauth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ def get_token():
description=args.description,
name=args.name,
is_confidential=True,
is_internal=True,)
is_internal=True,
ratelimit=1.0)
client.gen_salt()
db.session.add(client)
db.session.commit()
Expand Down

0 comments on commit 6ea3799

Please sign in to comment.