<COMMENT>(--------------------------------------------------------------------)

<CHAPTER>(Raw TCP/IP Socket\chapter_raw_socket)

<P> For subprocess scripting the raw TCP/IP socket can be made available for
scripts to transfer data directly to the client.  The socket
BG<EMPHASIS>(nnnn): 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 (<QUOTE>(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.
<ENDNOTE>

<P> 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. 

<P> The script must supply a full HTTP response.  This means a NPH-style header
(see <REFERENCE>(head_nph_output)) and body, with full carriage-control as
required, etc.  The server <UNDERLINE>(must) be notified that the script is
using the gateway device, by providing a CGI callout (see
<REFERENCE>(chapter_scripting_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.

<P> The

<COMMENT>(....................................................................)

<COMMENT>(HTML=
<A HREF="/cgi-bin/gateway_bg_example">HT_ROOT:[SCRIPT]GATEWAY_BG_EXAMPLE.COM</A>
)

<COMMENT>(HTML/OFF)
HT_ROOT:[SCRIPT]GATEWAY_BG_EXAMPLE.COM
<BOX>(online demonstration)
<COMMENT>(HTML/ON)

<COMMENT>(....................................................................)

example script demonstrates the use of the raw socket from DCL.  The priciples
can be applied to any scripting laguage.

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

<CODE_EXAMPLE>
  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 <LITERAL>(<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");

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

  if (gatewayBg)
  {
     /* reopen <LITERAL>(<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);
  }
<ENDCODE_EXAMPLE>

<HEAD>(Not Supported?\head_raw_socket_not_supp)

<P> 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
BG<EMPHASIS>(nnnn): 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.

<P> 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.

<COMMENT>(--------------------------------------------------------------------)
