This is an automated email from the ASF dual-hosted git repository.

paziz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new b115de7  option for using the host field for response lookup
b115de7 is described below

commit b115de779c4399199989ddce7b745cf18f2d9a86
Author: Persia Aziz <per...@yahoo-inc.com>
AuthorDate: Tue Dec 12 19:01:07 2017 -0600

    option for using the host field for response lookup
---
 tests/gold_tests/autest-site/microserver.test.ext | 57 ++++++++++++++++---
 tests/gold_tests/remap/gold/lookupTest.gold       | 14 +++++
 tests/gold_tests/remap/remap_http.test.py         | 21 ++++++-
 tests/tools/microServer/uWServer.py               | 67 ++++++++++++++++++-----
 4 files changed, 134 insertions(+), 25 deletions(-)

diff --git a/tests/gold_tests/autest-site/microserver.test.ext 
b/tests/gold_tests/autest-site/microserver.test.ext
index 1ca1cb4..4ab6783 100644
--- a/tests/gold_tests/autest-site/microserver.test.ext
+++ b/tests/gold_tests/autest-site/microserver.test.ext
@@ -49,16 +49,54 @@ def addResponse(self, filename, testName, request_header, 
response_header):
     self.Setup.CopyAs(absFilepath, self.Variables.DataDir)
     return
 
+def getHeaderFieldVal(request_header, field):
+    requestline = request_header["headers"].split("\r\n")[0]
+    requestline = requestline.split(" ")[1]
+    field = field+':'
+    valField = request_header["headers"].split(field,1);
+    val=""
+    if len(valField)>1:
+            field_v = valField[1].split("\r\n",1)
+            if len(field_v)>0:
+                val = field_v[0].strip()
+    return val
 
 # addResponse adds customized response with respect to request_header. 
request_header and response_header are both dictionaries
 def addResponse(self, filename, request_header, response_header):
     requestline = request_header["headers"].split("\r\n")[0]
-    requestline = requestline.split(" ")[1]
-    resourceLocation = requestline.split("/", 1)
-    if len(resourceLocation) > 1:
-        rl = resourceLocation[1]
-    else:
-        rl = ""
+    host_ = ""
+    path_ = ""
+    if requestline:
+        url_part = requestline.split(" ")
+        if len(url_part)>1:
+            if url_part[1].startswith("http"):
+                path_ = url_part[1].split("/",2)[2]
+                host_,path_ = path_.split("/",1)
+            else:
+                path_ = url_part[1].split("/",1)[1]
+
+    kpath = ""
+    #print("Format of lookup key",self.Variables.lookup_key)
+    
+    argsList = []
+    keyslist = self.Variables.lookup_key.split("}")
+    for keystr in keyslist:
+        if keystr == '{PATH':
+            kpath = kpath+path_
+            continue
+        if keystr == '{HOST':
+            kpath = kpath + host_
+            continue
+        if keystr == '': #empty
+            continue
+        stringk = keystr.replace("{%","")
+        argsList.append(stringk)
+    KeyList = []
+    for argsL in argsList:
+        field_val = getHeaderFieldVal(request_header,argsL)
+        if field_val!=None:
+            KeyList.append(field_val)
+    rl = "".join(KeyList)+kpath
     txn = dict()
     txn["timestamp"] = ""
     txn["uuid"] = rl
@@ -103,7 +141,7 @@ def makeHeader(self, requestString, **kwargs):
     return headerStr
 
 
-def MakeOriginServer(obj, name, port=False, ip=False, delay=False, ssl=False, 
options={}):
+def MakeOriginServer(obj, name, port=False, ip=False, delay=False, ssl=False, 
lookup_key='{PATH}', options={}):
     server_path = os.path.join(obj.Variables.AtsTestToolsDir, 
'microServer/uWServer.py')
     data_dir = os.path.join(obj.RunDirectory, name)
     # create Process
@@ -114,8 +152,8 @@ def MakeOriginServer(obj, name, port=False, ip=False, 
delay=False, ssl=False, op
         ip = '127.0.0.1'
     if (delay == False):
         delay = 0
-    command = "python3 {0} --data-dir {1} --port {2} --ip_address {3} --delay 
{4} -m test --ssl {5}".format(
-        server_path, data_dir, port, ip, delay, ssl)
+    command = "python3 {0} --data-dir {1} --port {2} --ip_address {3} --delay 
{4} -m test --ssl {5} --lookupkey '{6}'".format(
+        server_path, data_dir, port, ip, delay, ssl,lookup_key)
     for flag, value in options.items():
         command += " {} {}".format(flag, value)
 
