Annotation of libwww/Library/src/HTHost.html, revision 2.23

2.1       frystyk     1: <HTML>
                      2: <HEAD>
2.4       frystyk     3:   <!-- Changed by: Henrik Frystyk Nielsen,  2-Jul-1996 -->
2.14      frystyk     4:   <TITLE>W3C Sample Code Library libwww Host Class</TITLE>
2.1       frystyk     5: </HEAD>
                      6: <BODY>
2.3       frystyk     7: <H1>
                      8:   The Host Class
                      9: </H1>
2.1       frystyk    10: <PRE>
                     11: /*
                     12: **     (c) COPYRIGHT MIT 1995.
                     13: **     Please first read the full copyright statement in the file COPYRIGH.
                     14: */
                     15: </PRE>
2.3       frystyk    16: <P>
                     17: The Host class manages what we know about a remote host. This can for example
                     18: be what type of host it is, and what version it is using. Notice that a host
                     19: object can be used to describe both a server or a client - all information
                     20: in the Host object can be shared regardless of whether it is to be used in
                     21: a server application or a client application.
                     22: <P>
                     23: This module is implemented by <A HREF="HTHost.c">HTHost.c</A>, and it is
2.21      frystyk    24: a part of the <A HREF="http://www.w3.org/Library/"> W3C Sample Code
2.3       frystyk    25: Library</A>.
2.1       frystyk    26: <PRE>
                     27: #ifndef HTHOST_H
                     28: #define HTHOST_H
                     29: 
                     30: typedef struct _HTHost HTHost;
2.8       frystyk    31: #define HOST_HASH_SIZE         67
2.1       frystyk    32: 
                     33: #include "HTChannl.h"
                     34: #include "HTReq.h"
2.2       frystyk    35: #include "HTEvent.h"
2.8       frystyk    36: #include "HTProt.h"
2.15      frystyk    37: #include "HTTimer.h"
2.1       frystyk    38: </PRE>
2.3       frystyk    39: <P>
                     40: The Host class contains information about the remote host, for example the
                     41: type (HTTP/1.0, HTTP/1.1, FTP etc.) along with information on how the connections
                     42: can be used (if it supports persistent connections, interleaved access etc.)
                     43: <H2>
                     44:   Creation and Deletion Methods
                     45: </H2>
                     46: <P>
                     47: We keep a cache of information that we know about a remote host. This allows
2.5       frystyk    48: us to be much more detailed in generating requests. Search the host info
                     49: cache for a host object or create a new one and add it. Examples of host
                     50: names are
2.1       frystyk    51: <UL>
2.3       frystyk    52:   <LI>
                     53:     www.w3.org
                     54:   <LI>
                     55:     www.foo.com:8000
2.1       frystyk    56: </UL>
2.3       frystyk    57: <H3>
                     58:   Add a Host Object
                     59: </H3>
2.1       frystyk    60: <PRE>
2.10      eric       61: extern HTHost * HTHost_new (char * host, u_short u_port);
                     62: extern HTHost * HTHost_newWParse(HTRequest * request, char * url, u_short u_port);
2.8       frystyk    63: extern int HTHost_hash (HTHost * host);
2.1       frystyk    64: </PRE>
2.3       frystyk    65: <H3>
                     66:   Delete a Host Object
                     67: </H3>
                     68: <P>
                     69: The Host Class contains an automatic garbage collection of Host objects so
                     70: that we don't keep information around that is stale.
2.6       frystyk    71: <H3>
                     72:   Find a Host Object
                     73: </H3>
                     74: <P>
                     75: Searches the cache of known hosts to see if we already have information about
                     76: this host. If not then we return NULL.
                     77: <PRE>extern HTHost * HTHost_find (char * host);
                     78: </PRE>
2.3       frystyk    79: <H2>
2.12      frystyk    80:   Remote Host Information
2.3       frystyk    81: </H2>
                     82: <P>
