We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
nginx-opentracing + libdd_opentracing_plugin: SpanContextCorruptedException: failed to extract span context
I'm trying to set up an integration of nginx + nginx-opentracing module + DataDog tracer plugin + sample python app in order to get working multi-span traces in a manner when an app uses propagated context.

I'm getting the following error on every call:

```
ERROR:root:trace extract failed: failed to extract span context
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/opentracing_instrumentation/http_server.py", line 75, in before_request
    format=Format.HTTP_HEADERS, carrier=carrier
  File "/usr/local/lib/python2.7/dist-packages/ddtrace-0.20.4-py2.7.egg/ddtrace/opentracer/tracer.py", line 294, in extract
    ot_span_ctx = propagator.extract(carrier)
  File "/usr/local/lib/python2.7/dist-packages/ddtrace-0.20.4-py2.7.egg/ddtrace/opentracer/propagation/http.py", line 73, in extract
    raise SpanContextCorruptedException('failed to extract span context')
SpanContextCorruptedException: failed to extract span context
```

Components used:
 - nginx/1.15.7
 - nginx-opentracing: 
https://github.com/opentracing-contrib/nginx-opentracing/releases/tag/v0.8.0
 - DataDog tracer plugin: https://github.com/DataDog/dd-opentracing-cpp/releases/download/v0.4.2/linux-amd64-libdd_opentracing_plugin.so.gz

nginx configuration:

```
# configuration file /etc/nginx/nginx.conf:
load_module modules/ngx_http_opentracing_module.so;

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_id';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    opentracing_load_tracer /etc/nginx/linux-amd64-libdd_opentracing_plugin.so /etc/nginx/dd-config.json;
    opentracing on;
    opentracing_trace_locations off;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag http_uri $request_uri;
    opentracing_tag http_request_id $request_id;

    include /etc/nginx/conf.d/*.conf;
}

# configuration file /etc/nginx/conf.d/default.conf:
upstream u {
    server 62.210.92.35:80;
    keepalive 20;
    zone u 128k;
}

upstream upload-app {
    server 127.0.0.1:8080;
}

server {
    listen       80 default_server;
    server_name  localhost;

    opentracing_operation_name $uri;

    location / {
        opentracing_propagate_context;
        proxy_set_header Host nginx.org;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        proxy_pass http://u;
    }

    location /upload/ {
        opentracing_propagate_context;
        proxy_pass http://upload-app;
        client_max_body_size 256m;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

DataDog tracer configuration (/etc/nginx/dd-config.json):

```
{
  "service": "nginx",
  "operation_name_override": "nginx.handle",
  "agent_host": "localhost",
  "agent_port": 8126
}
```

DataDog agent version, OS used:

```
# dpkg -s datadog-agent
Package: datadog-agent
Status: install ok installed
Priority: extra
Section: utils
Installed-Size: 390206
Maintainer: Datadog Packages <package@datadoghq.com>
Architecture: amd64
Version: 1:6.9.0-1
Description: Datadog Monitoring Agent
  The Datadog Monitoring Agent is a lightweight process that monitors system
  processes and services, and sends information back to your Datadog account.
  .
  This package installs and runs the advanced Agent daemon, which queues and
  forwards metrics from your applications as well as system services.
  .
  See http://www.datadoghq.com/ for more information
License: Apache License Version 2.0
Vendor: Datadog <package@datadoghq.com>
Homepage: http://www.datadoghq.com

# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic
```

App itself:

```
#!/usr/bin/env python

import logging
import hashlib
from flask import Flask
from flask import request
from  werkzeug.debug import get_current_traceback
from opentracing_instrumentation import http_server
from opentracing_instrumentation import config
import opentracing
from ddtrace.opentracer import Tracer
from random import randint

application = Flask(__name__)
tracer = None 

def init_dd_tracer(service_name='upload-app'):
    print "INIT DATADOG TRACER"
    return Tracer(service_name=service_name, config={})

@application.before_request
def before_request():
    global tracer
    request.stderr = request.environ['wsgi.errors'] if 'wsgi.errors' in request.environ else stderr
    headers_summary = "HEADERS:\n\n" + "\n".join(["{0}: {1}".format(k, request.headers[k]) for k in sorted(request.headers.keys())]) + "\n"
    request.stderr.write(headers_summary)

    request.full_url = request.url
    request.remote_ip = request.remote_addr
    request.remote_port = request.environ['REMOTE_PORT']
    request.caller_name = "n/a"
    request.operation = request.method

    if not tracer:
        tracer = init_dd_tracer()

    request.span = http_server.before_request(request=request, tracer=tracer)

