# WASD Hypertext Services - Scripting Environment

## 10 - Raw TCP/IP Socket

[next] [previous] [contents] [full-page]

For subprocess scripting the raw TCP/IP socket can be made available for scripts to transfer data directly to the client. The socket BGnnnn: device name is made available via the CGI variable WWW_GATEWAY_BG. This is enabled using the [DclGatewayBg] configuration directive. As it is a completely raw stream it cannot be used, and is not made available for SSL ("https:") encrypted requests.

> NOTE

> Although one might imagine this direct transfer to be significantly more efficient than the standard script mailbox the test-bench indicates that to all purposes it provides a negligable improvement in throughput, even under high load. It probably only translates into measurable benefits for scripts producing large quantities of output (for instance hundreds of thousands or millions of bytes). For the average script the overhead of opening a stream to the raw TCP/IP device (which is not insignificant) and complications of the callout requirements isn't worth the effort. Still, it's there if someone wants or requires it.

The socket is created shareable between processes, and so a channel may be assigned by the script subprocess and have data written to it. The data is raw, in the sense the script must provide all carriage control, etc. All data transfered this way is outside of the server and so may not be WATCHed, etc.

The script must supply a full HTTP response. This means a NPH-style header (see 2.2.2 - Non-Parsed-Header Output) and body, with full carriage-control as required, etc. The server must be notified that the script is using the gateway device, by providing a CGI callout (see 5 - CGI Callouts) before any script output and after output is concluded. The first callout provides the response HTTP status code, the second the number of bytes transfered. These are also required for correct logging of the request. If a channel to the BG: device is opened it should always be closed when it is finished with. Failure to do so could lead to resource starvation for the server.

The HT_ROOT:[SCRIPT]GATEWAY_BG_EXAMPLE.COM example script demonstrates the use of the raw socket from DCL. The priciples can be applied to any scripting laguage.

The following code fragment shows the essential requirements using the C language.

      int  byteCount;
      char  *gatewayBg;

      /* see if there's a raw socket available */
      if (gatewayBg = getenv ("WWW_GATEWAY_BG"))
      {
         /* yes, begin a callout */
         fputs (getenv("CGIPLUSESC"), stdout);
         fflush (stdout);

         /* notify of script response and HTTP status */
         fprintf (stdout, "GATEWAY-BEGIN: %d", 200);
         fflush (stdout);

         /* reopen <stdout> to the raw TCP/IP device */
         if ((stdout = freopen (gatewayBgPtr, "w", stdout, "ctx=bin")) == NULL)
            exit (vaxc$errno);
      }

      byteCount = fprintf (stdout,
      "HTTP/1.0 200 OK\n\
      Content-Type: text/plain\n\
      \n");

      ... processing to <stdout>
         e.g. byteCount += fprintf (stdout, "Hello world!\n");

      if (gatewayBg)
      {
         /* reopen <stdout> so that it's communicating via the mailbox again */
         if ((stdout = freopen ("SYS$OUTPUT:", "w", stdout, "ctx=rec")) == NULL)
            exit (vaxc$errno);

         /* continue callout, notify of request data transfered */
         fprintf (stdout, "GATEWAY-END: %d", byteCount);
         fflush (stdout);

         /* end the callout */
         fputs (getenv("CGIPLUSEOT"), stdout);
         fflush (stdout);
      }

###
Not Supported?

Not all vendor's TCP/IP package BG drivers, or not all older versions, may support the C_SHARE option when creating sockets. Symptoms may range from it being ignored (and the script being unable to open a channel to the BGnnnn: device) to an error being reported as the socket is being created (and the server being unable to start at all). If this occurs merely disable the [DclGatewayBg] configuration option. Script output is of course still available via the standard script output mailbox.

For portability scripts that use the raw socket for output should always use a construct similar to the above example code so only to redirect output when the GATEWAY_BG device is indicated as available.

[next] [previous] [contents] [full-page]