2.12      frystyk    83: We keep track of the capabilities of the host in the other end so thatwe
                     84: may adjust our queries to fit it better
2.3       frystyk    85: <H3>
2.5       frystyk    86:   Remote Host Name
                     87: </H3>
                     88: <P>
                     89: Get the name of the remote host. This is set automatically when a new Host
                     90: object and can be asked for at any point in time. You can not change the
                     91: host name but must create a new Host object instead.
                     92: <PRE>
                     93: extern char * HTHost_name      (HTHost * host);
                     94: </PRE>
                     95: <H3>
                     96:   Remote Host Protocol Class and Version
2.3       frystyk    97: </H3>
                     98: <P>
                     99: Define the <EM>host class</EM> of the host at the other end. A class is a
                    100: generic description of the protocol which is exactly like the access method
                    101: in a URL, for example "http" etc. The <EM>host version</EM> is a finer
                    102: distinction (sub-class) between various versions of the host class, for example
                    103: HTTP/0.9, HTTP/1.1 etc. The host version is a bit flag that the protocol
                    104: module can define on its own. That way we don't have to change this module
                    105: when registering a new protocol module. The <EM>host type</EM> is a description
                    106: of whether we can keep the connection persistent or not.
2.1       frystyk   107: <PRE>
                    108: extern char * HTHost_class     (HTHost * host);
                    109: extern void HTHost_setClass    (HTHost * host, char * s_class);
                    110: 
                    111: extern int  HTHost_version     (HTHost * host);
                    112: extern void HTHost_setVersion  (HTHost * host, int version);
                    113: </PRE>
2.3       frystyk   114: <H3>
2.12      frystyk   115:   Public Methods accessible on This Host
2.4       frystyk   116: </H3>
                    117: <P>
                    118: A server can inform a client about the supported methods using the
                    119: <CODE>Public</CODE> header.
                    120: <PRE>extern HTMethod HTHost_publicMethods      (HTHost * me);
                    121: extern void HTHost_setPublicMethods    (HTHost * me, HTMethod methodset);
                    122: extern void HTHost_appendPublicMethods (HTHost * me, HTMethod methodset);
                    123: </PRE>
2.12      frystyk   124: <H3>
2.4       frystyk   125:   Server Name of Remote Host
2.12      frystyk   126: </H3>
2.4       frystyk   127: <P>
                    128: A server can send its server application name and version in a HTTP response.
                    129: We pick up this information and add it to the Host object
                    130: <PRE>extern char * HTHost_server       (HTHost * host);
                    131: extern BOOL HTHost_setServer   (HTHost * host, const char * server);
                    132: </PRE>
2.12      frystyk   133: <H3>
2.4       frystyk   134:   User Agent Name of Remote Host
2.12      frystyk   135: </H3>
2.4       frystyk   136: <P>
                    137: A client can send the name of the client application in a HTTP request. We
2.5       frystyk   138: pick up this information and add it to the Host Object
2.4       frystyk   139: <PRE>extern char * HTHost_userAgent    (HTHost * host);
                    140: extern BOOL HTHost_setUserAgent        (HTHost * host, const char * userAgent);
                    141: </PRE>
2.12      frystyk   142: <H3>
2.7       frystyk   143:   Range Units Accepted by this Host
2.12      frystyk   144: </H3>
2.7       frystyk   145: <P>
                    146: Since all HTTP entities are represented in HTTP messages as sequences of
                    147: bytes, the concept of a byte range is meaningful for any HTTP entity. (However,
                    148: not all clients and servers need to support byte-range operations.) Byte
                    149: range specifications in HTTP apply to the sequence of bytes in the entity-body
                    150: (not necessarily the same as the message-body). A byte range operation may
                    151: specify a single range of bytes, or a set of ranges within a single entity.
                    152: <P>
                    153: You can also check whether a specific range unit is OK. We always say
                    154: <CODE>YES</CODE> except if we have a specific statement from the server that
                    155: it doesn't understand byte ranges - that is - it has sent "none" in a
                    156: "Accept-Range" response header
                    157: <PRE>
                    158: extern char * HTHost_rangeUnits  (HTHost * host);
                    159: extern BOOL HTHost_setRangeUnits (HTHost * host, const char * units);
                    160: extern BOOL HTHost_isRangeUnitAcceptable (HTHost * host, const char * unit);
                    161: </PRE>