@application.route("/", methods=['GET', 'POST'])
def default():
    try:
        environ_summary = "ENVIRON:\n\n" + "\n".join(["{0}: {1}".format(k, request.environ[k]) for k in sorted(request.environ.keys())]) + "\n"
        args = "REQUEST ARGS: %s" % request.args
        body = "REQUETS BODY: %s" % request.data
        return "%s\n%s\n%s\n" % (args, body, environ_summary)
    except Exception, e:
        track = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=False)
        track.log()
        abort(500)

@application.route("/upload/", methods=['GET', 'POST'])
@application.route("/upload-http/", methods=['GET', 'POST'])
def upload():
    global tracer
    with tracer.start_span('ProcessUpload', child_of=request.span) as span:
        span.log_kv({'ProcessUpload': 'started'})
        span.set_tag('payload-size', int(request.headers.get('Content-Length')) if 'Content-Length' in request.headers else 0)

        if 'Content-Length' in request.headers and int(request.headers.get('Content-Length')):
            body = request.stream.read()
            for x in range(1, randint(2, 10)):
                 with tracer.start_span('SubPart%02d' % x, child_of=span) as subpart_span:
                     subpart_span.log_kv({'subpart_iteration': x, 'action': 'begin'})
                     m = hashlib.md5()
                     m.update(body)
                     response_body = "%d:%s\n" % (len(body), m.hexdigest())
                     subpart_span.log_kv({'subpart_iteration': x, 'action': 'end'})
            request.stderr.write('ProcessUpload finished with %d iterations\n' % x)

        else:
            response_body = 'no data was uploaded'

        try:
            span.set_tag('iterations', x)
        except NameError:
            pass

        span.log_kv({'ProcessUpload': 'finished'})

    return response_body

@application.errorhandler(500)
def internal_error(error):
    return "500 error"

