25
25
"""
26
26
27
27
from __future__ import absolute_import
28
+
29
+ import io
28
30
import logging
29
31
import socket
30
32
import ssl
31
- from io import BytesIO
32
-
33
- from splunklib .six .moves import urllib
34
- import io
35
33
import sys
36
-
37
34
from base64 import b64encode
35
+ from contextlib import contextmanager
38
36
from datetime import datetime
39
37
from functools import wraps
38
+ from io import BytesIO
39
+ from xml .etree .ElementTree import XML
40
+
41
+ from splunklib import six
40
42
from splunklib .six import StringIO
43
+ from splunklib .six .moves import urllib
41
44
42
- from contextlib import contextmanager
45
+ from . data import record
43
46
44
- from xml .etree .ElementTree import XML
45
- from splunklib import six
46
47
try :
47
48
from xml .etree .ElementTree import ParseError
48
49
except ImportError as e :
49
50
from xml .parsers .expat import ExpatError as ParseError
50
51
51
- from .data import record
52
52
53
53
__all__ = [
54
54
"AuthenticationError" ,
@@ -449,6 +449,8 @@ class Context(object):
449
449
:type username: ``string``
450
450
:param password: The password for the Splunk account.
451
451
:type password: ``string``
452
+ :param headers: List of extra HTTP headers to send (optional).
453
+ :type headers: ``list`` of 2-tuples.
452
454
:param handler: The HTTP request handler (optional).
453
455
:returns: A ``Context`` instance.
454
456
@@ -478,6 +480,7 @@ def __init__(self, handler=None, **kwargs):
478
480
self .password = kwargs .get ("password" , "" )
479
481
self .basic = kwargs .get ("basic" , False )
480
482
self .autologin = kwargs .get ("autologin" , False )
483
+ self .additional_headers = kwargs .get ("headers" , [])
481
484
482
485
# Store any cookies in the self.http._cookies dict
483
486
if "cookie" in kwargs and kwargs ['cookie' ] not in [None , _NoAuthenticationToken ]:
@@ -613,7 +616,7 @@ def delete(self, path_segment, owner=None, app=None, sharing=None, **query):
613
616
614
617
@_authentication
615
618
@_log_duration
616
- def get (self , path_segment , owner = None , app = None , sharing = None , ** query ):
619
+ def get (self , path_segment , owner = None , app = None , headers = None , sharing = None , ** query ):
617
620
"""Performs a GET operation from the REST path segment with the given
618
621
namespace and query.
619
622
@@ -636,6 +639,8 @@ def get(self, path_segment, owner=None, app=None, sharing=None, **query):
636
639
:type owner: ``string``
637
640
:param app: The app context of the namespace (optional).
638
641
:type app: ``string``
642
+ :param headers: List of extra HTTP headers to send (optional).
643
+ :type headers: ``list`` of 2-tuples.
639
644
:param sharing: The sharing mode of the namespace (optional).
640
645
:type sharing: ``string``
641
646
:param query: All other keyword arguments, which are used as query
@@ -663,10 +668,14 @@ def get(self, path_segment, owner=None, app=None, sharing=None, **query):
663
668
c.logout()
664
669
c.get('apps/local') # raises AuthenticationError
665
670
"""
671
+ if headers is None :
672
+ headers = []
673
+
666
674
path = self .authority + self ._abspath (path_segment , owner = owner ,
667
675
app = app , sharing = sharing )
668
676
logging .debug ("GET request to %s (body: %s)" , path , repr (query ))
669
- response = self .http .get (path , self ._auth_headers , ** query )
677
+ all_headers = headers + self .additional_headers + self ._auth_headers
678
+ response = self .http .get (path , all_headers , ** query )
670
679
return response
671
680
672
681
@_authentication
@@ -738,7 +747,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, *
738
747
739
748
path = self .authority + self ._abspath (path_segment , owner = owner , app = app , sharing = sharing )
740
749
logging .debug ("POST request to %s (body: %s)" , path , repr (query ))
741
- all_headers = headers + self ._auth_headers
750
+ all_headers = headers + self .additional_headers + self . _auth_headers
742
751
response = self .http .post (path , all_headers , ** query )
743
752
return response
744
753
@@ -804,7 +813,7 @@ def request(self, path_segment, method="GET", headers=None, body="",
804
813
path = self .authority \
805
814
+ self ._abspath (path_segment , owner = owner ,
806
815
app = app , sharing = sharing )
807
- all_headers = headers + self ._auth_headers
816
+ all_headers = headers + self .additional_headers + self . _auth_headers
808
817
logging .debug ("%s request to %s (headers: %s, body: %s)" ,
809
818
method , path , str (all_headers ), repr (body ))
810
819
response = self .http .request (path ,
@@ -858,6 +867,7 @@ def login(self):
858
867
self .authority + self ._abspath ("/services/auth/login" ),
859
868
username = self .username ,
860
869
password = self .password ,
870
+ headers = self .additional_headers ,
861
871
cookie = "1" ) # In Splunk 6.2+, passing "cookie=1" will return the "set-cookie" header
862
872
863
873
body = response .body .read ()
@@ -968,6 +978,8 @@ def connect(**kwargs):
968
978
:type username: ``string``
969
979
:param password: The password for the Splunk account.
970
980
:type password: ``string``
981
+ :param headers: List of extra HTTP headers to send (optional).
982
+ :type headers: ``list`` of 2-tuples.
971
983
:param autologin: When ``True``, automatically tries to log in again if the
972
984
session terminates.
973
985
:type autologin: ``Boolean``
@@ -1190,7 +1202,7 @@ def post(self, url, headers=None, **kwargs):
1190
1202
# to support the receivers/stream endpoint.
1191
1203
if 'body' in kwargs :
1192
1204
# We only use application/x-www-form-urlencoded if there is no other
1193
- # Content-Type header present. This can happen in cases where we
1205
+ # Content-Type header present. This can happen in cases where we
1194
1206
# send requests as application/json, e.g. for KV Store.
1195
1207
if len ([x for x in headers if x [0 ].lower () == "content-type" ]) == 0 :
1196
1208
headers .append (("Content-Type" , "application/x-www-form-urlencoded" ))
0 commit comments