2.18      frystyk   162: <H3>
2.23    ! frystyk   163:   User Defined Contexts
2.18      frystyk   164: </H3>
2.23    ! frystyk   165: <P>
        !           166: This can be used for anything that the application would like to keep tabs
        !           167: on.
2.18      frystyk   168: <PRE>
                    169: extern void HTHost_setContext (HTHost * me, void * context);
                    170: extern void * HTHost_context  (HTHost * me);
                    171: </PRE>
2.12      frystyk   172: <H2>
                    173:   Persistent Connections
                    174: </H2>
2.3       frystyk   175: <P>
2.23    ! frystyk   176: We don't want more than <TT>(Max open sockets) - 2</TT> connections to be
        !           177: persistent in order to avoid deadlock. You can set the max number of simultaneous
        !           178: open connection in the <A HREF="HTNet.html#Resources">HTNet manager</A>.
2.1       frystyk   179: <PRE>
2.19      kahan     180: extern int HTHost_catchClose (SOCKET soc, void * context, HTEventType type);
2.8       frystyk   181: extern BOOL HTHost_setPersistent (HTHost * host, BOOL persistent,
                    182:                                   HTTransportMode mode);
2.5       frystyk   183: extern BOOL HTHost_clearChannel (HTHost * host, int status);
2.1       frystyk   184: 
                    185: extern HTChannel * HTHost_channel (HTHost * host);
                    186: </PRE>
2.3       frystyk   187: <H3>
                    188:   Is this host Persistent?
                    189: </H3>
                    190: <P>
2.1       frystyk   191: Check whether we have a persistent channel or not
                    192: <PRE>
                    193: extern BOOL HTHost_isPersistent (HTHost * host);
2.15      frystyk   194: extern BOOL HTHost_setCloseNotification (HTHost * host, BOOL mode);
                    195: extern BOOL HTHost_closeNotification (HTHost * host);
2.1       frystyk   196: </PRE>
2.3       frystyk   197: <H3>
                    198:   Timing Persistent Channels
                    199: </H3>
                    200: <P>
                    201: Normally we wait for the peer process to close persistent connections but
                    202: in order not to use up our own resources, we have a timeout on our own. The
                    203: default value is 1 hour, but you can modify the value using the following
                    204: methods:
2.1       frystyk   205: <PRE>
                    206: extern time_t HTHost_persistTimeout (time_t timeout);
                    207: extern void HTHost_setPersistTimeout (time_t timeout);
                    208: </PRE>
2.3       frystyk   209: <P>
                    210: Each persistent connection has an absolute value of when this connection
                    211: most likely will expire. If the peer process does not inform us, we use our
                    212: own timeout.
2.1       frystyk   213: <PRE>
                    214: extern void HTHost_setPersistExpires (HTHost * host, time_t expires);
                    215: extern time_t HTHost_persistExpires (HTHost * host);
2.11      eric      216: extern void HTHost_setReqsPerConnection (HTHost * host, int reqs);
                    217: extern int HTHost_reqsPerConnection (HTHost * host);
                    218: extern void HTHost_setReqsMade (HTHost * host, int reqs);
                    219: extern int HTHost_reqsMade (HTHost * host);
