def perform_custom_request(self, method, url, headers, data): try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: proxies = {"https": proxy_setting} else: proxies = None r = requests.request(pyNativeStr(method), pyNativeStr(url), headers=headers, data=data, proxies=proxies) response = r.content if len(response) == 0: core.BNSetErrorForDownloadInstance(self.handle, "No data received from server!") return None raw_bytes = (ctypes.c_ubyte * len(response)).from_buffer_copy(response) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return None continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_wrote, bytes_wrote) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return None return DownloadInstance.Response(r.status_code, r.headers, None) except requests.RequestException as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) return None except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return None
def perform_custom_request(self, method, url, headers, data_generator): result = None try: proxy_setting = settings.Settings().get_string( 'network.httpsProxy') if proxy_setting: opener = build_opener( ProxyHandler({'https': proxy_setting})) install_opener(opener) # Cannot have Content-Length if the body is chunked if b"Content-Length" in headers: del headers[b"Content-Length"] req = PythonDownloadInstance.CustomRequest( url.decode('utf8'), data=data_generator, headers=headers, method=method.decode('utf8')) result = urlopen(req) except HTTPError as he: result = he total_size = 0 for (key, value) in result.headers.items(): if key.lower() == b'content-length': total_size = int(value) break bytes_sent = 0 while True: data = result.read(4096) if not data: break raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance( self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance( self.handle, "Bytes written mismatch!") return None bytes_sent = bytes_sent + bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance( self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance( self.handle, "Download aborted!") return None return DownloadInstance.Response(result.getcode(), result.headers, None)
def perform_request(self, url): try: proxy_setting = settings.Settings().get_string( 'network.httpsProxy') if proxy_setting: opener = build_opener( ProxyHandler({'https': proxy_setting})) install_opener(opener) r = urlopen(url.decode('utf8')) total_size = int(r.headers.get('content-length', 0)) bytes_sent = 0 while True: data = r.read(4096) if not data: break raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance( self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance( self.handle, "Bytes written mismatch!") return -1 bytes_sent = bytes_sent + bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance( self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance( self.handle, "Download aborted!") return -1 if not bytes_sent: core.BNSetErrorForDownloadInstance( self.handle, "Received no data!") return -1 except URLError as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) log_error(str(e)) return -1 except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log_error(traceback.format_exc()) return -1 return 0
def perform_custom_request(self, method, url, headers, data): result = None try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: opener = build_opener(ProxyHandler({'https': proxy_setting})) install_opener(opener) if b"Content-Length" in headers: del headers[b"Content-Length"] req = PythonDownloadInstance.CustomRequest(pyNativeStr(url), data=data, headers=headers, method=pyNativeStr(method)) result = urlopen(req) except HTTPError as he: result = he except URLError as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) log.log_error(str(e)) return None except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return None total_size = int(result.headers.get('content-length', 0)) bytes_sent = 0 while True: data = result.read(4096) if not data: break raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return None bytes_sent = bytes_sent + bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return None if not bytes_sent: core.BNSetErrorForDownloadInstance(self.handle, "Received no data!") return None return DownloadInstance.Response(result.getcode(), result.headers, None)
def perform_custom_request(self, method, url, headers, data_generator): proxy_setting = settings.Settings().get_string( 'network.httpsProxy') if proxy_setting: proxies = {"https": proxy_setting} else: proxies = None # Cannot have Content-Length if the body is chunked if b"Content-Length" in headers: del headers[b"Content-Length"] r = requests.request(method.decode('utf8'), url.decode('utf8'), headers=headers, data=data_generator, proxies=proxies, stream=True) total_size = 0 for (key, value) in r.headers.items(): if key.lower() == b'content-length': total_size = int(value) break bytes_sent = 0 for chunk in r.iter_content(None): raw_bytes = (ctypes.c_ubyte * len(chunk)).from_buffer_copy(chunk) bytes_wrote = core.BNWriteDataForDownloadInstance( self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance( self.handle, "Bytes written mismatch!") return None bytes_sent += bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance( self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return None return DownloadInstance.Response(r.status_code, r.headers, None)
def perform_request(self, url): try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: proxies = {"https": proxy_setting} else: proxies = None r = requests.get(pyNativeStr(url), proxies=proxies) if not r.ok: core.BNSetErrorForDownloadInstance(self.handle, "Received error from server") return -1 data = r.content if len(data) == 0: core.BNSetErrorForDownloadInstance(self.handle, "No data received from server!") return -1 raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return -1 continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_wrote, bytes_wrote) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return -1 except requests.RequestException as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) return -1 except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return -1 return 0
def _perform_custom_request(self, ctxt, method, url, header_count, header_keys, header_values, response): # Cast response to an array of length 1 so ctypes can write to the pointer # out_response = ((BNDownloadInstanceResponse*)[1])response out_response = (ctypes.POINTER(core.BNDownloadInstanceResponse) * 1).from_address(ctypes.addressof( response.contents)) # type: ignore try: # Extract headers keys_ptr = ctypes.cast(header_keys, ctypes.POINTER(ctypes.c_char_p)) values_ptr = ctypes.cast(header_values, ctypes.POINTER(ctypes.c_char_p)) header_key_array = (ctypes.c_char_p * header_count).from_address( ctypes.addressof(keys_ptr.contents)) header_value_array = (ctypes.c_char_p * header_count).from_address( ctypes.addressof(values_ptr.contents)) headers = {} for i in range(header_count): headers[header_key_array[i]] = header_value_array[i] # Generator function that returns a chunk of data on every iteration def data_generator(): while True: read_buffer = ctypes.create_string_buffer(0x1000) read_len = core.BNReadDataForDownloadInstance( self.handle, ctypes.cast(read_buffer, ctypes.POINTER(ctypes.c_uint8)), 0x1000) if read_len == 0: break if read_len < 0: raise IOError() yield read_buffer[:read_len] try: py_response = self.perform_custom_request( method, url, headers, data_generator()) except Exception as e: out_response[0] = None core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) log_error(traceback.format_exc()) return -1 if py_response is not None: # Assign to an instance variable so the memory stays live until the request is done self.bn_response = core.BNDownloadInstanceResponse() self.bn_response.statusCode = py_response.status_code self.bn_response.headerCount = len(py_response.headers) self.bn_response.headerKeys = (ctypes.c_char_p * len(py_response.headers))() self.bn_response.headerValues = (ctypes.c_char_p * len(py_response.headers))() for i, (key, value) in enumerate(py_response.headers.items()): self.bn_response.headerKeys[i] = core.BNAllocString( key.decode('utf8')) self.bn_response.headerValues[i] = core.BNAllocString( value.decode('utf8')) out_response[0] = ctypes.pointer(self.bn_response) else: out_response[0] = None return 0 if py_response is not None else -1 except: out_response[0] = None log_error(traceback.format_exc()) return -1