You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by rr...@apache.org on 2021/07/21 17:25:01 UTC

[trafficserver] branch master updated: Adds new X-Effective-URL header to the xdebug plugin (#7931)

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

rrm 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 170e12b  Adds new X-Effective-URL header to the xdebug plugin (#7931)
170e12b is described below

commit 170e12b43c0e28cf44d3e5c80220a2a8a2d4fba9
Author: jhiapple <85...@users.noreply.github.com>
AuthorDate: Wed Jul 21 20:24:51 2021 +0300

    Adds new X-Effective-URL header to the xdebug plugin (#7931)
    
    By adding "X-Effective-URL" to the request header "X-Debug",
    the header "X-Effective-URL" header will be inserted to the
    request headers with the effective URL value.
    
    Exposes the TSHttpTxnEffectiveUrlStringGet() result, which is
    the URL after the remap.
---
 plugins/xdebug/xdebug.cc                           | 30 ++++++++
 .../pluginTest/xdebug/x_effective_url/none.in      |  5 ++
 .../pluginTest/xdebug/x_effective_url/one.in       |  5 ++
 .../pluginTest/xdebug/x_effective_url/out.gold     | 61 ++++++++++++++++
 .../pluginTest/xdebug/x_effective_url/three.in     |  5 ++
 .../pluginTest/xdebug/x_effective_url/two.in       |  5 ++
 .../xdebug/x_effective_url/x_effective_url.test.py | 81 ++++++++++++++++++++++
 7 files changed, 192 insertions(+)

diff --git a/plugins/xdebug/xdebug.cc b/plugins/xdebug/xdebug.cc
index f0b1d30..9d34655 100644
--- a/plugins/xdebug/xdebug.cc
+++ b/plugins/xdebug/xdebug.cc
@@ -83,6 +83,7 @@ enum {
   XHEADER_X_PROBE_HEADERS  = 1u << 9,
   XHEADER_X_PSELECT_KEY    = 1u << 10,
   XHEADER_X_CACHE_INFO     = 1u << 11,
+  XHEADER_X_EFFECTIVE_URL  = 1u << 12,
 };
 
 static TSCont XInjectHeadersCont  = nullptr;
@@ -377,6 +378,29 @@ InjectRemapHeader(TSHttpTxn txn, TSMBuffer buffer, TSMLoc hdr)
 }
 
 static void
+InjectEffectiveURLHeader(TSHttpTxn txn, TSMBuffer buffer, TSMLoc hdr)
+{
+  struct {
+    char *ptr;
+    int len;
+  } strval = {nullptr, 0};
+
+  TSDebug("xdebug", "attempting to inject X-Effective-URL header");
+
+  strval.ptr = TSHttpTxnEffectiveUrlStringGet(txn, &strval.len);
+
+  if (strval.ptr != nullptr && strval.len > 0) {
+    TSMLoc dst = FindOrMakeHdrField(buffer, hdr, "X-Effective-URL", lengthof("X-Effective-URL"));
+    if (dst != TS_NULL_MLOC) {
+      TSReleaseAssert(TSMimeHdrFieldValueStringInsert(buffer, hdr, dst, -1 /* idx */, strval.ptr, strval.len) == TS_SUCCESS);
+      TSHandleMLocRelease(buffer, hdr, dst);
+    }
+  }
+
+  TSfree(strval.ptr);
+}
+
+static void
 InjectTxnUuidHeader(TSHttpTxn txn, TSMBuffer buffer, TSMLoc hdr)
 {
   TSMLoc dst = FindOrMakeHdrField(buffer, hdr, "X-Transaction-ID", lengthof("X-Transaction-ID"));
@@ -484,6 +508,10 @@ XInjectResponseHeaders(TSCont /* contp */, TSEvent event, void *edata)
     InjectRemapHeader(txn, buffer, hdr);
   }
 
+  if (xheaders & XHEADER_X_EFFECTIVE_URL) {
+    InjectEffectiveURLHeader(txn, buffer, hdr);
+  }
+
   // intentionally placed after all injected headers.
 
   if (xheaders & XHEADER_X_DUMP_HEADERS) {
@@ -649,6 +677,8 @@ XScanRequestHeaders(TSCont /* contp */, TSEvent event, void *edata)
           snprintf(newVal, sizeof(newVal), "fwd=%" PRIiMAX, fwdCnt - 1);
           TSMimeHdrFieldValueStringSet(buffer, hdr, field, i, newVal, std::strlen(newVal));
         }
+      } else if (header_field_eq("x-effective-url", value, vsize)) {
+        xheaders |= XHEADER_X_EFFECTIVE_URL;
       } else {
         TSDebug("xdebug", "ignoring unrecognized debug tag '%.*s'", vsize, value);
       }
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/none.in b/tests/gold_tests/pluginTest/xdebug/x_effective_url/none.in
new file mode 100644
index 0000000..e07b306
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/none.in
@@ -0,0 +1,5 @@
+GET /argh HTTP/1.1
+Host: none
+X-Debug: X-Effective-URL
+Connection: close
+
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/one.in b/tests/gold_tests/pluginTest/xdebug/x_effective_url/one.in
new file mode 100644
index 0000000..d922325
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/one.in
@@ -0,0 +1,5 @@
+GET /argh HTTP/1.1
+Host: one
+X-Debug: x-effective-url
+Connection: close
+
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/out.gold b/tests/gold_tests/pluginTest/xdebug/x_effective_url/out.gold
new file mode 100644
index 0000000..7af772a
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/out.gold
@@ -0,0 +1,61 @@
+HTTP/1.1 500 Cannot find server.
+Date: ``
+Connection: close
+Server: ATS/``
+Cache-Control: no-store
+Content-Type: text/html
+Content-Language: en
+X-Effective-URL: http://none/argh
+Content-Length: 391
+
+<HTML>
+<HEAD>
+<TITLE>Unknown Host</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="white" FGCOLOR="black">
+<H1>Unknown Host</H1>
+<HR>
+
+<FONT FACE="Helvetica,Arial"><B>
+Description: Unable to locate the server requested ---
+the server does not have a DNS entry.  Perhaps there is a misspelling
+in the server name, or the server no longer exists.  Double-check the
+name and try again.
+</B></FONT>
+<HR>
+</BODY>
+======
+HTTP/1.1 200 OK
+Date: ``
+Age: ``
+Transfer-Encoding: chunked
+Connection: close
+Server: ATS/``
+X-Effective-URL: http://127.0.0.1:SERVER_PORT/argh
+
+0
+
+======
+HTTP/1.1 200 OK
+Date: ``
+Age: ``
+Transfer-Encoding: chunked
+Connection: close
+Server: ATS/``
+X-Effective-URL: http://127.0.0.1:SERVER_PORT/two/argh
+
+0
+
+======
+HTTP/1.1 200 OK
+Date: ``
+Age: ``
+Transfer-Encoding: chunked
+Connection: close
+Server: ATS/``
+X-Effective-URL: http://127.0.0.1:SERVER_PORT/argh
+
+0
+
+======
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/three.in b/tests/gold_tests/pluginTest/xdebug/x_effective_url/three.in
new file mode 100644
index 0000000..7076c1a
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/three.in
@@ -0,0 +1,5 @@
+GET /argh HTTP/1.1
+Host: three123
+X-Debug: X-effective-url
+Connection: close
+
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/two.in b/tests/gold_tests/pluginTest/xdebug/x_effective_url/two.in
new file mode 100644
index 0000000..52ded33
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/two.in
@@ -0,0 +1,5 @@
+GET /argh HTTP/1.1
+Host: two
+X-Debug: X-EFFECTIVE-URL
+Connection: close
+
diff --git a/tests/gold_tests/pluginTest/xdebug/x_effective_url/x_effective_url.test.py b/tests/gold_tests/pluginTest/xdebug/x_effective_url/x_effective_url.test.py
new file mode 100644
index 0000000..ed1c3b5
--- /dev/null
+++ b/tests/gold_tests/pluginTest/xdebug/x_effective_url/x_effective_url.test.py
@@ -0,0 +1,81 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+Test.Summary = '''
+Test xdebug plugin X-Effective header
+'''
+
+server = Test.MakeOriginServer("server")
+
+request_header = {
+    "headers": "GET /argh HTTP/1.1\r\nHost: doesnotmatter\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n",
+                   "timestamp": "1469733493.993", "body": ""}
+server.addResponse("sessionlog.json", request_header, response_header)
+
+request_header_two = {
+    "headers": "GET /two/argh HTTP/1.1\r\nHost: doesnotmatter\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+server.addResponse("sessionlog.json", request_header_two, response_header)
+
+ts = Test.MakeATSProcess("ts")
+
+ts.Disk.records_config.update({
+    'proxy.config.url_remap.remap_required': 0,
+    'proxy.config.diags.debug.enabled': 0,
+})
+
+ts.Disk.plugin_config.AddLine('xdebug.so')
+
+ts.Disk.remap_config.AddLine(
+    "map http://one http://127.0.0.1:{0}".format(server.Variables.Port)
+)
+ts.Disk.remap_config.AddLine(
+    "map http://two http://127.0.0.1:{0}".format(server.Variables.Port) + "/two"
+)
+ts.Disk.remap_config.AddLine(
+    "regex_map http://three[0-9]+ http://127.0.0.1:{0}".format(server.Variables.Port)
+)
+
+tr = Test.AddTestRun()
+tr.Processes.Default.StartBefore(Test.Processes.ts)
+tr.Processes.Default.StartBefore(Test.Processes.server)
+tr.Processes.Default.Command = "cp {}/tcp_client.py {}/tcp_client.py".format(
+    Test.Variables.AtsTestToolsDir, Test.RunDirectory)
+tr.Processes.Default.ReturnCode = 0
+
+
+def sendMsg(msgFile):
+
+    tr = Test.AddTestRun()
+    tr.Processes.Default.Command = (
+        "( python3 {}/tcp_client.py 127.0.0.1 {} {}/{}.in".format(
+            Test.RunDirectory, ts.Variables.port, Test.TestDirectory, msgFile) +
+        " ; echo '======' ) | sed 's/:{}/:SERVER_PORT/' >>  {}/out.log 2>&1 ".format(
+            server.Variables.Port, Test.RunDirectory)
+    )
+    tr.Processes.Default.ReturnCode = 0
+
+
+sendMsg('none')
+sendMsg('one')
+sendMsg('two')
+sendMsg('three')
+
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = "echo test out.gold"
+tr.Processes.Default.ReturnCode = 0
+f = tr.Disk.File("out.log")
+f.Content = "out.gold"