Configuring the Genero Application Server / How to implement delegation |
In this example, the REST service returns an HTTP error code 404 to the browser until the query string contains the string ByPass.
When the GWC application is started, the parameter ACCESS is also set and can be retrieved in the Genero program with fgl_getenv("ACCESS").
IMPORT COM IMPORT XML PRIVATE CONSTANT C_BASEURL = "/ws/r/qa-test/delegateService/" PRIVATE CONSTANT C_X_FOURJS_ENVIRONEMENT_ = "X-FourJs-Environment-" PRIVATE CONSTANT C_X_FOURJS_ENVIRONEMENT_PARAMETER_ = "X-FourJs-Environment-Parameter-" PRIVATE CONSTANT C_GENERO_INTERNAL_DELEGATE = "_GENERO_INTERNAL_DELEGATE_" MAIN DEFINE req com.HttpServiceRequest DEFINE methd STRING DEFINE url STRING DEFINE path STRING DEFINE query STRING DEFINE ind INTEGER DEFINE tmp STRING CALL com.WebServiceEngine.Start() WHILE TRUE TRY LET req = com.WebServiceEngine.GetHttpServiceRequest(-1) IF req IS NULL THEN EXIT WHILE ELSE LET url = req.getUrl() DISPLAY "URL : ",url LET methd = req.getMethod() CALL SplitUrl(url) RETURNING path, query DISPLAY "Incoming request: ",methd," path=",path," query=",query LET ind = path.getIndexOf(C_BASEURL,1) IF ind<1 THEN CALL req.sendResponse(400,"Invalid request") ELSE CALL DispatchService(req,path.subString(ind+C_BASEURL.getLength(), path.getLength()),query) END IF DISPLAY "Sent response: ",methd," path=",path," query=",query END IF CATCH EXIT WHILE END TRY END WHILE END MAIN FUNCTION DispatchService(req,path,query) DEFINE req com.HttpServiceRequest DEFINE path STRING DEFINE query STRING DEFINE ind INTEGER LET ind = path.getIndexOf("/",1) IF ind>0 THEN CALL req.sendResponse(400,"invalid path") ELSE CASE path WHEN "Delegate" # Handle a dispatcher delegate service CALL DelegateWA(req,query) OTHERWISE CALL req.sendResponse(400,"unknown service '"||path||"'."); END CASE END IF END FUNCTION # # Delegate WA service # If browser URL doesn't contain 'ByPass' in query string then return a 404 error, # otherwise start GWC application # FUNCTION DelegateWA(req,query) DEFINE req com.HttpServiceRequest DEFINE query STRING DEFINE url STRING DEFINE queryString STRING DEFINE parameter STRING DEFINE ind INTEGER DEFINE ByPass BOOLEAN DEFINE q DYNAMIC ARRAY OF RECORD qname STRING, qvalue STRING END RECORD # Read requests LET query = req.readFormEncodedRequest(false) IF query IS NULL THEN CALL req.sendResponse(400,"no query string") ELSE LET ByPass = FALSE CALL SplitUrl(query) RETURNING url,queryString CALL ParseQueryString(queryString) RETURNING q # Check if user-agent query string has a ByPass string ? FOR ind=1 TO q.getLength() IF q[ind].qname="ByPass" THEN LET ByPass = TRUE END IF END FOR IF NOT ByPass THEN # return error CALL req.sendResponse(404,"ByPass is missing") ELSE # Set parameter for GWC application via environment variable: ACCESS=OK CALL req.setResponseHeader(C_X_FOURJS_ENVIRONEMENT_||"ACCESS","OK") # Start application with HTTP code 307 CALL req.sendResponse(307,C_GENERO_INTERNAL_DELEGATE) END IF END IF END FUNCTION # # Parse given string and returns a dynamic array of the element inside the # query string # FUNCTION ParseQueryString(str) DEFINE str STRING DEFINE tkz base.StringTokenizer DEFINE token STRING DEFINE ind INTEGER DEFINE ret DYNAMIC ARRAY OF RECORD qname STRING, qvalue STRING END RECORD INITIALIZE ret TO NULL LET tkz = base.StringTokenizer.create(str,"&") WHILE (tkz.hasMoreTokens()) LET token = tkz.nextToken() CALL ret.appendElement() LET ind = ind + 1 CALL ExtractKeyValueFromQuery(token) RETURNING ret[ind].qname,ret[ind].qvalue END WHILE RETURN ret END FUNCTION # # Extract Key and Value from query string # FUNCTION ExtractKeyValueFromQuery(str) DEFINE str STRING DEFINE ind INTEGER LET ind = str.getIndexOf("=",1) IF ind>1 THEN RETURN str.subString(1,ind-1),str.subString(ind+1,str.getLength()) ELSE RETURN str,NULL END IF END FUNCTION # # Splits an URL into path and query string parts # FUNCTION SplitUrl(url) DEFINE url STRING DEFINE ind INTEGER DEFINE query STRING DEFINE path STRING LET ind = url.getIndexOf("?",1) IF ind>1 THEN LET query = url.subString(ind+1,url.getLength()) LET path = url.subString(1,ind-1) ELSE LET query = NULL LET path = url.subString(1,url.getLength()) END IF RETURN path, query END FUNCTION