9bdf94e079f5ad55dcc3723ff4fdfeb40c22e358
[osm/osmclient.git] / osmclient / sol005 / http.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
17 from io import BytesIO
18 import pycurl
19 import json
20 import logging
21 import copy
22 from osmclient.common import http
23 from osmclient.common.exceptions import OsmHttpException
24
25
26 class Http(http.Http):
27
28 def __init__(self, url, user='admin', password='admin'):
29 self._url = url
30 self._user = user
31 self._password = password
32 self._http_header = None
33 self._logger = logging.getLogger('osmclient')
34
35 def _get_curl_cmd(self, endpoint):
36 self._logger.debug("")
37 curl_cmd = pycurl.Curl()
38 if self._logger.getEffectiveLevel() == logging.DEBUG:
39 curl_cmd.setopt(pycurl.VERBOSE, True)
40 curl_cmd.setopt(pycurl.URL, self._url + endpoint)
41 curl_cmd.setopt(pycurl.SSL_VERIFYPEER, 0)
42 curl_cmd.setopt(pycurl.SSL_VERIFYHOST, 0)
43 if self._http_header:
44 curl_cmd.setopt(pycurl.HTTPHEADER, self._http_header)
45 return curl_cmd
46
47 def delete_cmd(self, endpoint):
48 self._logger.debug("")
49 data = BytesIO()
50 curl_cmd = self._get_curl_cmd(endpoint)
51 curl_cmd.setopt(pycurl.CUSTOMREQUEST, "DELETE")
52 curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
53 self._logger.info("Request METHOD: {} URL: {}".format("DELETE",self._url + endpoint))
54 curl_cmd.perform()
55 http_code = curl_cmd.getinfo(pycurl.HTTP_CODE)
56 self._logger.info("Response HTTPCODE: {}".format(http_code))
57 curl_cmd.close()
58 self.check_http_response(http_code, data)
59 # TODO 202 accepted should be returned somehow
60 if data.getvalue():
61 self._logger.verbose("Response DATA: {}".format(json.loads(data.getvalue().decode())))
62 return http_code, data.getvalue().decode()
63 else:
64 return http_code, None
65
66 def send_cmd(self, endpoint='', postfields_dict=None,
67 formfile=None, filename=None,
68 put_method=False, patch_method=False):
69 self._logger.debug("")
70 data = BytesIO()
71 curl_cmd = self._get_curl_cmd(endpoint)
72 if put_method:
73 curl_cmd.setopt(pycurl.CUSTOMREQUEST, "PUT")
74 elif patch_method:
75 curl_cmd.setopt(pycurl.CUSTOMREQUEST, "PATCH")
76 curl_cmd.setopt(pycurl.POST, 1)
77 curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
78
79 if postfields_dict is not None:
80 jsondata = json.dumps(postfields_dict)
81 if 'password' in postfields_dict:
82 postfields_dict_copy = copy.deepcopy(postfields_dict)
83 postfields_dict_copy['password']='******'
84 jsondata_log = json.dumps(postfields_dict_copy)
85 else:
86 jsondata_log = jsondata
87 self._logger.verbose("Request POSTFIELDS: {}".format(jsondata_log))
88 curl_cmd.setopt(pycurl.POSTFIELDS, jsondata)
89 elif formfile is not None:
90 curl_cmd.setopt(
91 pycurl.HTTPPOST,
92 [((formfile[0],
93 (pycurl.FORM_FILE,
94 formfile[1])))])
95 elif filename is not None:
96 with open(filename, 'rb') as stream:
97 postdata=stream.read()
98 self._logger.verbose("Request POSTFIELDS: Binary content")
99 curl_cmd.setopt(pycurl.POSTFIELDS, postdata)
100
101 if put_method:
102 self._logger.info("Request METHOD: {} URL: {}".format("PUT",self._url + endpoint))
103 elif patch_method:
104 self._logger.info("Request METHOD: {} URL: {}".format("PATCH",self._url + endpoint))
105 else:
106 self._logger.info("Request METHOD: {} URL: {}".format("POST",self._url + endpoint))
107 curl_cmd.perform()
108 http_code = curl_cmd.getinfo(pycurl.HTTP_CODE)
109 self._logger.info("Response HTTPCODE: {}".format(http_code))
110 curl_cmd.close()
111 self.check_http_response(http_code, data)
112 if data.getvalue():
113 self._logger.verbose("Response DATA: {}".format(json.loads(data.getvalue().decode())))
114 return http_code, data.getvalue().decode()
115 else:
116 return http_code, None
117
118 def post_cmd(self, endpoint='', postfields_dict=None,
119 formfile=None, filename=None):
120 self._logger.debug("")
121 return self.send_cmd(endpoint=endpoint,
122 postfields_dict=postfields_dict,
123 formfile=formfile,
124 filename=filename,
125 put_method=False, patch_method=False)
126
127 def put_cmd(self, endpoint='', postfields_dict=None,
128 formfile=None, filename=None):
129 self._logger.debug("")
130 return self.send_cmd(endpoint=endpoint,
131 postfields_dict=postfields_dict,
132 formfile=formfile,
133 filename=filename,
134 put_method=True, patch_method=False)
135
136 def patch_cmd(self, endpoint='', postfields_dict=None,
137 formfile=None, filename=None):
138 self._logger.debug("")
139 return self.send_cmd(endpoint=endpoint,
140 postfields_dict=postfields_dict,
141 formfile=formfile,
142 filename=filename,
143 put_method=False, patch_method=True)
144
145 def get2_cmd(self, endpoint):
146 self._logger.debug("")
147 data = BytesIO()
148 curl_cmd = self._get_curl_cmd(endpoint)
149 curl_cmd.setopt(pycurl.HTTPGET, 1)
150 curl_cmd.setopt(pycurl.WRITEFUNCTION, data.write)
151 self._logger.info("Request METHOD: {} URL: {}".format("GET",self._url + endpoint))
152 curl_cmd.perform()
153 http_code = curl_cmd.getinfo(pycurl.HTTP_CODE)
154 self._logger.info("Response HTTPCODE: {}".format(http_code))
155 curl_cmd.close()
156 self.check_http_response(http_code, data)
157 if data.getvalue():
158 self._logger.debug("Response DATA: {}".format(json.loads(data.getvalue().decode())))
159 return http_code, data.getvalue().decode()
160 return http_code, None
161
162 def check_http_response(self, http_code, data):
163 if http_code >= 300:
164 resp = ""
165 if data.getvalue():
166 resp=": " + data.getvalue().decode()
167 raise OsmHttpException("Error {}{}".format(http_code, resp))