def call_backend(self, environ, start_response): request = Request(environ) # Compatibility with django, use request.args preferrably request.GET = request.args # By using fcgi, mediagoblin can run under a base path # like /mediagoblin/. request.path_info contains the # path inside mediagoblin. If the something needs the # full path of the current page, that should include # the basepath. # Note: urlgen and routes are fine! request.full_path = environ["SCRIPT_NAME"] + request.path # python-routes uses SCRIPT_NAME. So let's use that too. # The other option would be: # request.full_path = environ["SCRIPT_URL"] # Fix up environ for urlgen # See bug: https://bitbucket.org/bbangert/routes/issue/55/cache_hostinfo-breaks-on-https-off if environ.get('HTTPS', '').lower() == 'off': environ.pop('HTTPS') ## Attach utilities to the request object with self.gen_context(request) as request: return self._finish_call_backend(request, environ, start_response)
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ urls = self._url_map.bind_to_environ(environ) try: endpoint, args = urls.match() except HTTPException as exc: return exc assert endpoint == "rpc" response = Response() if self._auth is not None and not self._auth(environ): response.status_code = 403 response.mimetype = "plain/text" response.data = "Request not allowed." return response request = Request(environ) request.encoding_errors = "strict" remote_service = ServiceCoord(args['service'], args['shard']) if remote_service not in self._service.remote_services: return NotFound() # TODO Check content_encoding and content_md5. if request.mimetype != "application/json": return UnsupportedMediaType() if request.accept_mimetypes.quality("application/json") <= 0: return NotAcceptable() try: data = json.load(request.stream, encoding='utf-8') except ValueError: return BadRequest() if not self._service.remote_services[remote_service].connected: return ServiceUnavailable() result = self._service.remote_services[remote_service].execute_rpc( args['method'], data) # XXX We could set a timeout on the .wait(). result.wait() response.status_code = 200 response.mimetype = "application/json" response.data = json.dumps({ "data": result.value, "error": None if result.successful() else "%s" % result.exception}) return response
def application(environ, start_response): # The WSGI server puts content length and type in the environment # even when not provided with the request. Drop them if they are empty. if environ.get('CONTENT_LENGTH') == '': del environ['CONTENT_LENGTH'] if environ.get('CONTENT_TYPE') == '': del environ['CONTENT_TYPE'] wrequest = WerkzeugRequest(environ) data = wrequest.get_data() request = Request( method=wrequest.method, url=wrequest.url, headers=wrequest.headers, data=data, ) prepared = request.prepare() stream = streams.build_output_stream( args, env, prepared, response=None, output_options=args.output_options) streams.write_stream(stream, env.stdout, env.stdout_isatty) # When there is data in the request, give the next one breathing room. if data: print("\n", file=env.stdout) # Make dreams come true. response = Response(headers={'Server': server}) return response(environ, start_response)
def build_request_obj(query_strings): print(query_strings) builder = EnvironBuilder() # query_string=) env = builder.get_environ() request = Request(env) request.args = MultiDict(query_strings.items()) return request
def __call__(self, environ, start_response): request = Request(environ) lang = request.values.get('_lang') if lang is None: lang = (request.accept_languages.best or 'en').split('-')[0].lower() if not has_language(lang): lang = 'en' request.translations = load_translations(lang) request.translations.language = lang request.gettext = request.translations.gettext request.timezone = request.values.get('_timezone', 'UTC') response = None if request.path == '/': view = request.values.get('_current', 'start') if request.values.get('_startsetup'): response = self.start_setup(request) elif view in self.views: handler = self.views[view] if handler is not None and \ request.values.get('_next'): ctx = handler(request) if ctx is not None: response = self.handle_view(request, view, ctx) if response is None: if request.values.get('_next'): view = self.next[view] elif request.values.get('_prev'): view = self.prev[view] response = self.handle_view(request, view) if response is None: response = redirect('') return response(environ, start_response)
def _load_form_data(self): BaseRequest._load_form_data(self) if (self.debug and self.mimetype != 'multipart/form-data' and not self.files): from .debughelpers import attach_enctype_error_multidict attach_enctype_error_multidict(self)
def wsgi_app(self, environ, start_response): route = self.router.bind_to_environ(environ) try: endpoint, args = route.match() except HTTPException as exc: return exc(environ, start_response) assert endpoint == "sublist" request = Request(environ) request.encoding_errors = "strict" if request.accept_mimetypes.quality("application/json") <= 0: raise NotAcceptable() result = list() for task_id in self.task_store._store.keys(): result.extend( self.scoring_store.get_submissions( args["user_id"], task_id ).values() ) result.sort(key=lambda x: (x.task, x.time)) result = list(a.__dict__ for a in result) response = Response() response.status_code = 200 response.mimetype = "application/json" response.data = json.dumps(result) return response(environ, start_response)
def wsgi_app(self, environ, start_response): route = self.router.bind_to_environ(environ) try: endpoint, args = route.match() except HTTPException as exc: return exc(environ, start_response) if endpoint == "events": return self.event_handler(environ, start_response) elif endpoint == "logo": return self.logo_handler(environ, start_response) elif endpoint == "root": return self.root_handler(environ, start_response) else: request = Request(environ) request.encoding_errors = "strict" response = Response() if endpoint == "sublist": SubListHandler(request, response, args["user_id"]) elif endpoint == "scores": ScoreHandler(request, response) elif endpoint == "history": HistoryHandler(request, response) return response(environ, start_response)
def wsgi_app(self, environ, start_response): route = self.router.bind_to_environ(environ) try: endpoint, args = route.match() except HTTPException as exc: return exc request = Request(environ) request.encoding_errors = "strict" response = Response() try: if endpoint == "get": self.get(request, response, args["key"]) elif endpoint == "get_list": self.get_list(request, response) elif endpoint == "put": self.put(request, response, args["key"]) elif endpoint == "put_list": self.put_list(request, response) elif endpoint == "delete": self.delete(request, response, args["key"]) elif endpoint == "delete_list": self.delete_list(request, response) else: raise RuntimeError() except HTTPException as exc: return exc return response
def __init__(self, environ, app=None): RequestBase.__init__(self, environ) self.queries = [] self.metanav = [] self.navbar = [] self.ctxnavbar = {} if app is None: app = get_application() self.app = app engine = self.app.database_engine # get the session and try to get the user object for this request. from ilog.database import db, User user = None cookie_name = app.cfg['cookie_name'] session = SecureCookie.load_cookie(self, cookie_name, app.secret_key) user_id = session.get('uid') if user_id: user = User.query.options( db.eagerload('groups'), db.eagerload('groups', 'privileges') ).get(user_id) if user is None: self.locale = self.app.default_locale self.translations = self.app.default_translations user = User.query.get_nobody() else: self.locale = Locale(user.locale) self.translations = i18n.load_translations(self.locale) self.user = user self.user.update_last_login() db.commit() self.session = session
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ urls = self._url_map.bind_to_environ(environ) try: endpoint, args = urls.match() except HTTPException as exc: return exc assert endpoint == "get" request = Request(environ) request.encoding_errors = "strict" response = Response() result = dict() for task_type in self._task_types: result[task_type.__name__] = \ list(p.describe() for p in task_type.ACCEPTED_PARAMETERS) response.status_code = 200 response.mimetype = "application/json" response.data = json.dumps(result) return response
def _load_form_data(self): RequestBase._load_form_data(self) # in debug mode we're replacing the files multidict with an ad-hoc # subclass that raises a different error for key errors. ctx = _request_ctx_stack.top if ctx is not None and ctx.app.debug and self.mimetype != "multipart/form-data" and not self.files: attach_enctype_error_multidict(self)
def _load_from_data(self): RequestBase._load_from_data(self) context = _requestContextStack.top if context is not None and context.app.debug \ and self.mimetype != 'multipart/form-data' and not self.files: attachEnctypeErrorMultidict(self)
def wsgi_app(self, environ, start_response): request = Request(environ) sid = request.cookies.get("expSession") request.sessionid = sid response = self.dispatch_request(request) return response(environ, start_response)
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ urls = self._url_map.bind_to_environ(environ) try: endpoint, args = urls.match() except HTTPException as exc: return exc assert endpoint == "rpc" request = Request(environ) request.encoding_errors = "strict" response = Response() remote_service = ServiceCoord(args['service'], args['shard']) if remote_service not in self._service.remote_services: return NotFound() # TODO Check content_encoding and content_md5. if request.mimetype != "application/json": return UnsupportedMediaType() if request.accept_mimetypes.quality("application/json") <= 0: return NotAcceptable() try: data = json.load(request.stream, encoding='utf-8') except ValueError: return BadRequest() if not self._service.remote_services[remote_service].connected: return ServiceUnavailable() value = AsyncResult() @rpc_callback def callback(service, data, plus=None, error=None): value.set({'data': data, 'error': error}) self._service.remote_services[remote_service].execute_rpc( args['method'], data, callback) response.status_code = 200 response.mimetype = "application/json" # XXX We could set a timeout on the .get(). response.data = json.dumps(value.get()) return response
def __init__(self, environ, url_map, session_store = None, cookie_name = None): RequestBase.__init__(self, environ) self.url_adapter = url_map.bind_to_environ(environ) self.session_store = session_store self.cookie_name = cookie_name if session_store is not None and cookie_name is not None: if cookie_name in self.cookies: self.session = session_store.get(self.cookies[cookie_name]) else: self.session = session_store.new()
def _request_signature(self, environ, digest): h = hmac.new( self._secret_key.encode('utf8'), self.string_to_sign(environ).encode('utf8'), digest, ) request = Request(environ) if 'wsgi.input' in environ: h.update(request.get_data()) return digest().name + ' ' + base64.b64encode(h.digest()).decode('utf8')
def __call__(self, environ, start_response): request = Request(environ) try: name, args, kwargs = loads(request.get_data(cache=True)) debug('calling function: "%s"', name) result = self.rpc()(name, *args, **kwargs) execution_error = None except Exception, e: execution_error = ErrorMessage.from_exception(e, address=request.host_url) result = None error('error: %s, traceback: \n%s', e, traceback.format_exc())
def _wsgi_app(environ, start_response): rq = Request(environ) environ['werkzeug.request'] = None cx = rq.context = factory() try: rsp = handler(rq) finally: rq.close() if hasattr(cx, 'close'): cx.close() return rsp(environ, start_response)
def wsgi_app(self, environ, start_response): script_name = environ.get('HTTP_X_SCRIPT_NAME', '') if script_name: environ['SCRIPT_NAME'] = script_name path_info = environ['PATH_INFO'] if path_info.startswith(script_name): environ['PATH_INFO'] = path_info[len(script_name):] request = Request(environ) request.app = self response = self.dispatch_request(request) return response(environ, start_response)
def _load_form_data(self): RequestBase._load_form_data(self) # In debug mode we're replacing the files multidict with an ad-hoc # subclass that raises a different error for key errors. if ( current_app and current_app.debug and self.mimetype != 'multipart/form-data' and not self.files ): from .debughelpers import attach_enctype_error_multidict attach_enctype_error_multidict(self)
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ original_response = Response.from_app(self.wrapped_app, environ) # We send relative locations to play nice with reverse proxies # but Werkzeug by default turns them into absolute ones. original_response.autocorrect_location_header = False if self.DIGEST_HEADER not in original_response.headers: return original_response digest = original_response.headers.pop(self.DIGEST_HEADER) filename = original_response.headers.pop(self.FILENAME_HEADER, None) mimetype = original_response.mimetype try: fobj = self.file_cacher.get_file(digest) size = self.file_cacher.get_size(digest) except KeyError: return NotFound() except TombstoneError: return ServiceUnavailable() request = Request(environ) request.encoding_errors = "strict" response = Response() response.status_code = 200 response.mimetype = mimetype if filename is not None: response.headers.add( "Content-Disposition", "attachment", filename=filename) response.set_etag(digest) response.cache_control.max_age = SECONDS_IN_A_YEAR response.cache_control.private = True response.response = \ wrap_file(environ, fobj, buffer_size=FileCacher.CHUNK_SIZE) response.direct_passthrough = True try: # This takes care of conditional and partial requests. response.make_conditional( request, accept_ranges=True, complete_length=size) except HTTPException as exc: return exc return response
def test_redirect_respects_urlgen_args(self): """Test that redirect returns a 302 to location from urlgen args.""" # Using a mock urlgen here so we're only testing redirect itself. We # could instantiate a url_map and map_adaptor with WSGI environ as per # app.py, but that would really just be testing Werkzeug. def urlgen(endpoint, **kwargs): return "/test?foo=bar" request = Request({}) request.urlgen = urlgen response = redirect(request, "test-endpoint", foo="bar") assert response.status_code == 302 assert response.location == "/test?foo=bar"
def get_request(self, environ): request = Request(environ) request.app = self.app request.translations = load_core_translations(self.app.cfg['language']) request.is_admin = False request.is_somebody = False cookie_name = self.app.cfg['session_cookie_name'] session = SecureCookie.load_cookie( request, cookie_name, self.app.cfg['secret_key'].encode('utf-8') ) request.session = session engine = self.app.database_engine user_id = session.get('uid') if user_id: admin_privilege = engine.execute( privileges.select(privileges.c.name=='BLOG_ADMIN') ).fetchone() admin = engine.execute(user_privileges.select(and_( user_privileges.c.user_id==int(user_id), user_privileges.c.privilege_id==admin_privilege.privilege_id ))).fetchone() request.is_somebody = True request.is_admin = admin is not None return request
def test_redirect_obj_calls_url_for_self(self): """Test that redirect_obj returns a 302 to obj's url_for_self().""" # Using a mock obj here so that we're only testing redirect_obj itself, # rather than also testing the url_for_self implementation. class Foo(object): def url_for_self(*args, **kwargs): return "/foo" request = Request({}) request.urlgen = None response = redirect_obj(request, Foo()) assert response.status_code == 302 assert response.location == "/foo"
def test_wrapper_support(self): req = Request.from_values() resp = Response() c = EncryptedCookie.load_cookie(req, crypter_or_keys_location=KEYS_DIR) assert c.new c['foo'] = 42 assert c.crypter is not None c.save_cookie(resp) req = Request.from_values(headers={ 'Cookie': 'session="%s"' % parse_cookie(resp.headers['set-cookie'])['session'] }) c2 = EncryptedCookie.load_cookie(req, crypter_or_keys_location=KEYS_DIR) assert not c2.new assert c2 == c
def test_wrapper_support(self): req = Request.from_values() resp = Response() c = SecureCookie.load_cookie(req, secret_key="foo") assert c.new c["foo"] = 42 assert c.secret_key == "foo" c.save_cookie(resp) req = Request.from_values( headers={"Cookie": 'session="%s"' % parse_cookie(resp.headers["set-cookie"])["session"]} ) c2 = SecureCookie.load_cookie(req, secret_key="foo") assert not c2.new assert c2 == c
def test_wrapper_support(): req = Request.from_values() resp = Response() c = SecureCookie.load_cookie(req, secret_key=b'foo') assert c.new c['foo'] = 42 assert c.secret_key == b'foo' c.save_cookie(resp) req = Request.from_values(headers={ 'Cookie': 'session="%s"' % parse_cookie(resp.headers['set-cookie'])['session'] }) c2 = SecureCookie.load_cookie(req, secret_key=b'foo') assert not c2.new assert c2 == c
def wsgi_app(self, environ, start_response): request = Request(environ) request.encoding_errors = "strict" response = Response() response.status_code = 200 response.mimetype = "text/html" response.last_modified = \ datetime.utcfromtimestamp(os.path.getmtime(self.path))\ .replace(microsecond=0) # TODO check for If-Modified-Since and If-None-Match response.response = wrap_file(environ, open(self.path, 'rb')) response.direct_passthrough = True return response
def wsgi_app(self, environ, start_response): request = Request(environ) request.encoding_errors = "strict" if request.accept_mimetypes.quality("application/json") <= 0: raise NotAcceptable() result = list(self.scoring_store.get_global_history()) response = Response() response.status_code = 200 response.mimetype = "application/json" response.data = json.dumps(result) return response(environ, start_response)
def prepare_asset(request, unique_name=False): req = Request(request.environ) data = None # For backward compatibility try: data = json.loads(req.data) except ValueError: data = json.loads(req.form['model']) except TypeError: data = json.loads(req.form['model']) def get(key): val = data.get(key, '') if isinstance(val, unicode): return val.strip() elif isinstance(val, basestring): return val.strip().decode('utf-8') else: return val if not all([get('name'), get('uri'), get('mimetype')]): raise Exception( "Not enough information provided. Please specify 'name', 'uri', and 'mimetype'." ) name = get('name') if unique_name: with db.conn(settings['database']) as conn: names = assets_helper.get_names_of_assets(conn) if name in names: i = 1 while True: new_name = '%s-%i' % (name, i) if new_name in names: i += 1 else: name = new_name break asset = { 'name': name, 'mimetype': get('mimetype'), 'asset_id': get('asset_id'), 'is_enabled': get('is_enabled'), 'is_processing': get('is_processing'), 'nocache': get('nocache'), } uri = get('uri').encode('utf-8') if uri.startswith('/'): if not path.isfile(uri): raise Exception("Invalid file path. Failed to add asset.") else: if not validate_url(uri): raise Exception("Invalid URL. Failed to add asset.") if not asset['asset_id']: asset['asset_id'] = uuid.uuid4().hex if uri.startswith('/'): rename(uri, path.join(settings['assetdir'], asset['asset_id'])) uri = path.join(settings['assetdir'], asset['asset_id']) if 'youtube_asset' in asset['mimetype']: uri, asset['name'], asset['duration'] = download_video_from_youtube( uri, asset['asset_id']) asset['mimetype'] = 'video' asset['is_processing'] = 1 asset['uri'] = uri if "video" in asset['mimetype']: if get('duration') == 'N/A' or int(get('duration')) == 0: asset['duration'] = int(get_video_duration(uri).total_seconds()) else: # Crashes if it's not an int. We want that. asset['duration'] = int(get('duration')) asset['skip_asset_check'] = int(get('skip_asset_check')) if int( get('skip_asset_check')) else 0 # parse date via python-dateutil and remove timezone info if get('start_date'): asset['start_date'] = date_parser.parse( get('start_date')).replace(tzinfo=None) else: asset['start_date'] = "" if get('end_date'): asset['end_date'] = date_parser.parse( get('end_date')).replace(tzinfo=None) else: asset['end_date'] = "" return asset
def prepare_asset_v1_2(request, asset_id=None): req = Request(request.environ) data = json.loads(req.data) def get(key): val = data.get(key, '') if isinstance(val, unicode): return val.strip() elif isinstance(val, basestring): return val.strip().decode('utf-8') else: return val if not all([ get('name'), get('uri'), get('mimetype'), str(get('is_enabled')), get('start_date'), get('end_date') ]): raise Exception( "Not enough information provided. Please specify 'name', 'uri', 'mimetype', 'is_enabled', 'start_date' and 'end_date'." ) asset = { 'name': get('name'), 'mimetype': get('mimetype'), 'is_enabled': get('is_enabled'), 'nocache': get('nocache') } uri = get('uri') if uri.startswith('/'): if not path.isfile(uri): raise Exception("Invalid file path. Failed to add asset.") else: if not validate_url(uri): raise Exception("Invalid URL. Failed to add asset.") if not asset_id: asset['asset_id'] = uuid.uuid4().hex if uri.startswith('/'): rename(uri, path.join(settings['assetdir'], asset['asset_id'])) uri = path.join(settings['assetdir'], asset['asset_id']) if 'youtube_asset' in asset['mimetype']: uri, asset['name'], asset['duration'] = download_video_from_youtube( uri, asset['asset_id']) asset['mimetype'] = 'video' asset['is_processing'] = 1 asset['uri'] = uri if "video" in asset['mimetype']: if get('duration') == 'N/A' or int(get('duration')) == 0: asset['duration'] = int(get_video_duration(uri).total_seconds()) elif get('duration'): # Crashes if it's not an int. We want that. asset['duration'] = int(get('duration')) else: asset['duration'] = 10 asset['play_order'] = get('play_order') if get('play_order') else 0 # parse date via python-dateutil and remove timezone info asset['start_date'] = date_parser.parse( get('start_date')).replace(tzinfo=None) asset['end_date'] = date_parser.parse(get('end_date')).replace(tzinfo=None) return asset
def test_easteregg(self): req = Request.from_values('/?macgybarchakku') resp = Response.force_type(internal._easteregg(None), req) assert 'About Werkzeug' in resp.data assert 'the Swiss Army knife of Python web development' in resp.data
def make_req_headers(**kwargs): environ = create_environ('/collections/obs/items', 'http://localhost:5000/') environ.update(kwargs) request = Request(environ) return request.headers
def test_result_configurability(self): req = Request.from_values() assert isinstance(RequestParser().parse_args(req), ParseResult) assert type(RequestParser(result_class=dict).parse_args(req)) is dict
def __init__(self, environ): RequestBase.__init__(self, environ) self.endpoint = None self.view_args = None
def __call__(self, environ, start_response): request = Request(environ) self.count += 1 environ['HTTP_COUNT'] = self.count return self.dispatch_request(request)(environ, start_response)
def __call__(self, environ, start_response): request = Request(environ) response = self.dispatch_request(request) return response(environ, start_response)
def test_strict_parsing_on_partial_hit(self, app): req = Request.from_values("/bubble?foo=1&bar=bees&n=22") parser = RequestParser() parser.add_argument("foo", type=int) with pytest.raises(BadRequest): parser.parse_args(req, strict=True)
def test_limiting(self): data = b'foo=Hello+World&bar=baz' req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_content_length = 400 strict_eq(req.form['foo'], u'Hello World') req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_form_memory_size = 7 pytest.raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='application/x-www-form-urlencoded', method='POST') req.max_form_memory_size = 400 strict_eq(req.form['foo'], u'Hello World') data = (b'--foo\r\nContent-Disposition: form-field; name=foo\r\n\r\n' b'Hello World\r\n' b'--foo\r\nContent-Disposition: form-field; name=bar\r\n\r\n' b'bar=baz\r\n--foo--') req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_content_length = 4 pytest.raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_content_length = 400 strict_eq(req.form['foo'], u'Hello World') req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_form_memory_size = 7 pytest.raises(RequestEntityTooLarge, lambda: req.form['foo']) req = Request.from_values( input_stream=BytesIO(data), content_length=len(data), content_type='multipart/form-data; boundary=foo', method='POST') req.max_form_memory_size = 400 strict_eq(req.form['foo'], u'Hello World')
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ urls = self._url_map.bind_to_environ(environ) try: endpoint, args = urls.match() except HTTPException as exc: return exc assert endpoint == "rpc" response = Response() if self._auth is not None and not self._auth(environ): response.status_code = 403 response.mimetype = "plain/text" response.data = "Request not allowed." return response request = Request(environ) request.encoding_errors = "strict" remote_service = ServiceCoord(args['service'], args['shard']) if remote_service not in self._service.remote_services: return NotFound() # TODO Check content_encoding and content_md5. if request.mimetype != "application/json": return UnsupportedMediaType() if request.accept_mimetypes.quality("application/json") <= 0: return NotAcceptable() try: data = json.load(request.stream, encoding='utf-8') except ValueError: return BadRequest() if not self._service.remote_services[remote_service].connected: return ServiceUnavailable() result = self._service.remote_services[remote_service].execute_rpc( args['method'], data) # XXX We could set a timeout on the .wait(). result.wait() response.status_code = 200 response.mimetype = "application/json" response.data = json.dumps({ "data": result.value, "error": None if result.successful() else "%s" % result.exception }) return response
def test_strict_parsing_off_partial_hit(self, app): req = Request.from_values("/bubble?foo=1&bar=bees&n=22") parser = RequestParser() parser.add_argument("foo", type=int) args = parser.parse_args(req) assert args["foo"] == 1
def __call__(self, environ, start_response): return self.handle_req(Request(environ), environ, start_response)
def test_strict_parsing_off(self): req = Request.from_values("/bubble?foo=baz") parser = RequestParser() args = parser.parse_args(req) assert args == {}
def test_strict_parsing_on(self): req = Request.from_values("/bubble?foo=baz") parser = RequestParser() with pytest.raises(BadRequest): parser.parse_args(req, strict=True)
def __init__(self, environ): self.request = Request(environ)
def test_parse_lte_gte_missing(self): parser = RequestParser() parser.add_argument("foo", operators=["<=", "="]) args = parser.parse_args(Request.from_values("/bubble?foo<=bar")) self.assertEquals(args['foo'], "bar")
def set_request(**kwargs): builder = EnvironBuilder(**kwargs) frappe.local.request = Request(builder.get_environ())
def wsgi_app(self, environ, start_response): request = Request(environ) response = self.dispatch_request(request) return response(environ, start_response)
def test_parse_foo_operators_ignore(self): parser = RequestParser() parser.add_argument("foo", ignore=True, store_missing=True) args = parser.parse_args(Request.from_values("/bubble")) self.assertEquals(args['foo'], None)
def prepare_asset(request): req = Request(request.environ) data = None data = json.loads(req.form['model']) if 'model' in req.form else req.form def get(key): val = data.get(key, '') if isinstance(val, unicode): return val.strip() elif isinstance(val, basestring): return val.strip().decode('utf-8') else: return val if all([get('name'), get('uri') or req.files.get('file_upload'), get('mimetype')]): asset = { 'name': get('name'), 'mimetype': get('mimetype'), 'asset_id': get('asset_id'), 'is_enabled': get('is_enabled'), 'nocache': get('nocache'), } uri = get('uri') or False if not asset['asset_id']: asset['asset_id'] = uuid.uuid4().hex try: file_upload = req.files.get('file_upload') filename = file_upload.filename except AttributeError: file_upload = None filename = None if filename and 'web' in asset['mimetype']: raise Exception("Invalid combination. Can't upload a web resource.") if uri and filename: raise Exception("Invalid combination. Can't select both URI and a file.") if uri and not uri.startswith('/'): if not validate_url(uri): raise Exception("Invalid URL. Failed to add asset.") else: asset['uri'] = uri else: asset['uri'] = uri if filename: asset['uri'] = path.join(settings['assetdir'], asset['asset_id']) file_upload.save(asset['uri']) if "video" in asset['mimetype']: video_duration = get_video_duration(asset['uri']) if video_duration: asset['duration'] = int(video_duration.total_seconds()) else: asset['duration'] = 'N/A' else: # Crashes if it's not an int. We want that. asset['duration'] = int(get('duration')) if get('start_date'): asset['start_date'] = datetime.strptime(get('start_date').split(".")[0], "%Y-%m-%dT%H:%M:%S") else: asset['start_date'] = "" if get('end_date'): asset['end_date'] = datetime.strptime(get('end_date').split(".")[0], "%Y-%m-%dT%H:%M:%S") else: asset['end_date'] = "" if not asset['asset_id']: raise Exception if not asset['uri']: raise Exception return asset else: raise Exception("Not enough information provided. Please specify 'name', 'uri', and 'mimetype'.")
def __init__(self, app, environ): self.app = app self.url_adapter = app.url_map.bind_to_environ(environ) # url适配器,绑定 self.request = Request(environ) self.session = app.open_session(self.request)
def get_response(ip, forwarded=None): req_dict = {'REMOTE_ADDR': ip} if forwarded: req_dict['HTTP_X_FORWARDED_FOR'] = forwarded return protected(None, Request(req_dict))
def wsgi_app(self, environ, start_response): """Execute this instance as a WSGI application. See the PEP for the meaning of parameters. The separation of __call__ and wsgi_app eases the insertion of middlewares. """ request = Request(environ) request.encoding_errors = "strict" # The problem here is that we'd like to send an infinite stream # of events, but WSGI has been designed to handle only finite # responses. Hence, to do this we will have to "abuse" the API # a little. This works well with gevent's pywsgi implementation # but it may not with others (still PEP-compliant). Therefore, # just to be extra-safe, we will terminate the response anyway, # after a long timeout, to make it finite. # The first such "hack" is the mechanism to trigger the chunked # transfer-encoding. The PEP states just that "the server *may* # use chunked encoding" to send each piece of data we give it, # if we don't specify a Content-Length header and if both the # client and the server support it. According to the HTTP spec. # all (and only) HTTP/1.1 compliant clients have to support it. # We'll assume that the server software supports it too, and # actually uses it (gevent does!) even if we have no way to # check it. We cannot try to force such behavior as the PEP # doesn't even allow us to set the Transfer-Encoding header. # The second abuse is the use of the write() callable, returned # by start_response, even if the PEP strongly discourages its # use in new applications. We do it because we need a way to # detect when the client disconnects, and we hope to achieve # this by seeing when a call to write() fails, i.e. raises an # exception. This behavior isn't documented by the PEP, but it # seems reasonable and it's present in gevent (which raises a # socket.error). # The third non-standard behavior that we expect (related to # the previous one) is that no one in the application-to-client # chain does response buffering: neither any middleware nor the # server (gevent doesn't!). This should also hold outside the # server realm (i.e. no proxy buffering) but that's definitely # not our responsibility. # The fourth "hack" is to avoid an error to be printed on the # logs. If the client terminates the connection, we catch and # silently ignore the exception and return gracefully making # the server try to write the last zero-sized chunk (used to # mark the end of the stream). This will fail and produce an # error. To avoid this we detect if we're running on a gevent # server and make it "forget" this was a chunked response. # Check if the client will understand what we will produce. if request.accept_mimetypes.quality("text/event-stream") <= 0: return NotAcceptable()(environ, start_response) # Initialize the response and get the write() callback. The # Cache-Control header is useless for conforming clients, as # the spec. already imposes that behavior on them, but we set # it explicitly to avoid unwanted caching by unaware proxies and # middlewares. write = start_response( text_to_native_str("200 OK"), [(text_to_native_str("Content-Type"), text_to_native_str("text/event-stream; charset=utf-8")), (text_to_native_str("Cache-Control"), text_to_native_str("no-cache"))]) # This is a part of the fourth hack (see above). if hasattr(start_response, "__self__") and \ isinstance(start_response.__self__, WSGIHandler): handler = start_response.__self__ else: handler = None # One-shot means that we will terminate the request after the # first batch of sent events. We do this when we believe the # client doesn't support chunked transfer. As this encoding has # been introduced in HTTP/1.1 (as mandatory!) we restrict to # requests in that HTTP version. Also, if it comes from an # XMLHttpRequest it has been probably sent from a polyfill (not # from the native browser implementation) which will be able to # read the response body only when it has been fully received. if environ["SERVER_PROTOCOL"] != "HTTP/1.1" or request.is_xhr: one_shot = True else: one_shot = False # As for the Server-Sent Events [1] spec., this is the way for # the client to tell us the ID of the last event it received # and to ask us to send it the ones that happened since then. # [1] http://www.w3.org/TR/eventsource/ # The spec. requires implementations to retry the connection # when it fails, adding the "Last-Event-ID" HTTP header. But in # case of an error they stop, and we have to (manually) delete # the EventSource and create a new one. To obtain that behavior # again we give the "last_event_id" as a URL query parameter # (with lower priority, to have the header override it). last_event_id = request.headers.get("Last-Event-ID") if last_event_id is None: last_event_id = request.args.get("last_event_id") # We subscribe to the publisher to receive events. sub = self._pub.get_subscriber(last_event_id) # Send some data down the pipe. We need that to make the user # agent announces the connection (see the spec.). Since it's a # comment it will be ignored. write(b":\n") # XXX We could make the client change its reconnection timeout # by sending a "retry:" line. # As a last line of defence from very bad-behaving servers we # don't want to the request to last longer than _GLOBAL_TIMEOUT # seconds (see above). We use "False" to just cause the control # exit the with block, instead of raising an exception. with Timeout(self._GLOBAL_TIMEOUT, False): # Repeat indefinitely. while True: # Proxies often have a read timeout. We try not to hit # it by not being idle for more than _PING_TIMEOUT # seconds, sending a ping (i.e. a comment) if there's # no real data. try: with Timeout(self._PING_TIMEOUT): data = b"".join(sub.get()) got_sth = True except Timeout: data = b":\n" got_sth = False try: with Timeout(self._WRITE_TIMEOUT): write(data) # The PEP doesn't tell what has to happen when a write # fails. We're conservative, and allow any unexpected # event to interrupt the request. We hope it's enough # to detect when the client disconnects. It is with # gevent, which raises a socket.error. The timeout (we # catch that too) is just an extra precaution. except Exception: # This is part of the fourth hack (see above). if handler is not None: handler.response_use_chunked = False break # If we decided this is one-shot, stop the long-poll as # soon as we sent the client some real data. if one_shot and got_sth: break # An empty iterable tells the server not to send anything. return []
def application(env, start_response): request = Request(env) try: uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', '')) except OSError as err: logging.info('handshake_failed') else: with cursor_for_request(request) as cursor: db_connection = cursor.connection db_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) db_conn_fd = db_connection.fileno() websocket_fd = uwsgi.connection_fd() logging.info('connection established') try: while True: uwsgi.wait_fd_read(websocket_fd) uwsgi.wait_fd_read(db_conn_fd) uwsgi.suspend() fd = uwsgi.ready_fd() if fd == websocket_fd: cmd_json = uwsgi.websocket_recv_nb() if cmd_json: cmd = json.loads(cmd_json.decode('utf-8')) if cmd: try: if cmd['method'] != 'ping': logging.info('command received: %s' % cmd['method']) if cmd['method'] == 'request': request_method(cmd, cursor) elif cmd['method'] == 'attach': attach_method(cmd, cursor, db_connection) elif cmd['method'] == 'detach': detach_method(cmd, cursor, db_connection, env) except Warning as err: logging.error(str(err)) # uwsgi.websocket_send(json.dumps({ # "method": "log", # "args": { # "level": "warning", # "message": err.diag.message_primary # } # })) elif fd == db_conn_fd: handle_db_notifications(db_connection) else: logging.info( 'timeout reached') # This is never reached # handle timeout of above wait_fd_read for ping/pong uwsgi.websocket_recv_nb() except (OSError, IOError) as err: logging.info('connection closed (role: %s)' % env['DB_USER']) return []