88import time
99
1010import pkg_resources
11+ from urllib import parse
1112
1213from .log import logger
1314
15+
1416if sys .version_info .major is 2 :
1517 string_types = basestring
1618else :
@@ -28,7 +30,7 @@ def generate_id():
2830 global _current_pid
2931
3032 pid = os .getpid ()
31- if ( _current_pid != pid ) :
33+ if _current_pid != pid :
3234 _current_pid = pid
3335 _rnd .seed (int (1000000 * time .time ()) ^ pid )
3436 return _rnd .randint (- 9223372036854775808 , 9223372036854775807 )
@@ -41,8 +43,8 @@ def id_to_header(id):
4143 if not isinstance (id , int ):
4244 return BAD_ID_HEADER
4345
44- byteString = struct .pack ('>q' , id )
45- return str (binascii .hexlify (byteString ).decode ('UTF-8' ).lstrip ('0' ))
46+ byte_string = struct .pack ('>q' , id )
47+ return str (binascii .hexlify (byte_string ).decode ('UTF-8' ).lstrip ('0' ))
4648 except Exception as e :
4749 logger .debug (e )
4850 return BAD_ID_HEADER
@@ -75,15 +77,90 @@ def to_json(obj):
7577
7678
7779def package_version ():
80+ version = ""
7881 try :
79- version = ""
8082 version = pkg_resources .get_distribution ('instana' ).version
8183 except pkg_resources .DistributionNotFound :
8284 version = 'unknown'
8385 finally :
8486 return version
8587
8688
89+ def strip_secrets (qp , matcher , kwlist ):
90+ """
91+ This function will scrub the secrets from a query param string based on the passed in matcher and kwlist.
92+
93+ blah=1&secret=password&valid=true will result in blah=1&secret=<redacted>&valid=true
94+
95+ You can even pass in path query combinations:
96+
97+ /signup?blah=1&secret=password&valid=true will result in /signup?blah=1&secret=<redacted>&valid=true
98+
99+ :param qp: a string representing the query params in URL form (unencoded)
100+ :param matcher: the matcher to use
101+ :param kwlist: the list of keywords to match
102+ :return: a scrubbed query param string
103+ """
104+ path = None
105+
106+ try :
107+ if qp is None :
108+ return ''
109+
110+ if type (kwlist ) is not list :
111+ logger .debug ("strip_secrets: bad keyword list" )
112+ return qp
113+
114+ # If there are no key=values, then just return
115+ if not '=' in qp :
116+ return qp
117+
118+ if '?' in qp :
119+ path , query = qp .split ('?' )
120+ else :
121+ query = qp
122+
123+ params = parse .parse_qs (query , keep_blank_values = True )
124+ redacted = ['<redacted>' ]
125+
126+ if matcher == 'equals-ignore-case' :
127+ for keyword in kwlist :
128+ for key in params .keys ():
129+ if key .lower () == keyword .lower ():
130+ params [key ] = redacted
131+ elif matcher == 'equals' :
132+ for keyword in kwlist :
133+ if keyword in params :
134+ params [keyword ] = redacted
135+ elif matcher == 'contains-ignore-case' :
136+ for keyword in kwlist :
137+ for key in params .keys ():
138+ if keyword .lower () in key .lower ():
139+ params [key ] = redacted
140+ elif matcher == 'contains' :
141+ for keyword in kwlist :
142+ for key in params .keys ():
143+ if keyword in key :
144+ params [key ] = redacted
145+ elif matcher == 'regex' :
146+ for regexp in kwlist :
147+ for key in params .keys ():
148+ if re .match (regexp , key ):
149+ params [key ] = redacted
150+ else :
151+ logger .debug ("strip_secrets: unknown matcher" )
152+ return qp
153+
154+ result = parse .urlencode (params , doseq = True )
155+ query = parse .unquote (result )
156+
157+ if path :
158+ query = path + '?' + query
159+
160+ return query
161+ except :
162+ logger .debug ("strip_secrets" , exc_info = True )
163+
87164def get_py_source (file ):
88165 """
89166 Retrieves and returns the source code for any Python
0 commit comments