def _log_debug(self, response): url = response.request.url debug_data = response.debug self._logger.debug( ("Communication debug info for calling: {url}\n" "--Debug Communication Info Start--\n" "{data}\n" "--Debug Communication Info End--").format(url=url, data=debug_data)) self._reporter.report( reports.node_communication_debug_info(url, debug_data))
def _log_debug(self, response): url = response.request.url debug_data = response.debug self._logger.debug( ( "Communication debug info for calling: {url}\n" "--Debug Communication Info Start--\n" "{data}\n" "--Debug Communication Info End--" ).format(url=url, data=debug_data) ) self._reporter.process( reports.node_communication_debug_info(url, debug_data) )
def call_host(self, host, request, data, request_timeout=None): """ Send a request to a host host host address request command to be run on the host data command parameters, encoded by format_data_* method request timeout float timeout for request, if not set object property will be used """ def __debug_callback(data_type, debug_data): prefixes = { pycurl.DEBUG_TEXT: b"* ", pycurl.DEBUG_HEADER_IN: b"< ", pycurl.DEBUG_HEADER_OUT: b"> ", pycurl.DEBUG_DATA_IN: b"<< ", pycurl.DEBUG_DATA_OUT: b">> ", } if data_type in prefixes: debug_output.write(prefixes[data_type]) debug_output.write(debug_data) if not debug_data.endswith(b"\n"): debug_output.write(b"\n") output = io.BytesIO() debug_output = io.BytesIO() cookies = self.__prepare_cookies(host) timeout = (request_timeout if request_timeout is not None else self.request_timeout) url = "https://{host}:2224/{request}".format( host=("[{0}]".format(host) if ":" in host else host), request=request) handler = pycurl.Curl() handler.setopt(pycurl.PROTOCOLS, pycurl.PROTO_HTTPS) handler.setopt(pycurl.TIMEOUT_MS, int(timeout * 1000)) handler.setopt(pycurl.URL, url.encode("utf-8")) handler.setopt(pycurl.WRITEFUNCTION, output.write) handler.setopt(pycurl.VERBOSE, 1) handler.setopt(pycurl.DEBUGFUNCTION, __debug_callback) handler.setopt(pycurl.SSL_VERIFYHOST, 0) handler.setopt(pycurl.SSL_VERIFYPEER, 0) handler.setopt(pycurl.NOSIGNAL, 1) # required for multi-threading handler.setopt(pycurl.HTTPHEADER, ["Expect: "]) if cookies: handler.setopt(pycurl.COOKIE, ";".join(cookies).encode("utf-8")) if data: handler.setopt(pycurl.COPYPOSTFIELDS, data.encode("utf-8")) msg = "Sending HTTP Request to: {url}" if data: msg += "\n--Debug Input Start--\n{data}\n--Debug Input End--" self._logger.debug(msg.format(url=url, data=data)) self._reporter.process(reports.node_communication_started(url, data)) result_msg = ( "Finished calling: {url}\nResponse Code: {code}" + "\n--Debug Response Start--\n{response}\n--Debug Response End--") try: handler.perform() response_data = output.getvalue().decode("utf-8") response_code = handler.getinfo(pycurl.RESPONSE_CODE) self._logger.debug( result_msg.format(url=url, code=response_code, response=response_data)) self._reporter.process( reports.node_communication_finished(url, response_code, response_data)) if response_code == 400: # old pcsd protocol: error messages are commonly passed in plain # text in response body with HTTP code 400 # we need to be backward compatible with that raise NodeCommandUnsuccessfulException(host, request, response_data.rstrip()) elif response_code == 401: raise NodeAuthenticationException( host, request, "HTTP error: {0}".format(response_code)) elif response_code == 403: raise NodePermissionDeniedException( host, request, "HTTP error: {0}".format(response_code)) elif response_code == 404: raise NodeUnsupportedCommandException( host, request, "HTTP error: {0}".format(response_code)) elif response_code >= 400: raise NodeCommunicationException( host, request, "HTTP error: {0}".format(response_code)) return response_data except pycurl.error as e: # In pycurl versions lower then 7.19.3 it is not possible to set # NOPROXY option. Therefore for the proper support of proxy settings # we have to use environment variables. if is_proxy_set(os.environ): self._logger.warning("Proxy is set") self._reporter.process( reports.node_communication_proxy_is_set()) errno, reason = e.args msg = "Unable to connect to {node} ({reason})" self._logger.debug(msg.format(node=host, reason=reason)) self._reporter.process( reports.node_communication_not_connected(host, reason)) if errno == pycurl.E_OPERATION_TIMEDOUT: raise NodeConnectionTimedOutException(host, request, reason) else: raise NodeConnectionException(host, request, reason) finally: debug_data = debug_output.getvalue().decode("utf-8", "ignore") self._logger.debug( ("Communication debug info for calling: {url}\n" "--Debug Communication Info Start--\n" "{data}\n" "--Debug Communication Info End--").format(url=url, data=debug_data)) self._reporter.process( reports.node_communication_debug_info(url, debug_data))