| 30 |
ashish |
1 |
#
|
|
|
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
|
|
|
9 |
#
|
|
|
10 |
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
11 |
#
|
|
|
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
|
|
|
17 |
# under the License.
|
|
|
18 |
#
|
|
|
19 |
|
|
|
20 |
from TTransport import *
|
|
|
21 |
from cStringIO import StringIO
|
|
|
22 |
|
|
|
23 |
import urlparse
|
|
|
24 |
import httplib
|
|
|
25 |
import warnings
|
|
|
26 |
|
|
|
27 |
class THttpClient(TTransportBase):
|
|
|
28 |
|
|
|
29 |
"""Http implementation of TTransport base."""
|
|
|
30 |
|
|
|
31 |
def __init__(self, uri_or_host, port=None, path=None):
|
|
|
32 |
"""THttpClient supports two different types constructor parameters.
|
|
|
33 |
|
|
|
34 |
THttpClient(host, port, path) - deprecated
|
|
|
35 |
THttpClient(uri)
|
|
|
36 |
|
|
|
37 |
Only the second supports https."""
|
|
|
38 |
|
|
|
39 |
if port is not None:
|
|
|
40 |
warnings.warn("Please use the THttpClient('http://host:port/path') syntax", DeprecationWarning, stacklevel=2)
|
|
|
41 |
self.host = uri_or_host
|
|
|
42 |
self.port = port
|
|
|
43 |
assert path
|
|
|
44 |
self.path = path
|
|
|
45 |
self.scheme = 'http'
|
|
|
46 |
else:
|
|
|
47 |
parsed = urlparse.urlparse(uri_or_host)
|
|
|
48 |
self.scheme = parsed.scheme
|
|
|
49 |
assert self.scheme in ('http', 'https')
|
|
|
50 |
if self.scheme == 'http':
|
|
|
51 |
self.port = parsed.port or httplib.HTTP_PORT
|
|
|
52 |
elif self.scheme == 'https':
|
|
|
53 |
self.port = parsed.port or httplib.HTTPS_PORT
|
|
|
54 |
self.host = parsed.hostname
|
|
|
55 |
self.path = parsed.path
|
|
|
56 |
self.__wbuf = StringIO()
|
|
|
57 |
self.__http = None
|
|
|
58 |
|
|
|
59 |
def open(self):
|
|
|
60 |
if self.scheme == 'http':
|
|
|
61 |
self.__http = httplib.HTTP(self.host, self.port)
|
|
|
62 |
else:
|
|
|
63 |
self.__http = httplib.HTTPS(self.host, self.port)
|
|
|
64 |
|
|
|
65 |
def close(self):
|
|
|
66 |
self.__http.close()
|
|
|
67 |
self.__http = None
|
|
|
68 |
|
|
|
69 |
def isOpen(self):
|
|
|
70 |
return self.__http != None
|
|
|
71 |
|
|
|
72 |
def read(self, sz):
|
|
|
73 |
return self.__http.file.read(sz)
|
|
|
74 |
|
|
|
75 |
def write(self, buf):
|
|
|
76 |
self.__wbuf.write(buf)
|
|
|
77 |
|
|
|
78 |
def flush(self):
|
|
|
79 |
if self.isOpen():
|
|
|
80 |
self.close()
|
|
|
81 |
self.open();
|
|
|
82 |
|
|
|
83 |
# Pull data out of buffer
|
|
|
84 |
data = self.__wbuf.getvalue()
|
|
|
85 |
self.__wbuf = StringIO()
|
|
|
86 |
|
|
|
87 |
# HTTP request
|
|
|
88 |
self.__http.putrequest('POST', self.path)
|
|
|
89 |
|
|
|
90 |
# Write headers
|
|
|
91 |
self.__http.putheader('Host', self.host)
|
|
|
92 |
self.__http.putheader('Content-Type', 'application/x-thrift')
|
|
|
93 |
self.__http.putheader('Content-Length', str(len(data)))
|
|
|
94 |
self.__http.endheaders()
|
|
|
95 |
|
|
|
96 |
# Write payload
|
|
|
97 |
self.__http.send(data)
|
|
|
98 |
|
|
|
99 |
# Get reply to flush the request
|
|
|
100 |
self.code, self.message, self.headers = self.__http.getreply()
|