Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong URI when using auth_request directive #180

Open
sriemer opened this issue Aug 9, 2021 · 0 comments
Open

Wrong URI when using auth_request directive #180

sriemer opened this issue Aug 9, 2021 · 0 comments

Comments

@sriemer
Copy link
Contributor

sriemer commented Aug 9, 2021

This is about:

{ngx_string("http.url"), ngx_string("$scheme://$http_host$request_uri")},

This uses the unparsed URI. But the parsed URI $scheme://$http_host$uri is required for (auth) subrequests.

Got NGINX Plus R24 and the Instana tracer with patched defaults here (tracing is always on, locations aren't traced).
Test config: nginx-auth-test.conf.txt
Issuing the request: wget -O- 'http://127.0.0.1:8081/private'

Getting spans:

/private (301, port 8081)
 \
   /private (200, port 8081, in reality subrequest to /auth)
    \
      /auth (200, port 8080)
 \
   /private (301, port 8080)

I've implemented this like this now:

--- a/opentracing/src/request_tracing.cpp
+++ b/opentracing/src/request_tracing.cpp
@@ -45,7 +45,23 @@ static void add_script_tags(ngx_array_t *tags, ngx_http_request_t *request,
   auto add_tag = [&](const opentracing_tag_t &tag) {
     auto key = tag.key_script.run(request);
     auto value = tag.value_script.run(request);
-    if (key.data && value.data) span.SetTag(to_string(key), to_string(value));
+    if (key.data && value.data) {
+      // Replace unparsed URI with parsed URI for subrequests
+      // Needed for using `auth_request` directive
+      if (request != request->main && to_string(key) == "http.url") {
+        std::string new_value = to_string(value);
+        size_t uri_pos = new_value.rfind(to_string(request->unparsed_uri));
+        if (uri_pos != std::string::npos) {
+          new_value.replace(uri_pos, new_value.length() - uri_pos,
+              reinterpret_cast<const char *>(request->uri.data), request->uri.len);
+          span.SetTag(to_string(key), new_value);
+        } else {
+          span.SetTag(to_string(key), to_string(value));
+        }
+      } else {
+        span.SetTag(to_string(key), to_string(value));
+      }
+    }
   };
   for_each<opentracing_tag_t>(*tags, add_tag);
 }

Getting spans:

/private (301, port 8081)
 \
   /auth (200, port 8081, subrequest)
    \
      /auth (200, port 8080)
 \
   /private (301, port 8080)

The search for the key and the possible further memory allocation are sub optimal. I haven't found any better possibility yet.

Thoughts on this? Do you have a better idea how to implement this? TIA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant