matlab-proxy 0.25.0__py3-none-any.whl → 0.26.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matlab-proxy might be problematic. Click here for more details.
- matlab_proxy/app.py +66 -12
- matlab_proxy/constants.py +1 -0
- matlab_proxy/gui/index.html +1 -1
- matlab_proxy/gui/static/js/{index.qK3VCGVb.js → index.CZgGkMCD.js} +15 -15
- matlab_proxy/settings.py +22 -1
- matlab_proxy/util/cookie_jar.py +72 -0
- matlab_proxy/util/mwi/environment_variables.py +10 -0
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/METADATA +4 -1
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/RECORD +24 -21
- matlab_proxy_manager/lib/api.py +156 -114
- matlab_proxy_manager/storage/server.py +5 -2
- matlab_proxy_manager/utils/constants.py +2 -1
- matlab_proxy_manager/utils/environment_variables.py +6 -1
- matlab_proxy_manager/utils/exceptions.py +45 -0
- matlab_proxy_manager/utils/helpers.py +2 -2
- matlab_proxy_manager/utils/logger.py +4 -1
- matlab_proxy_manager/web/app.py +71 -19
- tests/unit/test_app.py +116 -17
- tests/unit/test_settings.py +26 -6
- tests/unit/util/test_cookie_jar.py +252 -0
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/LICENSE.md +0 -0
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/WHEEL +0 -0
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/entry_points.txt +0 -0
- {matlab_proxy-0.25.0.dist-info → matlab_proxy-0.26.0.dist-info}/top_level.txt +0 -0
matlab_proxy/app.py
CHANGED
|
@@ -283,6 +283,10 @@ async def start_matlab(req):
|
|
|
283
283
|
JSONResponse: JSONResponse object containing updated information on the state of MATLAB among other information.
|
|
284
284
|
"""
|
|
285
285
|
state = req.app["state"]
|
|
286
|
+
cookie_jar = req.app["settings"]["cookie_jar"]
|
|
287
|
+
|
|
288
|
+
if cookie_jar:
|
|
289
|
+
cookie_jar.clear()
|
|
286
290
|
|
|
287
291
|
# Start MATLAB
|
|
288
292
|
await state.start_matlab(restart_matlab=True)
|
|
@@ -349,7 +353,7 @@ async def set_licensing_info(req):
|
|
|
349
353
|
raise Exception(
|
|
350
354
|
'License type must be "NLM" or "MHLM" or "ExistingLicense"!'
|
|
351
355
|
)
|
|
352
|
-
except Exception
|
|
356
|
+
except Exception:
|
|
353
357
|
raise web.HTTPBadRequest(text="Error with licensing!")
|
|
354
358
|
|
|
355
359
|
# This is true for a user who has only one license associated with their account
|
|
@@ -495,9 +499,13 @@ def make_static_route_table(app):
|
|
|
495
499
|
"""
|
|
496
500
|
import importlib_resources
|
|
497
501
|
|
|
498
|
-
from matlab_proxy import gui
|
|
499
|
-
from matlab_proxy.gui import static
|
|
500
|
-
from matlab_proxy.gui.static import
|
|
502
|
+
from matlab_proxy import gui # noqa: F401
|
|
503
|
+
from matlab_proxy.gui import static # noqa: F401
|
|
504
|
+
from matlab_proxy.gui.static import (
|
|
505
|
+
css, # noqa: F401
|
|
506
|
+
js, # noqa: F401
|
|
507
|
+
media, # noqa: F401
|
|
508
|
+
)
|
|
501
509
|
|
|
502
510
|
base_url = app["settings"]["base_url"]
|
|
503
511
|
|
|
@@ -557,6 +565,9 @@ async def matlab_view(req):
|
|
|
557
565
|
matlab_protocol = req.app["settings"]["matlab_protocol"]
|
|
558
566
|
mwapikey = req.app["settings"]["mwapikey"]
|
|
559
567
|
matlab_base_url = f"{matlab_protocol}://127.0.0.1:{matlab_port}"
|
|
568
|
+
cookie_jar = req.app["settings"]["cookie_jar"]
|
|
569
|
+
|
|
570
|
+
cookies_from_jar = cookie_jar.get_dict() if cookie_jar else None
|
|
560
571
|
|
|
561
572
|
# If we are trying to send request to matlab while the matlab_port is still not assigned
|
|
562
573
|
# by embedded connector, return service not available and log a message
|
|
@@ -575,17 +586,23 @@ async def matlab_view(req):
|
|
|
575
586
|
and reqH.get(UPGRADE, "").lower() == "websocket"
|
|
576
587
|
and req.method == "GET"
|
|
577
588
|
):
|
|
578
|
-
ws_server = web.WebSocketResponse(
|
|
589
|
+
ws_server = web.WebSocketResponse(
|
|
590
|
+
max_msg_size=constants.MAX_WEBSOCKET_MESSAGE_SIZE_IN_MB, compress=True
|
|
591
|
+
)
|
|
579
592
|
await ws_server.prepare(req)
|
|
580
593
|
|
|
581
594
|
async with aiohttp.ClientSession(
|
|
595
|
+
cookies=(
|
|
596
|
+
cookies_from_jar if cookie_jar else req.cookies
|
|
597
|
+
), # If cookie jar is not provided, use the cookies from the incoming request
|
|
582
598
|
trust_env=True,
|
|
583
|
-
cookies=req.cookies,
|
|
584
599
|
connector=aiohttp.TCPConnector(ssl=False),
|
|
585
600
|
) as client_session:
|
|
586
601
|
try:
|
|
587
602
|
async with client_session.ws_connect(
|
|
588
603
|
matlab_base_url + req.path_qs,
|
|
604
|
+
max_msg_size=constants.MAX_WEBSOCKET_MESSAGE_SIZE_IN_MB, # max websocket message size from MATLAB to browser
|
|
605
|
+
compress=12, # enable websocket messages compression
|
|
589
606
|
) as ws_client:
|
|
590
607
|
|
|
591
608
|
async def wsforward(ws_from, ws_to):
|
|
@@ -617,16 +634,28 @@ async def matlab_view(req):
|
|
|
617
634
|
await ws_to.close(
|
|
618
635
|
code=ws_to.close_code, message=msg.extra
|
|
619
636
|
)
|
|
637
|
+
elif mt == aiohttp.WSMsgType.ERROR:
|
|
638
|
+
logger.error(f"WebSocket error received: {msg}")
|
|
639
|
+
if "exceeds limit" in str(msg.data):
|
|
640
|
+
logger.error(
|
|
641
|
+
f"Message too large: {msg.data}. Please refresh browser tab to reconnect."
|
|
642
|
+
)
|
|
643
|
+
break
|
|
620
644
|
else:
|
|
621
645
|
raise ValueError(f"Unexpected message type: {msg}")
|
|
622
646
|
|
|
623
647
|
await asyncio.wait(
|
|
624
648
|
[
|
|
625
|
-
asyncio.create_task(
|
|
626
|
-
|
|
649
|
+
asyncio.create_task(
|
|
650
|
+
wsforward(ws_server, ws_client)
|
|
651
|
+
), # browser to MATLAB
|
|
652
|
+
asyncio.create_task(
|
|
653
|
+
wsforward(ws_client, ws_server)
|
|
654
|
+
), # MATLAB to browser
|
|
627
655
|
],
|
|
628
656
|
return_when=asyncio.FIRST_COMPLETED,
|
|
629
657
|
)
|
|
658
|
+
|
|
630
659
|
return ws_server
|
|
631
660
|
|
|
632
661
|
except Exception as err:
|
|
@@ -666,11 +695,37 @@ async def matlab_view(req):
|
|
|
666
695
|
allow_redirects=False,
|
|
667
696
|
data=req_body,
|
|
668
697
|
params=None,
|
|
698
|
+
cookies=cookies_from_jar, # Pass cookies from cookie_jar for HTTP requests to MATLAB. This value will
|
|
699
|
+
# be none if cookie jar is not enabled
|
|
669
700
|
) as res:
|
|
670
701
|
headers = res.headers.copy()
|
|
671
702
|
body = await res.read()
|
|
672
|
-
|
|
673
|
-
|
|
703
|
+
|
|
704
|
+
response = web.Response(
|
|
705
|
+
status=res.status, headers=headers, body=body
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
# Purpose of the cookie-jar in matlab-proxy is to:
|
|
709
|
+
# 1) Update the cookies within it when the Embedded Connector sends back Set-Cookie headers in the response.
|
|
710
|
+
# 2) Read these cookies from the cookie jar and insert them into subsequent requests to the Embedded Connector.
|
|
711
|
+
|
|
712
|
+
# Due to matlab-proxy's PING requests to EC, the number cookies present in the cookie-jar and their
|
|
713
|
+
# value will be more than the ones present on the browser side.
|
|
714
|
+
# Example: The JSESSIONID cookie will be present in the cookie-jar but not on the browser side.
|
|
715
|
+
# This inconsistency of cookies between the browser and matlab-proxy's cookie-jar is expected and okay
|
|
716
|
+
# as these cookies are HttpOnly cookies.
|
|
717
|
+
|
|
718
|
+
# Incase the Embedded Connector sends cookies which are not HttpOnly, then additional logic needs to be written
|
|
719
|
+
# to update the response with cookies from the cookie jar before it is forwarded to the browser.
|
|
720
|
+
if cookie_jar:
|
|
721
|
+
# Update the cookies in the cookie jar with the Set-Cookie headers in the response.
|
|
722
|
+
cookie_jar.update_from_response_headers(headers)
|
|
723
|
+
|
|
724
|
+
response.headers.update(
|
|
725
|
+
req.app["settings"]["mwi_custom_http_headers"]
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
return response
|
|
674
729
|
|
|
675
730
|
# Handles any pending HTTP requests from the browser when the MATLAB process is terminated before responding to them.
|
|
676
731
|
except (
|
|
@@ -852,7 +907,7 @@ def configure_and_start(app):
|
|
|
852
907
|
|
|
853
908
|
logger.debug("Starting MATLAB proxy app")
|
|
854
909
|
logger.debug(
|
|
855
|
-
f
|
|
910
|
+
f" with base_url: {app['settings']['base_url']} and app_port:{app['settings']['app_port']}."
|
|
856
911
|
)
|
|
857
912
|
|
|
858
913
|
app["state"].create_server_info_file()
|
|
@@ -987,7 +1042,6 @@ def print_version_and_exit():
|
|
|
987
1042
|
|
|
988
1043
|
def main():
|
|
989
1044
|
"""Starting point of the integration. Creates the web app and runs indefinitely."""
|
|
990
|
-
|
|
991
1045
|
if util.parse_cli_args()["version"]:
|
|
992
1046
|
print_version_and_exit()
|
|
993
1047
|
|
matlab_proxy/constants.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Final, List
|
|
|
6
6
|
CONNECTOR_SECUREPORT_FILENAME: Final[str] = "connector.securePort"
|
|
7
7
|
VERSION_INFO_FILE_NAME: Final[str] = "VersionInfo.xml"
|
|
8
8
|
MAX_HTTP_REQUEST_SIZE: Final[int] = 500_000_000 # 500MB
|
|
9
|
+
MAX_WEBSOCKET_MESSAGE_SIZE_IN_MB: Final[int] = 500_000_000 # 500MB
|
|
9
10
|
MATLAB_LOGS_FILE_NAME: Final[str] = "matlab_logs.txt"
|
|
10
11
|
USER_CODE_OUTPUT_FILE_NAME: Final[str] = "startup_code_output.txt"
|
|
11
12
|
|
matlab_proxy/gui/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<meta name="internal_mw_identifier" content="MWI_MATLAB_PROXY_IDENTIFIER" />
|
|
12
12
|
<link rel="manifest" href="./manifest.json" />
|
|
13
13
|
<title>MATLAB</title>
|
|
14
|
-
<script type="module" crossorigin src="./static/js/index.
|
|
14
|
+
<script type="module" crossorigin src="./static/js/index.CZgGkMCD.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="./static/css/index.BSVLACuY.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|