Optimize delegation with HTTP options
The delegation mechanism for a service can be optimized using HTTP OPTIONS.
The delegation mechanism can be configured to avoid sending the original request body destined for the final proxy to the delegate service, when it is not needed as part of an authorization request.
When configured, only the headers are sent, from which the delegate service determines whether
the original request body can be sent to the final proxy. Use the DELEGATE_OPTIONS
element
for this configuration.
Delegate optimization example
When DELEGATE_OPTIONS
with verb="OPTIONS"
is set, the following
original HTTP POST request is transformed as shown in the example requests:
POST /ws/r/my_service HTTP/1.1
Content-Type: text/plain
Authorization: Bearer Token_ID
User-Agent: GWS Agent
Date: Mon, 16 Jul 2018 14:39:43 GMT
Host: localhost:6363
Connection: close
Content-Length: 11
X-FourJs-Environment-Variable-REMOTE_ADDR: 127.0.0.1
X-FourJs-Environment-Variable-SERVER_NAME: localhost
Hello world
It is then for optimization purpose, transformed by the dispatcher as an HTTP OPTIONS request to the delegation service:
OPTIONS /ws/r/my_delegate/Delegate?url=http://localhost:6363/ws/r/my_service HTTP/1.1
Content-Type: text/plain
Authorization: Bearer Token_ID
User-Agent: GWS Agent
Date: Mon, 16 Jul 2018 14:39:43 GMT
Host: localhost:6363
Connection: close
Access-Control-Request-Method: POST
Content-Length: 0
X-FourJs-Environment-Variable-REMOTE_ADDR: 127.0.0.1
X-FourJs-Environment-Variable-SERVER_NAME: localhost
- It removes the body of the original request, ("Hello World").
- It keeps the original headers (it sets the body length to zero,
Content-Length: 0
). - It adds a new HTTP header (
Access-Control-Request-Method: POST
) to provide the original HTTP request verb (for example POST) to the delegate service.
Delegate service responses
- If the delegate service agrees to transmit the request to the final proxy, it returns the HTTP code 307 response. The dispatcher then forwards the original request plus the message body to the final proxy.
- In the case that the delegate service returns something other than HTTP code 307, the dispatcher will then discard the original request body and the original request will get the delegate response (plus body) as response (standard delegation mechanism).
Example
In this sample Web Service server code you see it is using OPTIONS
to handle
RESTful requests to optimize delegation.
FUNCTION DoDelegate(req)
DEFINE req com.HttpServiceRequest
DEFINE query WSHelper.WSQueryType
DEFINE ori_url STRING
DEFINE access_token STRING
DEFINE ind INTEGER
DEFINE method STRING
# Ensure we work in optimized delegation via OPTIONS
IF req.getMethod()!="OPTIONS" THEN
CALL req.sendResponse(400,"bad delete request, HTTP OPTIONS verb required");
RETURN
END IF
# Ensure we got the Access-Control-Request-Method header
LET method = req.getRequestHeader(C_ACCESS_CONTROL_REQUEST_METHOD)
IF method IS NULL THEN
CALL req.sendResponse(400,"bad delete request, Access-Control-Request-Method is missing");
RETURN
END IF
# Ensure we have a valid delegate request
CALL req.getUrlQuery(query)
IF query[1].name!="url" THEN
CALL req.sendResponse(400,"bad delete request, no url found");
RETURN
END IF
# Extract original URL
LET ori_url = query[1].value
CALL query.deleteElement(1)
# Retrieve access token from query string
LET ind = query.search("name","access_token")
IF ind>0 THEN
LET access_token = query[1].VALUE
ELSE
CALL req.sendResponse( 401, "No access token found")
RETURN
END IF
# Check Access
IF CheckAccess(req, baseURL, method, ori_url, access_token) THEN
CALL req.sendResponse( 307, "GENERO_INTERNAL_DELEGATE")
ELSE
CALL req.sendResponse( 403, "Forbidden")
END IF
END FUNCTION