Annotation of libwww/Library/src/HTReq.html, revision 2.69
2.69 ! kirschpi 1: <html>
! 2: <head>
! 3: <meta http-equiv="Content-Type" content="text/html">
2.40 frystyk 4: <!-- Changed by: Henrik Frystyk Nielsen, 15-Jul-1996 -->
2.69 ! kirschpi 5: <title>W3C Sample Code Library libwww Request Class</title>
! 6: </head>
! 7:
! 8: <body>
! 9: <h1>The Request Class</h1>
! 10: <pre>/*
2.1 frystyk 11: ** (c) COPYRIGHT MIT 1995.
12: ** Please first read the full copyright statement in the file COPYRIGH.
2.69 ! kirschpi 13: */</pre>
! 14:
! 15: <p>Libwww is based on a request/response paradigm and the Request class
! 16: defines "<i>an operation to be performed on a URL</i>". The request object is
! 17: the main entry point for an application to issue a request to the Library -
! 18: all operations on a URL <i>must</i> use a Request object. The request object
2.31 frystyk 19: is application independent in that both servers and clients use the same
20: Request class. Examples of requests passed to the Library are a client
2.69 ! kirschpi 21: application issuing a <b>GET</b> request on a HTTP URL, or a server issuing a
! 22: load on a local file URL. The only difference is that the client gets the
! 23: input from a user whereas the server gets the input via the network.</p>
! 24:
! 25: <p>A request object is created with a default set of parameters which are
! 26: applicable for many URL requests but the class defines a huge set of methods
! 27: that an be used to customize a request for a particular purpose. Example of
! 28: things that you can define is natural language, media types, what RFC 822
! 29: headers to use, whether the request should be refreshed from cache etc.
! 30: Scroll down and see the set of parameters you can tune.</p>
! 31:
! 32: <p>A request object is registered in the library by issuing an operation on a
! 33: URL - for example <b>PUT</b>, <b>POST</b>, or <b>DELETE</b>. You can find
! 34: many higher level "request issuing functions" in the <a
! 35: href="HTAccess.html">Access module</a> - the methods defined by the Request
! 36: class itself are very low level but can of course be used directly if
! 37: needed.</p>
! 38:
! 39: <p>Whereas the lifetime of the URL (in form of an anchor) often is very long
! 40: (for example as long as the application is running), the lifetime of a
! 41: request is limited to the time it takes to service the request. The core does
! 42: not automatically delete any request object created by the application - it
! 43: is for the application to do. In many cases a request object can be deleted
! 44: when any of the <a href="HTNet.html#callout">termination callback
! 45: functions</a> are called but the application may keep request objects around
! 46: longer than that</p>
! 47:
! 48: <p>The Library can accept an unlimited number of simultaneous requests passed
! 49: by the application. One of the main functions of the Library core is to
! 50: handle any number of ongoing requests in an intelligent manner by limiting
! 51: the number of active request to the fit the available resources as defined by
! 52: the application. This is described in more detail in the <a
! 53: href="HTNet.html">HTNet module</a>.</p>
! 54:
! 55: <p>This module is implemented by <a href="HTReqMan.c">HTReqMan.c</a>, and it
! 56: is a part of the <a href="http://www.w3.org/Library/"> W3C Sample Code
! 57: Library</a>.</p>
! 58: <pre>#ifndef HTREQ_H
2.1 frystyk 59: #define HTREQ_H
60:
2.20 frystyk 61: typedef long HTRequestID;
2.1 frystyk 62: typedef struct _HTRequest HTRequest;
63:
2.29 frystyk 64: #include "HTEvent.h"
2.1 frystyk 65: #include "HTList.h"
2.23 frystyk 66: #include "HTAssoc.h"
2.1 frystyk 67: #include "HTFormat.h"
68: #include "HTStream.h"
2.10 frystyk 69: #include "HTError.h"
2.1 frystyk 70: #include "HTNet.h"
2.31 frystyk 71: #include "HTUser.h"
2.69 ! kirschpi 72: #include "HTResponse.h"</pre>
! 73:
! 74: <h2><a name="Creation">Creation and Deletion Methods</a></h2>
! 75:
! 76: <p>The request object is intended to live as long as the request is still
! 77: active, but can be deleted as soon as it has terminated, for example in one
! 78: of the request termination callback functions as described in the <a
! 79: href="HTNet.html">Net Manager</a>. Only the anchor object stays around after
! 80: the request itself is terminated.</p>
! 81:
! 82: <h3>Create new Object</h3>
! 83:
! 84: <p>Creates a new request object with a default set of options -- in most
! 85: cases it will need some information added which can be done using the methods
! 86: in this module, but it will work as is for a simple request.</p>
! 87: <pre>extern HTRequest * HTRequest_new (void);</pre>
! 88:
! 89: <h3>Clear a Request Object</h3>
! 90:
! 91: <p>Clears all protocol specific information so that the request object can be
2.68 kahan 92: used for another request. It should be used with care as application specific
2.69 ! kirschpi 93: information is <b>not</b> re-initialized. Returns YES if OK, else NO.</p>
! 94: <pre>extern BOOL HTRequest_clear (HTRequest * me);</pre>
! 95:
! 96: <h3>Create a duplicate</h3>
! 97:
! 98: <p>Creates a new HTRequest object as a duplicate of the src request. Returns
! 99: YES if OK, else NO</p>
! 100: <pre>extern HTRequest * HTRequest_dup (HTRequest * src);</pre>
! 101:
! 102: <h4>Create a duplicate for Internal use</h4>
! 103:
! 104: <p>Creates a new HTRequest object as a duplicate of the src request. The
! 105: difference to the HTRequest_dup function is that we don't copy the
! 106: error_stack and other information that the application keeps in its copy of
! 107: the request object. Otherwise it will be freed multiple times. Returns YES if
! 108: OK, else NO</p>
! 109: <pre>extern HTRequest * HTRequest_dupInternal (HTRequest * src);
2.66 frystyk 110:
111: extern BOOL HTRequest_setInternal (HTRequest * request, BOOL mode);
2.69 ! kirschpi 112: extern BOOL HTRequest_internal (HTRequest * request);</pre>
! 113:
! 114: <h3>Delete Object</h3>
! 115:
! 116: <p>This function deletes the object and cleans up the memory.</p>
! 117: <pre>extern void HTRequest_delete (HTRequest * request);</pre>
! 118:
! 119: <h2><a name="Issuing">Issuing a Request</a></h2>
! 120:
! 121: <p>These are the "<i>basic request methods</i>" provided directly by the
! 122: Request class. This is a very low level API as the caller must have set up
! 123: the request object before passing it to libwww. There are two versions: one
! 124: for issuing client requests and one for issuing server requests. You will
! 125: probably most often use the client version, but, in fact, libwww can also
! 126: deal with incoming connections. You can find many higher level issuing
! 127: functions in the <a href="HTAccess.html">HTAccess module</a>. If you like,
! 128: you can of course use this directly!</p>
! 129: <pre>extern BOOL HTLoad (HTRequest * request, BOOL recursive);
! 130: extern BOOL HTServe(HTRequest * request, BOOL recursive);</pre>
! 131:
! 132: <h2><a name="Killing">Killing a Request</a></h2>
! 133:
! 134: <p>This function kills this particular request, see <a
! 135: href="HTNet.html">HTNet module</a> for a function that kills them all. If you
! 136: know that you are pipelining requests (typically the case for GUI browsers,
! 137: robots etc.) then it is often not enough to just kill a single request as the
! 138: whole pipeline gets affected. Therefore, in that case you MUST call the
! 139: <tt><a href="HTHost.html#Pipeline">HTHost_killPipe</a></tt> function
! 140: instead,</p>
! 141: <pre>extern BOOL HTRequest_kill(HTRequest * request);</pre>
! 142:
! 143: <p>Note that you can get to the HTHost object via the <a
! 144: href="HTNet.html">HTNet object</a> which you can <a href="#HTNet">get by
! 145: calling HTRequest_net(...)</a>.</p>
! 146:
! 147: <h2><a name="Relations">Relations to Other Libwww Objects</a></h2>
! 148:
! 149: <p>The Request object is linked to a set of other libwww objects - here's how
! 150: to get to these objects...</p>
! 151:
! 152: <h3><a name="Anchor">Binding to an Anchor Object</a></h3>
! 153:
! 154: <p>Every request object has an <a href="HTAnchor.html">anchor</a> associated
2.66 frystyk 155: with it. The anchor normally lives until the application terminates but a
156: request object only lives as long as the request is being serviced. If the
2.69 ! kirschpi 157: anchor that we have requested is a child anchor then we always load the
! 158: parent anchor; after the load jump to the location. A child anchor is a an
! 159: anchor which points to a subpart of the document (has a "#" in the URL).</p>
! 160: <pre>extern void HTRequest_setAnchor (HTRequest *request, HTAnchor *anchor);
2.66 frystyk 161: extern HTParentAnchor * HTRequest_anchor (HTRequest *request);
162:
2.69 ! kirschpi 163: extern HTChildAnchor * HTRequest_childAnchor (HTRequest * request);</pre>
! 164:
! 165: <h3><a name="User">Binding to a User Profile</a></h3>
! 166:
! 167: <p>Each request is associated with a <a href="HTUser.html">User profile</a>
2.66 frystyk 168: which contains information about the local host name, email address of the
169: user, news server etc. A request object is created with a default "generic
2.69 ! kirschpi 170: user" but can be assigned a specific user at any time.</p>
! 171: <pre>extern BOOL HTRequest_setUserProfile (HTRequest * request, HTUserProfile * up);
! 172: extern HTUserProfile * HTRequest_userProfile (HTRequest * request);</pre>
! 173:
! 174: <h3><a name="HTNet">Binding to a Net Object</a></h3>
! 175:
! 176: <p>If a request is actually going on the net then the <a
! 177: href="HTNet.html">Net Manager</a> is contacted to handle the request. The Net
! 178: manager creates a HTNEt object and links it to the Request object. You can
! 179: get to the HTNet object using the following functions.</p>
! 180: <pre>extern HTNet * HTRequest_net (HTRequest * request);
! 181: extern BOOL HTRequest_setNet (HTRequest * request, HTNet * net);</pre>
! 182:
! 183: <p>Note that you can go from the HTNet object to the <a
! 184: href="HTHost.html">HTHost</a> object by calling <tt>HTNet_host(...)</tt>.</p>
! 185:
! 186: <h3><a name="Response">Binding to a Response Object</a></h3>
! 187:
! 188: <p>If a request is actually going on the net and we are getting a response
! 189: back then we also create a <a href="HTResponse.html">HTResponse object</a>
! 190: and bind it to the request object. Once we know what to do with the response,
! 191: we may transfer the information to the anchor object.</p>
! 192: <pre>extern HTResponse * HTRequest_response (HTRequest * request);
! 193: extern BOOL HTRequest_setResponse (HTRequest * request, HTResponse * response);</pre>
! 194:
! 195: <h2><a name="Method">Set the Method for the Request</a></h2>
! 196:
! 197: <p>The Method is the operation to be executed on the requested object. The
! 198: default set if the set of operations defined by the HTTP protocol, that is
! 199: "GET", "HEAD", "PUT", "POST", "LINK", "UNLINK", and "DELETE" but many of
! 200: these can be used in other protocols as well. The important thing is to think
! 201: of the requested element as an object on which you want to perform an
! 202: operation. Then it is for the specific protocol implementation to try and
! 203: carry this operation out. However, not all operations can be implemented (or
! 204: make sense) in all protocols.</p>
! 205:
! 206: <p>Methods are handled by the <a href="HTMethod.html">Method Module</a>, and
! 207: the default value is "GET".</p>
! 208: <pre>extern void HTRequest_setMethod (HTRequest *request, HTMethod method);
! 209: extern HTMethod HTRequest_method (HTRequest *request);</pre>
! 210:
! 211: <h2><a name="Priority">Priority Management</a></h2>
! 212:
! 213: <p>The request can be assigned an initial priority which then gets inherited
! 214: by all <a href="HTNet.html">HTNet objects</a> and other requests objects
! 215: created as a result of this one. You can also assign a separate priority to
! 216: an indicidual HTNet object by using the methods in the <a
! 217: href="HTNet.html">Net manager</a>.</p>
! 218: <pre>extern HTPriority HTRequest_priority (HTRequest * request);
! 219: extern BOOL HTRequest_setPriority (HTRequest * request, HTPriority priority);</pre>
! 220:
! 221: <h2><a name="Pipelining">Pipelining Managament</a></h2>
! 222:
! 223: <p>Libwww supports HTTP/1.1 pipelining which greatly optimizes HTTP's
! 224: behavior over TCP. libwww also tries very hard to minimize the number of TCP
! 225: packets sent over the network. This is done by buffering outgoing requests
! 226: until either a minimum amount of data has been collected or a timeout causes
! 227: a flush to happen. The application can override the output buffering by
! 228: explicit request a request object to be flushed.</p>
! 229: <pre>extern BOOL HTRequest_setFlush (HTRequest * me, BOOL mode);
! 230: extern BOOL HTRequest_flush (HTRequest * me);</pre>
! 231:
! 232: <h3>Force the Pipeline to be Flushed Immediately</h3>
! 233:
! 234: <p>Forcing a fluch immediatly is slightly different as this can be done in
! 235: "retrospect". That is, if suddenly the application decides on performing a
! 236: flush after the request was initiated then it can use this function to flush
! 237: at a later time.</p>
! 238: <pre>extern int HTRequest_forceFlush (HTRequest * request);</pre>
! 239:
! 240: <h2><a name="Error">Dealing with Request Error Messages</a></h2>
! 241:
! 242: <p>Errors are, like almost anything, kept in lists. An error list can be
2.68 kahan 243: associated with a request using the following functions. In order to make
2.69 ! kirschpi 244: life easier, there are also some easy mapping functions to the <a
! 245: href="HTError.html">HTError object</a>, so that you can add an error directly
! 246: to a request object.</p>
! 247: <pre>extern HTList * HTRequest_error (HTRequest * request);
2.47 frystyk 248: extern void HTRequest_setError (HTRequest * request, HTList * list);
2.69 ! kirschpi 249: extern void HTRequest_deleteAllErrors (HTRequest * request);</pre>
! 250:
! 251: <p>These are the cover functions that go directly to the <a
! 252: href="HTError.html">Error Object</a></p>
! 253: <pre>extern BOOL HTRequest_addError (HTRequest * request,
2.47 frystyk 254: HTSeverity severity,
255: BOOL ignore,
256: int element,
257: void * par,
258: unsigned int length,
259: char * where);
260:
261: extern BOOL HTRequest_addSystemError (HTRequest * request,
262: HTSeverity severity,
263: int errornumber,
264: BOOL ignore,
2.69 ! kirschpi 265: char * syscall);</pre>
! 266:
! 267: <h2><a name="MaxRetry">Max number of Retrys for a Down Load</a></h2>
! 268:
! 269: <p>Automatic reload can happen in two situations:</p>
! 270: <ul>
! 271: <li>The server sends a redirection response</li>
! 272: <li>The document has expired</li>
! 273: </ul>
! 274:
! 275: <p>In order to avoid the Library going into an infinite loop, it is necessary
2.30 frystyk 276: to keep track of the number of automatic reloads. Loops can occur if the
2.69 ! kirschpi 277: server has a reload to the same document or if the server sends back a
! 278: Expires header which has already expired. The default maximum number of
! 279: automatic reloads is 6.</p>
! 280: <pre>extern BOOL HTRequest_setMaxRetry (int newmax);
2.1 frystyk 281: extern int HTRequest_maxRetry (void);
2.41 frystyk 282:
283: extern int HTRequest_retrys (HTRequest * request);
284: extern BOOL HTRequest_doRetry (HTRequest *request);
2.44 frystyk 285: extern BOOL HTRequest_addRetry (HTRequest * request);
2.62 kahan 286:
287: extern int HTRequest_AAretrys (HTRequest * request);
2.69 ! kirschpi 288: extern BOOL HTRequest_addAARetry (HTRequest * request);</pre>
! 289:
! 290: <h2><a name="MaxForward">Set Max Forwards for TRACE methods</a></h2>
! 291:
! 292: <p>The <code>TRACE</code> method is used to invoke a remote,
! 293: application-layer loop-back of the request message. The final recipient of
! 294: the request SHOULD reflect the message received back to the client as the
! 295: entity-body of a 200 (OK) response. The final recipient is either the origin
! 296: server or the first proxy or gateway to receive a Max-Forwards value of zero
! 297: (0) in the request. A <code>TRACE</code> request <i>MUST NOT</i> include an
! 298: entity.</p>
! 299: <pre>extern BOOL HTRequest_setMaxForwards (HTRequest * request, int maxforwards);
! 300: extern int HTRequest_maxForwards (HTRequest * request);</pre>
! 301:
! 302: <h2><a name="preemptive">Preemptive or Non-preemptive Access</a></h2>
! 303:
! 304: <p>An access scheme is defined with a default for using either preemptive
! 305: (blocking I/O) or non-preemptive (non-blocking I/O). This is basically a
! 306: result of the implementation of the protocol module itself. However, if
! 307: non-blocking I/O is the default then some times it is nice to be able to set
! 308: the mode to blocking instead. For example, when loading the first document
! 309: (the home page), blocking mode can be used instead of non-blocking.</p>
! 310: <pre>extern void HTRequest_setPreemptive (HTRequest *request, BOOL mode);
! 311: extern BOOL HTRequest_preemptive (HTRequest *request);</pre>
! 312:
! 313: <h2><a name="conneg">Content Negotiation</a></h2>
! 314:
! 315: <p>When accessing the local file system, the Library is capable of performing
2.47 frystyk 316: content negotioation as described by the HTTP protocol. This is mainly for
317: server applications, but some client applications might also want to use
318: content negotiation when accessing the local file system. This method enables
2.69 ! kirschpi 319: or disables content negotiation - the default value is <em>ON</em>.</p>
! 320: <pre>extern void HTRequest_setNegotiation (HTRequest *request, BOOL mode);
! 321: extern BOOL HTRequest_negotiation (HTRequest *request);</pre>
! 322:
! 323: <h2><a name="Preconditions">Request Preconditions (HTTP If-* Headers)</a></h2>
! 324:
! 325: <p>Should this request use preconditions when doing a <tt>PUT</tt> or a
! 326: <tt>POST</tt>? These are the "<tt>if-*</tt>" header fields that can be used
2.64 frystyk 327: to avoid version conflicts etc. The default is not to use any preconsitions
2.69 ! kirschpi 328: (<tt>HT_NO_MATCH</tt>). The <tt>_THIS</tt> versions use etags and/or time
! 329: stamps and the <tt>_ANY</tt> versions use the "<tt>*</tt>" header field value
! 330: of the <tt>if-match</tt> and <tt>if-non-match</tt> header fields.</p>
! 331: <pre>typedef enum _HTPreconditions {
2.64 frystyk 332: HT_NO_MATCH = 0,
333: HT_MATCH_THIS,
334: HT_MATCH_ANY,
335: HT_DONT_MATCH_THIS,
336: HT_DONT_MATCH_ANY
337: } HTPreconditions;
338:
339: extern void HTRequest_setPreconditions (HTRequest * me, HTPreconditions mode);
2.69 ! kirschpi 340: extern HTPreconditions HTRequest_preconditions (HTRequest * me);</pre>
! 341:
! 342: <h2><a name="Parsers">Local MIME header Parsers</a></h2>
! 343:
! 344: <p>MIMEParsers get their own type which is optimized for static and regex
! 345: parser strings.</p>
! 346: <pre>typedef struct _HTMIMEParseSet HTMIMEParseSet;
2.66 frystyk 347: extern void HTRequest_setMIMEParseSet (HTRequest *request,
348: HTMIMEParseSet * parseSet, BOOL local);
349: extern HTMIMEParseSet * HTRequest_MIMEParseSet (HTRequest *request,
2.69 ! kirschpi 350: BOOL * pLocal);</pre>
! 351:
! 352: <h2><a name="default">Which Default Protocol Header Fields To Use?</a></h2>
! 353:
! 354: <p>Libwww supports a large set of headers that can be sent along with a
! 355: request (or a response for that matter). All headers can be either disabled
! 356: or enabled using bit flags that are defined in the following. See also the <a
! 357: href="#extra">section on how to extend the default set of supported header
! 358: fields</a>.</p>
! 359:
! 360: <h3><a name="gnhd">General HTTP Header Mask</a></h3>
! 361:
! 362: <p>There are a few header fields which have general applicability for both
! 363: request and response mesages, but which do not apply to the communication
! 364: parties or theentity being transferred. This mask enables and disables these
! 365: headers. If the bit is not turned on they are not sent.</p>
! 366: <pre>typedef enum _HTGnHd {
2.45 frystyk 367: HT_G_CC = 0x1,
368: HT_G_CONNECTION = 0x2,
369: HT_G_DATE = 0x4,
370: HT_G_PRAGMA_NO_CACHE= 0x8,
371: HT_G_FORWARDED = 0x10,
372: HT_G_MESSAGE_ID = 0x20,
2.53 frystyk 373: HT_G_MIME = 0x40,
2.54 frystyk 374: HT_G_TRAILER = 0x80,
2.66 frystyk 375: HT_G_TRANSFER = 0x100,
376: HT_G_EXTRA_HEADERS = 0x200
2.1 frystyk 377: } HTGnHd;
378:
2.54 frystyk 379: #define DEFAULT_GENERAL_HEADERS \
2.66 frystyk 380: HT_G_CONNECTION + HT_G_CC + HT_G_TRANSFER + HT_G_TRAILER + \
381: HT_G_EXTRA_HEADERS
2.1 frystyk 382:
383: extern void HTRequest_setGnHd (HTRequest *request, HTGnHd gnhd);
384: extern void HTRequest_addGnHd (HTRequest *request, HTGnHd gnhd);
2.69 ! kirschpi 385: extern HTGnHd HTRequest_gnHd (HTRequest *request);</pre>
! 386:
! 387: <h3><a name="rqhd">Request Headers</a></h3>
! 388:
! 389: <p>The request header fields allow the client to pass additional information
2.30 frystyk 390: about the request (and about the client itself) to the server. All headers
391: are optional but the default value is all request headers if present
2.69 ! kirschpi 392: <em>except</em> <code>From</code> and <code>Pragma</code>.</p>
! 393: <pre>typedef enum _HTRqHd {
2.16 frystyk 394: HT_C_ACCEPT_TYPE = 0x1,
395: HT_C_ACCEPT_CHAR = 0x2,
396: HT_C_ACCEPT_ENC = 0x4,
2.53 frystyk 397: HT_C_ACCEPT_TE = 0x8,
398: HT_C_ACCEPT_LAN = 0x10,
399: HT_C_AUTH = 0x20, /* Includes proxy authentication */
400: HT_C_EXPECT = 0x40,
401: HT_C_FROM = 0x80,
402: HT_C_HOST = 0x100,
403: HT_C_IMS = 0x200,
404: HT_C_IF_MATCH = 0x400,
2.64 frystyk 405: HT_C_IF_MATCH_ANY = 0x800,
2.63 frystyk 406: HT_C_IF_NONE_MATCH = 0x1000,
2.64 frystyk 407: HT_C_IF_NONE_MATCH_ANY=0x2000,
2.63 frystyk 408: HT_C_IF_RANGE = 0x4000,
409: HT_C_IF_UNMOD_SINCE = 0x8000,
410: HT_C_MAX_FORWARDS = 0x10000,
411: HT_C_RANGE = 0x20000,
412: HT_C_REFERER = 0x40000,
413: HT_C_USER_AGENT = 0x80000
2.1 frystyk 414: } HTRqHd;
415:
2.16 frystyk 416: #define DEFAULT_REQUEST_HEADERS \
2.37 frystyk 417: HT_C_ACCEPT_TYPE + HT_C_ACCEPT_CHAR + \
2.53 frystyk 418: HT_C_ACCEPT_ENC + HT_C_ACCEPT_TE + HT_C_ACCEPT_LAN + HT_C_AUTH + \
419: HT_C_EXPECT + HT_C_HOST + HT_C_REFERER + HT_C_USER_AGENT
2.1 frystyk 420:
421: extern void HTRequest_setRqHd (HTRequest *request, HTRqHd rqhd);
422: extern void HTRequest_addRqHd (HTRequest *request, HTRqHd rqhd);
2.69 ! kirschpi 423: extern HTRqHd HTRequest_rqHd (HTRequest *request);</pre>
! 424:
! 425: <h3><a name="rshd">Response Headers</a></h3>
! 426:
! 427: <p>The response header fields allow the server to pass additional information
2.30 frystyk 428: about the response (and about the server itself) to the client. All headers
2.69 ! kirschpi 429: are optional.</p>
! 430: <pre>typedef enum _HTRsHd {
2.37 frystyk 431: HT_S_AGE = 0x1,
432: HT_S_LOCATION = 0x2,
433: HT_S_PROXY_AUTH = 0x4,
434: HT_S_PUBLIC = 0x8,
435: HT_S_RETRY_AFTER = 0x10,
436: HT_S_SERVER = 0x20,
437: HT_S_VARY = 0x40,
438: HT_S_WARNING = 0x80,
2.53 frystyk 439: HT_S_WWW_AUTH = 0x100,
440: HT_S_TRAILER = 0x200
2.16 frystyk 441: } HTRsHd;
442:
443: #define DEFAULT_RESPONSE_HEADERS HT_S_SERVER
444:
445: extern void HTRequest_setRsHd (HTRequest * request, HTRsHd rshd);
446: extern void HTRequest_addRsHd (HTRequest * request, HTRsHd rshd);
2.69 ! kirschpi 447: extern HTRsHd HTRequest_rsHd (HTRequest * request);</pre>
! 448:
! 449: <h3><a name="enhd">Entity Header Mask</a></h3>
! 450:
! 451: <p>The entity headers contain information about the object sent in the HTTP
! 452: transaction. See the <a href="HTAnchor.html">Anchor module</a>, for the
! 453: storage of entity headers. This flag defines which headers are to be sent in
! 454: a request together with an entity body. All headers are optional but the
! 455: default value is <em>ALL ENTITY HEADERS IF PRESENT</em></p>
! 456: <pre>typedef enum _HTEnHd {
2.37 frystyk 457: HT_E_ALLOW = 0x1,
458: HT_E_CONTENT_BASE = 0x2,
459: HT_E_CONTENT_ENCODING = 0x4,
460: HT_E_CONTENT_LANGUAGE = 0x8,
461: HT_E_CONTENT_LENGTH = 0x10,
462: HT_E_CONTENT_LOCATION = 0x20,
463: HT_E_CONTENT_MD5 = 0x40,
464: HT_E_CONTENT_RANGE = 0x80,
465: HT_E_CTE = 0x100, /* Content-Transfer-Encoding */
466: HT_E_CONTENT_TYPE = 0x200,
467: HT_E_DERIVED_FROM = 0x400,
468: HT_E_ETAG = 0x800,
469: HT_E_EXPIRES = 0x1000,
470: HT_E_LAST_MODIFIED = 0x2000,
471: HT_E_LINK = 0x4000,
472: HT_E_TITLE = 0x8000,
473: HT_E_URI = 0x10000,
474: HT_E_VERSION = 0x20000
2.1 frystyk 475: } HTEnHd;
476:
2.66 frystyk 477: #define DEFAULT_ENTITY_HEADERS 0xFFFFFFFF /* all */
2.1 frystyk 478:
479: extern void HTRequest_setEnHd (HTRequest *request, HTEnHd enhd);
480: extern void HTRequest_addEnHd (HTRequest *request, HTEnHd enhd);
2.69 ! kirschpi 481: extern HTEnHd HTRequest_enHd (HTRequest *request);</pre>
! 482:
! 483: <h2><a name="extra">Extending The Default Set Of Header Fields</a></h2>
! 484:
! 485: <p>See also how to <a href="#default">set up default header fields</a>. There
! 486: are three ways to extend the set of headers that are sent in a request:</p>
! 487: <ol>
! 488: <li>A simple <a href="HTAssoc.html">association list</a></li>
! 489: <li>A <a href="HTHeader.html">stream oriented approach where the stream
! 490: (called a generator)</a> has direct access to the outgoing stream. That
! 491: is, it can add any header it likes.</li>
! 492: <li><a href="/Protocols/HTTP/ietf-http-ext/">HTTP extension mechanism</a>
! 493: which is a much better way for handling extensions.</li>
! 494: </ol>
! 495:
! 496: <h3>1) Simple Association List</h3>
! 497:
! 498: <p>Add the (name, value) and it will be converted into MIME header format as
! 499: name: value. Do NOT add <tt>CRLF</tt> line termination - this is done by the
! 500: HTTP header generator stream</p>
! 501: <pre>extern BOOL HTRequest_addExtraHeader (HTRequest * request,
2.66 frystyk 502: char * token, char * value);
503: extern HTAssocList * HTRequest_extraHeader (HTRequest * request);
2.69 ! kirschpi 504: extern BOOL HTRequest_deleteExtraHeaderAll (HTRequest * request);</pre>
! 505:
! 506: <h3>2) Stream Oriented Header Generators</h3>
! 507:
! 508: <p>Extra header information can be send along with a request using <a
! 509: href="HTHeader.html">header generators</a>. The text is sent as is so it must
! 510: be preformatted with <tt>CRLF</tt> line terminators. You can also register <a
! 511: href="HTHeader.html">MIME header parsers</a> using the HTHeader module.</p>
! 512: <pre>extern void HTRequest_setGenerator (HTRequest *request, HTList *gens,
2.66 frystyk 513: BOOL override);
2.69 ! kirschpi 514: extern HTList * HTRequest_generator (HTRequest *request, BOOL *override);</pre>
! 515:
! 516: <h3>3) HTTP Extension Framework</h3>
! 517:
! 518: <p>These association lists contain the information that we are to send as
! 519: HTTP Extension Framework. This is not done yet but you can find some hints in
! 520: the PEP module</p>
! 521: <pre>/* TBD */</pre>
! 522:
! 523: <h2><a name="Accept">User And Application Preferences Using Accept
! 524: Headers</a></h2>
! 525:
! 526: <p>The Accept family of headers is an important part of HTTP handling the
! 527: format negotiation. The Library supports both a global set of accept headers
! 528: that are used in <em>all</em> HTTP requests and a local set of accept headers
2.47 frystyk 529: that are used in specific requests only. The global ones are defined in the
2.69 ! kirschpi 530: <a href="HTFormat.html">Format Manager</a>.</p>
! 531:
! 532: <p>Each request can have its local set of accept headers that either are
! 533: added to the global set or replaces the global set of accept headers. Non of
! 534: the headers <em>have</em> to be set. If the global set is sufficient for all
! 535: requests then this us perfectly fine. If the parameter "override" is set then
! 536: only local accept headers are used, else <em>both</em> local and global
! 537: headers are used.</p>
! 538:
! 539: <h3>Content Types</h3>
! 540:
! 541: <p>The <em>local</em> list of specific conversions which the format manager
! 542: can do in order to fulfill the request. It typically points to a list set up
! 543: on initialisation time for example by <a href="HTInit.html">HTInit()</a>.
! 544: There is also a <a href="HTFormat.html#z17"><em>global</em></a> list of
! 545: conversions which contains a generic set of possible conversions.</p>
! 546: <pre>extern void HTRequest_setConversion (HTRequest *request, HTList *type, BOOL override);
! 547: extern HTList * HTRequest_conversion (HTRequest *request);</pre>
! 548:
! 549: <h3>Content Encodings</h3>
! 550:
! 551: <p>The list of encodings acceptable in the output stream.</p>
! 552: <pre>extern void HTRequest_setEncoding (HTRequest *request, HTList *enc, BOOL override);
! 553: extern HTList * HTRequest_encoding (HTRequest *request);</pre>
! 554:
! 555: <h3>Transfer Encodings</h3>
! 556:
! 557: <p>The list of transfer encodings acceptable in the output stream.</p>
! 558: <pre>extern void HTRequest_setTransfer (HTRequest *request, HTList *te, BOOL override);
! 559: extern HTList * HTRequest_transfer (HTRequest *request);</pre>
! 560:
! 561: <h3>Content Languages</h3>
! 562:
! 563: <p>The list of (human) language values acceptable in the response. The
! 564: default is all languages.</p>
! 565: <pre>extern void HTRequest_setLanguage (HTRequest *request, HTList *lang, BOOL override);
! 566: extern HTList * HTRequest_language (HTRequest *request);</pre>
! 567:
! 568: <h3>Content Charsets</h3>
! 569:
! 570: <p>The list of charsets accepted by the application</p>
! 571: <pre>extern void HTRequest_setCharset (HTRequest *request, HTList *charset, BOOL override);
! 572: extern HTList * HTRequest_charset (HTRequest *request);</pre>
! 573:
! 574: <h2><a name="Cache">HTTP Cache Validation and Cache Control</a></h2>
! 575:
! 576: <p>The Library has two concepts of caching: in memory and on file. When
! 577: loading a document, this flag can be set in order to define who can give a
! 578: response to the request. The memory buffer is considered to be equivalent to
! 579: a history buffer. That is, it doesn't not follow the same expiration
! 580: mechanism that is characteristic for a persistent file cache.</p>
! 581:
! 582: <p>You can also set the cache to run in disconnected mode - see the <a
! 583: href="HTCache.html">Cache manager</a> for more details on how to do this.</p>
! 584: <pre>typedef enum _HTReload {
2.47 frystyk 585: HT_CACHE_OK = 0x0, /* Use any version available */
586: HT_CACHE_FLUSH_MEM = 0x1, /* Reload from file cache or network */
587: HT_CACHE_VALIDATE = 0x2, /* Validate cache entry */
588: HT_CACHE_END_VALIDATE = 0x4, /* End to end validation */
589: HT_CACHE_RANGE_VALIDATE = 0x8,
2.52 frystyk 590: HT_CACHE_FLUSH = 0x10, /* Force full reload */
591: HT_CACHE_ERROR = 0x20 /* An error occurred in the cache */
2.47 frystyk 592: } HTReload;
593:
594: extern void HTRequest_setReloadMode (HTRequest *request, HTReload mode);
2.69 ! kirschpi 595: extern HTReload HTRequest_reloadMode (HTRequest *request);</pre>
! 596:
! 597: <h2>Default PUT name</h2>
! 598:
! 599: <p>When publishing to a server which doesn't accept a URL ending in "/", e.g,
2.67 kahan 600: the default Overview, index page, you can use
2.69 ! kirschpi 601: <code>HTRequest_setAltPutName</code> to setup the intended URL. If this
2.67 kahan 602: variable is defined, it'll be used during the cache lookup and update
2.69 ! kirschpi 603: operationsm, so that cache-wise, it will look as if we had published only to
! 604: "/".</p>
! 605: <pre>extern char * HTRequest_defaultPutName (HTRequest * me);
2.67 kahan 606: extern BOOL HTRequest_setDefaultPutName (HTRequest * me, char * name);
2.69 ! kirschpi 607: extern BOOL HTRequest_deleteDefaultPutName (HTRequest * me);</pre>
! 608:
! 609: <h3>HTTP Cache Control Directives</h3>
! 610:
! 611: <p>The cache control directives are all part of the cache control header and
! 612: control the behavior of any intermediate cache between the user agent and the
! 613: origin server. This association list is a list of the connection control
! 614: directives that are to be sent as part of the <code>Cache-Control</code>
! 615: header.</p>
! 616: <pre>extern BOOL HTRequest_addCacheControl (HTRequest * request,
2.47 frystyk 617: char * token, char *value);
618: extern BOOL HTRequest_deleteCacheControlAll (HTRequest * request);
2.69 ! kirschpi 619: extern HTAssocList * HTRequest_cacheControl (HTRequest * request);</pre>
! 620:
! 621: <h2><a name="Date">Date and Time Stamp when Request was Issued</a></h2>
! 622:
! 623: <p>The start time when the request was issued may be of value to the cache
! 624: validation mechanism as described by the HTTP/1.1 specification. The value is
! 625: automatically set when creating the request headers and sending off the
! 626: request. The time is a local time.</p>
! 627: <pre>extern time_t HTRequest_date (HTRequest * request);
! 628: extern BOOL HTRequest_setDate (HTRequest * request, time_t date);</pre>
! 629:
! 630: <h2><a name="Expect">HTTP Expect Directives</a></h2>
! 631:
! 632: <p>The Expect request-header field is used to indicate that particular server
! 633: behaviors are required by the client. A server that does not understand or is
! 634: unable to comply with any of the expectation values in the Expect field of a
! 635: request MUST respond with appropriate error status.</p>
! 636: <pre>extern BOOL HTRequest_addExpect (HTRequest * me,
2.53 frystyk 637: char * token, char * value);
638: extern BOOL HTRequest_deleteExpect (HTRequest * me);
2.69 ! kirschpi 639: extern HTAssocList * HTRequest_expect (HTRequest * me);</pre>
! 640:
! 641: <h2><a name="Partial">Partial Requests and Range Retrievals</a></h2>
! 642:
! 643: <p>Libwww can issue range requests in case we have already obtained a part of
! 644: the entity body. Since all HTTP entities are represented in HTTP messages as
! 645: sequences of bytes, the concept of a byte range is meaningful for any HTTP
! 646: entity. (However, not all clients and servers need to support byte-range
2.47 frystyk 647: operations.) Byte range specifications in HTTP apply to the sequence of bytes
648: in the entity-body (not necessarily the same as the message-body). A byte
2.69 ! kirschpi 649: range operation may specify a single range of bytes, or a set of ranges
! 650: within a single entity.</p>
! 651: <pre>extern BOOL HTRequest_addRange (HTRequest * request,
2.47 frystyk 652: char * unit, char * range);
653: extern BOOL HTRequest_deleteRangeAll (HTRequest * request);
2.69 ! kirschpi 654: extern HTAssocList * HTRequest_range (HTRequest * request);</pre>
! 655:
! 656: <h2><a name="Connection">HTTP Connection Control Request Directives</a></h2>
! 657:
! 658: <p>The connection control directives are all part of the connection header
! 659: and control the behavior of this connection. This association list is a list
2.47 frystyk 660: of the connection control directives that are to be sent as part of the
2.69 ! kirschpi 661: <code>Connection</code> header.</p>
! 662: <pre>extern BOOL HTRequest_addConnection (HTRequest * request,
2.47 frystyk 663: char * token, char * value);
664: extern BOOL HTRequest_deleteConnection (HTRequest * request);
2.69 ! kirschpi 665: extern HTAssocList * HTRequest_connection (HTRequest * request);</pre>
! 666:
! 667: <h2><a name="Access">HTTP Access Authentication Credentials</a></h2>
! 668:
! 669: <p>When a access denied response is returned to the Library, for example from
2.47 frystyk 670: a remote HTTP server, this code is passed back to the application. The
671: application can then decide whether a new request should be established or
672: not. These two methods return the authentication information required to
2.69 ! kirschpi 673: issue a new request, that is the new anchor and any list of keywords
! 674: associated with this anchor.</p>
! 675: <pre>extern BOOL HTRequest_addCredentials (HTRequest * request,
2.47 frystyk 676: char * token, char * value);
677: extern BOOL HTRequest_deleteCredentialsAll (HTRequest * request);
2.69 ! kirschpi 678: extern HTAssocList * HTRequest_credentials (HTRequest * request);</pre>
! 679:
! 680: <h3>Realms</h3>
! 681:
! 682: <p>The realm is normally set and used by the authentication filters.</p>
! 683: <pre>extern BOOL HTRequest_setRealm (HTRequest * request, char * realm);
2.47 frystyk 684: extern const char * HTRequest_realm (HTRequest * request);
2.69 ! kirschpi 685: extern BOOL HTRequest_deleteRealm (HTRequest * me);</pre>
! 686:
! 687: <h2><a name="Referer">HTTP Referer Field</a></h2>
! 688:
! 689: <p>If this parameter is set then a `Referer: <parent address> can be
! 690: generated in the request to the server, see <a
! 691: href="http://www.w3.org/Protocols/">Referer field in a HTTP Request</a></p>
! 692: <pre>extern void HTRequest_setParent (HTRequest *request, HTParentAnchor *parent);
! 693: extern HTParentAnchor * HTRequest_parent (HTRequest *request);</pre>
! 694:
! 695: <h2><a name="before">Local BEFORE and AFTER Filters</a></h2>
! 696:
! 697: <p>The request object may have it's own before and after <a
! 698: href="HTFilter.html">filters</a>. These may override or suplement the global
! 699: set in <a href="HTNet.html">HTNet</a>. The request object itself handles the
! 700: list element, that is this should not be freed bu the caller.</p>
! 701:
! 702: <h3>BEFORE Filters</h3>
! 703:
! 704: <p>The BEFORE <a href="HTFilter.html">filters</a> are called just after the
2.47 frystyk 705: request has been passed to the Library but before any request is issued over
2.69 ! kirschpi 706: the network. A BEFORE can infact stop a request completely from being
! 707: processed.</p>
! 708:
! 709: <h4>Add a local BEFORE Filter</h4>
! 710:
! 711: <p>You can add a local <i>BEFORE</i> filter for a single request so that the
! 712: both the local and global <i>BEFORE</i> filters are called or you can replace
2.47 frystyk 713: the global filters with a local set. Note that the local set can be NULL.
2.69 ! kirschpi 714: This can be used to effectively disable all <i>BEFORE</i> filters without
! 715: unregistering the global ones.</p>
! 716: <pre>extern BOOL HTRequest_addBefore (HTRequest * request, HTNetBefore * filter,
2.47 frystyk 717: const char * tmplate, void * param,
2.48 frystyk 718: HTFilterOrder order, BOOL override);
2.69 ! kirschpi 719: extern HTList * HTRequest_before (HTRequest * request, BOOL * override);</pre>
! 720:
! 721: <h4>Delete a Local BEFORE Filter</h4>
! 722:
! 723: <p>You can delete a local BEFORE filter explicitly by passing the filter
! 724: itself or you can delete all filters which are registered for a certain
! 725: status code.</p>
! 726: <pre>extern BOOL HTRequest_deleteBefore (HTRequest * request, HTNetBefore * filter);
! 727: extern BOOL HTRequest_deleteBeforeAll (HTRequest * request);</pre>
! 728:
! 729: <h3>AFTER Filters</h3>
! 730:
! 731: <p>You can add a local AFTER filter for a single request so that the both the
! 732: local and global AFTER filters are called or you can replace the global
! 733: filters with a local set. Note that the local set can be NULL. This can be
! 734: used to effectively disable all AFTER filters without unregistering the
! 735: global ones.</p>
! 736:
! 737: <p>AFTER filters can be registered to handle a certain set of return values
2.47 frystyk 738: from the protocol modules, for example explicitly to handle redirection,
739: authentication, etc. You can find all the available codes in the HTNet object
2.69 ! kirschpi 740: description.</p>
! 741:
! 742: <h4>Add a local AFTER Filter</h4>
! 743: <pre>extern BOOL HTRequest_addAfter (HTRequest * request, HTNetAfter * filter,
2.47 frystyk 744: const char * tmplate, void * param,
2.48 frystyk 745: int status, HTFilterOrder order,
746: BOOL override);
2.69 ! kirschpi 747: extern HTList * HTRequest_after (HTRequest * request, BOOL * override);</pre>
! 748:
! 749: <h4>Delete an AFTER Filter</h4>
! 750:
! 751: <p>You can delete a local AFTER filter explicitly by passing the filter
! 752: itself or you can delete all filters which are registered for a certain
! 753: status code.</p>
! 754: <pre>extern BOOL HTRequest_deleteAfter (HTRequest * request, HTNetAfter * filter);
2.47 frystyk 755: extern BOOL HTRequest_deleteAfterStatus (HTRequest * request, int status);
2.69 ! kirschpi 756: extern BOOL HTRequest_deleteAfterAll (HTRequest * request);</pre>
! 757:
! 758: <h2><a name="App2Net">Sending data from App to Network</a></h2>
! 759:
! 760: <p>Multiple Request objects can be connected in order to create a <a
! 761: href="../User/Architecture/PostWeb.html">PostWeb</a> for sending data from
! 762: one location (source) to another (destination). Request objects are bound
! 763: together by connecting the output stream of the source with the input stream
! 764: of the destination requst. The connection can be done directly so that the
! 765: output from the source is exactly what is sent to the destination or there
! 766: can be a conversion between the two streams so that we can do conversions on
! 767: the fly while copying data. This is in fact the way we use for building a
! 768: proxy server.</p>
! 769:
! 770: <p>The Library supports two ways of posting a data object to a remote
! 771: destination: Input comes from a socket descriptor or from memory. In the case
! 772: where you want to <em>copy</em> a URL, for example from local file system
! 773: <em>or</em> from a remote HTTP server then you must use the <a
! 774: href="../User/Architecture/PostWeb.html">PostWeb design</a>. This model
2.30 frystyk 775: operates by using at least two request objects which gets linked to eachother
2.33 frystyk 776: as part of the PostWeb model. However, if you are posting from memory, we
2.69 ! kirschpi 777: only use <em>one</em> request object to perform the operation. In order to do
! 778: this, the application must register a callback function that can be called
! 779: when the <a href="HTTP.c">HTTP client module</a> is ready for accepting data.
! 780: be included as part of the body and/or as extra metainformation. In the
! 781: latter case you need to register a callback function of the following type
! 782: using the methods provided in the next section.</p>
! 783: <pre>typedef int HTPostCallback (HTRequest * request, HTStream * target);
2.33 frystyk 784:
785: extern void HTRequest_setPostCallback (HTRequest * request, HTPostCallback * cbf);
2.69 ! kirschpi 786: extern HTPostCallback * HTRequest_postCallback (HTRequest * request);</pre>
! 787:
! 788: <p>The Entity Anchor is either the anchor directly associated with the
! 789: Request object or the post anchor associated with the object. The purpose of
! 790: the entity anchor is if we are to send data to a remote server then we get
! 791: the metainformation using the entity anchor.</p>
! 792: <pre>extern BOOL HTRequest_setEntityAnchor (HTRequest * request, HTParentAnchor * anchor);
! 793: extern HTParentAnchor * HTRequest_entityAnchor (HTRequest * request);</pre>
! 794:
! 795: <h3>Input Stream</h3>
! 796:
! 797: <p>The input stream is to be used to put data <em>to</em> the network.
! 798: Normally each protocol sets the input stream in order to generate the
! 799: protocol headers while making a request.</p>
! 800: <pre>extern void HTRequest_setInputStream (HTRequest * request, HTStream * input);
! 801: extern HTStream *HTRequest_inputStream (HTRequest * request);</pre>
! 802:
! 803: <h3>Is This Request part of a Post Web? (Deprecated)</h3>
! 804:
! 805: <p>Check to see if this request object is part of a Post Web.</p>
! 806: <pre>extern BOOL HTRequest_isPostWeb (HTRequest * request);</pre>
! 807:
! 808: <h3>Source of a Request</h3>
! 809:
! 810: <p>A request may have a source in which is another request object that as
! 811: output stream has the input stream of this request object.</p>
! 812: <pre>extern BOOL HTRequest_setSource (HTRequest * request, HTRequest * source);
! 813: extern HTRequest * HTRequest_source (HTRequest * request);</pre>
! 814:
! 815: <h2><a name="Net2App">Streams From Network to Application</a></h2>
! 816:
! 817: <h3>Default Output Stream</h3>
! 818:
! 819: <p>The output stream is to be used to put data down to as they come in
! 820: <b>from</b> the network and back to the application. The default value is
! 821: <code>NULL</code> which means that the stream goes to the user (display).</p>
! 822: <pre>extern void HTRequest_setOutputStream (HTRequest *request, HTStream *output);
! 823: extern HTStream *HTRequest_outputStream (HTRequest *request);</pre>
! 824:
! 825: <h3>Default Output Stream Format</h3>
! 826:
! 827: <p>The desired format of the output stream. This is used in the <a
! 828: href="HTFormat.html">stream stack builder</a> to determine which stream to
! 829: plug in to deal with the data. If <code>NULL</code>, then <a
! 830: href="HTFormat.html#FormatTypes">WWW_PRESENT</a> is default value.</p>
! 831: <pre>extern void HTRequest_setOutputFormat (HTRequest *request, HTFormat format);
! 832: extern HTFormat HTRequest_outputFormat (HTRequest *request);</pre>
! 833:
! 834: <h3>Has Output Stream been Connected to Channel? (Deprecated)</h3>
! 835:
! 836: <p>Has output stream been connected to the channel? If not then we must free
! 837: it explicitly when deleting the request object</p>
! 838: <pre>extern void HTRequest_setOutputConnected (HTRequest * request, BOOL mode);
! 839: extern BOOL HTRequest_outputConnected (HTRequest * request);</pre>
! 840:
! 841: <h3>Default Debug Stream</h3>
! 842:
! 843: <p>All object bodies sent from the server with status codes different from
! 844: <code>200 OK</code> will be put down this stream. This can be used for
2.30 frystyk 845: redirecting body information in status codes different from "200 OK" to for
2.69 ! kirschpi 846: example a debug window. If the value is NULL (default) then the stream is not
! 847: set up.</p>
! 848: <pre>extern void HTRequest_setDebugStream (HTRequest *request, HTStream *debug);
! 849: extern HTStream *HTRequest_debugStream (HTRequest *request);</pre>
! 850:
! 851: <h3>Default Debug Stream Format</h3>
! 852:
! 853: <p>The desired format of the error stream. This can be used to get
! 854: unconverted data etc. from the library. The default value if
! 855: <code>WWW_HTML</code> as a character based only has one WWW_PRESENT.</p>
! 856: <pre>extern void HTRequest_setDebugFormat (HTRequest *request, HTFormat format);
! 857: extern HTFormat HTRequest_debugFormat (HTRequest *request);</pre>
! 858:
! 859: <h2><a name="context">Context Swapping</a></h2>
! 860:
! 861: <p>In multi threaded applications it is often required to keep track of the
2.30 frystyk 862: context of a request so that when the Library returns a result of a request,
863: it can be put into the context it was in before the request was first passed
2.69 ! kirschpi 864: to the Library. This call back function allows the application to do this.</p>
! 865: <pre>typedef int HTRequestCallback (HTRequest * request, void *param);
2.1 frystyk 866:
867: extern void HTRequest_setCallback (HTRequest *request, HTRequestCallback *cb);
2.69 ! kirschpi 868: extern HTRequestCallback *HTRequest_callback (HTRequest *request);</pre>
! 869:
! 870: <p>The callback function can be passed an arbitrary pointer (the void part)
2.30 frystyk 871: which can describe the context of the current request structure. If such
2.69 ! kirschpi 872: context information is required then it can be set using the following
! 873: methods:</p>
! 874: <pre>extern void HTRequest_setContext (HTRequest *request, void *context);
! 875: extern void *HTRequest_context (HTRequest *request);</pre>
! 876:
! 877: <h2><a name="FullURI">Should we Issue a full HTTP Request-URI?</a></h2>
! 878:
! 879: <p>In early versions of HTTP, the request sent to the remote server varies
! 880: whether we use a proxy or go directly to the origin server. The default value
! 881: is <em>OFF</em> but we use a full request if we are talking to a proxy
! 882: server.</p>
! 883: <pre>extern void HTRequest_setFullURI (HTRequest *request, BOOL mode);
! 884: extern BOOL HTRequest_fullURI (HTRequest *request);</pre>
! 885:
! 886: <h2><a name="Proxies">Handling Proxies</a></h2>
! 887:
! 888: <p>In case we are using a proxy for this requst then we can register it
! 889: together with the request object. That way we can find the proxy and look for
! 890: authentication information, for example in the <a
! 891: href="HTAAUtil.html">Authentication filter</a>. The string is freed by the
! 892: Request object on deletion. This is normally handled automatically by the <a
! 893: href="HTProxy.html">proxy and gateway module</a></p>
! 894: <pre>extern BOOL HTRequest_setProxy (HTRequest * request, const char * proxy);
2.43 frystyk 895: extern char * HTRequest_proxy (HTRequest * request);
2.69 ! kirschpi 896: extern BOOL HTRequest_deleteProxy (HTRequest * request);</pre>
! 897:
! 898: <p></p>
! 899:
! 900: <h2>Message Body Manipulation</h2>
! 901:
! 902: <p>An application may use these functions to set and manipulate the request
! 903: message body. This message body is specially indicate for methods that use
! 904: small XML message bodies. Once the application define it, this message body
! 905: will be send just after the headers. It <strong> does not</strong> use
! 906: "<strong>Expect: 100-continue</strong>" header, and the application
! 907: <strong>should not</strong> try to use both. It's important to remark that
! 908: "Expect: 100-continue" header is a very importante feature defined in HTTP.
! 909: It's prevents that, for example, the server must read many unnecessary bytes
! 910: from request body. Using "Expect: 100-continue" header, your application
! 911: safes time and network (see <a
! 912: href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>, section 8.2.3).
! 913: Please, if possible, use always HTRequest Entity and entity callback, leave
! 914: this only for small XML bodies in extension methods (see <a
! 915: href="HTMethod.html">HTMethod</a>), and when using it, <strong>be very
! 916: careful</strong>!</p>
! 917:
! 918: <p>When using a message body, the application may define its length and
! 919: format. If the message body is set and its length is also set and it greater
! 920: than 0, a Content-Lenght header will be added to the request, and if the
! 921: message body and its type are set. Otherwise, those header will not be
! 922: included, a Content-Type header will be added to the request too.</p>
! 923:
! 924: <p><strong>Note</strong>: The caller should free the string returned by
! 925: HTRequest_messageBody function!</p>
! 926: <pre>#if defined(HT_EXT)
! 927: extern BOOL HTRequest_setMessageBody (HTRequest * request, const char * body);
! 928: extern BOOL HTRequest_deleteMessageBody (HTRequest * request);
! 929: extern char * HTRequest_messageBody (HTRequest * request);
! 930:
! 931: extern BOOL HTRequest_setMessageBodyLength (HTRequest * request, long int length);
! 932: extern long int HTRequest_messageBodyLength (HTRequest * request);
! 933:
! 934: extern BOOL HTRequest_setMessageBodyFormat (HTRequest * request, HTFormat format);
! 935: extern HTFormat HTRequest_messageBodyFormat (HTRequest * request);
! 936:
! 937: #endif</pre>
! 938:
! 939: <p></p>
! 940:
! 941: <p></p>
! 942:
! 943: <h2><a name="Count">Bytes Read or Written in a Request</a></h2>
! 944:
! 945: <p>This function returns the bytes read in the current request. For a deeper
2.30 frystyk 946: description of what the current request is, please read the user's guide.
2.69 ! kirschpi 947: This function can be used in for example the <a href="HTAlert.html">HTAlert
! 948: module</a> to give the number of bytes read or written in a progress
! 949: message.</p>
! 950: <pre>extern long HTRequest_bodyRead (HTRequest * request);
! 951: extern long HTRequest_bodyWritten (HTRequest * request);</pre>
! 952:
! 953: <p>You can also get the total number of bytes read or written including the
! 954: headers</p>
! 955: <pre>extern long HTRequest_bytesRead (HTRequest * request);
! 956: extern long HTRequest_bytesWritten (HTRequest * request);</pre>
! 957: <pre>#endif /* HTREQ_H */</pre>
! 958:
! 959: <p></p>
! 960: <hr>
! 961: <address>
! 962: @(#) $Id: HTReq.html,v 2.68 2000/07/12 10:44:41 kahan Exp $
! 963: </address>
! 964: </body>
! 965: </html>
Webmaster