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