def request(self, flow: Flow) -> None: if flow.response or flow.error or (flow.reply and flow.reply.state == 'taken'): return if not (self.filter and self.filter(flow)): return headers = { 'server': version.MITMPROXY, } script = self._get_script() if not script: flow.response = Response.make(404, None, headers) return headers['content-type'] = 'application/javascript' flow.response = Response.make(200, script, headers)
async def _async_request(self, flow: Flow) -> None: referer = flow.request.headers['referer'] log.info(f'Webmanifest request from {referer}.') headers = { 'server': version.MITMPROXY, } try: character_info = await wait_for(self.data.get(referer), timeout=15) except (TimeoutError, CancelledError): log.error( f'Timeout while waiting for character data from {referer}.') flow.response = Response.make(404, b'', headers) return data = loads(character_info.decode('utf-8'))['data'] character_name = data['name'] avatar_url = data['decorations'].get('avatarUrl', None) manifest = { 'name': f'{character_name} - D&D Beyond', 'short_name': character_name, 'description': 'An official digital toolset for Fifth Edition (5e) Dungeons & Dragons (D&D).', 'icons': [], 'display': 'fullscreen', 'start_url': referer, } if avatar_url: manifest['icons'].append({ 'src': avatar_url, 'sizes': '192x192', 'type': 'image/webp', }) else: manifest['icons'].append({ 'src': 'https://www.dndbeyond.com/Content/Skins/Waterdeep/images/characters/default-avatar-builder.png', 'sizes': '192x192', 'type': 'image/png', }) headers['content-type'] = 'application/webmanifest+json' flow.response = Response.make(200, dumps(manifest).encode('utf-8'), headers)