def update_one_book_full(object_id): try: book = request.get_json() result = data.update_book_full(object_id, book) if result is None: return jsonify(error="The id specified is not a valid id"), 400 if result.upserted_id is not None: book['_id'] = str(result.upserted_id) resp = Response(json.dumps(book), status=201, mimetype='application/json') resp.headers['Location'] = f'/{object_id}' resp.autocorrect_location_header = False return resp book['_id'] = object_id resp = Response(json.dumps(book), status=200, mimetype='application/json') resp.headers['Location'] = f'/{object_id}' resp.autocorrect_location_header = False return resp except Exception as e: print(e) return jsonify(error=str(e)), 500
def recipe_step(recipe_id, step_id): if request.method == 'GET': try: step = services.get_step(recipe_id=recipe_id, step_id=step_id) except NoResultFound: abort(404) return jsonify({'steps': step}) elif request.method == 'PUT': recipe_id = request.form['recipe_id'] order_no = request.form['order_no'] instructions = request.form['instructions'] result = services.edit_step(step_id=step_id, recipe_id=recipe_id, order_no=order_no, instructions=instructions) resp = jsonify({'step': result.data}) resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}/steps/{1}'.format(recipe_id, result.id) resp.autocorrect_location_header = False return resp elif request.method == 'DELETE': services.delete_step(step_id) resp = Response() resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}/steps' resp.autocorrect_location_header = False return resp
def index(path=''): logger.info(f'<Core> On request {request.url}') resp = None req_context = HandlerContext(request) req_context.update_client_req_time() flow_editor_handler.on_request_handler(req_context) req_context.update_server_req_time() mock_handler.handle(req_context) if not req_context.response_source: flow_editor_handler.on_request_upstream_handler(req_context) proxy_handler.handle(req_context) if req_context.is_proxiable: req_context.set_response_source_proxy() req_context.update_response_headers_code2flow() flow_editor_handler.on_response_upstream_handler(req_context) req_context.update_server_resp_time() flow_editor_handler.on_response_handler(req_context) if req_context.response_source: gen = req_context.get_response_generator() resp = Response( gen(), status=req_context.flow['response']['code'], headers=req_context.flow['response']['headers'] ) elif req_context.flow['response']: resp = Response( req_context.flow['response'].get('data', ''), status=req_context.flow['response'].get('code', 200), headers=req_context.flow['response'].get('headers', {}) ) else: path_not_found_handler.handle(req_context) req_context.update_client_resp_time() resp = req_context.response if context.application.is_diff_mode == context.MockMode.MULTIPLE and req_context.response_source == 'mock': proxy_handler.handle(req_context) if req_context.is_proxiable: req_context.update_response_headers_code2flow(output_key='proxy_response') req_context.update_response_data2flow(output_key='proxy_response') DuplicateHeaderKeyHandler.set_origin_header(resp.headers, req_context.flow['response']['headers']) context.emit('action', 'add flow log') # Close autocorrect response location. resp.autocorrect_location_header = False return resp
def proxy_request(request, new_header): try: endpoint_path = request.full_path if request.method == 'POST': res = post(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, data=request.data, stream=False) elif request.method == 'GET': res = get(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, stream=False) elif request.method == 'PUT': res = put(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, data=request.data, stream=False) elif request.method == 'DELETE': res = delete(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, stream=False) elif request.method == 'HEAD': res = head(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, stream=False) elif request.method == 'PATCH': res = patch(g_config["resource_server_endpoint"] + endpoint_path, headers=new_header, data=request.data, stream=False) else: response = Response() response.status_code = 501 return response excluded_headers = ['transfer-encoding'] headers = [(name, value) for (name, value) in res.raw.headers.items() if name.lower() not in excluded_headers] response = Response(res.content, res.status_code, headers) if "Location" in response.headers: response.autocorrect_location_header = False response.headers["Location"] = response.headers[ "Location"].replace(g_config["resource_server_endpoint"], '') return response except Exception as e: response = Response() logger.debug("Error while redirecting to resource: " + traceback.format_exc(), file=sys.stderr) response.status_code = 500 response.content = "Error while redirecting to resource: " + str(e) return response
def redirect(location): "drop-in replacement for flask's redirect that doesn't sanitize the redirect target URL" response = Response(f'Redirecting... to {location}', 302, mimetype="text/html") response.headers["Location"] = location response.headers["Content-Type"] = 'text/plain' response.autocorrect_location_header = False return response
def redirect(path, next_path=None): print(next_path) if (next_path): if (next_path[-1] == "?"): next_path = next_path[:-1] next_path = urllib.parse.quote(next_path) path += "?next=" + next_path res = Response("Redirect...") res.headers["Content-Type"] = "text/plain" res.headers["Location"] = path res.autocorrect_location_header = False return res, 302
def redirect(path,next_path=None): print(next_path) if(next_path): if(next_path[-1]=="?"): next_path = next_path[:-1] next_path = urllib.parse.quote(next_path) path += "?next=" + next_path res = Response("Redirect...") res.headers["Content-Type"] = "text/plain" res.headers["Location"] = path res.autocorrect_location_header = False return res,302
def _get_client(client_id): if request.method == 'GET': try: client = services.get_client(client_id=client_id) except NoResultFound: abort(404) resp = jsonify({'client': client}) resp.headers['Location'] = 'localhost:5000/clients' resp.status_code = 200 return resp # js = json.dumps(client) # # resp = Response(response=js, status=200, mimetype='application/json') # resp.headers['Location'] = 'localhost:5000/piece-mea/index' # # return resp elif request.method == 'PUT': name = request.form['name'] nickname = request.form['nickname'] email = request.form['email'] home = request.form['home'] mobile = request.form['mobile'] work = request.form['work'] result = services.edit_client(name=name, nickname=nickname, email=email, home=home, mobile=mobile, work=work) resp = jsonify({'client': result.data}) resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/client/{0}'.format(result.id) resp.autocorrect_location_header = False return resp elif request.method == 'DELETE': services.delete_client(client_id=client_id) resp = Response() resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/clients' resp.autocorrect_location_header = False return resp
def logout(): auth = request.authorization logout_user = request.args.get('user') if auth is not None and logout_user == auth.username: return authenticate() else: response = Response('<p>You should be redirected to URL: ' '<a href="%s">%s</a>.' % ('/index.html', '/index.html'), 302, mimetype='text/html') response.autocorrect_location_header = False response.headers['Location'] = '/index.html' return response
def _get_recipe(recipe_id): if request.method == 'GET': try: recipe = services.get_recipe(recipe_id=recipe_id) except NoResultFound: abort(404) resp = jsonify({'recipe': recipe.data}) resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}'.format(recipe.id) resp.autocorrect_location_header = False return resp elif request.method == 'PUT': recipe_name = request.form['recipe_name'] description = request.form['description'] style = request.form['style'] type = request.form['type'] result = services.edit_recipe(recipe_id=recipe_id, recipe_name=recipe_name, description=description, style=style, type=type) resp = jsonify({'recipe': result.data}) resp.status_code = 201 resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}'.format(result.id) resp.autocorrect_location_header = False # Get the parsed contents of the form data json = request.json print(json) # Render template return resp elif request.method == 'POST': recipe_id = request.form['recipe_id'] services.delete_recipe(recipe_id) resp = Response() resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/recipes' resp.autocorrect_location_header = False return resp
def get_one_book(object_id): try: book = data.get_book(object_id) if book is None: return jsonify(error="No book with an id of " + object_id + " found"), 404 resp = Response(json.dumps(book), status=200, mimetype='application/json') resp.headers['Location'] = f'/{object_id}' resp.autocorrect_location_header = False return resp except Exception as e: print(e) return jsonify(error=str(e)), 500
def update_one_book_partial(object_id): try: result = data.update_book_partial(object_id, request.get_json()) if result is None: return jsonify(error="The id specified is not a valid id"), 400 if result.matched_count == 0: return jsonify( error=f"No book with an id of {object_id} found to update" ), 404 resp = Response(status=200, mimetype='application/json') resp.headers['Location'] = f'/{object_id}' resp.autocorrect_location_header = False return resp except Exception as e: print(e) return jsonify(error=str(e)), 500
def create_one_book(): try: book = request.get_json() result = data.create_book(book) if result is None: return jsonify(error="The id specified is not a valid id"), 400 if "_id" in book: book['_id'] = str(book['_id']) resp = Response(json.dumps(book), status=201, mimetype='application/json') resp.headers['Location'] = f'/{result.inserted_id}' resp.autocorrect_location_header = False return resp except Exception as e: print(e) return jsonify(error=str(e)), 500
def _get_menu(menu_id): if request.method == 'GET': try: menu = services.get_menu(menu_id=menu_id) except NoResultFound: abort(404) return jsonify({'menu': menu}) elif request.method == 'PUT': id = request.form['menu_id'] description = request.form['description'] start_date = request.form['start_date'] end_date = request.form['end_date'] result = services.edit_menu(id=id, start_date=start_date, description=description, end_date=end_date) resp = jsonify({'ingredient': result.data}) resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/ingredients/{0}'.format(result.id) resp.autocorrect_location_header = False # Get the parsed contents of the form data json = request.json return resp elif request.method == 'DELETE': services.delete_menu(menu_id=menu_id) resp = Response() resp.status_code = 200 resp.headers['Location'] = '/cah/api/v1.0/menus' resp.autocorrect_location_header = False return resp
def handle_request(): request_id = request.headers.get('X-B3-TraceId') or ''.join(choices(request_id_alphabet, k=8)) logger.info('[%s] Start', request_id) # Must have X-CF-Forwarded-Url to match route try: forwarded_url = request.headers['X-CF-Forwarded-Url'] except KeyError: logger.error('[%s] Missing X-CF-Forwarded-Url header', request_id) return render_access_denied('Unknown', 'Unknown', request_id) logger.info('[%s] Forwarded URL: %s', request_id, forwarded_url) parsed_url = urllib.parse.urlsplit(forwarded_url) # Find x-forwarded-for try: x_forwarded_for = request.headers['X-Forwarded-For'] except KeyError: logger.error('[%s] X-Forwarded-For header is missing', request_id) return render_access_denied('Unknown', forwarded_url, request_id) logger.debug('[%s] X-Forwarded-For: %s', request_id, x_forwarded_for) def get_client_ip(route): try: return x_forwarded_for.split(',')[int(route['IP_DETERMINED_BY_X_FORWARDED_FOR_INDEX'])].strip() except IndexError: logger.debug('[%s] Not enough addresses in x-forwarded-for %s', request_id, x_forwarded_for) routes = env['ROUTES'] hostname_ok = [ re.match(route['HOSTNAME_REGEX'], parsed_url.hostname) for route in routes ] client_ips = [ get_client_ip(route) for route in routes ] ip_ok = [ any(client_ips[i] and IPv4Address(client_ips[i]) in IPv4Network(ip_range) for ip_range in route['IP_RANGES']) for i, route in enumerate(routes) ] shared_secrets = [ route.get('SHARED_SECRET_HEADER', []) for route in routes ] shared_secret_ok = [ [ ( shared_secret['NAME'] in request.headers and constant_time_is_equal(shared_secret['VALUE'].encode(), request.headers[shared_secret['NAME']].encode()) ) for shared_secret in shared_secrets[i] ] for i, _ in enumerate(routes) ] # In general, any matching basic auth credentials are accepted. However, # on authentication paths, only those with that path are accepted, and # on failure, a 401 is returned to request the correct credentials basic_auths = [ route.get('BASIC_AUTH', []) for route in routes ] basic_auths_ok = [ [ request.authorization and constant_time_is_equal(basic_auth['USERNAME'].encode(), request.authorization.username.encode()) and constant_time_is_equal(basic_auth['PASSWORD'].encode(), request.authorization.password.encode()) for basic_auth in basic_auths[i] ] for i, _ in enumerate(routes) ] on_auth_path_and_ok = [ [ basic_auths_ok[i][j] for j, basic_auth in enumerate(basic_auths[i]) if parsed_url.path == basic_auth['AUTHENTICATE_PATH'] ] for i, _ in enumerate(routes) ] any_on_auth_path_and_ok = any([ any(on_auth_path_and_ok[i]) for i, _ in enumerate(routes) ]) should_request_auth = not any_on_auth_path_and_ok and any( ( hostname_ok[i] and ip_ok[i] and (not shared_secrets[i] or any(shared_secret_ok[i])) and len(on_auth_path_and_ok[i]) and all(not ok for ok in on_auth_path_and_ok[i]) ) for i, _ in enumerate(routes) ) should_respond_ok_to_auth_request = any( ( hostname_ok[i] and ip_ok[i] and (not shared_secrets[i] or any(shared_secret_ok[i])) and len(on_auth_path_and_ok[i]) and any(on_auth_path_and_ok[i]) ) for i, _ in enumerate(routes) ) any_route_with_all_checks_passed = any( ( hostname_ok[i] and ip_ok[i] and (not shared_secrets[i] or any(shared_secret_ok[i])) and (not basic_auths[i] or any(basic_auths_ok[i])) ) for i, _ in enumerate(routes) ) # There is no perfect answer as to which IP to present to the client in # the light of multiple routes with different indexes of the # x-forwarded-for header. However, in real cases it is likely that if the # host matches, then that will be the correct one. If 'Unknown' is then # shown to the user, it suggests something has been misconfigured client_ip = next( (client_ips[i] for i, _ in enumerate(routes) if hostname_ok[i]) , 'Unknown') headers_to_remove = tuple(set( shared_secret['NAME'].lower() for i, _ in enumerate(routes) for shared_secret in shared_secrets[i] )) + ('host', 'x-cf-forwarded-url', 'connection') if should_request_auth: return Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) if should_respond_ok_to_auth_request: return 'ok' if not any_route_with_all_checks_passed: logger.warning( '[%s] No matching route; host: %s client ip: %s', request_id, parsed_url.hostname, client_ip) return render_access_denied(client_ip, forwarded_url, request_id) logger.info('[%s] Making request to origin', request_id) def downstream_data(): while True: contents = request.stream.read(65536) if not contents: break yield contents origin_response = http.request( request.method, forwarded_url, headers={ k: v for k, v in request.headers if k.lower() not in headers_to_remove }, preload_content=False, redirect=False, assert_same_host=False, body=downstream_data(), ) logger.info('[%s] Origin response status: %s', request_id, origin_response.status) def release_conn(): origin_response.release_conn() logger.info('[%s] End', request_id) downstream_response = Response( origin_response.stream(65536, decode_content=False), status=origin_response.status, headers=[ (k, v) for k, v in origin_response.headers.items() if k.lower() != 'connection' ], ) downstream_response.autocorrect_location_header = False downstream_response.call_on_close(release_conn) logger.info('[%s] Starting response to client', request_id) return downstream_response