async def abort(self, errorCode: str = 'failed') -> None: """Abort request. To use this, request interception should be enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. If request interception is not enabled, raise ``NetworkError``. ``errorCode`` is an optional error code string. Defaults to ``failed``, could be one of the following: ``aborted``, ``accesdenied``, ``addressunreachable``, ``connectionaborted``, ``connectionclosed``, ``connectionfailed``, ``connnectionrefused``, ``connectionreset``, ``internetdisconnected``, ``namenotresolved``, ``timedout``, ``failed`` """ errorReason = errorReasons[errorCode] if not errorReason: raise NetworkError('Unknown error code: {}'.format(errorCode)) if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True await self._client.send( 'Network.continueInterceptedRequest', dict( interceptionId=self._interceptionId, errorReason=errorReason, ))
async def continue_(self, overrides: Dict = None) -> None: """Continue request with optional request overrides. To use this method, request interception should be enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. If request interception is not enabled, raise ``NetworkError``. ``overrides`` can have the following fields: * ``url`` (str): If set, the request url will be changed. * ``method`` (str): If set, change the request method (e.g. ``GET``). * ``postData`` (str): If set, change the post data or request. * ``headers`` (dict): If set, change the request HTTP header. """ if overrides is None: overrides = {} if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True opt = {'interceptionId': self._interceptionId} opt.update(overrides) try: await self._client.send('Network.continueInterceptedRequest', opt) except Exception as e: debugError(logger, e)
def send(self, method: str, params: dict = None) -> Awaitable: """Send message to the connected session. :arg str method: Protocol method name. :arg dict params: Optional method parameters. """ if not self._connection: raise NetworkError( f'Protocol Error ({method}): Session closed. Most likely the ' f'{self._targetType} has been closed.') self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) logger_session.debug(f'SEND: {msg}') callback = self._loop.create_future() self._callbacks[_id] = callback callback.error: Exception = NetworkError() # type: ignore callback.method: str = method # type: ignore try: self._connection.send('Target.sendMessageToTarget', { 'sessionId': self._sessionId, 'message': msg, }) except Exception as e: # The response from target might have been already dispatched if _id in self._callbacks: del self._callbacks[_id] _callback = self._callbacks[_id] _callback.set_exception( _rewriteError( _callback.error, # type: ignore e.args[0], )) return callback
def send(self, method: str, params: dict = None) -> Awaitable: 'Send message to the connected session.\n\n :arg str method: Protocol method name.\n :arg dict params: Optional method parameters.\n ' if (not self._connection): raise NetworkError(''.join([ 'Protocol Error (', '{}'.format(method), '): Session closed. Most likely the ', '{}'.format(self._targetType), ' has been closed.' ])) self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) logger_session.debug(''.join(['SEND: ', '{}'.format(msg)])) callback = self._loop.create_future() self._callbacks[_id] = callback callback.error = NetworkError() callback.method = method try: self._connection.send('Target.sendMessageToTarget', { 'sessionId': self._sessionId, 'message': msg, }) except Exception as e: if (_id in self._callbacks): del self._callbacks[_id] _callback = self._callbacks[_id] _callback.set_exception( _rewriteError(_callback.error, e.args[0])) return callback
async def respond(self, response: Dict) -> None: # noqa: C901 """Fulfills request with given response. To use this, request interception should by enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. Request interception is not enabled, raise ``NetworkError``. ``response`` is a dictionary which can have the following fields: * ``status`` (int): Response status code, defaults to 200. * ``headers`` (dict): Optional response headers. * ``contentType`` (str): If set, equals to setting ``Content-Type`` response header. * ``body`` (str|bytes): Optional response body. """ if self._url.startswith('data:'): return if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True if response.get('body') and isinstance(response['body'], str): responseBody: Optional[bytes] = response['body'].encode('utf-8') else: responseBody = response.get('body') responseHeaders = [] if response.get('headers'): for key, value in response['headers'].items(): responseHeaders.append({"name": key.lower(), "value": value}) if response.get('contentType'): responseHeaders.append({ "name": 'content-type', "value": response['contentType'] }) if responseBody and 'content-length' not in responseHeaders: responseHeaders.append({ "name": 'content-length', "value": str(len(responseBody)) }) try: await self._client.send( 'Fetch.fulfillRequest', { 'requestId': self._interceptionId, 'responseCode': response.get("status", 200), 'responseHeaders': responseHeaders, 'body': base64.b64encode(responseBody).decode('ascii') if responseBody else None }) except Exception as e: debugError(logger, e)
async def respond(self, response: Dict) -> None: # noqa: C901 """Fulfills request with given response. To use this, request interception should by enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. Request interception is not enabled, raise ``NetworkError``. ``response`` is a dictionary which can have the following fields: * ``status`` (int): Response status code, defaults to 200. * ``headers`` (dict): Optional response headers. * ``contentType`` (str): If set, equals to setting ``Content-Type`` response header. * ``body`` (str|bytes): Optional response body. """ if self._url.startswith('data:'): return if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True if response.get('body') and isinstance(response['body'], str): responseBody: Optional[bytes] = response['body'].encode('utf-8') else: responseBody = response.get('body') responseHeaders = {} if response.get('headers'): for header in response['headers']: responseHeaders[header.lower()] = response['headers'][header] if response.get('contentType'): responseHeaders['content-type'] = response['contentType'] if responseBody and 'content-length' not in responseHeaders: responseHeaders['content-length'] = len(responseBody) statusCode = response.get('status', 200) statusText = statusTexts.get(statusCode, '') statusLine = f'HTTP/1.1 {statusCode} {statusText}' CRLF = '\r\n' text = statusLine + CRLF for header in responseHeaders: text = f'{text}{header}: {responseHeaders[header]}{CRLF}' text = text + CRLF responseBuffer = text.encode('utf-8') if responseBody: responseBuffer = responseBuffer + responseBody rawResponse = base64.b64encode(responseBuffer).decode('ascii') try: await self._client.send( 'Network.continueInterceptedRequest', { 'interceptionId': self._interceptionId, 'rawResponse': rawResponse, }) except Exception as e: debugError(logger, e)
async def abort(self) -> None: """Abort request.""" if self.url.startswith('data:'): return if not self._allowInterception: raise NetworkError('Request intercetion is not enabled!') if self._interceptionHandled: raise NetworkError('Intercetion is already handled!') self._interceptionHandled = True await self._client.send('Network.continueInterceptedRequest', dict( interceptionId=self._interceptionId, errorReason='Failed', ))
async def respond(self, response: Dict) -> None: # noqa: C901 """Fulfills request with given response. To use this, request interception should by enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. Request interception is not enabled, raise ``NetworkError``. ``response`` is a dictionary which can have the following fields: * ``responseCode`` (int): Response status code, defaults to 200. * ``headers`` (dict): Optional response headers. * ``body`` (str|bytes): Optional response body. * ``responsePhrase`` (string): A textual representation of responseCode. If absent, a standard phrase matching responseCode is used. """ if self._url.startswith('data:'): return if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True if response.get('body') and isinstance(response['body'], str): responseBody: Optional[bytes] = response['body'].encode('utf-8') else: responseBody = response.get('body') responseHeaders = {} if response.get('headers'): for header in response['headers']: responseHeaders[header.lower()] = response['headers'][header] if response.get('contentType'): responseHeaders['content-type'] = response['contentType'] if responseBody and 'content-length' not in responseHeaders: responseHeaders['content-length'] = len(responseBody) statusCode = response.get('responseCode', 200) statusText = statusTexts.get(str(statusCode)) rawResponse = base64.b64encode(responseBody).decode('ascii') try: await self._client.send('Fetch.fulfillRequest', { 'requestId': self._interceptionId, 'responseCode': statusCode if statusCode is not None else 200, 'responsePhrase': statusText if statusText is not None else statusTexts['200'], 'responseHeaders': headersArray(responseHeaders), 'body': rawResponse }) except Exception as e: debugError(logger, e)
async def abort(self, errorCode: str = 'failed') -> None: """Abort request. To use this, request interception should be enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. If request interception is not enabled, raise ``NetworkError``. ``errorCode`` is an optional error code string. Defaults to ``failed``, could be one of the following: - ``aborted``: An operation was aborted (due to user action). - ``accessdenied``: Permission to access a resource, other than the network, was denied. - ``addressunreachable``: The IP address is unreachable. This usually means that there is no route to the specified host or network. - ``blockedbyclient``: The client chose to block the request. - ``blockedbyresponse``: The request failed because the request was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor check, for instance). - ``connectionaborted``: A connection timeout as a result of not receiving an ACK for data sent. - ``connectionclosed``: A connection was closed (corresponding to a TCP FIN). - ``connectionfailed``: A connection attempt failed. - ``connectionrefused``: A connection attempt was refused. - ``connectionreset``: A connection was reset (corresponding to a TCP RST). - ``internetdisconnected``: The Internet connection has been lost. - ``namenotresolved``: The host name could not be resolved. - ``timedout``: An operation timed out. - ``failed``: A generic failure occurred. """ errorReason = errorReasons[errorCode] if not errorReason: raise NetworkError('Unknown error code: {}'.format(errorCode)) if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True try: await self._client.send( 'Network.continueInterceptedRequest', dict( interceptionId=self._interceptionId, errorReason=errorReason, )) except Exception as e: debugError(logger, e)
async def detach(self) -> None: "Detach session from target.\n\n Once detached, session won't emit any events and can't be used to send\n messages.\n " if (not self._connection): raise NetworkError('Connection already closed.') (await self._connection.send('Target.detachFromTarget', { 'sessionId': self._sessionId, }))
async def continue_(self, overrides: Dict=None) -> None: 'Continue request with optional request overrides.\n\n To use this method, request interception should be enabled by\n :meth:`pyppeteer.page.Page.setRequestInterception`. If request\n interception is not enabled, raise ``NetworkError``.\n\n ``overrides`` can have the following fields:\n\n * ``url`` (str): If set, the request url will be changed.\n * ``method`` (str): If set, change the request method (e.g. ``GET``).\n * ``postData`` (str): If set, change the post data or request.\n * ``headers`` (dict): If set, change the request HTTP header.\n ' if (overrides is None): overrides = { } if (not self._allowInterception): raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True opt = { 'interceptionId': self._interceptionId, } opt.update(overrides) (await self._client.send('Network.continueInterceptedRequest', opt))
async def _on_response(self, msg: dict) -> None: callback = self._callbacks.pop(msg.get('id', -1)) if 'error' in msg: error = msg['error'] callback.set_exception(NetworkError(f'Protocol Error: {error}')) else: callback.set_result(msg.get('result'))
def _on_response(self, msg: dict) -> None: callback = self._callbacks.pop(msg.get('id', (- 1))) if ('error' in msg): error = msg['error'] callback.set_exception(NetworkError( ''.join(['Protocol Error: ', '{}'.format(error)]))) else: callback.set_result(msg.get('result'))
def _onRequestIntercepted(self, event: dict) -> None: # noqa: C901 if event.get('authChallenge'): response = 'Default' if event['interceptionId'] in self._attemptedAuthentications: response = 'CancelAuth' elif self._credentials: response = 'ProvideCredentials' self._attemptedAuthentications.add(event['interceptionId']) username = getattr(self, '_credentials', {}).get('username') password = getattr(self, '_credentials', {}).get('password') asyncio.ensure_future( self._client.send( 'Network.continueInterceptedRequest', { 'interceptionId': event['interceptionId'], 'authChallengeResponse': { 'response': response, 'username': username, 'password': password, } })) return if (not self._userRequestInterceptionEnabled and self._protocolRequestInterceptionEnabled): asyncio.ensure_future( self._client.send('Network.continueInterceptedRequest', { 'interceptionId': event['interceptionId'], })) if 'redirectStatusCode' in event: request = self._interceptionIdToRequest.get( event.get('interceptionId', '')) if not request: raise NetworkError('INTERNAL ERROR: failed to find request ' 'for interception redirect.') self._handleRequestRedirect(request, event.get('redirectStatusCode', 0), event.get('redirectHeaders', {})) self._handleRequestStart(request._requestId, event.get('interceptionId', ''), event.get('redirectUrl', ''), event.get('resourceType', ''), event.get('request', {})) return requestHash = generateRequestHash(event['request']) requestId = self._requestHashToRequestIds.firstValue(requestHash) if requestId: self._requestHashToRequestIds.delete(requestHash, requestId) self._handleRequestStart(requestId, event['interceptionId'], event['request']['url'], event['resourceType'], event['request']) else: self._requestHashToInterceptionIds.set(requestHash, event['interceptionId']) self._handleRequestStart(None, event['interceptionId'], event['request']['url'], event['resourceType'], event['request'])
async def waitForNavigation(self) -> None: """Wait until navigatoin completes.""" self._requestIds: Set[str] = set() self._eventListeners: List[dict] = list() navigationPromises = list() loop = asyncio.get_event_loop() def watchdog_cb(fut: Awaitable) -> None: self._raise_error(asyncio.TimeoutError( 'Navigation Timeout Exceeded: {} ms exceeded'.format( self._timeout) )) watchdog: asyncio.Future = asyncio.ensure_future( asyncio.sleep(self._timeout / 1000)) self._maximumTimer = watchdog watchdog.add_done_callback(watchdog_cb) navigationPromises.append(watchdog) if not self._ignoreHTTPSErrors: certificateError = loop.create_future() self._eventListeners.append( helper.addEventListener( self._client, 'Security.certificateError', lambda event: certificateError.set_exception( NetworkError('SSL Certificate error: ' + str(event.get('errorType'))) ) ) ) navigationPromises.append(certificateError) if self._waitUntil == 'load': loadEventFired = loop.create_future() self._eventListeners.append( helper.addEventListener( self._client, 'Page.loadEventFired', lambda event: loadEventFired.set_result(None) ) ) navigationPromises.append(loadEventFired) else: self._eventListeners.extend(( helper.addEventListener(self._client, 'Network.requestWillBeSent', self._onLoadingStarted), # noqa helper.addEventListener(self._client, 'Network.loadingFinished', self._onLoadingCompleted), # noqa helper.addEventListener(self._client, 'Network.loadingFailed', self._onLoadingCompleted), # noqa helper.addEventListener(self._client, 'Network.webSocketCreated', self._onLoadingStarted), # noqa helper.addEventListener(self._client, 'Network.webSocketClosed', self._onLoadingCompleted), # noqa )) networkIdle = loop.create_future() self._networkIdleCallback = lambda f: networkIdle.set_result(None) navigationPromises.append(networkIdle) await asyncio.wait(navigationPromises, return_when=concurrent.futures.FIRST_COMPLETED) if not watchdog.done(): watchdog.remove_done_callback(watchdog_cb) self._cleanup()
async def respond(self, response: Dict) -> None: 'Fulfills request with given response.\n\n To use this, request interception should by enabled by\n :meth:`pyppeteer.page.Page.setRequestInterception`. Request\n interception is not enabled, raise ``NetworkError``.\n\n ``response`` is a dictionary which can have the following fields:\n\n * ``status`` (int): Response status code, defaults to 200.\n * ``headers`` (dict): Optional response headers.\n * ``contentType`` (str): If set, equals to setting ``Content-Type``\n response header.\n * ``body`` (str|bytes): Optional response body.\n ' if self._url.startswith('data:'): return if (not self._allowInterception): raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True if (response.get('body') and isinstance(response['body'], str)): responseBody = response['body'].encode('utf-8') else: responseBody = response.get('body') responseHeaders = { } if response.get('headers'): for header in response['headers']: responseHeaders[header.lower()] = response['headers'][header] if response.get('contentType'): responseHeaders['content-type'] = response['contentType'] if (responseBody and ('content-length' not in responseHeaders)): responseHeaders['content-length'] = len(responseBody) statusCode = response.get('status', 200) statusText = statusTexts.get(statusCode, '') statusLine = ''.join( ['HTTP/1.1 ', '{}'.format(statusCode), ' ', '{}'.format(statusText)]) CRLF = '\r\n' text = (statusLine + CRLF) for header in responseHeaders: text = ''.join(['{}'.format(text), '{}'.format(header), ': ', '{}'.format( responseHeaders[header]), '{}'.format(CRLF)]) text = (text + CRLF) responseBuffer = text.encode('utf-8') if responseBody: responseBuffer = (responseBuffer + responseBody) rawResponse = base64.b64encode(responseBuffer).decode('ascii') try: (await self._client.send('Network.continueInterceptedRequest', { 'interceptionId': self._interceptionId, 'rawResponse': rawResponse, })) except Exception as e: debugError(logger, e)
async def _on_close(self) -> None: if not self._recv_fut.done(): if hasattr(self, 'connection'): # may not have connection await self.connection.close() for cb in self._callbacks.values(): cb.set_exception(NetworkError('connection closed')) self._callbacks.clear() for session in self._sessions.values(): session._on_closed() self._sessions.clear()
def send(self, method: str, params: dict = None) -> Awaitable: """Send message to the connected session. :arg str method: Protocol method name. :arg dict params: Optional method parameters. """ if not params: params = dict() if not self._connection: raise NetworkError( f'Protocol Error ({method}): Session closed. Most likely the ' f'{self._targetType} has been closed.') _id = self._connection._rawSend(sessionId=self._sessionId, method=method, params=params) callback = self._loop.create_future() self._callbacks[_id] = callback callback.error: Exception = NetworkError() # type: ignore callback.method: str = method # type: ignore return callback
def _handleRequestRedirect(self, request, responsePayload) -> None: response = Response(self._client, request, responsePayload) request._response = response request._redirectChain.append(request) response._bodyLoadedPromiseFulfill( NetworkError('Response body is unavailable for redirect response')) self._requestIdToRequest.pop(request._requestId, None) self._interceptionIdToRequest.pop(request._interceptionId, None) self._attemptedAuthentications.discard(request._interceptionId) self.emit(NetworkManager.Events.Response, response) self.emit(NetworkManager.Events.RequestFinished, request)
def __init__(self, frameManager: FrameManager, frame: Frame, waitUntil: str, timeout: int) -> None: if isinstance(waitUntil, list): waitUntil = waitUntil[::] elif isinstance(waitUntil, str): waitUntil = [waitUntil] if "documentloaded" in waitUntil: logging.getLogger(__name__).warning( '`documentloaded` option is no longer supported. ' 'Use `domcontentloaded` instead.') self._hasSameDocumentNavigation = False self._expectedLifecycle: List[str] = [] for value in waitUntil: protocolEvent = pyppeteerToProtocolLifecycle.get(value) if protocolEvent is None: raise ValueError( f'Unknown value for options.waitUntil: {value}') self._expectedLifecycle.append(protocolEvent) self._maximumTimer = None self._timeoutOrTermination = None self._frameManager = frameManager self._loop = self._frameManager._client._loop self._frame = frame self._initialLoaderId = frame._loaderId self._timeout = timeout self._navigationRequest = None self._eventListeners = [ helper.addEventListener(frameManager._client, CDPSession.Events.Disconnected, lambda: self._terminate(NetworkError( 'Navigation failed because browser has disconnected!')) ), helper.addEventListener(self._frameManager, FrameManager.Events.LifecycleEvent, self._checkLifecycleComplete), helper.addEventListener(self._frameManager, FrameManager.Events.FrameNavigatedWithinDocument, self._navigatedWithinDocument), helper.addEventListener(self._frameManager, FrameManager.Events.FrameDetached, self._onFrameDetached), helper.addEventListener(self._frameManager.NetworkManager, NetworkManager.Events.Request, self._onRequest), ] self._timeoutPromise = self._createTimeoutPromise() self._sameDocumentNavigationPromise = self._loop.create_future() self._lifecyclePromise = self._loop.create_future() self._newDocumentNavigationPromise = self._loop.create_future() self._terminationPromise = self._loop.create_future() self._checkLifecycleComplete()
def _handleRequestRedirect(self, request: 'Request', redirectStatus: int, redirectHeaders: Dict, fromDiskCache: bool, fromServiceWorker: bool, securityDetails: Dict = None) -> None: response = Response(self._client, request, redirectStatus, redirectHeaders, fromDiskCache, fromServiceWorker, securityDetails) request._response = response request._redirectChain.append(request) response._bodyLoadedPromiseFulfill(NetworkError( 'Response body is unavailable for redirect response')) self._requestIdToRequest.pop(request._requestId, None) self._interceptionIdToRequest.pop(request._interceptionId, None) self._attemptedAuthentications.discard(request._interceptionId) self.emit(NetworkManager.Events.Response, response) self.emit(NetworkManager.Events.RequestFinished, request)
def send(self, method: str, params: dict = None) -> Awaitable: """Send message via the connection.""" # Detect connection availability from the second transmission if self._lastId and not self._connected: raise ConnectionError('Connection is closed') if params is None: params = dict() _id = self._rawSend(method=method, params=params) callback = self._loop.create_future() self._callbacks[_id] = callback callback.error: Exception = NetworkError() # type: ignore callback.method: str = method # type: ignore return callback
async def continue_(self, overrides: Dict = None) -> None: """Continue request with optional request overrides. To use this method, request interception should be enabled by :meth:`pyppeteer.page.Page.setRequestInterception`. If request interception is not enabled, raise ``NetworkError``. ``overrides`` can have the following fields: * ``url`` (str): If set, the request url will be changed. * ``method`` (str): If set, change the request method (e.g. ``GET``). * ``postData`` (str): If set, change the post data or request. * ``headers`` (dict): If set, change the request HTTP header. """ if overrides is None: overrides = {} if not self._allowInterception: raise NetworkError('Request interception is not enabled.') if self._interceptionHandled: raise NetworkError('Request is already handled.') self._interceptionHandled = True url = overrides.get('url') method = overrides.get('method') postData = overrides.get('postData') headers = overrides.get('headers') try: await self._client.send('Fetch.continueRequest', {'requestId': self._interceptionId, 'url': url, 'method': method, 'postData': postData, 'headers': headersArray(headers) if headers else None } ) except Exception as e: debugError(logger, e)
async def send(self, method: str, params: dict = None) -> dict: """Send message to the connected session. :arg str method: Protocol method name. :arg dict params: Optional method parameters. """ self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) callback = self._loop.create_future() self._callbacks[_id] = callback callback.method: str = method # type: ignore if not self._connection: raise NetworkError('Connection closed.') try: await self._connection.send('Target.sendMessageToTarget', { 'sessionId': self._sessionId, 'message': msg, }) except concurrent.futures.CancelledError: raise NetworkError("connection unexpectedly closed") return await callback
async def send(self, method: str, params: dict=None) -> dict: 'Send message to the connected session.\n\n :arg str method: Protocol method name.\n :arg dict params: Optional method parameters.\n ' self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) callback = asyncio.get_event_loop().create_future() self._callbacks[_id] = callback callback.method = method if (not self._connection): raise NetworkError('Connection closed.') (await self._connection.send('Target.sendMessageToTarget', { 'sessionId': self._sessionId, 'message': msg, })) return (await callback)
def _on_message(self, msg: str) -> None: obj = json.loads(msg) _id = obj.get('id') if _id and _id in self._callbacks: callback = self._callbacks.pop(_id) if 'error' in obj: error = obj['error'] msg = error.get('message') data = error.get('data') callback.set_exception( NetworkError(f'Protocol Error: {msg} {data}')) else: result = obj.get('result') callback.set_result(result) else: self.emit(obj.get('method'), obj.get('params'))
def _on_message(self, msg: str) -> None: obj = json.loads(msg) _id = obj.get('id') if (_id and (_id in self._callbacks)): callback = self._callbacks.pop(_id) if ('error' in obj): error = obj['error'] msg = error.get('message') data = error.get('data') callback.set_exception(NetworkError( ''.join(['Protocol Error: ', '{}'.format(msg), ' ', '{}'.format(data)]))) else: result = obj.get('result') callback.set_result(result) else: self.emit(obj.get('method'), obj.get('params'))
def send(self, method: str, params: dict = None) -> Awaitable: 'Send message via the connection.' if (self._lastId and (not self._connected)): raise ConnectionError('Connection is closed') if (params is None): params = dict() self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) logger_connection.debug(''.join(['SEND: ', '{}'.format(msg)])) self._loop.create_task(self._async_send(msg, _id)) callback = self._loop.create_future() self._callbacks[_id] = callback callback.error = NetworkError() callback.method = method return callback
async def send(self, method: str, params: dict = None) -> dict: """Send message to the connected session.""" self._lastId += 1 _id = self._lastId msg = json.dumps(dict(id=_id, method=method, params=params)) callback = asyncio.get_event_loop().create_future() self._callbacks[_id] = callback callback.method: str = method # type: ignore if not self._connection: raise NetworkError('Connection closed.') await self._connection.send('Target.sendMessageToTarget', { 'sessionId': self._sessionId, 'message': msg, }) return await callback
def _onRequestIntercepted(self, event: dict) -> None: event['request']['url'] = removeURLHash(event['request'].get('url')) if event.get('redirectStatusCode'): request = self._interceptionIdToRequest[event['interceptionId']] if not request: raise NetworkError('INTERNAL ERROR: failed to find request ' 'for interception redirect.') self._handleRequestRedirect(request, event.get('redirectStatusCode', 0), event.get('redirectHeaders', {})) self._handleRequestStart(request._requestId, event.get('interceptionId', ''), event.get('redirectUrl', ''), event.get('resourceType', ''), event.get('request', {})) return requestHash = generateRequestHash(event['request']) self._requestHashToInterceptions.set(requestHash, event) self._maybeResolveInterception(requestHash)