2.1       frystyk   220: </PRE>
2.5       frystyk   221: <H2>
2.12      frystyk   222:   Transport Mode
                    223: </H2>
                    224: <P>
                    225: Handle the connection mode. The mode may change mode in the middle of a
                    226: connection If the new mode is lower than the old mode then adjust the pipeline
                    227: accordingly. That is, if we are going into single mode then move all entries
                    228: in the pipeline and move the rest to the pending queue. They will get launched
                    229: at a later point in time.
                    230: <PRE>extern HTTransportMode HTHost_mode (HTHost * host, BOOL * active);
                    231: extern BOOL HTHost_setMode (HTHost * host, HTTransportMode mode);
                    232: </PRE>
                    233: <H2>
2.5       frystyk   234:   Queuing Requests
                    235: </H2>
                    236: <P>
                    237: Requests are queued in the Host object until we have resources to start them.
                    238: The request is in the form of a Net object as we may have multiple socket
                    239: requests per <A HREF="HTReq.html">Request object</A>. This is for example
                    240: the case with <A HREF="WWWFTp.html">FTP</A> which uses two connections.
2.23    ! frystyk   241: <PRE>
        !           242: extern int  HTHost_addNet    (HTHost * host, HTNet * net);
        !           243: extern BOOL HTHost_deleteNet (HTHost * host, HTNet * net, int status);
        !           244: 
2.5       frystyk   245: extern HTList * HTHost_net   (HTHost * host);
                    246: </PRE>
                    247: <H3>
2.12      frystyk   248:   Is the Host Idle?
2.5       frystyk   249: </H3>
                    250: <P>
                    251: Before we can start a new connection to the host we must be sure that the
                    252: host is idle. That is, if it can accept a new connection. We have several
                    253: modes describing how and when a host is idle. This is a function of the
                    254: <A HREF="HTTrans.html">Transport Object</A>
                    255: <PRE>extern BOOL HTHost_isIdle (HTHost * host);
                    256: </PRE>
2.3       frystyk   257: <H3>
2.5       frystyk   258:   Handling Pending Requests
2.3       frystyk   259: </H3>
                    260: <P>
2.5       frystyk   261: There are two ways we can end up with pending reqyests:
                    262: <OL>
                    263:   <LI>
                    264:     If we are out of sockets then register new host objects as pending.
                    265:   <LI>
                    266:     If we are pending on a connection then register new net objects as pending
                    267: </OL>
                    268: <P>
                    269: This set of functions handles pending host objects and can start new requests
                    270: as resources get available. The first function checks the host object for
                    271: any pending <A HREF="HTNet.html">Net objects</A> and return the first of
                    272: these Net objects.
2.3       frystyk   273: <PRE>
2.5       frystyk   274: extern HTNet * HTHost_nextPendingNet (HTHost * host);
                    275: </PRE>
                    276: <P>
                    277: The second checks the list of pending host objects waiting for a socket and
                    278: returns the first of these Host objects.
                    279: <PRE>
                    280: extern HTHost * HTHost_nextPendingHost (void);
                    281: </PRE>
                    282: <P>
                    283: Start the next pending request if any. First we look for pending requests
                    284: for the same host and then we check for any other pending hosts. If nothing
                    285: pending then register a catch close event handler to have something catching
                    286: the socket if the remote server closes the connection, for example due to
                    287: timeout.
2.8       frystyk   288: <PRE>
                    289: extern BOOL HTHost_launchPending (HTHost * host);
                    290: 
                    291: extern int HTHost_connect (HTHost * host, HTNet * net, char * url,
                    292:                            HTProtocolId port);
                    293: </PRE>
                    294: <P>
                    295: HTHost clients can use the host for all IO and take advantage of host
                    296: multiplexing and pipelining.
2.22      frystyk   297: <H3>
                    298:   How many Requests can we Pipeline onto the same Connection?
                    299: </H3>
2.23    ! frystyk   300: <P>
        !           301: Use these functions to set the max number of requests that can be pipelined
        !           302: at any one time on a single, persistent connection. The higher the number,
        !           303: the more we have to recover if the server closes the connection prematurely.
        !           304: The default is about 50 requests which is enough to fill most links.
