]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/py/src/transport/THttpClient.py
2 # Licensed to the Apache Software Foundation (ASF) under one
3 # or more contributor license agreements. See the NOTICE file
4 # distributed with this work for additional information
5 # regarding copyright ownership. The ASF licenses this file
6 # to you under the Apache License, Version 2.0 (the
7 # "License"); you may not use this file except in compliance
8 # with the License. You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing,
13 # software distributed under the License is distributed on an
14 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # KIND, either express or implied. See the License for the
16 # specific language governing permissions and limitations
20 from io
import BytesIO
27 from six
.moves
import urllib
28 from six
.moves
import http_client
30 from .TTransport
import TTransportBase
34 class THttpClient(TTransportBase
):
35 """Http implementation of TTransport base."""
37 def __init__(self
, uri_or_host
, port
=None, path
=None, cafile
=None, cert_file
=None, key_file
=None, ssl_context
=None):
38 """THttpClient supports two different types of construction:
40 THttpClient(host, port, path) - deprecated
41 THttpClient(uri, [port=<n>, path=<s>, cafile=<filename>, cert_file=<filename>, key_file=<filename>, ssl_context=<context>])
43 Only the second supports https. To properly authenticate against the server,
44 provide the client's identity by specifying cert_file and key_file. To properly
45 authenticate the server, specify either cafile or ssl_context with a CA defined.
46 NOTE: if both cafile and ssl_context are defined, ssl_context will override cafile.
50 "Please use the THttpClient('http{s}://host:port/path') constructor",
53 self
.host
= uri_or_host
59 parsed
= urllib
.parse
.urlparse(uri_or_host
)
60 self
.scheme
= parsed
.scheme
61 assert self
.scheme
in ('http', 'https')
62 if self
.scheme
== 'http':
63 self
.port
= parsed
.port
or http_client
.HTTP_PORT
64 elif self
.scheme
== 'https':
65 self
.port
= parsed
.port
or http_client
.HTTPS_PORT
66 self
.certfile
= cert_file
67 self
.keyfile
= key_file
68 self
.context
= ssl
.create_default_context(cafile
=cafile
) if (cafile
and not ssl_context
) else ssl_context
69 self
.host
= parsed
.hostname
70 self
.path
= parsed
.path
72 self
.path
+= '?%s' % parsed
.query
74 proxy
= urllib
.request
.getproxies()[self
.scheme
]
78 if urllib
.request
.proxy_bypass(self
.host
):
81 parsed
= urllib
.parse
.urlparse(proxy
)
82 self
.realhost
= self
.host
83 self
.realport
= self
.port
84 self
.host
= parsed
.hostname
85 self
.port
= parsed
.port
86 self
.proxy_auth
= self
.basic_proxy_auth_header(parsed
)
88 self
.realhost
= self
.realport
= self
.proxy_auth
= None
89 self
.__wbuf
= BytesIO()
91 self
.__http
_response
= None
93 self
.__custom
_headers
= None
96 def basic_proxy_auth_header(proxy
):
97 if proxy
is None or not proxy
.username
:
99 ap
= "%s:%s" % (urllib
.parse
.unquote(proxy
.username
),
100 urllib
.parse
.unquote(proxy
.password
))
101 cr
= base64
.b64encode(ap
).strip()
104 def using_proxy(self
):
105 return self
.realhost
is not None
108 if self
.scheme
== 'http':
109 self
.__http
= http_client
.HTTPConnection(self
.host
, self
.port
,
110 timeout
=self
.__timeout
)
111 elif self
.scheme
== 'https':
112 self
.__http
= http_client
.HTTPSConnection(self
.host
, self
.port
,
113 key_file
=self
.keyfile
,
114 cert_file
=self
.certfile
,
115 timeout
=self
.__timeout
,
116 context
=self
.context
)
117 if self
.using_proxy():
118 self
.__http
.set_tunnel(self
.realhost
, self
.realport
,
119 {"Proxy-Authorization": self
.proxy_auth
})
124 self
.__http
_response
= None
127 return self
.__http
is not None
129 def setTimeout(self
, ms
):
131 self
.__timeout
= None
133 self
.__timeout
= ms
/ 1000.0
135 def setCustomHeaders(self
, headers
):
136 self
.__custom
_headers
= headers
139 return self
.__http
_response
.read(sz
)
141 def write(self
, buf
):
142 self
.__wbuf
.write(buf
)
149 # Pull data out of buffer
150 data
= self
.__wbuf
.getvalue()
151 self
.__wbuf
= BytesIO()
154 if self
.using_proxy() and self
.scheme
== "http":
155 # need full URL of real host for HTTP proxy here (HTTPS uses CONNECT tunnel)
156 self
.__http
.putrequest('POST', "http://%s:%s%s" %
157 (self
.realhost
, self
.realport
, self
.path
))
159 self
.__http
.putrequest('POST', self
.path
)
162 self
.__http
.putheader('Content-Type', 'application/x-thrift')
163 self
.__http
.putheader('Content-Length', str(len(data
)))
164 if self
.using_proxy() and self
.scheme
== "http" and self
.proxy_auth
is not None:
165 self
.__http
.putheader("Proxy-Authorization", self
.proxy_auth
)
167 if not self
.__custom
_headers
or 'User-Agent' not in self
.__custom
_headers
:
168 user_agent
= 'Python/THttpClient'
169 script
= os
.path
.basename(sys
.argv
[0])
171 user_agent
= '%s (%s)' % (user_agent
, urllib
.parse
.quote(script
))
172 self
.__http
.putheader('User-Agent', user_agent
)
174 if self
.__custom
_headers
:
175 for key
, val
in six
.iteritems(self
.__custom
_headers
):
176 self
.__http
.putheader(key
, val
)
178 self
.__http
.endheaders()
181 self
.__http
.send(data
)
183 # Get reply to flush the request
184 self
.__http
_response
= self
.__http
.getresponse()
185 self
.code
= self
.__http
_response
.status
186 self
.message
= self
.__http
_response
.reason
187 self
.headers
= self
.__http
_response
.msg