|1CGI Callouts| |^ During CGI or CGIplus processing (though not DECnet-based CGI) it is possible to suspend normal script output to the client and for the script to interact directly with the server, then resume output to the client. This may done more than once during processing. During the |/callout| the script makes a request of the server and receives a response. These requests are to perform some server function, such as the mapping of a path to a file specification, on behalf of the script. Naturally, this makes the script no longer portable, but may be extrememly useful in some circumstances. |^ It is this general callout mechanism that allows specific authentication agents (|link%|../features/##Authentication and Authorization++in++WASD Features||) to be implemented as standard CGIplus scripts. |^ The mechanism is quite simple. |number| |item| The script suspends normal output by writing a record containing a unique |/escape| sequence. |item| It then writes a record containing a formatted request. The server interprets the request, performs the action and returns a success or error response. |item| The script concludes the callout by writing a record containing a unique |/end-of-text| sequence. |item| The script reads the server's response and continues processing. In reality the response read could occur immediately after the request write (i.e. before the concluding end-of-text sequence). |!number| |^ This is a basic callout. Between the callout escape and end-of-text sequences multiple request/responses transactions may be undertaken. |2Requests and Responses| |^ The request record is plain text, comprising a request key-word (case-insensitive), full-colon, and following optional white-space and parameter(s). It is designed not to be implementation language specific. |^ The response record is also plain-text. It begins with a three-digit response code, with similar meanings and used for the same purpose as HTTP response codes. That is 200 is a success status, 500 a server error, 400 a request error, etc. Following the response code is white-space and the plain text result or error message. A response to any given callout request may be suppressed by providing a request record with a leading |=.!| (exclamation point) or |=.#| (hash symbol). |bullet| |item| |*AGENT-BEGIN:| |/.| |^ WASD v12.0 and later agents require the agent to declare its role and typically provide some information about itself. An example callout is shown below. |code| CgiLibCgiPlusCallout ("!AGENT-BEGIN: %s (%s) usage:%d", SoftwareId, CgiLibEnvironmentVersion(), CgiPlusUsageCount); |!code| |item| |*AGENT-END:| |/.| |^ WASD v12.0 and later agents are required to declare process concluded, and optionally to return any results to the calling code. |code| CgiLibCgiPlusCallout ("!AGENT-END:"); |!code| |code| CgiLibCgiPlusCallout ("!AGENT-END: 418 %s", cptr); |!code| |item| |*AUTH-FILE:| |/.| |^ If the specialized /PROFILE capability is enabled (|link%|../features/##SYSUAF Security Profile++in++WASD Features||) this can determine whether the specified file name is allowed access by the request's username. |item| |*BUFFER-BEGIN:| |/.[k\|M]| |^ Create a temporary global section to act as a memory buffer shared between a script process and the server. The default is |*M||egabytes. See |link|Bulk Content Output| for a description of the purpose and use of all the BUFFER-.. callouts. |item| |*BUFFER-END:| |^ Dispose of the shared memory buffer created by callout BUFFER-BEGIN. |item| |*BUFFER-WRITE:| |/.| |^ Instruct the server to write bytes from the shared memory buffer to the client. |item| |*CGI:| |/string| |^ Specialised callout allowing an access agent, lookup agent or meta agent to insert, modify or delete a CGI variable for a request. These agents are currently only |*proof-of-concept||. See sources in |^+ |link%=|/wasd_root/src/agent/*.*|WASD_ROOT:[SRC.AGENT]| |item| |*CGIPLUS:| |/string| |^ This callout is used to indicate to the server that a CGIplus script can process the CGI variables in "struct" mode. By default each CGI variable is transfered to a CGIplus script one "record" at a time. In "struct" mode all variables are transfered in a single, binary I/O which must the be parsed by the the script. It is of course a much more efficient method for CGIplus (|link|Struct-Mode CGIplus||). |item| |*CSP:| |/.| |^- |*CSPRO:| |/.| |^ Provide Content Security Policy (CSP) configuration(s) from a script. |^ See |link%|../config/##Content Security Policy (CSP)++in++WASD Configuration||. |item| |*DICT:| |/string| |^ Specialised callout allowing an access agent, lookup agent or meta agent to insert, modify or delete a dictionary entry. These agents are currently only |*proof-of-concept||. See sources in |^+ |link%=|/wasd_root/src/agent/*.*|WASD_ROOT:[SRC.AGENT]| |item| |*GATEWAY-BEGIN:| |/.| |^ When using the raw TCP/IP socket for output (|link|Raw TCP/IP Socket||) this callout is used to notify the server that the script will be using the gateway device and the HTTP status code (e.g. 200, 302, 404, etc.) |item| |*GATEWAY-CCL:| |/.| |^ When using the raw TCP/IP socket for output (|link|Raw TCP/IP Socket||) this can be used to change the BG: device carriage-control. A value of 1 enables a with each record (the default), while 0 disables it. This is analagous to the APACHE$SET_CCL utility. |item| |*GATEWAY-END:| |/.| |^ When using the raw TCP/IP socket for output (|link|Raw TCP/IP Socket||) this callout is used to notify the server of the quantity of data transfered directly to the client by the script. |item| |*LIFETIME:| |/.| |^ Sets/resets a scripting process' lifetime which may be expressed as an integer number of minutes or in the format |/hh:mm:ss||. For instance, use to give frequently used CGIplus scripts an extended lifetime before being rundown by the server (override the [DclCgiPlusLifeTime] configuration parameter). Specifying "none" (or -1) gives it an |/infinite| lifetime, zero resets to default. |item| |*MAP-FILE:| |/.| |^ Map the supplied file specification to its URL-style path equivalent, and against the server's mapping rule. This does not check the file name is legal RMS syntax. |item| |*MAP-PATH:| |/.| |^ Map the supplied URL-style path against the server's rule database into a VMS file specification. Note that this does not verify the file name legaility or that the file actually exists. |item| |*NOOP:| |^ No operation. Just return a success response. |item| |*NOTICED:| |/.| |^ Place the supplied string into the server process log. Used to report incidental processing or other errors. |item| |*OPCOM:| |/.| |^ Send the supplied string to OPCOM. |item| |*REDACT:|| |^ See |link|Request Redaction||. |item| |*REDACT-SIZE:| |^ See |link|Request Redaction||. |item| |*SCRIPT-CONTROL:| |^ Equivalent to the script issuing a "Script-Control:" response header field (although of course some script control directives will not apply after header generation). |item| |*TIMEOUT-BIT-BUCKET:| |/.| |^ Specifies the period for which a script continues to execute if the client disconnects. Overrides the WASD_CONFIG_GLOBAL [DclBitBucketTimeout] confiuration directive. |item| |*TIMEOUT-OUTPUT:| |/.| |^ Sets/resets a script request lifetime (in minutes, overrides the [TimeoutOutput] configuration parameter). Specifying "none" (or -1) gives it an |/infinite| lifetime, zero resets to default. |item| |*TIMEOUT-NOPROGRESS:| |/.| |^ Sets/resets a script request no-progress (in minutes, overrides the [TimeoutNoProgress] configuration parameter). The |/no-progress| period is the maximum number of seconds that there may be no output from the script before it is aborted. Specifying "none" (or -1) gives it an |/infinite| lifetime, zero resets to default. |!bullet| |2Code Examples| |^ The record-oriented callout sequences and request/response makes implementation quite straight-forward. The following C language and DCL procedure code fragments illustrate the basics. |code| /* C language */ CgiPlusIn = fopen ("CGIPLUSIN:", "r"); printf ("%s\\nMAP-FILE: %s\\n%s\\n", getenv("CGIPLUSESC"), FileNamePtr, getenv("CGIPLUSEOT")); fgets (CalloutResponse, sizeof(CalloutResponse), CgiPlusIn); $! DCL procedure $ open /read CgiPlusIn CGIPLUSIN $ write sys$output f$trnlnm("CGIPLUSESC") $ write sys$output "MAP-PATH: " + PathPtr $ read CgiPlusIn Response $!(no need to read a response for this next request, it's suppressed) $ write sys$output "#TIMEOUT-OUTPUT:10" $ write sys$output f$trnlnm("CGIPLUSEOT") |!code| |^ Also see working examples in |link%=|/wasd_root/src/CGIplus/*callout*.*|WASD_ROOT:[SRC.CGIPLUS]|