From ffeda35ff75a2802a03281e7d7ccc351009f0714 Mon Sep 17 00:00:00 2001 From: Tirumarai Selvan Date: Thu, 14 Nov 2019 01:55:11 +0530 Subject: [PATCH] add few x-forwarded- headers (close #2572) (#3347) --- server/src-lib/Hasura/GraphQL/Execute.hs | 9 ++++++++- server/tests-py/conftest.py | 2 +- server/tests-py/context.py | 3 ++- server/tests-py/graphql_server.py | 14 ++++++++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/server/src-lib/Hasura/GraphQL/Execute.hs b/server/src-lib/Hasura/GraphQL/Execute.hs index b2faf129..a2cedfbb 100644 --- a/server/src-lib/Hasura/GraphQL/Execute.hs +++ b/server/src-lib/Hasura/GraphQL/Execute.hs @@ -366,9 +366,10 @@ execRemoteGQ reqId userInfo reqHdrs q rsi opDef = do let confHdrs = map (\(k, v) -> (CI.mk $ CS.cs k, CS.cs v)) hdrs clientHdrs = bool [] filteredHeaders fwdClientHdrs -- filter out duplicate headers - -- priority: conf headers > resolved userinfo vars > client headers + -- priority: conf headers > resolved userinfo vars > x-forwarded headers > client headers hdrMaps = [ Map.fromList confHdrs , Map.fromList userInfoToHdrs + , Map.fromList xForwardedHeaders , Map.fromList clientHdrs ] headers = Map.toList $ foldr Map.union Map.empty hdrMaps @@ -400,6 +401,12 @@ execRemoteGQ reqId userInfo reqHdrs q rsi opDef = do userInfoToList userInfo filteredHeaders = filterUserVars $ filterRequestHeaders reqHdrs + xForwardedHeaders = flip mapMaybe reqHdrs $ \(hdrName, hdrValue) -> + case hdrName of + "Host" -> Just ("X-Forwarded-Host", hdrValue) + "User-Agent" -> Just ("X-Forwarded-User-Agent", hdrValue) + _ -> Nothing + filterUserVars hdrs = let txHdrs = map (\(n, v) -> (bsToTxt $ CI.original n, bsToTxt v)) hdrs in map (\(k, v) -> (CI.mk $ CS.cs k, CS.cs v)) $ diff --git a/server/tests-py/conftest.py b/server/tests-py/conftest.py index 408af263..056a25e9 100644 --- a/server/tests-py/conftest.py +++ b/server/tests-py/conftest.py @@ -102,13 +102,13 @@ def pytest_cmdline_preparse(config, args): def pytest_configure(config): if is_master(config): - config.hge_ctx_gql_server = HGECtxGQLServer() if not config.getoption('--hge-urls'): print("hge-urls should be specified") if not config.getoption('--pg-urls'): print("pg-urls should be specified") config.hge_url_list = config.getoption('--hge-urls') config.pg_url_list = config.getoption('--pg-urls') + config.hge_ctx_gql_server = HGECtxGQLServer(config.hge_url_list) if config.getoption('-n', default=None): xdist_threads = config.getoption('-n') assert xdist_threads <= len(config.hge_url_list), "Not enough hge_urls specified, Required " + str(xdist_threads) + ", got " + str(len(config.hge_url_list)) diff --git a/server/tests-py/context.py b/server/tests-py/context.py index bf988c8f..e18c510e 100644 --- a/server/tests-py/context.py +++ b/server/tests-py/context.py @@ -223,9 +223,10 @@ class EvtsWebhookServer(http.server.HTTPServer): self.evt_trggr_web_server.join() class HGECtxGQLServer: - def __init__(self): + def __init__(self, hge_urls): # start the graphql server self.graphql_server = graphql_server.create_server('127.0.0.1', 5000) + self.hge_urls = graphql_server.set_hge_urls(hge_urls) self.gql_srvr_thread = threading.Thread(target=self.graphql_server.serve_forever) self.gql_srvr_thread.start() diff --git a/server/tests-py/graphql_server.py b/server/tests-py/graphql_server.py index c747de65..e5cfdf02 100644 --- a/server/tests-py/graphql_server.py +++ b/server/tests-py/graphql_server.py @@ -12,6 +12,8 @@ from enum import Enum import time +HGE_URLS=[] + def mkJSONResp(graphql_result): return Response(HTTPStatus.OK, graphql_result.to_dict(), {'Content-Type': 'application/json'}) @@ -615,12 +617,16 @@ class HeaderTest(graphene.ObjectType): def resolve_wassup(self, info, arg): headers = info.context + hosts = list(map(lambda o: urlparse(o).netloc, HGE_URLS)) if not (headers.get_all('x-hasura-test') == ['abcd'] and headers.get_all('x-hasura-role') == ['user'] and headers.get_all('x-hasura-user-id') == ['abcd1234'] and headers.get_all('content-type') == ['application/json'] and - headers.get_all('Authorization') == ['Bearer abcdef']): - raise Exception('headers dont match. Received: ' + headers) + headers.get_all('Authorization') == ['Bearer abcdef'] and + len(headers.get_all('x-forwarded-host')) == 1 and + all(host in headers.get_all('x-forwarded-host') for host in hosts) and + headers.get_all('x-forwarded-user-agent') == ['python-requests/2.22.0']): + raise Exception('headers dont match. Received: ' + str(headers)) return "Hello " + arg @@ -669,6 +675,10 @@ def stop_server(server): server.shutdown() server.server_close() +def set_hge_urls(hge_urls = []): + global HGE_URLS + HGE_URLS=hge_urls + if __name__ == '__main__': s = create_server(host='0.0.0.0') s.serve_forever()