| 240 | # Handle incoming data (messages only since this is the signal sender) |
| 241 | @peerConnection.on(ConnectionEventType.Data) |
| 242 | async def pc_data(data): |
| 243 | logger.debug('data received from remote peer \n{}', data) |
| 244 | request = json.loads(data) |
| 245 | # check if the request is just a keepalive ping |
| 246 | if (request['url'].startswith('ping')): |
| 247 | logger.debug('received keepalive ping from remote peer') |
| 248 | await _pong(peer_connection=peerConnection) |
| 249 | return |
| 250 | logger.info('webrtc peer: http proxy request: \n{}', request) |
| 251 | # schedule frequent pings while waiting on response_header |
| 252 | # to keep the peer data channel open |
| 253 | waiting_on_fetch = asyncio.Event() |
| 254 | |
| 255 | asyncio.create_task(_ping(peer_connection=peerConnection, |
| 256 | stop_flag=waiting_on_fetch)) |
| 257 | response = None |
| 258 | try: |
| 259 | logger.debug(f'Proxy forwarding HTTP request: {request}.') |
| 260 | response, content = await _fetch(**request) |
| 261 | logger.debug(f'Proxy received HTTP response: {response}.') |
| 262 | except Exception as e: |
| 263 | logger.exception('Error {} while fetching response' |
| 264 | ' with request: \n {}', |
| 265 | e, request) |
| 266 | finally: |
| 267 | # fetch completed, cancel pings |
| 268 | waiting_on_fetch.set() |
| 269 | if not response: |
| 270 | response_header = { |
| 271 | # internal server error code |
| 272 | 'status': 500 |
| 273 | } |
| 274 | response_content = None |
| 275 | return |
| 276 | response_content = content |
| 277 | response_header = { |
| 278 | 'status': response.status, |
| 279 | 'content-type': response.headers.get('content-type', 'None'), |
| 280 | 'content-length': len(response_content) |
| 281 | } |
| 282 | logger.info('Proxy fetched response with headers: \n{}', response.headers) |
| 283 | logger.info('Answering request: \n{} ' |
| 284 | 'response header: \n {}', |
| 285 | request, response_header) |
| 286 | header_as_json = json.dumps(response_header) |
| 287 | await peerConnection.send(header_as_json) |
| 288 | if (response.status != 204): |
| 289 | # HTTP status 204 means: Success. No content. |
| 290 | await peerConnection.send(response_content) |
| 291 | |
| 292 | @peerConnection.on(ConnectionEventType.Close) |
| 293 | async def pc_close(): |