[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
|1Raw TCP/IP Socket|

|note|
|0Deprecated and Discouraged|
Unencrypted TCP/IP communication, especially for browser and other web
connections, increasingly is considered poor practise, even for trivial
purposes.  Access to the raw socket will likely be disabled in the future.  If
this facility is in use for script->client data transfer reasons the
consider using a shared-memory buffer as described in
|link|Bulk Content Output||.
|!note|

|^ For detached and subprocess scripting the raw TCP/IP socket can be made
available for  scripts to transfer data directly to the client.  The socket
BG|/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 ("https:") encrypted requests. 

|^ 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
(|link|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 (|link|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
|link%=|/wasd_root/src/other/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.

|code|
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);
}
|!code|

|0Carriage Control|

|^ By default the TCP/IP BG device driver supplies a <CR><LF> sequence as
carriage control for each record.  This supports record-oriented output such as
DCL and various VMS utilities but is an issue when needing to output a binary
object such as a large graphic. The CGI callout (|link|CGI Callouts||)
GATEWAY-CCL: directive allows the  device carriage control to be set and reset
programmatically.  A value of 1 enables a <CR><LF> with each record, while 0
disables it.  This is analagous to the APACHE$SET_CCL utility.

|0Not 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 BG|/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.

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