Example #1
0
    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)
Example #3
0
    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
Example #4
0
 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
Example #5
0
    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)
Example #7
0
 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)
Example #10
0
 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,
     }))
Example #11
0
    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))
Example #12
0
 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'))
Example #13
0
 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'))
Example #14
0
    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'])
Example #15
0
    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()
Example #16
0
    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)
Example #17
0
 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()
Example #18
0
    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
Example #19
0
 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)
Example #20
0
    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()
Example #21
0
 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)
Example #22
0
 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)
Example #24
0
    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
Example #25
0
 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)
Example #26
0
 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'))
Example #27
0
 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'))
Example #28
0
 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
Example #29
0
    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
Example #30
0
    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)