2.22      frystyk   305: <PRE>
                    306: extern BOOL HTHost_setMaxPipelinedRequests (int max);
                    307: extern int HTHost_maxPipelinedRequests (void);
                    308: </PRE>
2.12      frystyk   309: <H2>
2.8       frystyk   310:   Event Management
2.12      frystyk   311: </H2>
2.8       frystyk   312: <PRE>
                    313: extern int HTHost_register(HTHost * host, HTNet * net, HTEventType type);
                    314: extern int HTHost_unregister(HTHost * host, HTNet * net, HTEventType type);
                    315: extern int HTHost_tickleFirstNet(HTHost * host, HTEventType type);
2.16      frystyk   316: 
2.8       frystyk   317: extern BOOL HTHost_setRemainingRead(HTHost * host, size_t remainaing);
2.16      frystyk   318: extern size_t HTHost_remainingRead (HTHost * host);
                    319: 
2.8       frystyk   320: extern SockA * HTHost_getSockAddr(HTHost * host);
                    321: </PRE>
                    322: <H3>
2.12      frystyk   323:   Control the Delayed Flush Timer
2.8       frystyk   324: </H3>
2.12      frystyk   325: <P>
                    326: These methods can control how long we want to wait for a flush on a given
                    327: host.
2.8       frystyk   328: <PRE>
2.12      frystyk   329: extern BOOL HTHost_setWriteDelay (HTHost * host, ms_t delay);
                    330: extern ms_t HTHost_writeDelay (HTHost * host);
                    331: extern int HTHost_findWriteDelay(HTHost * host, ms_t lastFlushTime, int buffSize);
2.8       frystyk   332: </PRE>
2.12      frystyk   333: <P>
                    334: It is also possible to explicitly require a flush using the following method
2.8       frystyk   335: <PRE>
2.12      frystyk   336: extern int HTHost_forceFlush(HTHost * host);
2.8       frystyk   337: </PRE>
2.12      frystyk   338: <P>
                    339: You can also set the global value so that all new host objects will inherit
                    340: this value instead of setting it individually.
                    341: <PRE>extern BOOL HTHost_setDefaultWriteDelay (ms_t delay);
                    342: extern ms_t HTHost_defaultWriteDelay (void);
                    343: </PRE>
2.8       frystyk   344: <H3>
2.12      frystyk   345:   Event Timeouts
2.8       frystyk   346: </H3>
2.12      frystyk   347: <P>
                    348: Events can be assigned a timeout which causes the event to be triggered if
                    349: the timeout happens before other action is available on the socket. You can
                    350: assign a global timeout for all host object using the following methods
2.8       frystyk   351: <PRE>
2.12      frystyk   352: extern int HTHost_eventTimeout (void);
                    353: extern void HTHost_setEventTimeout (int millis);
2.8       frystyk   354: </PRE>
                    355: <H3>
2.12      frystyk   356:   Get the Next Net object for Reading and Writing
2.8       frystyk   357: </H3>
                    358: <PRE>
                    359: extern HTNet * HTHost_firstNet     (HTHost * host);
                    360: extern HTNet * HTHost_getReadNet  (HTHost * host);
                    361: extern HTNet * HTHost_getWriteNet (HTHost * host);
                    362: </PRE>
                    363: <H3>
                    364:   Get input and output Streams for this Host
                    365: </H3>
                    366: <PRE>
                    367: extern HTInputStream * HTHost_getInput (HTHost * host, HTTransport * transport,
                    368:                                        void * param, int mode);
                    369: 
                    370: extern HTOutputStream * HTHost_getOutput (HTHost * host, HTTransport * tp,
                    371:                                          void * param, int mode);
                    372: </PRE>
                    373: <H3>
2.12      frystyk   374:   The Channel Associated with this Host
                    375: </H3>
                    376: <PRE>
                    377: extern BOOL HTHost_setChannel (HTHost * host, HTChannel * channel);
                    378: extern HTChannel * HTHost_channel (HTHost * host);
                    379: </PRE>
                    380: <H3>