@@ -123,6 +161,7 @@ def MakeOriginServer(obj, name, port=False, ip=False, 
delay=False, ssl=False, op
     p.Command = command
     p.Setup.MakeDir(data_dir)
     p.Variables.DataDir = data_dir
+    p.Variables.lookup_key = lookup_key
     p.Ready = When.PortOpen(port, ip)
     p.ReturnCode = Any(None,0)
     AddMethodToInstance(p, addResponse)
diff --git a/tests/gold_tests/remap/gold/lookupTest.gold 
b/tests/gold_tests/remap/gold/lookupTest.gold
new file mode 100644
index 0000000..bdf7213
--- /dev/null
+++ b/tests/gold_tests/remap/gold/lookupTest.gold
@@ -0,0 +1,14 @@
+``
+> GET http://www.testexample.com/test``
+> Host: www.testexample.com``
+> User-Agent: curl/``
+> Accept: */*
+``
+< HTTP/1.1 200 OK
+< Date: ``
+< Age: ``
+< Transfer-Encoding: chunked
+< Proxy-Connection: keep-alive
+< Server: ATS/``
+< 
+``
diff --git a/tests/gold_tests/remap/remap_http.test.py 
b/tests/gold_tests/remap/remap_http.test.py
index 1be7211..7249f28 100644
--- a/tests/gold_tests/remap/remap_http.test.py
+++ b/tests/gold_tests/remap/remap_http.test.py
@@ -28,6 +28,7 @@ Test.ContinueOnFail = True
 # Define default ATS
 ts = Test.MakeATSProcess("ts")
 server = Test.MakeOriginServer("server")
+server2 = Test.MakeOriginServer("server2",lookup_key="{%Host}{PATH}")
 dns = Test.MakeDNServer("dns")
 
 Test.testName = ""
@@ -35,11 +36,16 @@ request_header = {"headers": "GET / HTTP/1.1\r\nHost: 
www.example.com\r\n\r\n",
 # expected response from the origin server
 response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
 
+request_header2 = {"headers": "GET /test HTTP/1.1\r\nHost: 
www.testexample.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+# expected response from the origin server
+response_header2 = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+
 # add response to the server dictionary
 server.addResponse("sessionfile.log", request_header, response_header)
+server2.addResponse("sessionfile.log",request_header2, response_header2)
 ts.Disk.records_config.update({
     'proxy.config.diags.debug.enabled': 1,
-    'proxy.config.diags.debug.tags': 'http.*|dns',
+    'proxy.config.diags.debug.tags': 'http.*|dns|conf_remap',
     'proxy.config.http.referer_filter': 1,
     'proxy.config.dns.nameservers': '127.0.0.1:{0}'.format(dns.Variables.Port),
     'proxy.config.dns.resolv_conf': 'NULL'
@@ -61,7 +67,12 @@ ts.Disk.remap_config.AddLine(
     'map http://testDNS.com 
http://audrey.hepburn.com:{0}'.format(server.Variables.Port)
 )
 
+ts.Disk.remap_config.AddLine(
+    'map http://www.testexample.com http://127.0.0.1:{0} @plugin=conf_remap.so 
@pparam=proxy.config.url_remap.pristine_host_hdr=1'.format(server2.Variables.Port)
+)
+
 dns.addRecords(records={"audrey.hepburn.com.": ["127.0.0.1"]})
+dns.addRecords(records={"whatever.com.": ["127.0.0.1"]})
 
 # call localhost straight
 tr = Test.AddTestRun()
@@ -135,3 +146,11 @@ tr.Processes.Default.Command = 'curl  --proxy 
127.0.0.1:{0} "http://testDNS.com";
     ts.Variables.port)
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Streams.stderr = "gold/remap-DNS-200.gold"
+
+# microserver lookup test
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'curl --proxy 127.0.0.1:{0} 
"http://www.testexample.com/test"; -H "Host: www.testexample.com" 
--verbose'.format(ts.Variables.port)
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.StartBefore(server2)
+tr.Processes.Default.Streams.stderr = "gold/lookupTest.gold"
+tr.StillRunningAfter = server2
diff --git a/tests/tools/microServer/uWServer.py 
b/tests/tools/microServer/uWServer.py
index 97aaaec..b646608 100644
--- a/tests/tools/microServer/uWServer.py
+++ b/tests/tools/microServer/uWServer.py
@@ -35,6 +35,7 @@ import socket
 import importlib.util
 import time
 test_mode_enabled = True
+lookup_key_ = "{PATH}"
 __version__ = "1.0"
 
 
@@ -168,17 +169,43 @@ class MyHandler(BaseHTTPRequestHandler):
         else:
             readChunks()
 
-    def getTestName(self, requestline):
-        key = None
-        keys = requestline.split(" ")
-        # print(keys)
-        if keys:
-            rkey = keys[1]
-        key = rkey.split("/", 1)[1]
-        if key + "/" in G_replay_dict:
-            key = key + "/"
-        elif len(key) > 1 and key[:-1] in G_replay_dict:
-            key = key[:-1]
+    def getLookupKey(self, requestline):
+        global lookup_key_
+        kpath= ""
+        path = ""
+        url_part = requestline.split(" ")
+        if url_part:
+            if url_part[1].startswith("http"):
+                path = url_part[1].split("/",2)[2]
+                host_, path = path.split("/",1)
+            else:
+                path = url_part[1].split("/",1)[1]
+        argsList = []
+        keyslist = lookup_key_.split("}")
+        for keystr in keyslist:            
+            if keystr == '{PATH':
+                kpath = kpath+path
+                continue # do not include path in the list of header fields
+            if keystr == '{HOST':
+                kpath = kpath+host_
+                continue
+            stringk = keystr.replace("{%","")
+            argsList.append(stringk)
+        KeyList = []
+        for argsL in argsList:
+            print("args",argsL,len(argsL))
+            if len(argsL)>0:
+                val = self.headers.get(argsL)
+                if val:
+                    field_val,__ = cgi.parse_header(val)
+                else:
+                    field_val=None
+                if field_val!=None:
+                    KeyList.append(field_val)
+        key = "".join(KeyList)+kpath
+        print("lookup key",key, len(key))
+
+
         return key
 
     def parseRequestline(self, requestline):
@@ -370,7 +397,7 @@ class MyHandler(BaseHTTPRequestHandler):
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
             time.sleep(time_delay)
-            request_hash = self.getTestName(self.requestline)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = 
cgi.parse_header(self.headers.get('Content-MD5'))
         # print("key:",request_hash)
@@ -445,7 +472,7 @@ class MyHandler(BaseHTTPRequestHandler):
     def do_HEAD(self):
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
-            request_hash = self.getTestName(self.requestline)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = 
cgi.parse_header(self.headers.get('Content-MD5'))
 
@@ -483,7 +510,7 @@ class MyHandler(BaseHTTPRequestHandler):
         chunkedResponse = False
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
-            request_hash = self.getTestName(self.requestline)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = 
cgi.parse_header(self.headers.get('Content-MD5'))
         try:
@@ -653,6 +680,15 @@ def main():
                         type=str,
                         default='',
                         help="A file which will install observers on hooks")
+    parser.add_argument("--lookupkey",
+                        type=str,
+                        default="{PATH}",
+                        help="format string used as a key for response lookup: 
\
+                        example: \"{%Host}{%Server}{PATH}\", \"{HOST}{PATH}\", 
\"{PATH}\"\
+                        All the args preceded by % are header fields in the 
request\
+                        The only two acceptable arguments which are not header 
fields are : fqdn (represented by HOST) and the url path (represented by PATH) 
in a request line.\
+                        Example: given a client request as  << GET 
/some/resource/location HTTP/1.1\nHost: hahaha.com\n\n >>, if the user wishes 
the host field and the path to be used for the response lookup\
+                        then the required format will be {%Host}{PATH}")
 
     args = parser.parse_args()
     options = args
@@ -668,7 +704,8 @@ def main():
     try:
         socket_timeout = args.timeout
         test_mode_enabled = args.mode == "test"
-
+        global lookup_key_
+        lookup_key_ = args.lookupkey
         MyHandler.protocol_version = HTTP_VERSION
         if options.ssl == "True" or options.ssl == "true":
             server = SSLServer((options.ip_address, options.port), MyHandler, 
options)

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].

Reply via email to