def obtainFilter(self, processing, uri): """ Checks the filter URI. @param processing: Processing The processing used for delivering the request. @param uri: string The URI to call, parameters are allowed. @return: tuple(boolean|None, integer, string) A tuple containing as the first True if the filter URI provided a True value, None if the filter cannot be fetched, on the second position the response status and on the last position the response text. """ assert isinstance(processing, Processing), "Invalid processing %s" % processing assert isinstance(uri, str), "Invalid URI %s" % uri request = processing.ctx.request() assert isinstance(request, RequestFilter), "Invalid request %s" % request url = urlparse(uri) request.scheme, request.method = self.scheme, HTTP_GET request.headers = {} request.uri = url.path.lstrip("/") request.parameters = parse_qsl(url.query, True, False) request.accTypes = [self.mimeTypeJson] request.accCharSets = [self.encodingJson] chain = Chain(processing) chain.process( request=request, requestCnt=processing.ctx.requestCnt(), response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt(), ).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), "Invalid response %s" % response assert isinstance(responseCnt, ResponseContentHTTP), "Invalid response content %s" % responseCnt if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None if ( ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess(response.status) ): return None, response.status, text if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) allowed = json.load(codecs.getreader(self.encodingJson)(source)) return allowed["HasAccess"] == "True", response.status, text
def process(self, processing, request: Request, response: Response, Gateway: Context, Match: Context, **keyargs): ''' @see: HandlerBranchingProceed.process Obtains the repository. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(request, Request), 'Invalid request %s' % request if response.isSuccess is False: return # Skip in case the response is in error assert isinstance( request.decoderHeader, IDecoderHeader ), 'Invalid decoder header %s' % request.decoderHeader authentication = request.decoderHeader.retrieve(self.nameAuthorization) if not authentication: return repository = self._repositories.get(authentication) if repository is None: robj, status, text = self.obtainGateways(processing, self.uri % authentication) if robj is None or not isSuccess(status): if status == BAD_REQUEST.status: response.code, response.status, response.isSuccess = INVALID_AUTHORIZATION if request.repository: assert isinstance( request.repository, IRepository ), 'Invalid repository %s' % request.repository request.match = request.repository.find( request.method, request.headers, request.uri, INVALID_AUTHORIZATION.status) else: log.info( 'Cannot fetch the authorized gateways from URI \'%s\', with response %s %s', self.uri, status, text) response.code, response.status, response.isSuccess = BAD_GATEWAY response.text = text return assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj repository = Repository([ self.populate(Identifier(Gateway()), obj) for obj in robj['GatewayList'] ], Match) self._repositories[authentication] = repository self._lastAccess[authentication] = datetime.now() if request.repository: request.repository = RepositoryJoined(repository, request.repository) else: request.repository = repository
def request(self, uri): ''' Request the OPTIONS headers for URI. @param uri: string The URI to call, parameters are allowed. @return: dictionary{string: string}|None The OPTIONS header or None if OPTIONS has not been delivered successful. ''' assert isinstance(uri, str), 'Invalid URI %s' % uri proc = self._processing assert isinstance(proc, Processing) request = proc.ctx.request() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request request.scheme, request.method = self._scheme, HTTP_OPTIONS request.uri = urlparse(uri).path.lstrip('/') request.parameters = [] arg = proc.execute(FILL_ALL, request=request) response, responseCnt = arg.response, arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt # We need to ensure that we close the response source. if ResponseContentHTTP.source in responseCnt and isinstance( responseCnt.source, IClosable): responseCnt.source.close() if isSuccess(response.status) and ResponseHTTP.headers in response: return response.headers if __debug__: if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None log.error('Cannot get OPTIONS from \'%s\', with response %s %s', request.uri, response.status, text)
def populate(self, data, content, response, responseCnt): ''' Populates the content object based on the response and response content. @param data: Data The data to use for content populating. @param content: ContentResponse The content to populate. @param response: ResponseHTTP The response to populate the content based on. @param responseCnt: ResponseContent The response content to populate the content based on. @return: ContentResponse The populated content. ''' assert isinstance(content, ContentResponse), 'Invalid content %s' % content assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None: content.errorStatus, content.errorText = UNAVAILABLE return content if isinstance(responseCnt.source, IInputStream): content.source = responseCnt.source elif isinstance(responseCnt.source, Iterable): content.source = StreamOnIterable(responseCnt.source) if content.charSet: charSet = codecs.lookup(content.charSet).name else: charSet = codecs.lookup(self.charSetDefault).name content.doEncode = self.createEncode(data, charSet) content.doDecode = self.createDecode(charSet) if not isSuccess(response.status): content.errorStatus = response.status if ResponseHTTP.text in response and response.text: content.errorText = response.text elif ResponseHTTP.code in response and response.code: content.errorText = response.code return content
def populate(self, data, content, response, responseCnt): ''' Populates the content object based on the response and response content. @param data: Data The data to use for content populating. @param content: ContentResponse The content to populate. @param response: ResponseHTTP The response to populate the content based on. @param responseCnt: ResponseContent The response content to populate the content based on. @return: ContentResponse The populated content. ''' assert isinstance(content, ContentResponse), 'Invalid content %s' % content assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance(responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None: content.errorStatus, content.errorText = UNAVAILABLE return content if isinstance(responseCnt.source, IInputStream): content.source = responseCnt.source elif isinstance(responseCnt.source, Iterable): content.source = StreamOnIterable(responseCnt.source) if content.charSet: charSet = codecs.lookup(content.charSet).name else: charSet = codecs.lookup(self.charSetDefault).name content.doEncode = self.createEncode(data, charSet) content.doDecode = self.createDecode(charSet) if not isSuccess(response.status): content.errorStatus = response.status if ResponseHTTP.text in response and response.text: content.errorText = response.text elif ResponseHTTP.code in response and response.code: content.errorText = response.code return content
def process(self, processing, request:Request, response:Response, Gateway:Context, Match:Context, **keyargs): ''' @see: HandlerBranchingProceed.process Obtains the repository. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(request, Request), 'Invalid request %s' % request if response.isSuccess is False: return # Skip in case the response is in error assert isinstance(request.decoderHeader, IDecoderHeader), 'Invalid decoder header %s' % request.decoderHeader authentication = request.decoderHeader.retrieve(self.nameAuthorization) if not authentication: return repository = self._repositories.get(authentication) if repository is None: robj, status, text = self.obtainGateways(processing, self.uri % authentication) if robj is None or not isSuccess(status): if status == BAD_REQUEST.status: response.code, response.status, response.isSuccess = INVALID_AUTHORIZATION if request.repository: assert isinstance(request.repository, IRepository), 'Invalid repository %s' % request.repository request.match = request.repository.find(request.method, request.headers, request.uri, INVALID_AUTHORIZATION.status) else: log.info('Cannot fetch the authorized gateways from URI \'%s\', with response %s %s', self.uri, status, text) response.code, response.status, response.isSuccess = BAD_GATEWAY response.text = text return assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj repository = Repository([self.populate(Identifier(Gateway()), obj) for obj in robj['GatewayList']], Match) self._repositories[authentication] = repository self._lastAccess[authentication] = datetime.now() if request.repository: request.repository = RepositoryJoined(repository, request.repository) else: request.repository = repository
def process(self, processing, request:Request, response:Response, Gateway:GatewayRepository, Match:MatchRepository, **keyargs): ''' @see: HandlerBranchingProceed.process Obtains the repository. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(request, Request), 'Invalid request %s' % request assert isinstance(response, Response), 'Invalid response %s' % response assert issubclass(Gateway, GatewayRepository), 'Invalid gateway class %s' % Gateway assert issubclass(Match, MatchRepository), 'Invalid match class %s' % Match if not self._repository: robj, status, text = self.obtainGateways(processing, self.uri) if robj is None or not isSuccess(status): log.info('Cannot fetch the gateways from URI \'%s\', with response %s %s', self.uri, status, text) response.code, response.status, response.isSuccess = BAD_GATEWAY response.text = text return assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj self._repository = Repository([self.populate(Identifier(Gateway()), obj) for obj in robj['GatewayList']], Match) if request.repository: request.repository = RepositoryJoined(request.repository, self._repository) else: request.repository = self._repository
def obtainFilter(self, processing, uri): ''' Checks the filter URI. @param processing: Processing The processing used for delivering the request. @param uri: string The URI to call, parameters are allowed. @return: tuple(boolean|None, integer, string) A tuple containing as the first True if the filter URI provided a True value, None if the filter cannot be fetched, on the second position the response status and on the last position the response text. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(uri, str), 'Invalid URI %s' % uri request = processing.ctx.request() assert isinstance(request, RequestFilter), 'Invalid request %s' % request url = urlparse(uri) request.scheme, request.method = self.scheme, HTTP_GET request.headers = {} request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) request.accTypes = [self.mimeTypeJson] request.accCharSets = [self.encodingJson] chain = Chain(processing) chain.process(request=request, requestCnt=processing.ctx.requestCnt(), response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess( response.status): return None, response.status, text if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) allowed = json.load(codecs.getreader(self.encodingJson)(source)) return allowed['HasAccess'] == 'True', response.status, text
def checkCaptcha(self, processing, clientIP, challenge, resolve): ''' Checks the filter URI. @param processing: Processing The processing used for delivering the request. @return: boolean True if the captcha is valid, False otherwise. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing request, requestCnt = processing.ctx.request( ), processing.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt request.scheme, request.method = self.scheme, HTTP_POST request.headers = {} request.uri = self.uriVerify request.parameters = [] message = self.message % dict(key=self.privateKey, clientIP=clientIP, challenge=challenge, resolve=resolve) message = message.encode(encoding='ascii') requestCnt.source = (message, ) request.headers['Content-Length'] = str(len(message)) # TODO: It should be like after integration with refactored: requestCnt.length = len(requestCnt.source) chain = Chain(processing) chain.process(request=request, requestCnt=requestCnt, response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess( response.status): return b'server-error' if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) content = source.read() if content.startswith(b'true'): return True return content
def checkCaptcha(self, processing, clientIP, challenge, resolve): ''' Checks the filter URI. @param processing: Processing The processing used for delivering the request. @return: boolean True if the captcha is valid, False otherwise. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing request, requestCnt = processing.ctx.request(), processing.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance(requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt request.scheme, request.method = self.scheme, HTTP_POST request.headers = {} request.uri = self.uriVerify request.parameters = [] message = self.message % dict(key=self.privateKey, clientIP=clientIP, challenge=challenge, resolve=resolve) message = message.encode(encoding='ascii') requestCnt.source = (message,) request.headers['Content-Length'] = str(len(message)) # TODO: It should be like after integration with refactored: requestCnt.length = len(requestCnt.source) chain = Chain(processing) chain.process(request=request, requestCnt=requestCnt, response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance(responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess(response.status): return b'server-error' if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) content = source.read() if content.startswith(b'true'): return True return content
def request(self, uri, details=False, headers=None): ''' Request the JSON object for URI. @param uri: string The URI to call, parameters are allowed. @param details: boolean If True will provide beside the JSON object also the response status and text. @param headers: dictionary{string: string}|None Additional headers to be placed on the request. @return: object|tuple(object, integer, string) Provides the loaded JSON object if details is False, otherwise a tuple containing as the first entry the JSON object, None if the object cannot be fetched, on the second position the response status and on the last position the response text. ''' assert isinstance(uri, str), 'Invalid URI %s' % uri assert isinstance(details, bool), 'Invalid details flag %s' % details assert headers is None or isinstance( headers, dict), 'Invalid headers %s' % headers proc = self._processing assert isinstance(proc, Processing) request = proc.ctx.request() assert isinstance( request, RequesterGetJSON.Request), 'Invalid request %s' % request url = urlparse(uri) request.scheme, request.method = self._scheme, HTTP_GET request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) request.accTypes = [self._contentType] request.accCharSets = [self._encoding] request.headers = headers arg = proc.execute(FILL_ALL, request=request) response, responseCnt = arg.response, arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess( response.status): assert log.error( 'Cannot get JSON from \'%s\', with response %s %s', request.uri, response.status, text) or True if details: return None, RequesterGetJSON.Error(response.status, text) return if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) jobj = json.load(codecs.getreader(self._encoding)(source)) if isinstance(source, IClosable): source.close( ) # We need to ensure that we close the response source. if details: return jobj, RequesterGetJSON.Error(response.status, text) return jobj
def obtainGateways(self, processing, uri): ''' Get the gateway objects representation. @param processing: Processing The processing used for delivering the request. @param uri: string The URI to call, parameters are allowed. @return: tuple(dictionary{...}|None, integer, string) A tuple containing as the first position the gateway objects representation, None if the gateways cannot be fetched, on the second position the response status and on the last position the response text. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(uri, str), 'Invalid URI %s' % uri request = processing.ctx.request() assert isinstance(request, RequestGateway), 'Invalid request %s' % request url = urlparse(uri) request.scheme, request.method = self.scheme, HTTP_GET request.headers = {} request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) request.accTypes = [self.mimeTypeJson] request.accCharSets = [self.encodingJson] chain = Chain(processing) chain.process(request=request, requestCnt=processing.ctx.requestCnt(), response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance(responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess(response.status): return None, response.status, text if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) return json.load(codecs.getreader(self.encodingJson)(source)), response.status, text