if __name__ == "__main__":
    application.debug = True
    application.config['PROPAGATE_EXCEPTIONS'] = True
    application.run(host='127.0.0.1', port=8080)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ddtrace/propagation/http.py`
Content:
```
1 import logging
2 
3 from ..context import Context
4 
5 from .utils import get_wsgi_header
6 
7 log = logging.getLogger(__name__)
8 
9 # HTTP headers one should set for distributed tracing.
10 # These are cross-language (eg: Python, Go and other implementations should honor these)
11 HTTP_HEADER_TRACE_ID = "x-datadog-trace-id"
12 HTTP_HEADER_PARENT_ID = "x-datadog-parent-id"
13 HTTP_HEADER_SAMPLING_PRIORITY = "x-datadog-sampling-priority"
14 
15 
16 # Note that due to WSGI spec we have to also check for uppercased and prefixed
17 # versions of these headers
18 POSSIBLE_HTTP_HEADER_TRACE_IDS = frozenset(
19     [HTTP_HEADER_TRACE_ID, get_wsgi_header(HTTP_HEADER_TRACE_ID)]
20 )
21 POSSIBLE_HTTP_HEADER_PARENT_IDS = frozenset(
22     [HTTP_HEADER_PARENT_ID, get_wsgi_header(HTTP_HEADER_PARENT_ID)]
23 )
24 POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES = frozenset(
25     [HTTP_HEADER_SAMPLING_PRIORITY, get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY)]
26 )
27 
28 
29 class HTTPPropagator(object):
30     """A HTTP Propagator using HTTP headers as carrier."""
31 
32     def inject(self, span_context, headers):
33         """Inject Context attributes that have to be propagated as HTTP headers.
34 
35         Here is an example using `requests`::
36 
37             import requests
38             from ddtrace.propagation.http import HTTPPropagator
39 
40             def parent_call():
41                 with tracer.trace("parent_span") as span:
42                     headers = {}
43                     propagator = HTTPPropagator()
44                     propagator.inject(span.context, headers)
45                     url = "<some RPC endpoint>"
46                     r = requests.get(url, headers=headers)
47 
48         :param Context span_context: Span context to propagate.
49         :param dict headers: HTTP headers to extend with tracing attributes.
50         """
51         headers[HTTP_HEADER_TRACE_ID] = str(span_context.trace_id)
52         headers[HTTP_HEADER_PARENT_ID] = str(span_context.span_id)
53         sampling_priority = span_context.sampling_priority
54         # Propagate priority only if defined
55         if sampling_priority is not None:
56             headers[HTTP_HEADER_SAMPLING_PRIORITY] = str(span_context.sampling_priority)
57 
58     @staticmethod
59     def extract_trace_id(headers):
60         trace_id = 0
61 
62         for key in POSSIBLE_HTTP_HEADER_TRACE_IDS:
63             if key in headers:
64                 trace_id = headers.get(key)
65 
66         return int(trace_id)
67 
68     @staticmethod
69     def extract_parent_span_id(headers):
70         parent_span_id = 0
71 
72         for key in POSSIBLE_HTTP_HEADER_PARENT_IDS:
73             if key in headers:
74                 parent_span_id = headers.get(key)
75 
76         return int(parent_span_id)
77 
78     @staticmethod
79     def extract_sampling_priority(headers):
80         sampling_priority = None
81 
82         for key in POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES:
83             if key in headers:
84                 sampling_priority = headers.get(key)
85 
86         return sampling_priority
87 
88     def extract(self, headers):
89         """Extract a Context from HTTP headers into a new Context.
90 
91         Here is an example from a web endpoint::
92 
93             from ddtrace.propagation.http import HTTPPropagator
94 
95             def my_controller(url, headers):
96                 propagator = HTTPPropagator()
97                 context = propagator.extract(headers)
98                 tracer.context_provider.activate(context)
99 
100                 with tracer.trace("my_controller") as span:
101                     span.set_meta('http.url', url)
102 
103         :param dict headers: HTTP headers to extract tracing attributes.
104         :return: New `Context` with propagated attributes.
105         """
106         if not headers:
107             return Context()
108 
109         try:
110             trace_id = HTTPPropagator.extract_trace_id(headers)
111             parent_span_id = HTTPPropagator.extract_parent_span_id(headers)
112             sampling_priority = HTTPPropagator.extract_sampling_priority(headers)
113 
114             if sampling_priority is not None:
115                 sampling_priority = int(sampling_priority)
116 
117             return Context(
118                 trace_id=trace_id,
119                 span_id=parent_span_id,
120                 sampling_priority=sampling_priority,
121             )
122         # If headers are invalid and cannot be parsed, return a new context and log the issue.
123         except Exception as error:
124             try:
125                 log.debug(
126                     "invalid x-datadog-* headers, trace-id: %s, parent-id: %s, priority: %s, error: %s",
127                     headers.get(HTTP_HEADER_TRACE_ID, 0),
128                     headers.get(HTTP_HEADER_PARENT_ID, 0),
129                     headers.get(HTTP_HEADER_SAMPLING_PRIORITY),
130                     error,
131                 )
132             # We might fail on string formatting errors ; in that case only format the first error
133             except Exception:
134                 log.debug(error)
135             return Context()
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ddtrace/propagation/http.py b/ddtrace/propagation/http.py
--- a/ddtrace/propagation/http.py
+++ b/ddtrace/propagation/http.py
@@ -56,34 +56,35 @@
             headers[HTTP_HEADER_SAMPLING_PRIORITY] = str(span_context.sampling_priority)
 
     @staticmethod
-    def extract_trace_id(headers):
-        trace_id = 0
+    def extract_header_value(possible_header_names, headers, default=None):
+        for header, value in headers.items():
+            for header_name in possible_header_names:
+                if header.lower() == header_name.lower():
+                    return value
 
-        for key in POSSIBLE_HTTP_HEADER_TRACE_IDS:
-            if key in headers:
-                trace_id = headers.get(key)
+        return default
 
-        return int(trace_id)
+    @staticmethod
+    def extract_trace_id(headers):
+        return int(
+            HTTPPropagator.extract_header_value(
+                POSSIBLE_HTTP_HEADER_TRACE_IDS, headers, default=0,
+            )
+        )
 
     @staticmethod
     def extract_parent_span_id(headers):
-        parent_span_id = 0
-
-        for key in POSSIBLE_HTTP_HEADER_PARENT_IDS:
-            if key in headers:
-                parent_span_id = headers.get(key)
-
-        return int(parent_span_id)
+        return int(
+            HTTPPropagator.extract_header_value(
+                POSSIBLE_HTTP_HEADER_PARENT_IDS, headers, default=0,
+            )
+        )
 
     @staticmethod
     def extract_sampling_priority(headers):
