def _test_url(data): import requests from octoprint import util as util class StatusCodeRange(object): def __init__(self, start=None, end=None): self.start = start self.end = end def __contains__(self, item): if not isinstance(item, int): return False if self.start and self.end: return self.start <= item < self.end elif self.start: return self.start <= item elif self.end: return item < self.end else: return False def as_dict(self): return {"start": self.start, "end": self.end} status_ranges = { "informational": StatusCodeRange(start=100, end=200), "success": StatusCodeRange(start=200, end=300), "redirection": StatusCodeRange(start=300, end=400), "client_error": StatusCodeRange(start=400, end=500), "server_error": StatusCodeRange(start=500, end=600), "normal": StatusCodeRange(end=400), "error": StatusCodeRange(start=400, end=600), "any": StatusCodeRange(start=100), "timeout": StatusCodeRange(start=0, end=1), } url = data["url"] method = data.get("method", "HEAD") timeout = 3.0 valid_ssl = True check_status = [status_ranges["normal"]] content_type_whitelist = None content_type_blacklist = None if "timeout" in data: try: timeout = float(data["timeout"]) except Exception: return make_response( "{!r} is not a valid value for timeout (must be int or float)". format(data["timeout"]), 400, ) if "validSsl" in data: valid_ssl = data["validSsl"] in valid_boolean_trues if "status" in data: request_status = data["status"] if not isinstance(request_status, list): request_status = [request_status] check_status = [] for rs in request_status: if isinstance(rs, int): check_status.append([rs]) else: if rs in status_ranges: check_status.append(status_ranges[rs]) else: code = requests.codes[rs] if code is not None: check_status.append([code]) if "content_type_whitelist" in data: if not isinstance(data["content_type_whitelist"], (list, tuple)): return make_response( "content_type_whitelist must be a list of mime types") content_type_whitelist = list( map(util.parse_mime_type, data["content_type_whitelist"])) if "content_type_blacklist" in data: if not isinstance(data["content_type_whitelist"], (list, tuple)): return make_response( "content_type_blacklist must be a list of mime types") content_type_blacklist = list( map(util.parse_mime_type, data["content_type_blacklist"])) response_result = None outcome = True status = 0 try: with requests.request(method=method, url=url, timeout=timeout, verify=valid_ssl, stream=True) as response: status = response.status_code outcome = outcome and any(map(lambda x: status in x, check_status)) content_type = response.headers.get("content-type") response_result = { "headers": dict(response.headers), "content_type": content_type, } if not content_type and data.get( "content_type_guess") in valid_boolean_trues: content = response.content content_type = util.guess_mime_type(bytearray(content)) if not content_type: content_type = "application/octet-stream" response_result = {"assumed_content_type": content_type} parsed_content_type = util.parse_mime_type(content_type) in_whitelist = content_type_whitelist is None or any( map( lambda x: util.mime_type_matches(parsed_content_type, x), content_type_whitelist, )) in_blacklist = content_type_blacklist is not None and any( map( lambda x: util.mime_type_matches(parsed_content_type, x), content_type_blacklist, )) if not in_whitelist or in_blacklist: # we don't support this content type response.close() outcome = False elif "response" in data and ( data["response"] in valid_boolean_trues or data["response"] in ("json", "bytes")): if data["response"] == "json": content = response.json() else: import base64 content = base64.standard_b64encode(response.content) response_result["content"] = content except Exception: logging.getLogger(__name__).exception( "Error while running a test {} request on {}".format(method, url)) outcome = False result = {"url": url, "status": status, "result": outcome} if response_result: result["response"] = response_result return jsonify(**result)
def _test_url(data): import requests class StatusCodeRange(object): def __init__(self, start=None, end=None): self.start = start self.end = end def __contains__(self, item): if not isinstance(item, int): return False if self.start and self.end: return self.start <= item < self.end elif self.start: return self.start <= item elif self.end: return item < self.end else: return False def as_dict(self): return dict( start=self.start, end=self.end ) status_ranges = dict( informational=StatusCodeRange(start=100, end=200), success=StatusCodeRange(start=200, end=300), redirection=StatusCodeRange(start=300, end=400), client_error=StatusCodeRange(start=400, end=500), server_error=StatusCodeRange(start=500, end=600), normal=StatusCodeRange(end=400), error=StatusCodeRange(start=400, end=600), any=StatusCodeRange(start=100), timeout=StatusCodeRange(start=0, end=1) ) url = data["url"] method = data.get("method", "HEAD") timeout = 3.0 valid_ssl = True check_status = [status_ranges["normal"]] content_type_whitelist = None content_type_blacklist = None if "timeout" in data: try: timeout = float(data["timeout"]) except: return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400) if "validSsl" in data: valid_ssl = data["validSsl"] in valid_boolean_trues if "status" in data: request_status = data["status"] if not isinstance(request_status, list): request_status = [request_status] check_status = [] for rs in request_status: if isinstance(rs, int): check_status.append([rs]) else: if rs in status_ranges: check_status.append(status_ranges[rs]) else: code = requests.codes[rs] if code is not None: check_status.append([code]) if "content_type_whitelist" in data: if not isinstance(data["content_type_whitelist"], (list, tuple)): return make_response("content_type_whitelist must be a list of mime types") content_type_whitelist = map(util.parse_mime_type, data["content_type_whitelist"]) if "content_type_blacklist" in data: if not isinstance(data["content_type_whitelist"], (list, tuple)): return make_response("content_type_blacklist must be a list of mime types") content_type_blacklist = map(util.parse_mime_type, data["content_type_blacklist"]) response_result = None outcome = True status = 0 try: with requests.request(method=method, url=url, timeout=timeout, verify=valid_ssl, stream=True) as response: status = response.status_code outcome = outcome and any(map(lambda x: status in x, check_status)) content_type = response.headers.get("content-type") response_result = dict(headers=dict(response.headers), content_type=content_type) parsed_content_type = util.parse_mime_type(content_type) in_whitelist = content_type_whitelist is None or any( map(lambda x: util.mime_type_matches(parsed_content_type, x), content_type_whitelist)) in_blacklist = content_type_blacklist is not None and any( map(lambda x: util.mime_type_matches(parsed_content_type, x), content_type_blacklist)) if not in_whitelist or in_blacklist: # we don't support this content type response.close() outcome = False elif "response" in data and ( data["response"] in valid_boolean_trues or data["response"] in ("json", "bytes")): if data["response"] == "json": content = response.json() else: import base64 content = base64.standard_b64encode(response.content) response_result["content"] = content except: logging.getLogger(__name__).exception("Error while running a test {} request on {}".format(method, url)) outcome = False result = dict( url=url, status=status, result=outcome ) if response_result: result["response"] = response_result return jsonify(**result)