Skip to content

Commit

Permalink
grpcweb: Error Handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ShahanaFarooqui committed Jan 14, 2025
1 parent 219cb5d commit 81a18de
Showing 1 changed file with 40 additions and 11 deletions.
51 changes: 40 additions & 11 deletions libs/gl-testing/gltesting/grpcweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import logging
import struct
import httpx
import re
import urllib.parse
from dataclasses import dataclass
from typing import Dict
import ssl


class GrpcWebProxy(object):
def __init__(self, scheduler: Scheduler, grpc_port: int):
Expand Down Expand Up @@ -67,6 +67,7 @@ class Request:
@dataclass
class Response:
body: bytes
headers: Dict[str, str]


class Handler(BaseHTTPRequestHandler):
Expand All @@ -91,9 +92,10 @@ def proxy(self, request) -> Response:
headers=headers,
content=content,
)
client = httpx.Client(http1=False, http2=True)
timeout = httpx.Timeout(10.0, connect=5.0)
client = httpx.Client(http1=False, http2=True, timeout=timeout)
res = client.send(req)
return Response(body=res.content)
return Response(body=res.content, headers=res.headers)

def auth(self, request: Request) -> bool:
"""Authenticate the request. True means allow."""
Expand All @@ -118,11 +120,16 @@ def do_POST(self):

req = Request(body=body, headers=self.headers, flags=flags, length=length)
if not self.auth(req):
self.wfile.write(b"HTTP/1.1 401 Unauthorized\r\n\r\n")
self.send_response(401)
self.send_header("grpc-status", "16")
self.end_headers()
self.wfile.write(b"Unauthorized")
return

response = self.proxy(req)
self.wfile.write(b"HTTP/1.0 200 OK\n\n")
self.send_response(200)
self.send_header("grpc-status", response.headers.get("grpc-status", "200"))
self.end_headers()
self.wfile.write(response.body)
self.wfile.flush()

Expand Down Expand Up @@ -195,6 +202,8 @@ def proxy(self, request: Request):
"user-agent": "gl-testing-grpc-web-proxy",
}
content = struct.pack("!cI", request.flags, request.length) + request.body
print(f'Request Body: {request.body}')
print(f'Request Content: {content}')

# Forward request
req = httpx.Request(
Expand All @@ -203,7 +212,27 @@ def proxy(self, request: Request):
headers=headers,
content=content,
)
res = client.send(req)

# Return response
return Response(body=res.content)

try:
res = client.send(req)
if res.status_code >= 400 or "grpc-status" in res.headers:
grpc_status = res.headers.get("grpc-status", "200")
error_message = urllib.parse.unquote(res.headers.get("grpc-message", "None"))
error_match = re.search(r"RpcError \{(.*?)\}", error_message)
if error_match:
error_message = error_match.group(1)
# Replace data: None with data: null for valid json and add parantheses for valid json
error_message = '{' + error_message.replace('None', 'null') + '}'
self.logger.warn(f"gRPC status code received: {grpc_status}")
self.logger.warn(f"gRPC message received: {error_message}")
error = f"{error_message}".encode("utf-8")
error_res = struct.pack("!cI", request.flags, len(error)) + error
return Response(body=error_res, headers={"grpc-status": grpc_status})

return Response(body=res.content, headers={"grpc-status": "200"})

except Exception as e:
self.logger.warn(f"gRPC request error received: {str(e)}")
error = f"Internal Server Error: {str(e)}".encode("utf-8")
error_res = struct.pack("!cI", request.flags, len(error)) + error
return Response(body=error_res, headers={"grpc-status": "14"})

0 comments on commit 81a18de

Please sign in to comment.