-        sampling_priority = None
-
-        for key in POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES:
-            if key in headers:
-                sampling_priority = headers.get(key)
-
-        return sampling_priority
+        return HTTPPropagator.extract_header_value(
+            POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES, headers,
+        )
 
     def extract(self, headers):
         """Extract a Context from HTTP headers into a new Context.

{"golden_diff": "diff --git a/ddtrace/propagation/http.py b/ddtrace/propagation/http.py\n--- a/ddtrace/propagation/http.py\n+++ b/ddtrace/propagation/http.py\n@@ -56,34 +56,35 @@\n             headers[HTTP_HEADER_SAMPLING_PRIORITY] = str(span_context.sampling_priority)\n \n     @staticmethod\n-    def extract_trace_id(headers):\n-        trace_id = 0\n+    def extract_header_value(possible_header_names, headers, default=None):\n+        for header, value in headers.items():\n+            for header_name in possible_header_names:\n+                if header.lower() == header_name.lower():\n+                    return value\n \n-        for key in POSSIBLE_HTTP_HEADER_TRACE_IDS:\n-            if key in headers:\n-                trace_id = headers.get(key)\n+        return default\n \n-        return int(trace_id)\n+    @staticmethod\n+    def extract_trace_id(headers):\n+        return int(\n+            HTTPPropagator.extract_header_value(\n+                POSSIBLE_HTTP_HEADER_TRACE_IDS, headers, default=0,\n+            )\n+        )\n \n     @staticmethod\n     def extract_parent_span_id(headers):\n-        parent_span_id = 0\n-\n-        for key in POSSIBLE_HTTP_HEADER_PARENT_IDS:\n-            if key in headers:\n-                parent_span_id = headers.get(key)\n-\n-        return int(parent_span_id)\n+        return int(\n+            HTTPPropagator.extract_header_value(\n+                POSSIBLE_HTTP_HEADER_PARENT_IDS, headers, default=0,\n+            )\n+        )\n \n     @staticmethod\n     def extract_sampling_priority(headers):\n-        sampling_priority = None\n-\n-        for key in POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES:\n-            if key in headers:\n-                sampling_priority = headers.get(key)\n-\n-        return sampling_priority\n+        return HTTPPropagator.extract_header_value(\n+            POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES, headers,\n+        )\n \n     def extract(self, headers):\n         \"\"\"Extract a Context from HTTP headers into a new Context.\n", "issue": "nginx-opentracing + libdd_opentracing_plugin: SpanContextCorruptedException: failed to extract span context\nI'm trying to set up an integration of nginx + nginx-opentracing module + DataDog tracer plugin + sample python app in order to get working multi-span traces in a manner when an app uses propagated context.\r\n\r\nI'm getting the following error on every call:\r\n\r\n```\r\nERROR:root:trace extract failed: failed to extract span context\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python2.7/dist-packages/opentracing_instrumentation/http_server.py\", line 75, in before_request\r\n    format=Format.HTTP_HEADERS, carrier=carrier\r\n  File \"/usr/local/lib/python2.7/dist-packages/ddtrace-0.20.4-py2.7.egg/ddtrace/opentracer/tracer.py\", line 294, in extract\r\n    ot_span_ctx = propagator.extract(carrier)\r\n  File \"/usr/local/lib/python2.7/dist-packages/ddtrace-0.20.4-py2.7.egg/ddtrace/opentracer/propagation/http.py\", line 73, in extract\r\n    raise SpanContextCorruptedException('failed to extract span context')\r\nSpanContextCorruptedException: failed to extract span context\r\n```\r\n\r\nComponents used:\r\n - nginx/1.15.7\r\n - nginx-opentracing: \r\nhttps://github.com/opentracing-contrib/nginx-opentracing/releases/tag/v0.8.0\r\n - DataDog tracer plugin: https://github.com/DataDog/dd-opentracing-cpp/releases/download/v0.4.2/linux-amd64-libdd_opentracing_plugin.so.gz\r\n\r\nnginx configuration:\r\n\r\n```\r\n# configuration file /etc/nginx/nginx.conf:\r\nload_module modules/ngx_http_opentracing_module.so;\r\n\r\nuser  nginx;\r\nworker_processes  auto;\r\n\r\nerror_log  /var/log/nginx/error.log debug;\r\npid        /var/run/nginx.pid;\r\n\r\nevents {\r\n    worker_connections  1024;\r\n}\r\n\r\nhttp {\r\n    log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\r\n                      '$status $body_bytes_sent \"$http_referer\" '\r\n                      '\"$http_user_agent\" \"$http_x_forwarded_for\" $request_id';\r\n\r\n    access_log  /var/log/nginx/access.log  main;\r\n\r\n    sendfile        on;\r\n\r\n    keepalive_timeout  65;\r\n\r\n    opentracing_load_tracer /etc/nginx/linux-amd64-libdd_opentracing_plugin.so /etc/nginx/dd-config.json;\r\n    opentracing on;\r\n    opentracing_trace_locations off;\r\n    opentracing_tag http_user_agent $http_user_agent;\r\n    opentracing_tag http_uri $request_uri;\r\n    opentracing_tag http_request_id $request_id;\r\n\r\n    include /etc/nginx/conf.d/*.conf;\r\n}\r\n\r\n# configuration file /etc/nginx/conf.d/default.conf:\r\nupstream u {\r\n    server 62.210.92.35:80;\r\n    keepalive 20;\r\n    zone u 128k;\r\n}\r\n\r\nupstream upload-app {\r\n    server 127.0.0.1:8080;\r\n}\r\n\r\nserver {\r\n    listen       80 default_server;\r\n    server_name  localhost;\r\n\r\n    opentracing_operation_name $uri;\r\n\r\n    location / {\r\n        opentracing_propagate_context;\r\n        proxy_set_header Host nginx.org;\r\n        proxy_set_header Connection \"\";\r\n        proxy_http_version 1.1;\r\n        proxy_pass http://u;\r\n    }\r\n\r\n    location /upload/ {\r\n        opentracing_propagate_context;\r\n        proxy_pass http://upload-app;\r\n        client_max_body_size 256m;\r\n    }\r\n\r\n    error_page   500 502 503 504  /50x.html;\r\n    location = /50x.html {\r\n        root   /usr/share/nginx/html;\r\n    }\r\n}\r\n```\r\n\r\nDataDog tracer configuration (/etc/nginx/dd-config.json):\r\n\r\n```\r\n{\r\n  \"service\": \"nginx\",\r\n  \"operation_name_override\": \"nginx.handle\",\r\n  \"agent_host\": \"localhost\",\r\n  \"agent_port\": 8126\r\n}\r\n```\r\n\r\nDataDog agent version, OS used:\r\n\r\n```\r\n# dpkg -s datadog-agent\r\nPackage: datadog-agent\r\nStatus: install ok installed\r\nPriority: extra\r\nSection: utils\r\nInstalled-Size: 390206\r\nMaintainer: Datadog Packages <package@datadoghq.com>\r\nArchitecture: amd64\r\nVersion: 1:6.9.0-1\r\nDescription: Datadog Monitoring Agent\r\n  The Datadog Monitoring Agent is a lightweight process that monitors system\r\n  processes and services, and sends information back to your Datadog account.\r\n  .\r\n  This package installs and runs the advanced Agent daemon, which queues and\r\n  forwards metrics from your applications as well as system services.\r\n  .\r\n  See http://www.datadoghq.com/ for more information\r\nLicense: Apache License Version 2.0\r\nVendor: Datadog <package@datadoghq.com>\r\nHomepage: http://www.datadoghq.com\r\n\r\n# lsb_release -a\r\nNo LSB modules are available.\r\nDistributor ID:\tUbuntu\r\nDescription:\tUbuntu 18.04.1 LTS\r\nRelease:\t18.04\r\nCodename:\tbionic\r\n```\r\n\r\nApp itself:\r\n\r\n```\r\n#!/usr/bin/env python\r\n\r\nimport logging\r\nimport hashlib\r\nfrom flask import Flask\r\nfrom flask import request\r\nfrom  werkzeug.debug import get_current_traceback\r\nfrom opentracing_instrumentation import http_server\r\nfrom opentracing_instrumentation import config\r\nimport opentracing\r\nfrom ddtrace.opentracer import Tracer\r\nfrom random import randint\r\n\r\napplication = Flask(__name__)\r\ntracer = None \r\n\r\ndef init_dd_tracer(service_name='upload-app'):\r\n    print \"INIT DATADOG TRACER\"\r\n    return Tracer(service_name=service_name, config={})\r\n\r\n@application.before_request\r\ndef before_request():\r\n    global tracer\r\n    request.stderr = request.environ['wsgi.errors'] if 'wsgi.errors' in request.environ else stderr\r\n    headers_summary = \"HEADERS:\\n\\n\" + \"\\n\".join([\"{0}: {1}\".format(k, request.headers[k]) for k in sorted(request.headers.keys())]) + \"\\n\"\r\n    request.stderr.write(headers_summary)\r\n\r\n    request.full_url = request.url\r\n    request.remote_ip = request.remote_addr\r\n    request.remote_port = request.environ['REMOTE_PORT']\r\n    request.caller_name = \"n/a\"\r\n    request.operation = request.method\r\n\r\n    if not tracer:\r\n        tracer = init_dd_tracer()\r\n\r\n    request.span = http_server.before_request(request=request, tracer=tracer)\r\n\r\n@application.route(\"/\", methods=['GET', 'POST'])\r\ndef default():\r\n    try:\r\n        environ_summary = \"ENVIRON:\\n\\n\" + \"\\n\".join([\"{0}: {1}\".format(k, request.environ[k]) for k in sorted(request.environ.keys())]) + \"\\n\"\r\n        args = \"REQUEST ARGS: %s\" % request.args\r\n        body = \"REQUETS BODY: %s\" % request.data\r\n        return \"%s\\n%s\\n%s\\n\" % (args, body, environ_summary)\r\n    except Exception, e:\r\n        track = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=False)\r\n        track.log()\r\n        abort(500)\r\n\r\n@application.route(\"/upload/\", methods=['GET', 'POST'])\r\n@application.route(\"/upload-http/\", methods=['GET', 'POST'])\r\ndef upload():\r\n    global tracer\r\n    with tracer.start_span('ProcessUpload', child_of=request.span) as span:\r\n        span.log_kv({'ProcessUpload': 'started'})\r\n        span.set_tag('payload-size', int(request.headers.get('Content-Length')) if 'Content-Length' in request.headers else 0)\r\n\r\n        if 'Content-Length' in request.headers and int(request.headers.get('Content-Length')):\r\n            body = request.stream.read()\r\n            for x in range(1, randint(2, 10)):\r\n                 with tracer.start_span('SubPart%02d' % x, child_of=span) as subpart_span:\r\n                     subpart_span.log_kv({'subpart_iteration': x, 'action': 'begin'})\r\n                     m = hashlib.md5()\r\n                     m.update(body)\r\n                     response_body = \"%d:%s\\n\" % (len(body), m.hexdigest())\r\n                     subpart_span.log_kv({'subpart_iteration': x, 'action': 'end'})\r\n            request.stderr.write('ProcessUpload finished with %d iterations\\n' % x)\r\n\r\n        else:\r\n            response_body = 'no data was uploaded'\r\n\r\n        try:\r\n            span.set_tag('iterations', x)\r\n        except NameError:\r\n            pass\r\n\r\n        span.log_kv({'ProcessUpload': 'finished'})\r\n\r\n    return response_body\r\n\r\n@application.errorhandler(500)\r\ndef internal_error(error):\r\n    return \"500 error\"\r\n\r\nif __name__ == \"__main__\":\r\n    application.debug = True\r\n    application.config['PROPAGATE_EXCEPTIONS'] = True\r\n    application.run(host='127.0.0.1', port=8080)\r\n```\r\n\n", "before_files": [{"content": "import logging\n\nfrom ..context import Context\n\nfrom .utils import get_wsgi_header\n\nlog = logging.getLogger(__name__)\n\n# HTTP headers one should set for distributed tracing.\n# These are cross-language (eg: Python, Go and other implementations should honor these)\nHTTP_HEADER_TRACE_ID = \"x-datadog-trace-id\"\nHTTP_HEADER_PARENT_ID = \"x-datadog-parent-id\"\nHTTP_HEADER_SAMPLING_PRIORITY = \"x-datadog-sampling-priority\"\n\n\n# Note that due to WSGI spec we have to also check for uppercased and prefixed\n# versions of these headers\nPOSSIBLE_HTTP_HEADER_TRACE_IDS = frozenset(\n    [HTTP_HEADER_TRACE_ID, get_wsgi_header(HTTP_HEADER_TRACE_ID)]\n)\nPOSSIBLE_HTTP_HEADER_PARENT_IDS = frozenset(\n    [HTTP_HEADER_PARENT_ID, get_wsgi_header(HTTP_HEADER_PARENT_ID)]\n)\nPOSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES = frozenset(\n    [HTTP_HEADER_SAMPLING_PRIORITY, get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY)]\n)\n\n\nclass HTTPPropagator(object):\n    \"\"\"A HTTP Propagator using HTTP headers as carrier.\"\"\"\n\n    def inject(self, span_context, headers):\n        \"\"\"Inject Context attributes that have to be propagated as HTTP headers.\n\n        Here is an example using `requests`::\n\n            import requests\n            from ddtrace.propagation.http import HTTPPropagator\n\n            def parent_call():\n                with tracer.trace(\"parent_span\") as span:\n                    headers = {}\n                    propagator = HTTPPropagator()\n                    propagator.inject(span.context, headers)\n                    url = \"<some RPC endpoint>\"\n                    r = requests.get(url, headers=headers)\n\n        :param Context span_context: Span context to propagate.\n        :param dict headers: HTTP headers to extend with tracing attributes.\n        \"\"\"\n        headers[HTTP_HEADER_TRACE_ID] = str(span_context.trace_id)\n        headers[HTTP_HEADER_PARENT_ID] = str(span_context.span_id)\n        sampling_priority = span_context.sampling_priority\n        # Propagate priority only if defined\n        if sampling_priority is not None:\n            headers[HTTP_HEADER_SAMPLING_PRIORITY] = str(span_context.sampling_priority)\n\n    @staticmethod\n    def extract_trace_id(headers):\n        trace_id = 0\n\n        for key in POSSIBLE_HTTP_HEADER_TRACE_IDS:\n            if key in headers:\n                trace_id = headers.get(key)\n\n        return int(trace_id)\n\n    @staticmethod\n    def extract_parent_span_id(headers):\n        parent_span_id = 0\n\n        for key in POSSIBLE_HTTP_HEADER_PARENT_IDS:\n            if key in headers:\n                parent_span_id = headers.get(key)\n\n        return int(parent_span_id)\n\n    @staticmethod\n    def extract_sampling_priority(headers):\n        sampling_priority = None\n\n        for key in POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES:\n            if key in headers:\n                sampling_priority = headers.get(key)\n\n        return sampling_priority\n\n    def extract(self, headers):\n        \"\"\"Extract a Context from HTTP headers into a new Context.\n\n        Here is an example from a web endpoint::\n\n            from ddtrace.propagation.http import HTTPPropagator\n\n            def my_controller(url, headers):\n                propagator = HTTPPropagator()\n                context = propagator.extract(headers)\n                tracer.context_provider.activate(context)\n\n                with tracer.trace(\"my_controller\") as span:\n                    span.set_meta('http.url', url)\n\n        :param dict headers: HTTP headers to extract tracing attributes.\n        :return: New `Context` with propagated attributes.\n        \"\"\"\n        if not headers:\n            return Context()\n\n        try:\n            trace_id = HTTPPropagator.extract_trace_id(headers)\n            parent_span_id = HTTPPropagator.extract_parent_span_id(headers)\n            sampling_priority = HTTPPropagator.extract_sampling_priority(headers)\n\n            if sampling_priority is not None:\n                sampling_priority = int(sampling_priority)\n\n            return Context(\n                trace_id=trace_id,\n                span_id=parent_span_id,\n                sampling_priority=sampling_priority,\n            )\n        # If headers are invalid and cannot be parsed, return a new context and log the issue.\n        except Exception as error:\n            try:\n                log.debug(\n                    \"invalid x-datadog-* headers, trace-id: %s, parent-id: %s, priority: %s, error: %s\",\n                    headers.get(HTTP_HEADER_TRACE_ID, 0),\n                    headers.get(HTTP_HEADER_PARENT_ID, 0),\n                    headers.get(HTTP_HEADER_SAMPLING_PRIORITY),\n                    error,\n                )\n            # We might fail on string formatting errors ; in that case only format the first error\n            except Exception:\n                log.debug(error)\n            return Context()\n", "path": "ddtrace/propagation/http.py"}], "after_files": [{"content": "import logging\n\nfrom ..context import Context\n\nfrom .utils import get_wsgi_header\n\nlog = logging.getLogger(__name__)\n\n# HTTP headers one should set for distributed tracing.\n# These are cross-language (eg: Python, Go and other implementations should honor these)\nHTTP_HEADER_TRACE_ID = \"x-datadog-trace-id\"\nHTTP_HEADER_PARENT_ID = \"x-datadog-parent-id\"\nHTTP_HEADER_SAMPLING_PRIORITY = \"x-datadog-sampling-priority\"\n\n\n# Note that due to WSGI spec we have to also check for uppercased and prefixed\n# versions of these headers\nPOSSIBLE_HTTP_HEADER_TRACE_IDS = frozenset(\n    [HTTP_HEADER_TRACE_ID, get_wsgi_header(HTTP_HEADER_TRACE_ID)]\n)\nPOSSIBLE_HTTP_HEADER_PARENT_IDS = frozenset(\n    [HTTP_HEADER_PARENT_ID, get_wsgi_header(HTTP_HEADER_PARENT_ID)]\n)\nPOSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES = frozenset(\n    [HTTP_HEADER_SAMPLING_PRIORITY, get_wsgi_header(HTTP_HEADER_SAMPLING_PRIORITY)]\n)\n\n\nclass HTTPPropagator(object):\n    \"\"\"A HTTP Propagator using HTTP headers as carrier.\"\"\"\n\n    def inject(self, span_context, headers):\n        \"\"\"Inject Context attributes that have to be propagated as HTTP headers.\n\n        Here is an example using `requests`::\n\n            import requests\n            from ddtrace.propagation.http import HTTPPropagator\n\n            def parent_call():\n                with tracer.trace(\"parent_span\") as span:\n                    headers = {}\n                    propagator = HTTPPropagator()\n                    propagator.inject(span.context, headers)\n                    url = \"<some RPC endpoint>\"\n                    r = requests.get(url, headers=headers)\n\n        :param Context span_context: Span context to propagate.\n        :param dict headers: HTTP headers to extend with tracing attributes.\n        \"\"\"\n        headers[HTTP_HEADER_TRACE_ID] = str(span_context.trace_id)\n        headers[HTTP_HEADER_PARENT_ID] = str(span_context.span_id)\n        sampling_priority = span_context.sampling_priority\n        # Propagate priority only if defined\n        if sampling_priority is not None:\n            headers[HTTP_HEADER_SAMPLING_PRIORITY] = str(span_context.sampling_priority)\n\n    @staticmethod\n    def extract_header_value(possible_header_names, headers, default=None):\n        for header, value in headers.items():\n            for header_name in possible_header_names:\n                if header.lower() == header_name.lower():\n                    return value\n\n        return default\n\n    @staticmethod\n    def extract_trace_id(headers):\n        return int(\n            HTTPPropagator.extract_header_value(\n                POSSIBLE_HTTP_HEADER_TRACE_IDS, headers, default=0,\n            )\n        )\n\n    @staticmethod\n    def extract_parent_span_id(headers):\n        return int(\n            HTTPPropagator.extract_header_value(\n                POSSIBLE_HTTP_HEADER_PARENT_IDS, headers, default=0,\n            )\n        )\n\n    @staticmethod\n    def extract_sampling_priority(headers):\n        return HTTPPropagator.extract_header_value(\n            POSSIBLE_HTTP_HEADER_SAMPLING_PRIORITIES, headers,\n        )\n\n    def extract(self, headers):\n        \"\"\"Extract a Context from HTTP headers into a new Context.\n\n        Here is an example from a web endpoint::\n\n            from ddtrace.propagation.http import HTTPPropagator\n\n            def my_controller(url, headers):\n                propagator = HTTPPropagator()\n                context = propagator.extract(headers)\n                tracer.context_provider.activate(context)\n\n                with tracer.trace(\"my_controller\") as span:\n                    span.set_meta('http.url', url)\n\n        :param dict headers: HTTP headers to extract tracing attributes.\n        :return: New `Context` with propagated attributes.\n        \"\"\"\n        if not headers:\n            return Context()\n\n        try:\n            trace_id = HTTPPropagator.extract_trace_id(headers)\n            parent_span_id = HTTPPropagator.extract_parent_span_id(headers)\n            sampling_priority = HTTPPropagator.extract_sampling_priority(headers)\n\n            if sampling_priority is not None:\n                sampling_priority = int(sampling_priority)\n\n            return Context(\n                trace_id=trace_id,\n                span_id=parent_span_id,\n                sampling_priority=sampling_priority,\n            )\n        # If headers are invalid and cannot be parsed, return a new context and log the issue.\n        except Exception as error:\n            try:\n                log.debug(\n                    \"invalid x-datadog-* headers, trace-id: %s, parent-id: %s, priority: %s, error: %s\",\n                    headers.get(HTTP_HEADER_TRACE_ID, 0),\n                    headers.get(HTTP_HEADER_PARENT_ID, 0),\n                    headers.get(HTTP_HEADER_SAMPLING_PRIORITY),\n                    error,\n                )\n            # We might fail on string formatting errors ; in that case only format the first error\n            except Exception:\n                log.debug(error)\n            return Context()\n", "path": "ddtrace/propagation/http.py"}]}