2.8       frystyk   381:   Read Management
                    382: </H3>
                    383: <PRE>
                    384: extern int HTHost_read(HTHost * host, HTNet * net);
                    385: extern BOOL HTHost_setConsumed(HTHost * host, size_t bytes);
2.3       frystyk   386: </PRE>
2.12      frystyk   387: <H2>
2.23    ! frystyk   388:   <A NAME="Pipeline">Handling a Pipeline</A>
        !           389: </H2>
        !           390: <P>
        !           391: Pipelines normally run by themselves (requests are issued and responses
        !           392: recieved). However, it may be necessry to either prematurely abort a pipeline
        !           393: or to recover a broken pipeline due to communication problems with the server.
        !           394: <H3>
        !           395:   Pipeline Recovery
        !           396: </H3>
        !           397: <P>
        !           398: In case a pipeline is broken then we have to recover it and start again.
        !           399: This is handled automatically by the host object, so you do not have to call
        !           400: this one explicitly.
        !           401: <PRE>
        !           402: extern BOOL HTHost_recoverPipe (HTHost * host);
        !           403: extern BOOL HTHost_doRecover (HTHost * host);
        !           404: </PRE>
        !           405: <H3>
        !           406:   Kill a Pipeline
        !           407: </H3>
        !           408: <P>
        !           409: Call this function to terminate all requests (pending as well as active)
        !           410: registered with a host object. This is typically the function that handles
        !           411: timeout, abort (user hits the red button, etc). You can also use the
        !           412: <A HREF="HTNet.html">HTNet object kill method</A> which in terms call this
        !           413: function.
        !           414: <PRE>extern BOOL HTHost_killPipe (HTHost * host);
        !           415: </PRE>
        !           416: <H2>
2.12      frystyk   417:   Multi homed Host Management
                    418: </H2>
                    419: <P>
                    420: We also keep track of if a host has multiple IP addresses. If so then it
                    421: is called a <I>multi-homed host</I>. This is used for two things: finding
                    422: the fastest host with this name and as a backup if one or more of the hosts
                    423: are down.
2.1       frystyk   424: <PRE>
2.12      frystyk   425: extern BOOL HTHost_setHome (HTHost * host, int home);
                    426: extern int HTHost_home (HTHost * host);
2.13      frystyk   427: 
                    428: extern BOOL HTHost_setRetry (HTHost * host, int retry);
                    429: extern int HTHost_retry (HTHost * host);
                    430: extern BOOL HTHost_decreaseRetry (HTHost * host);
2.19      kahan     431: </PRE>
2.23    ! frystyk   432: <H2>
        !           433:   Notify Request that it has become Active
        !           434: </H2>
2.19      kahan     435: <P>
                    436: A new callback plugged to the activation of a request. Allows to simplify
                    437: Amaya's use of libwww.
                    438: <PRE>
                    439: typedef int HTHost_ActivateRequestCallback (HTRequest *);
                    440: extern void HTHost_setActivateRequestCallback (HTHost_ActivateRequestCallback *
                    441: cbf);
                    442: </PRE>
                    443: <P>
                    444: Controls whether pending requests should be automatically activated.
                    445: <PRE>
                    446: extern void HTHost_enable_PendingReqLaunch (void);
                    447: extern void HTHost_disable_PendingReqLaunch (void);
                    448: </PRE>
2.12      frystyk   449: <PRE>
2.1       frystyk   450: #endif /* HTHOST_H */
                    451: </PRE>
2.3       frystyk   452: <P>
                    453:   <HR>
2.1       frystyk   454: <ADDRESS>
2.23    ! frystyk   455:   @(#) $Id: HTHost.html,v 2.22 1998/05/19 16:49:32 frystyk Exp $
2.1       frystyk   456: </ADDRESS>
2.3       frystyk   457: </BODY></HTML>

Webmaster