(self, *, body: Dict[str, any], headers: Dict[str, str])
| 57 | ) |
| 58 | |
| 59 | def _perform_http_request(self, *, body: Dict[str, any], headers: Dict[str, str]) -> WebhookResponse: |
| 60 | body = json.dumps(body) |
| 61 | headers["Content-Type"] = "application/json;charset=utf-8" |
| 62 | |
| 63 | if self.logger.level <= logging.DEBUG: |
| 64 | self.logger.debug(f"Sending a request - url: {self.url}, body: {body}, headers: {headers}") |
| 65 | try: |
| 66 | url = self.url |
| 67 | opener: Optional[OpenerDirector] = None |
| 68 | # for security (BAN-B310) |
| 69 | if url.lower().startswith("http"): |
| 70 | req = Request(method="POST", url=url, data=body.encode("utf-8"), headers=headers) |
| 71 | if self.proxy is not None: |
| 72 | if isinstance(self.proxy, str): |
| 73 | opener = urllib.request.build_opener( |
| 74 | ProxyHandler({"http": self.proxy, "https": self.proxy}), |
| 75 | HTTPSHandler(context=self.ssl), |
| 76 | ) |
| 77 | else: |
| 78 | raise SlackRequestError(f"Invalid proxy detected: {self.proxy} must be a str value") |
| 79 | else: |
| 80 | raise SlackRequestError(f"Invalid URL detected: {url}") |
| 81 | |
| 82 | # NOTE: BAN-B310 is already checked above |
| 83 | resp: Optional[HTTPResponse] = None |
| 84 | if opener: |
| 85 | resp = opener.open(req, timeout=self.timeout) # skipcq: BAN-B310 |
| 86 | else: |
| 87 | resp = urlopen(req, context=self.ssl, timeout=self.timeout) # skipcq: BAN-B310 |
| 88 | charset: str = resp.headers.get_content_charset() or "utf-8" |
| 89 | response_body: str = resp.read().decode(charset) |
| 90 | resp = WebhookResponse( |
| 91 | url=url, |
| 92 | status_code=resp.status, |
| 93 | body=response_body, |
| 94 | headers=resp.headers, |
| 95 | ) |
| 96 | _debug_log_response(self.logger, resp) |
| 97 | return resp |
| 98 | |
| 99 | except HTTPError as e: |
| 100 | charset = e.headers.get_content_charset() or "utf-8" |
| 101 | body: str = e.read().decode(charset) # read the response body here |
| 102 | resp = WebhookResponse( |
| 103 | url=url, |
| 104 | status_code=e.code, |
| 105 | body=body, |
| 106 | headers=e.headers, |
| 107 | ) |
| 108 | if e.code == 429: |
| 109 | # for backward-compatibility with WebClient (v.2.5.0 or older) |
| 110 | resp.headers["Retry-After"] = resp.headers["retry-after"] |
| 111 | _debug_log_response(self.logger, resp) |
| 112 | return resp |
| 113 | |
| 114 | except Exception as err: |
| 115 | self.logger.error(f"Failed to send a request to Slack API server: {err}") |
| 116 | raise err |
no test coverage detected