Annotation of libwww/Library/src/HTReqMan.c, revision 2.73

2.1       frystyk     1: /*                                                                  HTReqMan.c
                      2: **     REQUEST MANAGER
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.73    ! frystyk     6: **     @(#) $Id: HTReqMan.c,v 2.72 1998/11/19 17:14:39 frystyk Exp $
2.1       frystyk     7: **
                      8: ** Authors
                      9: **     TBL     Tim Berners-Lee timbl@w3.org
                     10: **     JFG     Jean-Francois Groff jfg@dxcern.cern.ch
                     11: **     DD      Denis DeLaRoca (310) 825-4580  <CSP1DWD@mvs.oac.ucla.edu>
                     12: **     HFN     Henrik Frystyk, frystyk@w3.org
                     13: ** History
                     14: **       8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL
                     15: **     26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG
                     16: **      6 Oct 92 Moved HTClientHost and HTlogfile into here. TBL
                     17: **     17 Dec 92 Tn3270 added, bug fix. DD
                     18: **      4 Feb 93 Access registration, Search escapes bad chars TBL
                     19: **               PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED
                     20: **     28 May 93 WAIS gateway explicit if no WAIS library linked in.
                     21: **        Dec 93 Bug change around, more reentrant, etc
                     22: **     09 May 94 logfile renamed to HTlogfile to avoid clash with WAIS
                     23: **      8 Jul 94 Insulate free() from _free structure element.
                     24: **     02 Sep 95 Rewritten and spawned from HTAccess.c, HFN
                     25: */
                     26: 
                     27: #if !defined(HT_DIRECT_WAIS) && !defined(HT_DEFAULT_WAIS_GATEWAY)
                     28: #define HT_DEFAULT_WAIS_GATEWAY "http://www.w3.org:8001/"
                     29: #endif
                     30: 
                     31: /* Library include files */
2.67      frystyk    32: #include "wwwsys.h"
2.40      frystyk    33: #include "WWWUtil.h"
2.1       frystyk    34: #include "HTParse.h"
                     35: #include "HTAlert.h"
                     36: #include "HTError.h"
2.2       frystyk    37: #include "HTNetMan.h"
2.39      frystyk    38: #include "HTEvent.h"
2.1       frystyk    39: #include "HTProt.h"
2.43      eric       40: #include "HTHeader.h"
2.46      frystyk    41: #include "HTLib.h"
2.1       frystyk    42: #include "HTReqMan.h"                                   /* Implemented here */
                     43: 
                     44: #ifndef HT_MAX_RELOADS
                     45: #define HT_MAX_RELOADS 6
                     46: #endif
2.13      frystyk    47: 
2.1       frystyk    48: PRIVATE int HTMaxRetry = HT_MAX_RELOADS;
                     49: 
                     50: struct _HTStream {
                     51:        HTStreamClass * isa;
                     52:        /* ... */
                     53: };
                     54: 
                     55: /* --------------------------------------------------------------------------*/
2.59      frystyk    56: /*                     Create and delete the HTRequest Object               */
2.1       frystyk    57: /* --------------------------------------------------------------------------*/
                     58: 
2.3       frystyk    59: PUBLIC HTRequest * HTRequest_new (void)
2.1       frystyk    60: {
2.29      frystyk    61:     HTRequest * me;
                     62:     if ((me = (HTRequest *) HT_CALLOC(1, sizeof(HTRequest))) == NULL)
                     63:         HT_OUTOFMEM("HTRequest_new()");
2.1       frystyk    64:     
2.7       frystyk    65:    /* Force Reload */
2.56      frystyk    66:     me->reload = HT_CACHE_OK;
2.1       frystyk    67: 
2.40      frystyk    68:     /* Set the default user profile */
                     69:     me->userprofile = HTLib_userProfile();
                     70: 
2.1       frystyk    71:     /* Format of output */
                     72:     me->output_format  = WWW_PRESENT;      /* default it to present to user */
2.21      frystyk    73:     me->debug_format   = WWW_DEBUG;     /* default format of error messages */
2.1       frystyk    74: 
                     75:     /* HTTP headers */
                     76:     me->GenMask                = DEFAULT_GENERAL_HEADERS;
                     77:     me->RequestMask    = DEFAULT_REQUEST_HEADERS;
2.22      frystyk    78:     me->ResponseMask   = DEFAULT_RESPONSE_HEADERS;
2.1       frystyk    79:     me->EntityMask     = DEFAULT_ENTITY_HEADERS;
                     80: 
                     81:     /* Default retry after value */
2.19      frystyk    82:     me->priority = HT_PRIORITY_MAX;
2.1       frystyk    83: 
2.54      frystyk    84:     /* Default max forward value */
                     85:     me->max_forwards = -1;
                     86: 
2.1       frystyk    87:     /* Content negotiation */
2.45      frystyk    88:     me->ContentNegotiation = YES;                     /* Do this by default */
2.1       frystyk    89: 
2.47      frystyk    90:     if (CORE_TRACE) HTTrace("Request..... Created %p\n", me);
                     91: 
2.1       frystyk    92:     return me;
                     93: }
                     94: 
2.28      frystyk    95: /*     HTRequest_clear
                     96: **     ---------------
                     97: **     Clears all protocol specific information so that the request object
                     98: **     can be used for another request.
                     99: **     Returns YES if OK, else NO
                    100: */
                    101: PUBLIC BOOL HTRequest_clear (HTRequest * me)
                    102: {
                    103:     if (me) {
                    104:        me->error_stack = NULL;
                    105:        me->net = NULL;
2.49      frystyk   106:        me->realm = NULL;
2.31      frystyk   107:        me->credentials = NULL;
2.47      frystyk   108:        me->connected = NO;
2.59      frystyk   109:        if (me->response) {
                    110:            HTResponse_delete(me->response);
                    111:            me->response = NULL;
                    112:        }
2.28      frystyk   113:        return YES;
                    114:     }
                    115:     return NO;
                    116: }
                    117: 
2.18      frystyk   118: /*     HTRequest_dup
                    119: **     -------------
                    120: **     Creates a new HTRequest object as a duplicate of the src request.
                    121: **     Returns YES if OK, else NO
                    122: */
                    123: PUBLIC HTRequest * HTRequest_dup (HTRequest * src)
                    124: {
                    125:     HTRequest * me;
2.47      frystyk   126:     if (!src) return NULL;
2.29      frystyk   127:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    128:         HT_OUTOFMEM("HTRequest_dup");
2.18      frystyk   129:     memcpy(me, src, sizeof(HTRequest));
2.47      frystyk   130:     if (CORE_TRACE) HTTrace("Request..... Duplicated %p to %p\n", src, me);
2.18      frystyk   131:     return me;
                    132: }
2.1       frystyk   133: 
2.23      frystyk   134: /*     HTRequest_dupInternal
                    135: **     ---------------------
                    136: **     Creates a new HTRequest object as a duplicate of the src request.
                    137: **     The difference to the HTRequest_dup function is that we don't copy the
                    138: **     error_stack and other information that the application keeps in its
                    139: **     copy of the request object. Otherwise it will be freed multiple times
                    140: **     Returns YES if OK, else NO
                    141: */
                    142: PUBLIC HTRequest * HTRequest_dupInternal (HTRequest * src)
                    143: {
                    144:     HTRequest * me;
2.33      eric      145:     if (!src) return 0;
2.29      frystyk   146:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    147:         HT_OUTOFMEM("HTRequest_dup");
2.23      frystyk   148:     memcpy(me, src, sizeof(HTRequest));
2.28      frystyk   149:     HTRequest_clear(me);
2.23      frystyk   150:     return me;
                    151: }
                    152: 
2.59      frystyk   153: PUBLIC void HTRequest_delete (HTRequest * me)
2.1       frystyk   154: {
2.59      frystyk   155:     if (me) {
                    156:        if (CORE_TRACE) HTTrace("Request..... Delete %p\n", me);
                    157:        if (me->net) HTNet_setRequest(me->net, NULL);
2.47      frystyk   158: 
                    159:        /* Should we delete the output stream? */
2.59      frystyk   160:        if (!me->connected && me->output_stream) {
2.47      frystyk   161:            if (CORE_TRACE)
                    162:                HTTrace("Request..... Deleting dangling output stream\n");
2.59      frystyk   163:            (*me->output_stream->isa->_free)(me->output_stream);
                    164:            me->output_stream = NULL;
2.47      frystyk   165:        }
                    166: 
                    167:        /* Clean up the error stack */
2.59      frystyk   168:        if (me->error_stack) HTError_deleteAll(me->error_stack);
2.13      frystyk   169: 
2.51      frystyk   170:        /* Before and After Filters */
2.65      frystyk   171:        if (me->afters) HTNetCall_deleteAfterAll(me->afters);
                    172:        if (me->befores) HTNetCall_deleteBeforeAll(me->befores);
2.51      frystyk   173: 
2.49      frystyk   174:        /* Access Authentication */
2.59      frystyk   175:        HT_FREE(me->realm);
                    176:        if (me->credentials) HTAssocList_delete(me->credentials);
2.49      frystyk   177: 
2.56      frystyk   178:        /* Cache control headers */
2.59      frystyk   179:        if (me->cache_control)
                    180:            HTAssocList_delete(me->cache_control);
2.57      frystyk   181: 
2.59      frystyk   182:        /* Byte ranges */
                    183:        if (me->byte_ranges) HTAssocList_delete(me->byte_ranges);
2.56      frystyk   184: 
                    185:        /* Connection headers */
2.59      frystyk   186:        if (me->connection) HTAssocList_delete(me->connection);
2.56      frystyk   187: 
2.64      frystyk   188:        /* Connection headers */
                    189:        if (me->expect) HTAssocList_delete(me->expect);
                    190: 
2.53      frystyk   191:        /* Proxy information */
2.59      frystyk   192:        HT_FREE(me->proxy);
2.53      frystyk   193: 
2.49      frystyk   194:        /* PEP Information */
2.59      frystyk   195:        if (me->protocol) HTAssocList_delete(me->protocol);
                    196:        if (me->protocol_request) HTAssocList_delete(me->protocol_request);
                    197:        if (me->protocol_info) HTAssocList_delete(me->protocol_info);
2.49      frystyk   198: 
2.59      frystyk   199:        /* Any response object */
                    200:        if (me->response) HTResponse_delete(me->response);
2.55      frystyk   201: 
2.59      frystyk   202:        HT_FREE(me);
2.1       frystyk   203:     }
                    204: }
                    205: 
                    206: /*
2.59      frystyk   207: **     Kill this request
2.1       frystyk   208: */
2.59      frystyk   209: PUBLIC BOOL HTRequest_kill(HTRequest * me)
2.1       frystyk   210: {
2.59      frystyk   211:     return me ? HTNet_kill(me->net) : NO;
2.1       frystyk   212: }
                    213: 
2.59      frystyk   214: /* --------------------------------------------------------------------------*/
                    215: /*                     Methods on the HTRequest Object                      */
                    216: /* --------------------------------------------------------------------------*/
2.1       frystyk   217: 
                    218: /*
2.59      frystyk   219: **  Internal request object
2.1       frystyk   220: */
2.59      frystyk   221: PUBLIC BOOL HTRequest_setInternal (HTRequest * me, BOOL mode)
2.1       frystyk   222: {
2.59      frystyk   223:     if (me) {
                    224:        me->internal = mode;
                    225:        return YES;
                    226:     }
                    227:     return NO;
2.1       frystyk   228: }
                    229: 
2.59      frystyk   230: PUBLIC BOOL HTRequest_internal (HTRequest * me)
2.1       frystyk   231: {
2.59      frystyk   232:     return (me ? me->internal : NO);
2.62      frystyk   233: }
                    234: 
                    235: /*
                    236: **  Should we flush immediately?
                    237: */
                    238: PUBLIC BOOL HTRequest_setFlush (HTRequest * me, BOOL mode)
                    239: {
                    240:     if (me) {
                    241:        me->flush = mode;
                    242:        return YES;
                    243:     }
                    244:     return NO;
                    245: }
                    246: 
                    247: PUBLIC BOOL HTRequest_flush (HTRequest * me)
                    248: {
                    249:     return (me ? me->flush : NO);
2.1       frystyk   250: }
                    251: 
                    252: /*
2.59      frystyk   253: **     Date/time stamp when then request was issued
                    254: **     This is normally set when generating the request headers.
2.1       frystyk   255: */
2.59      frystyk   256: PUBLIC time_t HTRequest_date (HTRequest * me)
2.1       frystyk   257: {
2.59      frystyk   258:     return me ? me->date : -1;
2.1       frystyk   259: }
                    260: 
2.59      frystyk   261: PUBLIC BOOL HTRequest_setDate (HTRequest * me, time_t date)
2.1       frystyk   262: {
2.59      frystyk   263:     if (me) {
                    264:        me->date = date;
                    265:        return YES;
2.1       frystyk   266:     }
2.59      frystyk   267:     return NO;
2.1       frystyk   268: }
                    269: 
2.37      frystyk   270: /*
2.59      frystyk   271: **     Method
2.37      frystyk   272: */
2.59      frystyk   273: PUBLIC void HTRequest_setMethod (HTRequest * me, HTMethod method)
2.37      frystyk   274: {
2.59      frystyk   275:     if (me) me->method = method;
2.37      frystyk   276: }
                    277: 
2.59      frystyk   278: PUBLIC HTMethod HTRequest_method (HTRequest * me)
2.37      frystyk   279: {
2.59      frystyk   280:     return me ? me->method : METHOD_INVALID;
2.37      frystyk   281: }
                    282: 
2.1       frystyk   283: /*
2.59      frystyk   284: **  Priority to be inherited by all HTNet object hanging off this request
                    285: **  The priority can later be chaned by calling the HTNet object directly
2.1       frystyk   286: */
2.59      frystyk   287: PUBLIC BOOL HTRequest_setPriority (HTRequest * me, HTPriority priority)
2.1       frystyk   288: {
2.59      frystyk   289:     if (me) {
                    290:        me->priority = priority;
                    291:        return YES;
2.1       frystyk   292:     }
2.59      frystyk   293:     return NO;
2.1       frystyk   294: }
                    295: 
2.59      frystyk   296: PUBLIC HTPriority HTRequest_priority (HTRequest * me)
2.1       frystyk   297: {
2.59      frystyk   298:     return (me ? me->priority : HT_PRIORITY_INV);
2.1       frystyk   299: }
                    300: 
                    301: /*
2.59      frystyk   302: **     User Profile
2.1       frystyk   303: */
2.59      frystyk   304: PUBLIC BOOL HTRequest_setUserProfile (HTRequest * me, HTUserProfile * up)
2.1       frystyk   305: {
2.59      frystyk   306:     if (me) {
                    307:        me->userprofile = up;
                    308:        return YES;
2.1       frystyk   309:     }
2.59      frystyk   310:     return NO;
2.1       frystyk   311: }
                    312: 
2.59      frystyk   313: PUBLIC HTUserProfile * HTRequest_userProfile (HTRequest * me)
2.1       frystyk   314: {
2.59      frystyk   315:     return me ? me->userprofile : NULL;
2.1       frystyk   316: }
                    317: 
                    318: /*
2.59      frystyk   319: **     Net Object
2.9       frystyk   320: */
2.59      frystyk   321: PUBLIC BOOL HTRequest_setNet (HTRequest * me, HTNet * net)
2.9       frystyk   322: {
2.59      frystyk   323:     if (me) {
                    324:        me->net = net;
                    325:        return YES;
2.9       frystyk   326:     }
2.59      frystyk   327:     return NO;
2.9       frystyk   328: }
                    329: 
2.59      frystyk   330: PUBLIC HTNet * HTRequest_net (HTRequest * me)
2.9       frystyk   331: {
2.59      frystyk   332:     return me ? me->net : NULL;
2.9       frystyk   333: }
                    334: 
                    335: /*
2.59      frystyk   336: **     Response Object. If the object does not exist then create it at the
                    337: **     same time it is asked for.
2.9       frystyk   338: */
2.59      frystyk   339: PUBLIC HTResponse * HTRequest_response (HTRequest * me)
2.9       frystyk   340: {
2.43      eric      341:     if (me) {
2.59      frystyk   342:        if (!me->response)
                    343:            me->response = HTResponse_new();
                    344:        return me->response;
2.9       frystyk   345:     }
2.59      frystyk   346:     return NULL;
2.9       frystyk   347: }
                    348: 
2.59      frystyk   349: PUBLIC BOOL HTRequest_setResponse (HTRequest * me, HTResponse * response)
2.9       frystyk   350: {
2.43      eric      351:     if (me) {
2.59      frystyk   352:        me->response = response;
                    353:        return YES;
2.9       frystyk   354:     }
2.59      frystyk   355:     return NO;
2.43      eric      356: }
                    357: 
2.59      frystyk   358: /*     Error Management
                    359: **     ----------------
                    360: **     Returns the error stack if a stream is 
2.1       frystyk   361: */
2.59      frystyk   362: PUBLIC HTList * HTRequest_error (HTRequest * me)
2.1       frystyk   363: {
2.59      frystyk   364:     return me ? me->error_stack : NULL;
2.1       frystyk   365: }
                    366: 
2.59      frystyk   367: PUBLIC void HTRequest_setError (HTRequest * me, HTList * list)
2.1       frystyk   368: {
2.59      frystyk   369:     if (me) me->error_stack = list;
2.1       frystyk   370: }
2.66      frystyk   371: 
                    372: /* begin _GM_ */
                    373: /* Note: libwww bug ID: GM11 */
                    374: PUBLIC void HTRequest_deleteAllErrors (HTRequest * request)
                    375: {
                    376:     HTError_deleteAll(request->error_stack);
                    377:     HTRequest_setError(request, NULL);
                    378: }
                    379: /* end _GM_ */
2.1       frystyk   380: 
2.59      frystyk   381: PUBLIC BOOL HTRequest_addError (HTRequest *    me,
                    382:                                HTSeverity      severity,
                    383:                                BOOL            ignore,
                    384:                                int             element,
                    385:                                void *          par,
                    386:                                unsigned int    length,
                    387:                                char *          where)
2.1       frystyk   388: {
2.59      frystyk   389:     if (me) {
                    390:        if (!me->error_stack) me->error_stack = HTList_new();
                    391:        return HTError_add(me->error_stack, severity, ignore, element,
                    392:                           par, length, where);
                    393:     }
                    394:     return NO;
2.1       frystyk   395: }
                    396: 
2.59      frystyk   397: PUBLIC BOOL HTRequest_addSystemError (HTRequest *      me,
                    398:                                      HTSeverity        severity,
                    399:                                      int               errornumber,
                    400:                                      BOOL              ignore,
                    401:                                      char *            syscall)
2.1       frystyk   402: {
2.59      frystyk   403:     if (me) {
                    404:        if (!me->error_stack) me->error_stack = HTList_new();
                    405:        return HTError_addSystem(me->error_stack, severity, errornumber,
                    406:                                 ignore, syscall);
                    407:     }
                    408:     return NO;
2.22      frystyk   409: }
                    410: 
                    411: /*
2.59      frystyk   412: **  Set max number of automatic reload. Default is HT_MAX_RELOADS
2.22      frystyk   413: */
2.59      frystyk   414: PUBLIC BOOL HTRequest_setMaxRetry (int newmax)
2.22      frystyk   415: {
2.59      frystyk   416:     if (newmax > 0) {
                    417:        HTMaxRetry = newmax;
                    418:        return YES;
                    419:     }
                    420:     return NO;
2.22      frystyk   421: }
                    422: 
2.59      frystyk   423: PUBLIC int HTRequest_maxRetry (void)
2.22      frystyk   424: {
2.59      frystyk   425:     return HTMaxRetry;
2.22      frystyk   426: }
                    427: 
2.59      frystyk   428: PUBLIC int HTRequest_retrys (HTRequest * me)
2.22      frystyk   429: {
2.59      frystyk   430:     return me ? me->retrys : 0;
2.1       frystyk   431: }
                    432: 
2.59      frystyk   433: PUBLIC BOOL HTRequest_addRetry (HTRequest * me)
2.1       frystyk   434: {
2.59      frystyk   435:     return (me && me->retrys++);
2.71      kahan     436: }
                    437: 
                    438: PUBLIC int HTRequest_AAretrys (HTRequest * me)
                    439: {
                    440:     return me ? me->AAretrys : 0;
                    441: }
                    442: 
                    443: PUBLIC BOOL HTRequest_addAARetry (HTRequest * me)
                    444: {
                    445:     return (me && me->AAretrys++);
2.1       frystyk   446: }
                    447: 
2.18      frystyk   448: /*
2.59      frystyk   449: **     Should we try again?
                    450: **     --------------------
                    451: **     Returns YES if we are to retry the load, NO otherwise. We check
                    452: **     this so that we don't go into an infinte loop
2.1       frystyk   453: */
2.59      frystyk   454: PUBLIC BOOL HTRequest_doRetry (HTRequest * me)
2.1       frystyk   455: {
2.59      frystyk   456:     return (me && me->retrys < HTMaxRetry-1);
2.56      frystyk   457: }
                    458: 
2.1       frystyk   459: /*
2.59      frystyk   460: **     Socket mode: preemptive or non-preemptive (blocking or non-blocking)
2.40      frystyk   461: */
2.59      frystyk   462: PUBLIC void HTRequest_setPreemptive (HTRequest * me, BOOL mode)
2.40      frystyk   463: {
2.59      frystyk   464:     if (me) me->preemptive = mode;
2.40      frystyk   465: }
                    466: 
2.59      frystyk   467: PUBLIC BOOL HTRequest_preemptive (HTRequest * me)
2.40      frystyk   468: {
2.59      frystyk   469:     return me ? me->preemptive : NO;
2.40      frystyk   470: }
                    471: 
                    472: /*
2.59      frystyk   473: **     Should we use content negotiation?
2.40      frystyk   474: */
2.59      frystyk   475: PUBLIC void HTRequest_setNegotiation (HTRequest * me, BOOL mode)
2.40      frystyk   476: {
2.59      frystyk   477:     if (me) me->ContentNegotiation = mode;
2.40      frystyk   478: }
                    479: 
2.59      frystyk   480: PUBLIC BOOL HTRequest_negotiation (HTRequest * me)
2.40      frystyk   481: {
2.59      frystyk   482:     return me ? me->ContentNegotiation : NO;
2.68      frystyk   483: }
                    484: 
                    485: /*
                    486: **  Use preconditions when doing a PUT or a POST. These are the
                    487: **  if-* header fields that can be used to avoid version conflicts
                    488: **  etc.
                    489: */
2.72      frystyk   490: PUBLIC void HTRequest_setPreconditions (HTRequest * me, HTPreconditions mode)
2.68      frystyk   491: {
                    492:     if (me) me->preconditions = mode;
                    493: }
                    494: 
2.72      frystyk   495: PUBLIC HTPreconditions HTRequest_preconditions (HTRequest * me)
2.68      frystyk   496: {
                    497:     return me ? me->preconditions : NO;
2.40      frystyk   498: }
                    499: 
                    500: /*
2.59      frystyk   501: **     Set General Headers
2.1       frystyk   502: */
2.59      frystyk   503: PUBLIC void HTRequest_setGnHd (HTRequest * me, HTGnHd gnhd)
2.1       frystyk   504: {
2.59      frystyk   505:     if (me) me->GenMask = gnhd;
2.1       frystyk   506: }
                    507: 
2.59      frystyk   508: PUBLIC void HTRequest_addGnHd (HTRequest * me, HTGnHd gnhd)
2.1       frystyk   509: {
2.59      frystyk   510:     if (me) me->GenMask |= gnhd;
2.1       frystyk   511: }
                    512: 
2.59      frystyk   513: PUBLIC HTGnHd HTRequest_gnHd (HTRequest * me)
2.1       frystyk   514: {
2.59      frystyk   515:     return me ? me->GenMask : 0;
2.1       frystyk   516: }
                    517: 
                    518: /*
2.59      frystyk   519: **     Set Request Headers
2.1       frystyk   520: */
2.59      frystyk   521: PUBLIC void HTRequest_setRqHd (HTRequest * me, HTRqHd rqhd)
2.1       frystyk   522: {
2.59      frystyk   523:     if (me) me->RequestMask = rqhd;
2.1       frystyk   524: }
                    525: 
2.59      frystyk   526: PUBLIC void HTRequest_addRqHd (HTRequest * me, HTRqHd rqhd)
2.1       frystyk   527: {
2.59      frystyk   528:     if (me) me->RequestMask |= rqhd;
2.1       frystyk   529: }
                    530: 
2.59      frystyk   531: PUBLIC HTRqHd HTRequest_rqHd (HTRequest * me)
2.1       frystyk   532: {
2.59      frystyk   533:     return me ? me->RequestMask : 0;
2.1       frystyk   534: }
                    535: 
                    536: /*
2.59      frystyk   537: **     Set Response Headers
2.1       frystyk   538: */
2.59      frystyk   539: PUBLIC void HTRequest_setRsHd (HTRequest * me, HTRsHd rshd)
2.1       frystyk   540: {
2.59      frystyk   541:     if (me) me->ResponseMask = rshd;
2.1       frystyk   542: }
                    543: 
2.59      frystyk   544: PUBLIC void HTRequest_addRsHd (HTRequest * me, HTRsHd rshd)
2.35      frystyk   545: {
2.59      frystyk   546:     if (me) me->ResponseMask |= rshd;
2.35      frystyk   547: }
                    548: 
2.59      frystyk   549: PUBLIC HTRsHd HTRequest_rsHd (HTRequest * me)
2.35      frystyk   550: {
2.59      frystyk   551:     return me ? me->ResponseMask : 0;
2.35      frystyk   552: }
                    553: 
2.1       frystyk   554: /*
2.59      frystyk   555: **     Set Entity Headers (for the object)
2.34      hallam    556: */
2.59      frystyk   557: PUBLIC void HTRequest_setEnHd (HTRequest * me, HTEnHd enhd)
2.34      hallam    558: {
2.59      frystyk   559:     if (me) me->EntityMask = enhd;
2.51      frystyk   560: }
                    561: 
2.59      frystyk   562: PUBLIC void HTRequest_addEnHd (HTRequest * me, HTEnHd enhd)
2.51      frystyk   563: {
2.59      frystyk   564:     if (me) me->EntityMask |= enhd;
2.51      frystyk   565: }
                    566: 
2.59      frystyk   567: PUBLIC HTEnHd HTRequest_enHd (HTRequest * me)
2.51      frystyk   568: {
2.59      frystyk   569:     return me ? me->EntityMask : 0;
2.34      hallam    570: }
                    571: 
2.59      frystyk   572: /*
                    573: **     Extra Header Generators. list can be NULL
                    574: */
                    575: PUBLIC void HTRequest_setGenerator (HTRequest * me, HTList *generator,
                    576:                                    BOOL override)
2.34      hallam    577: {
2.59      frystyk   578:     if (me) {
                    579:        me->generators = generator;
                    580:        me->gens_local = override;
2.34      hallam    581:     }
                    582: }
                    583: 
2.59      frystyk   584: PUBLIC HTList * HTRequest_generator (HTRequest * me, BOOL *override)
2.34      hallam    585: {
2.59      frystyk   586:     if (me) {
                    587:        *override = me->gens_local;
                    588:        return me->generators;
2.34      hallam    589:     }
2.59      frystyk   590:     return NULL;
2.51      frystyk   591: }
                    592: 
2.59      frystyk   593: /*
                    594: **     Extra Header Parsers. list can be NULL
                    595: */
                    596: PUBLIC void HTRequest_setMIMEParseSet (HTRequest * me, 
                    597:                                       HTMIMEParseSet * parseSet, BOOL local)
2.51      frystyk   598: {
2.59      frystyk   599:     if (me) {
                    600:         me->parseSet = parseSet;
                    601:        me->pars_local = local;
2.51      frystyk   602:     }
2.34      hallam    603: }
                    604: 
2.59      frystyk   605: PUBLIC HTMIMEParseSet * HTRequest_MIMEParseSet (HTRequest * me, BOOL * pLocal)
2.34      hallam    606: {
2.59      frystyk   607:     if (me) {
                    608:         if (pLocal) *pLocal = me->pars_local;
                    609:        return me->parseSet;
2.34      hallam    610:     }
                    611:     return NULL;
                    612: }
                    613: 
                    614: /*
2.59      frystyk   615: **     Accept Format Types
                    616: **     list can be NULL
2.1       frystyk   617: */
2.59      frystyk   618: PUBLIC void HTRequest_setConversion (HTRequest * me, HTList *type,
                    619:                                     BOOL override)
2.1       frystyk   620: {
2.59      frystyk   621:     if (me) {
                    622:        me->conversions = type;
                    623:        me->conv_local = override;
                    624:     }
2.1       frystyk   625: }
                    626: 
2.59      frystyk   627: PUBLIC HTList * HTRequest_conversion (HTRequest * me)
2.1       frystyk   628: {
2.59      frystyk   629:     return me ? me->conversions : NULL;
2.1       frystyk   630: }
                    631: 
                    632: /*
2.59      frystyk   633: **     Accept Encoding 
                    634: **     list can be NULL
2.1       frystyk   635: */
2.59      frystyk   636: PUBLIC void HTRequest_setEncoding (HTRequest * me, HTList *enc,
                    637:                                   BOOL override)
2.1       frystyk   638: {
2.59      frystyk   639:     if (me) {
                    640:        me->encodings = enc;
                    641:        me->enc_local = override;
                    642:     }
2.1       frystyk   643: }
                    644: 
2.59      frystyk   645: PUBLIC HTList * HTRequest_encoding (HTRequest * me)
2.1       frystyk   646: {
2.59      frystyk   647:     return me ? me->encodings : NULL;
2.1       frystyk   648: }
                    649: 
                    650: /*
2.59      frystyk   651: **     Accept Transfer Encoding 
                    652: **     list can be NULL
2.1       frystyk   653: */
2.59      frystyk   654: PUBLIC void HTRequest_setTransfer (HTRequest * me,
2.64      frystyk   655:                                   HTList * te, BOOL override)
2.1       frystyk   656: {
2.59      frystyk   657:     if (me) {
2.64      frystyk   658:        me->tes = te;
                    659:        me->te_local = override;
2.59      frystyk   660:     }
2.1       frystyk   661: }
                    662: 
2.59      frystyk   663: PUBLIC HTList * HTRequest_transfer (HTRequest * me)
2.1       frystyk   664: {
2.64      frystyk   665:     return me ? me->tes : NULL;
2.47      frystyk   666: }
                    667: 
                    668: /*
2.59      frystyk   669: **     Accept Language
                    670: **     list can be NULL
2.47      frystyk   671: */
2.59      frystyk   672: PUBLIC void HTRequest_setLanguage (HTRequest * me, HTList *lang,
                    673:                                   BOOL override)
2.47      frystyk   674: {
2.59      frystyk   675:     if (me) {
                    676:        me->languages = lang;
                    677:        me->lang_local = override;
                    678:     }
2.47      frystyk   679: }
                    680: 
2.59      frystyk   681: PUBLIC HTList * HTRequest_language (HTRequest * me)
2.47      frystyk   682: {
2.59      frystyk   683:     return me ? me->languages : NULL;
2.1       frystyk   684: }
                    685: 
                    686: /*
2.59      frystyk   687: **     Accept Charset
                    688: **     list can be NULL
2.1       frystyk   689: */
2.59      frystyk   690: PUBLIC void HTRequest_setCharset (HTRequest * me, HTList *charset,
                    691:                                  BOOL override)
2.1       frystyk   692: {
2.59      frystyk   693:     if (me) {
                    694:        me->charsets = charset;
                    695:        me->char_local = override;
                    696:     }
2.1       frystyk   697: }
                    698: 
2.59      frystyk   699: PUBLIC HTList * HTRequest_charset (HTRequest * me)
2.1       frystyk   700: {
2.59      frystyk   701:     return me ? me->charsets : NULL;
2.40      frystyk   702: }
                    703: 
                    704: /*
2.53      frystyk   705: **     Are we using the full URL in the request or not?
2.40      frystyk   706: */
2.59      frystyk   707: PUBLIC void HTRequest_setFullURI (HTRequest * me, BOOL mode)
2.40      frystyk   708: {
2.59      frystyk   709:     if (me) me->full_uri = mode;
2.40      frystyk   710: }
                    711: 
2.59      frystyk   712: PUBLIC BOOL HTRequest_fullURI (HTRequest * me)
2.40      frystyk   713: {
2.59      frystyk   714:     return me ? me->full_uri : NO;
2.53      frystyk   715: }
                    716: 
                    717: /*
                    718: **     Are we using a proxy or not and in that case, which one?
                    719: */
2.59      frystyk   720: PUBLIC BOOL HTRequest_setProxy (HTRequest * me, const char * proxy)
2.53      frystyk   721: {
2.59      frystyk   722:     if (me && proxy) {
                    723:        StrAllocCopy(me->proxy, proxy);
2.53      frystyk   724:        return YES;
                    725:     }
                    726:     return NO;
                    727: }
                    728: 
2.59      frystyk   729: PUBLIC char * HTRequest_proxy (HTRequest * me)
2.53      frystyk   730: {
2.59      frystyk   731:     return me ? me->proxy : NULL;
2.1       frystyk   732: }
                    733: 
2.59      frystyk   734: PUBLIC BOOL HTRequest_deleteProxy (HTRequest * me)
2.54      frystyk   735: {
2.59      frystyk   736:     if (me) {
                    737:        HT_FREE(me->proxy);
2.54      frystyk   738:        return YES;
                    739:     }
                    740:     return NO;
                    741: }
                    742: 
2.1       frystyk   743: /*
2.59      frystyk   744: **     Reload Mode
2.1       frystyk   745: */
2.59      frystyk   746: PUBLIC void HTRequest_setReloadMode (HTRequest * me, HTReload mode)
2.1       frystyk   747: {
2.59      frystyk   748:     if (me) me->reload = mode;
2.1       frystyk   749: }
                    750: 
2.59      frystyk   751: PUBLIC HTReload HTRequest_reloadMode (HTRequest * me)
2.23      frystyk   752: {
2.59      frystyk   753:     return me ? me->reload : HT_CACHE_OK;
2.23      frystyk   754: }
                    755: 
                    756: /*
2.59      frystyk   757: **     Cache control directives. The cache control can be initiated by both
                    758: **     the server and the client which is the reason for keeping two lists
2.1       frystyk   759: */
2.59      frystyk   760: PUBLIC BOOL HTRequest_addCacheControl (HTRequest * me,
                    761:                                       char * token, char * value)
2.1       frystyk   762: {
2.59      frystyk   763:     if (me) {
                    764:        if (!me->cache_control) me->cache_control = HTAssocList_new();
                    765:        return HTAssocList_replaceObject(me->cache_control, token, value);
                    766:     }
                    767:     return NO;
2.1       frystyk   768: }
                    769: 
2.59      frystyk   770: PUBLIC BOOL HTRequest_deleteCacheControl (HTRequest * me)
2.1       frystyk   771: {
2.59      frystyk   772:     if (me && me->cache_control) {
                    773:        HTAssocList_delete(me->cache_control);
                    774:        me->cache_control = NULL;
                    775:        return YES;
                    776:     }
                    777:     return NO;
2.1       frystyk   778: }
                    779: 
2.59      frystyk   780: PUBLIC HTAssocList * HTRequest_cacheControl (HTRequest * me)
2.11      frystyk   781: {
2.59      frystyk   782:     return (me ? me->cache_control : NULL);
2.11      frystyk   783: }
                    784: 
2.59      frystyk   785: /*
                    786: **  Byte ranges
                    787: */
                    788: PUBLIC BOOL HTRequest_deleteRange (HTRequest * me)
2.11      frystyk   789: {
2.59      frystyk   790:     if (me && me->byte_ranges) {
                    791:        HTAssocList_delete(me->byte_ranges);
                    792:        me->byte_ranges = NULL;
                    793:        return YES;
2.11      frystyk   794:     }
                    795:     return NO;
                    796: }
                    797: 
2.59      frystyk   798: PUBLIC BOOL HTRequest_addRange (HTRequest * me, char * unit, char * range)
2.11      frystyk   799: {
2.59      frystyk   800:     if (me) {
2.73    ! frystyk   801:        if (!me->byte_ranges) {
        !           802:            me->byte_ranges = HTAssocList_new();
        !           803:            HTRequest_addRqHd(me, HT_C_RANGE);
        !           804:        }
2.59      frystyk   805:        return HTAssocList_replaceObject(me->byte_ranges, unit, range);
2.11      frystyk   806:     }
                    807:     return NO;
                    808: }
                    809: 
2.59      frystyk   810: PUBLIC HTAssocList * HTRequest_range (HTRequest * me)
                    811: {
                    812:     return (me ? me->byte_ranges : NULL);
                    813: }
                    814: 
2.1       frystyk   815: /*
2.59      frystyk   816: **     Connection directives. The connection directies can be initiated by
                    817: **     both the server and the client which is the reason for keeping two
                    818: **     lists
2.1       frystyk   819: */
2.59      frystyk   820: PUBLIC BOOL HTRequest_addConnection (HTRequest * me,
                    821:                                     char * token, char * value)
2.1       frystyk   822: {
2.59      frystyk   823:     if (me) {
                    824:        if (!me->connection) me->connection = HTAssocList_new();
                    825:        return HTAssocList_replaceObject(me->connection, token, value);
                    826:     }
                    827:     return NO;
2.1       frystyk   828: }
                    829: 
2.59      frystyk   830: PUBLIC BOOL HTRequest_deleteConnection (HTRequest * me)
2.57      frystyk   831: {
2.59      frystyk   832:     if (me && me->connection) {
                    833:        HTAssocList_delete(me->connection);
                    834:        me->connection = NULL;
2.57      frystyk   835:        return YES;
                    836:     }
                    837:     return NO;
                    838: }
                    839: 
2.59      frystyk   840: PUBLIC HTAssocList * HTRequest_connection (HTRequest * me)
2.57      frystyk   841: {
2.59      frystyk   842:     return (me ? me->connection : NULL);
2.64      frystyk   843: }
                    844: 
                    845: /*
                    846: **     Expect directives. 
                    847: */
                    848: PUBLIC BOOL HTRequest_addExpect (HTRequest * me,
                    849:                                 char * token, char * value)
                    850: {
                    851:     if (me) {
                    852:        if (!me->expect) me->expect = HTAssocList_new();
                    853:        return HTAssocList_replaceObject(me->expect, token, value);
                    854:     }
                    855:     return NO;
                    856: }
                    857: 
                    858: PUBLIC BOOL HTRequest_deleteExpect (HTRequest * me)
                    859: {
                    860:     if (me && me->expect) {
                    861:        HTAssocList_delete(me->expect);
                    862:        me->expect = NULL;
                    863:        return YES;
                    864:     }
                    865:     return NO;
                    866: }
                    867: 
                    868: PUBLIC HTAssocList * HTRequest_expect (HTRequest * me)
                    869: {
                    870:     return (me ? me->expect : NULL);
2.57      frystyk   871: }
                    872: 
2.59      frystyk   873: /*
                    874: **  Access Authentication Credentials
                    875: */
                    876: PUBLIC BOOL HTRequest_deleteCredentialsAll (HTRequest * me)
2.57      frystyk   877: {
2.59      frystyk   878:     if (me && me->credentials) {
                    879:        HTAssocList_delete(me->credentials);
                    880:        me->credentials = NULL;
2.57      frystyk   881:        return YES;
                    882:     }
                    883:     return NO;
                    884: }
                    885: 
2.59      frystyk   886: PUBLIC BOOL HTRequest_addCredentials (HTRequest * me,
                    887:                                    char * token, char * value)
2.23      frystyk   888: {
2.59      frystyk   889:     if (me) {
                    890:        if (!me->credentials) me->credentials = HTAssocList_new();
                    891:        return HTAssocList_addObject(me->credentials, token, value);
                    892:     }
                    893:     return NO;
2.46      frystyk   894: }
                    895: 
2.59      frystyk   896: PUBLIC HTAssocList * HTRequest_credentials (HTRequest * me)
2.46      frystyk   897: {
2.59      frystyk   898:     return (me ? me->credentials : NULL);
2.23      frystyk   899: }
                    900: 
                    901: /*
2.59      frystyk   902: **  Access Authentication Realms
2.1       frystyk   903: */
2.59      frystyk   904: PUBLIC BOOL HTRequest_setRealm (HTRequest * me, char * realm)
2.1       frystyk   905: {
2.70      frystyk   906:     if (me && realm && realm != me->realm) {
2.59      frystyk   907:        StrAllocCopy(me->realm, realm);
2.1       frystyk   908:        return YES;
                    909:     }
                    910:     return NO;
                    911: }
                    912: 
2.59      frystyk   913: PUBLIC const char * HTRequest_realm (HTRequest * me)
2.1       frystyk   914: {
2.59      frystyk   915:     return (me ? me->realm : NULL);
2.70      frystyk   916: }
                    917: 
                    918: PUBLIC BOOL HTRequest_deleteRealm (HTRequest * me)
                    919: {
                    920:     if (me) {
                    921:        HT_FREE(me->realm);
                    922:        return YES;
                    923:     }
                    924:     return NO;
2.1       frystyk   925: }
                    926: 
2.59      frystyk   927: /*
                    928: **  PEP Protocol header
                    929: */
                    930: PUBLIC BOOL HTRequest_addProtocol (HTRequest * me,
                    931:                                   char * token, char * value)
2.52      frystyk   932: {
2.59      frystyk   933:     if (me) {
                    934:        if (!me->protocol) me->protocol = HTAssocList_new();
                    935:        return HTAssocList_addObject(me->protocol, token,value);
                    936:     }
                    937:     return NO;
2.52      frystyk   938: }
                    939: 
2.59      frystyk   940: PUBLIC BOOL HTRequest_deleteProtocolAll (HTRequest * me)
2.55      frystyk   941: {
2.59      frystyk   942:     if (me && me->protocol) {
                    943:        HTAssocList_delete(me->protocol);
                    944:        me->protocol = NULL;
                    945:        return YES;
                    946:     }
                    947:     return NO;
2.55      frystyk   948: }
                    949: 
2.59      frystyk   950: PUBLIC HTAssocList * HTRequest_protocol (HTRequest * me)
2.1       frystyk   951: {
2.59      frystyk   952:     return (me ? me->protocol : NULL);
2.54      frystyk   953: }
                    954: 
                    955: /*
2.59      frystyk   956: **  PEP Protocol Info header
2.54      frystyk   957: */
2.59      frystyk   958: PUBLIC BOOL HTRequest_addProtocolInfo (HTRequest * me,
                    959:                                       char * token, char * value)
2.54      frystyk   960: {
2.59      frystyk   961:     if (me) {
                    962:        if (!me->protocol_info) me->protocol_info = HTAssocList_new();
                    963:        return HTAssocList_addObject(me->protocol_info, token,value);
2.54      frystyk   964:     }
                    965:     return NO;
                    966: }
                    967: 
2.59      frystyk   968: PUBLIC BOOL HTRequest_deleteProtocolInfoAll (HTRequest * me)
2.9       frystyk   969: {
2.59      frystyk   970:     if (me && me->protocol_info) {
                    971:        HTAssocList_delete(me->protocol_info);
                    972:        me->protocol_info = NULL;
2.9       frystyk   973:        return YES;
                    974:     }
                    975:     return NO;
                    976: }
                    977: 
2.59      frystyk   978: PUBLIC HTAssocList * HTRequest_protocolInfo (HTRequest * me)
2.9       frystyk   979: {
2.59      frystyk   980:     return (me ? me->protocol_info : NULL);
2.9       frystyk   981: }
                    982: 
2.18      frystyk   983: /*
2.59      frystyk   984: **  PEP Protocol request header
2.31      frystyk   985: */
2.59      frystyk   986: PUBLIC BOOL HTRequest_addProtocolRequest (HTRequest * me,
                    987:                                          char * token, char * value)
2.49      frystyk   988: {
2.59      frystyk   989:     if (me) {
                    990:        if (!me->protocol_request) me->protocol_request = HTAssocList_new();
                    991:        return HTAssocList_addObject(me->protocol_request, token,value);
2.49      frystyk   992:     }
                    993:     return NO;
                    994: }
                    995: 
2.59      frystyk   996: PUBLIC BOOL HTRequest_deleteProtocolRequestAll (HTRequest * me)
2.31      frystyk   997: {
2.59      frystyk   998:     if (me && me->protocol_request) {
                    999:        HTAssocList_delete(me->protocol_request);
                   1000:        me->protocol_request = NULL;
                   1001:        return YES;
2.31      frystyk  1002:     }
                   1003:     return NO;
                   1004: }
                   1005: 
2.59      frystyk  1006: PUBLIC HTAssocList * HTRequest_protocolRequest (HTRequest * me)
2.31      frystyk  1007: {
2.59      frystyk  1008:     return (me ? me->protocol_request : NULL);
2.31      frystyk  1009: }
                   1010: 
                   1011: /*
2.59      frystyk  1012: **     Anchor
2.31      frystyk  1013: */
2.59      frystyk  1014: PUBLIC void HTRequest_setAnchor (HTRequest * me, HTAnchor *anchor)
2.31      frystyk  1015: {
2.59      frystyk  1016:     if (me) {
                   1017:        me->anchor = HTAnchor_parent(anchor);
                   1018:        me->childAnchor = ((HTAnchor *) me->anchor != anchor) ?
                   1019:            (HTChildAnchor *) anchor : NULL;
2.49      frystyk  1020:     }
                   1021: }
                   1022: 
2.59      frystyk  1023: PUBLIC HTParentAnchor * HTRequest_anchor (HTRequest * me)
2.49      frystyk  1024: {
2.59      frystyk  1025:     return me ? me->anchor : NULL;
2.31      frystyk  1026: }
                   1027: 
2.59      frystyk  1028: PUBLIC HTChildAnchor * HTRequest_childAnchor (HTRequest * me)
2.31      frystyk  1029: {
2.59      frystyk  1030:     return me ? me->childAnchor : NULL;
2.31      frystyk  1031: }
                   1032: 
                   1033: /*
2.59      frystyk  1034: **     Parent anchor for Referer field
2.18      frystyk  1035: */
2.59      frystyk  1036: PUBLIC void HTRequest_setParent (HTRequest * me, HTParentAnchor *parent)
2.18      frystyk  1037: {
2.59      frystyk  1038:     if (me) me->parentAnchor = parent;
2.18      frystyk  1039: }
                   1040: 
2.59      frystyk  1041: PUBLIC HTParentAnchor * HTRequest_parent (HTRequest * me)
2.18      frystyk  1042: {
2.59      frystyk  1043:     return me ? me->parentAnchor : NULL;
2.42      frystyk  1044: }
                   1045: 
                   1046: /*
2.59      frystyk  1047: **     Output stream
2.49      frystyk  1048: */
2.59      frystyk  1049: PUBLIC void HTRequest_setOutputStream (HTRequest * me, HTStream *output)
2.49      frystyk  1050: {
2.59      frystyk  1051:     if (me) me->output_stream = output;
2.49      frystyk  1052: }
                   1053: 
2.59      frystyk  1054: PUBLIC HTStream *HTRequest_outputStream (HTRequest * me)
2.49      frystyk  1055: {
2.59      frystyk  1056:     return me ? me->output_stream : NULL;
2.49      frystyk  1057: }
                   1058: 
                   1059: /*
2.59      frystyk  1060: **     Output format
2.42      frystyk  1061: */
2.59      frystyk  1062: PUBLIC void HTRequest_setOutputFormat (HTRequest * me, HTFormat format)
2.42      frystyk  1063: {
2.59      frystyk  1064:     if (me) me->output_format = format;
                   1065: }
                   1066: 
                   1067: PUBLIC HTFormat HTRequest_outputFormat (HTRequest * me)
                   1068: {
                   1069:     return me ? me->output_format : NULL;
2.42      frystyk  1070: }
                   1071: 
2.59      frystyk  1072: /*
                   1073: **     Debug stream
                   1074: */
                   1075: PUBLIC void HTRequest_setDebugStream (HTRequest * me, HTStream *debug)
2.42      frystyk  1076: {
2.59      frystyk  1077:     if (me) me->debug_stream = debug;
2.42      frystyk  1078: }
                   1079: 
2.59      frystyk  1080: PUBLIC HTStream *HTRequest_debugStream (HTRequest * me)
2.42      frystyk  1081: {
2.59      frystyk  1082:     return me ? me->debug_stream : NULL;
2.42      frystyk  1083: }
                   1084: 
                   1085: /*
2.59      frystyk  1086: **     Debug Format
2.42      frystyk  1087: */
2.59      frystyk  1088: PUBLIC void HTRequest_setDebugFormat (HTRequest * me, HTFormat format)
2.42      frystyk  1089: {
2.59      frystyk  1090:     if (me) me->debug_format = format;
2.42      frystyk  1091: }
                   1092: 
2.59      frystyk  1093: PUBLIC HTFormat HTRequest_debugFormat (HTRequest * me)
2.42      frystyk  1094: {
2.59      frystyk  1095:     return me ? me->debug_format : NULL;
2.42      frystyk  1096: }
                   1097: 
                   1098: /*
2.59      frystyk  1099: **     Input stream
2.42      frystyk  1100: */
2.59      frystyk  1101: PUBLIC void HTRequest_setInputStream (HTRequest * me, HTStream *input)
2.42      frystyk  1102: {
2.59      frystyk  1103:     if (me) me->input_stream = input;
2.42      frystyk  1104: }
                   1105: 
2.59      frystyk  1106: PUBLIC HTStream *HTRequest_inputStream (HTRequest * me)
2.42      frystyk  1107: {
2.59      frystyk  1108:     return me ? me->input_stream : NULL;
2.18      frystyk  1109: }
                   1110: 
2.50      frystyk  1111: /*
2.59      frystyk  1112: **     Net before and after callbacks
2.50      frystyk  1113: */
2.59      frystyk  1114: PUBLIC BOOL HTRequest_addBefore (HTRequest * me, HTNetBefore * filter,
                   1115:                                 const char * tmplate, void * param,
2.60      frystyk  1116:                                 HTFilterOrder order, BOOL override)
2.50      frystyk  1117: {
2.59      frystyk  1118:     if (me) {
                   1119:        me->befores_local = override;
                   1120:        if (filter) {
                   1121:            if (!me->befores) me->befores = HTList_new();
                   1122:            return HTNetCall_addBefore(me->befores, filter,
                   1123:                                       tmplate, param, order);
                   1124:        }
                   1125:        return YES;                     /* It's OK to register a NULL filter */
2.50      frystyk  1126:     }
                   1127:     return NO;
                   1128: }
                   1129: 
2.59      frystyk  1130: PUBLIC BOOL HTRequest_deleteBefore (HTRequest * me, HTNetBefore * filter)
2.50      frystyk  1131: {
2.59      frystyk  1132:     if (me && me->befores)
                   1133:        return HTNetCall_deleteBefore(me->befores, filter);
                   1134:     return NO;
2.55      frystyk  1135: }
                   1136: 
2.59      frystyk  1137: PUBLIC BOOL HTRequest_deleteBeforeAll (HTRequest * me)
2.57      frystyk  1138: {
2.59      frystyk  1139:     if (me && me->befores) {
                   1140:        HTNetCall_deleteBeforeAll(me->befores);
                   1141:        me->befores = NULL;
                   1142:        me->befores_local = NO;
                   1143:        return YES;
2.57      frystyk  1144:     }
                   1145:     return NO;
                   1146: }
                   1147: 
2.59      frystyk  1148: PUBLIC HTList * HTRequest_before (HTRequest * me, BOOL *override)
2.57      frystyk  1149: {
2.59      frystyk  1150:     if (me) {
                   1151:        *override = me->befores_local;
                   1152:        return me->befores;
                   1153:     }
                   1154:     return NULL;
                   1155: }
                   1156: 
                   1157: PUBLIC BOOL HTRequest_addAfter (HTRequest * me, HTNetAfter * filter,
                   1158:                                const char * tmplate, void * param,
2.60      frystyk  1159:                                int status, HTFilterOrder order,
                   1160:                                BOOL override)
2.59      frystyk  1161: {
                   1162:     if (me) {
                   1163:        me->afters_local = override;
                   1164:        if (filter) {
                   1165:            if (!me->afters) me->afters = HTList_new();
                   1166:            return HTNetCall_addAfter(me->afters, filter,
                   1167:                                      tmplate, param, status, order);
                   1168:        }
                   1169:        return YES;                     /* It's OK to register a NULL filter */
2.57      frystyk  1170:     }
                   1171:     return NO;
                   1172: }
                   1173: 
2.59      frystyk  1174: PUBLIC BOOL HTRequest_deleteAfter (HTRequest * me, HTNetAfter * filter)
                   1175: {
                   1176:     return (me && me->afters) ?
                   1177:        HTNetCall_deleteAfter(me->afters, filter) : NO;
                   1178: }
                   1179: 
                   1180: PUBLIC BOOL HTRequest_deleteAfterStatus (HTRequest * me, int status)
2.57      frystyk  1181: {
2.59      frystyk  1182:     return (me && me->afters) ?
                   1183:        HTNetCall_deleteAfterStatus(me->afters, status) : NO;
2.57      frystyk  1184: }
                   1185: 
2.59      frystyk  1186: PUBLIC BOOL HTRequest_deleteAfterAll (HTRequest * me)
2.55      frystyk  1187: {
2.59      frystyk  1188:     if (me && me->afters) {
                   1189:        HTNetCall_deleteAfterAll(me->afters);
                   1190:        me->afters = NULL;
                   1191:        me->afters_local = NO;
                   1192:        return YES;
2.55      frystyk  1193:     }
                   1194:     return NO;
                   1195: }
                   1196: 
2.59      frystyk  1197: PUBLIC HTList * HTRequest_after (HTRequest * me, BOOL *override)
2.55      frystyk  1198: {
2.59      frystyk  1199:     if (me) {
                   1200:        *override = me->afters_local;
                   1201:        return me->afters;
2.55      frystyk  1202:     }
2.59      frystyk  1203:     return NULL;
                   1204: }
                   1205: 
                   1206: /*
                   1207: **     Call back function for context swapping
                   1208: */
                   1209: PUBLIC void HTRequest_setCallback (HTRequest * me, HTRequestCallback *cbf)
                   1210: {
                   1211:     if (me) me->callback = cbf;
2.55      frystyk  1212: }
                   1213: 
2.59      frystyk  1214: PUBLIC HTRequestCallback *HTRequest_callback (HTRequest * me)
2.55      frystyk  1215: {
2.59      frystyk  1216:     return me ? me->callback : NULL;
2.56      frystyk  1217: }
                   1218: 
                   1219: /*
2.59      frystyk  1220: **     Context pointer to be used in context call back function
2.56      frystyk  1221: */
2.59      frystyk  1222: PUBLIC void HTRequest_setContext (HTRequest * me, void *context)
2.56      frystyk  1223: {
2.59      frystyk  1224:     if (me) me->context = context;
2.56      frystyk  1225: }
                   1226: 
2.59      frystyk  1227: PUBLIC void *HTRequest_context (HTRequest * me)
2.56      frystyk  1228: {
2.59      frystyk  1229:     return me ? me->context : NULL;
                   1230: }
                   1231: 
                   1232: /*
                   1233: **     Has output stream been connected to the channel? If not then we
                   1234: **     must free it explicitly when deleting the request object
                   1235: */
                   1236: PUBLIC void HTRequest_setOutputConnected (HTRequest * me, BOOL mode)
                   1237: {
                   1238:     if (me) me->connected = mode;
2.56      frystyk  1239: }
                   1240: 
2.59      frystyk  1241: PUBLIC BOOL HTRequest_outputConnected (HTRequest * me)
2.56      frystyk  1242: {
2.59      frystyk  1243:     return me ? me->connected : NO;
2.56      frystyk  1244: }
                   1245: 
                   1246: /*
2.59      frystyk  1247: **     Bytes read in this request
2.56      frystyk  1248: */
2.61      frystyk  1249: PUBLIC long HTRequest_bodyRead(HTRequest * me)
2.57      frystyk  1250: {
2.69      frystyk  1251:     return me ? HTNet_bytesRead(me->net) - HTNet_headerBytesRead(me->net) : -1;
                   1252: }
                   1253: 
                   1254: /*
                   1255: **     Bytes written in this request
                   1256: */
                   1257: PUBLIC long HTRequest_bodyWritten(HTRequest * me)
                   1258: {
                   1259:     return me ? HTNet_bytesWritten(me->net) - HTNet_headerBytesWritten(me->net) : -1;
                   1260: }
                   1261: 
                   1262: /*
                   1263: **     Total Bytes read in this request
                   1264: */
                   1265: PUBLIC long HTRequest_bytesRead (HTRequest * me)
                   1266: {
                   1267:     return me ? HTNet_bytesRead(me->net) : -1;
2.57      frystyk  1268: }
                   1269: 
2.59      frystyk  1270: /*
                   1271: **     Bytes written in this request
                   1272: */
                   1273: PUBLIC long HTRequest_bytesWritten (HTRequest * me)
2.57      frystyk  1274: {
2.59      frystyk  1275:     return me ? HTNet_bytesWritten(me->net) : -1;
                   1276: }
                   1277: 
                   1278: /*
                   1279: **     Handle the max forward header value
                   1280: */
                   1281: PUBLIC BOOL HTRequest_setMaxForwards (HTRequest * me, int maxforwards)
                   1282: {
                   1283:     if (me && maxforwards >= 0) {
                   1284:        me->max_forwards = maxforwards;
                   1285:        HTRequest_addRqHd(me, HT_C_MAX_FORWARDS);              /* Turn it on */
2.57      frystyk  1286:        return YES;
                   1287:     }
                   1288:     return NO;
                   1289: }
                   1290: 
2.59      frystyk  1291: PUBLIC int HTRequest_maxForwards (HTRequest * me)
2.57      frystyk  1292: {
2.59      frystyk  1293:     return me ? me->max_forwards : -1;
2.57      frystyk  1294: }
                   1295: 
                   1296: /*
2.59      frystyk  1297: **  Source request
2.57      frystyk  1298: */
2.59      frystyk  1299: PUBLIC BOOL HTRequest_setSource (HTRequest * me, HTRequest * source)
2.57      frystyk  1300: {
2.59      frystyk  1301:     if (me) {
                   1302:        me->source = source;
                   1303:        return YES;
2.57      frystyk  1304:     }
                   1305:     return NO;
                   1306: }
                   1307: 
2.59      frystyk  1308: PUBLIC HTRequest * HTRequest_source (HTRequest * me)
2.57      frystyk  1309: {
2.59      frystyk  1310:     return (me ? me->source : NULL);
                   1311: }
                   1312: 
                   1313: PUBLIC BOOL HTRequest_isPostWeb (HTRequest * me)
                   1314: {
                   1315:     return (me ? me->source != NULL: NO);
2.57      frystyk  1316: }
                   1317: 
2.59      frystyk  1318: /*
                   1319: **     POST Call back function for sending data to the destination
                   1320: */
                   1321: PUBLIC void HTRequest_setPostCallback (HTRequest * me, HTPostCallback *cbf)
2.57      frystyk  1322: {
2.59      frystyk  1323:     if (me) me->PostCallback = cbf;
2.57      frystyk  1324: }
                   1325: 
2.59      frystyk  1326: PUBLIC HTPostCallback * HTRequest_postCallback (HTRequest * me)
2.56      frystyk  1327: {
2.59      frystyk  1328:     return me ? me->PostCallback : NULL;
2.56      frystyk  1329: }
                   1330: 
2.59      frystyk  1331: /*
                   1332: **     Entity Anchor
                   1333: */
                   1334: PUBLIC BOOL HTRequest_setEntityAnchor (HTRequest * me,
                   1335:                                       HTParentAnchor * anchor)
2.56      frystyk  1336: {
2.59      frystyk  1337:     if (me) {
                   1338:        me->source_anchor = anchor;
2.56      frystyk  1339:        return YES;
                   1340:     }
                   1341:     return NO;
                   1342: }
                   1343: 
2.59      frystyk  1344: PUBLIC HTParentAnchor * HTRequest_entityAnchor (HTRequest * me)
2.56      frystyk  1345: {
2.59      frystyk  1346:     return me ? me->source_anchor ? me->source_anchor :
                   1347:        me->anchor : NULL;
2.50      frystyk  1348: }
                   1349: 
2.1       frystyk  1350: /* ------------------------------------------------------------------------- */
                   1351: /*                             POST WEB METHODS                             */
                   1352: /* ------------------------------------------------------------------------- */
                   1353: 
                   1354: /*
                   1355: **  Add a destination request to this source request structure so that we
                   1356: **  build the internal request representation of the POST web
                   1357: **  Returns YES if OK, else NO
                   1358: */
2.23      frystyk  1359: PUBLIC BOOL HTRequest_addDestination (HTRequest * src, HTRequest * dest)
2.1       frystyk  1360: {
                   1361:     if (src && dest) {
2.23      frystyk  1362:        dest->source = src->source = src;
2.1       frystyk  1363:        if (!src->mainDestination) {
                   1364:            src->mainDestination = dest;
                   1365:            src->destRequests = 1;
2.36      frystyk  1366:            if (CORE_TRACE)
2.30      eric     1367:                HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk  1368:                         dest, src);
2.1       frystyk  1369:            return YES;
                   1370:        } else {
2.23      frystyk  1371:            if (!src->destinations) src->destinations = HTList_new();
2.1       frystyk  1372:            if (HTList_addObject(src->destinations, (void *) dest)==YES) {
                   1373:                src->destRequests++;
2.36      frystyk  1374:                if (CORE_TRACE)
2.30      eric     1375:                    HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk  1376:                             dest, src);
2.1       frystyk  1377:                return YES;
                   1378:            }
                   1379:        }
                   1380:     }
                   1381:     return NO;
                   1382: }
                   1383: 
                   1384: /*
                   1385: **  Remove a destination request from this source request structure
2.23      frystyk  1386: **  Remember only to delete the internal request objects as the other
                   1387: **  comes from the application!
2.1       frystyk  1388: **  Returns YES if OK, else NO
                   1389: */
2.23      frystyk  1390: PUBLIC BOOL HTRequest_removeDestination (HTRequest * dest)
2.1       frystyk  1391: {
                   1392:     BOOL found=NO;
                   1393:     if (dest && dest->source) {
                   1394:        HTRequest *src = dest->source;
                   1395:        if (src->mainDestination == dest) {
                   1396:            dest->source = NULL;
                   1397:            src->mainDestination = NULL;
                   1398:            src->destRequests--;
                   1399:            found = YES;
2.23      frystyk  1400:        } else if (src->destinations) {
2.1       frystyk  1401:            if (HTList_removeObject(src->destinations, (void *) dest)) {
                   1402:                src->destRequests--;
                   1403:                found = YES;
                   1404:            }
                   1405:        }
                   1406:        if (found) {
2.23      frystyk  1407:            if (dest->internal) HTRequest_delete(dest);
2.36      frystyk  1408:            if (CORE_TRACE)
2.30      eric     1409:                HTTrace("POSTWeb..... Deleting dest %p from src %p\n",
2.23      frystyk  1410:                         dest, src);
2.1       frystyk  1411:        }
2.23      frystyk  1412:        if (src->destRequests <= 0) {
2.36      frystyk  1413:            if (CORE_TRACE)
2.30      eric     1414:                HTTrace("POSTWeb..... terminated\n");
2.23      frystyk  1415:            if (src->internal) HTRequest_delete(src);
2.1       frystyk  1416:        }
                   1417:     }
                   1418:     return found;
                   1419: }
                   1420: 
                   1421: /*
2.23      frystyk  1422: **  Check to see whether all destinations are ready. If so then enable the
                   1423: **  source as ready for reading.
                   1424: **  Returns YES if all dests are ready, NO otherwise
                   1425: */
                   1426: PUBLIC BOOL HTRequest_destinationsReady (HTRequest * me)
                   1427: {
                   1428:     HTRequest * source = me ? me->source : NULL;
                   1429:     if (source) {
                   1430:        if (source->destStreams == source->destRequests) {
                   1431:            HTNet * net = source->net;
2.36      frystyk  1432:            if (CORE_TRACE)
2.30      eric     1433:                HTTrace("POSTWeb..... All destinations are ready!\n");
2.23      frystyk  1434:            if (net)                          /* Might already have finished */
2.61      frystyk  1435:                HTEvent_register(HTNet_socket(net), HTEvent_READ, &net->event);
2.23      frystyk  1436:            return YES;
                   1437:        }
                   1438:     }
                   1439:     return NO;
                   1440: }
                   1441: 
                   1442: /*
                   1443: **  Find the source request object and make the link between the 
2.1       frystyk  1444: **  source output stream and the destination input stream. There can be
                   1445: **  a conversion between the two streams!
                   1446: **  Returns YES if link is made, NO otherwise
                   1447: */
2.3       frystyk  1448: PUBLIC BOOL HTRequest_linkDestination (HTRequest *dest)
2.1       frystyk  1449: {
                   1450:     if (dest && dest->input_stream && dest->source && dest!=dest->source) {
                   1451:        HTRequest *source = dest->source;
                   1452:        HTStream *pipe = HTStreamStack(source->output_format,
                   1453:                                       dest->input_format,
                   1454:                                       dest->input_stream,
                   1455:                                       dest, YES);
                   1456: 
                   1457:        /* Check if we are the only one - else spawn off T streams */
                   1458:        /* @@@ We don't do this yet @@@ */
                   1459: 
2.23      frystyk  1460:        /* Now set up output stream of the source */
                   1461:        if (source->output_stream)
                   1462:            (*source->output_stream->isa->_free)(source->output_stream);
2.1       frystyk  1463:        source->output_stream = pipe ? pipe : dest->input_stream;
                   1464: 
2.36      frystyk  1465:        if (CORE_TRACE)
2.30      eric     1466:            HTTrace("POSTWeb..... Linking dest %p to src %p\n",
2.23      frystyk  1467:                     dest, source);
2.1       frystyk  1468:        if (++source->destStreams == source->destRequests) {
                   1469:            HTNet *net = source->net;
2.36      frystyk  1470:            if (CORE_TRACE)
2.30      eric     1471:                HTTrace("POSTWeb..... All destinations ready!\n");
2.1       frystyk  1472:            if (net)                          /* Might already have finished */
2.61      frystyk  1473:                HTEvent_register(HTNet_socket(net), HTEvent_READ, &net->event);
2.1       frystyk  1474:            return YES;
                   1475:        }
                   1476:     }
                   1477:     return NO;
                   1478: }
                   1479: 
                   1480: /*
                   1481: **  Remove a feed stream to a destination request from this source
                   1482: **  request structure. When all feeds are removed the request tree is
                   1483: **  ready to take down and the operation can be terminated.
                   1484: **  Returns YES if removed, else NO
                   1485: */
2.3       frystyk  1486: PUBLIC BOOL HTRequest_unlinkDestination (HTRequest *dest)
2.1       frystyk  1487: {
                   1488:     BOOL found = NO;
                   1489:     if (dest && dest->source && dest != dest->source) {
                   1490:        HTRequest *src = dest->source;
                   1491:        if (src->mainDestination == dest) {
                   1492:            src->output_stream = NULL;
                   1493:            if (dest->input_stream)
                   1494:                (*dest->input_stream->isa->_free)(dest->input_stream);
                   1495:            found = YES;
                   1496:        } else if (src->destinations) {
                   1497: 
                   1498:            /* LOOK THROUGH THE LIST AND FIND THE RIGHT ONE */
                   1499: 
                   1500:        }       
                   1501:        if (found) {
                   1502:            src->destStreams--;
2.36      frystyk  1503:            if (CORE_TRACE)
2.30      eric     1504:                HTTrace("POSTWeb..... Unlinking dest %p from src %p\n",
2.23      frystyk  1505:                         dest, src);
2.1       frystyk  1506:            return YES;
                   1507:        }
                   1508:     }
                   1509:     return NO;
                   1510: }
                   1511: 
                   1512: /*
                   1513: **  Removes all request structures in this PostWeb.
                   1514: */
2.3       frystyk  1515: PUBLIC BOOL HTRequest_removePostWeb (HTRequest *me)
2.1       frystyk  1516: {
                   1517:     if (me && me->source) {
                   1518:        HTRequest *source = me->source;
                   1519: 
                   1520:        /* Kill main destination */
                   1521:        if (source->mainDestination)
                   1522:            HTRequest_removeDestination(source->mainDestination);
                   1523: 
                   1524:        /* Kill all other destinations */
                   1525:        if (source->destinations) {
                   1526:            HTList *cur = source->destinations;
                   1527:            HTRequest *pres;
                   1528:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
                   1529:                HTRequest_removeDestination(pres);
                   1530:        }
                   1531: 
                   1532:        /* Remove source request */
                   1533:        HTRequest_removeDestination(source);
                   1534:        return YES;
                   1535:     }
                   1536:     return NO;
                   1537: }
                   1538: 
                   1539: /*
                   1540: **  Kills all threads in a POST WEB connected to this request but
2.23      frystyk  1541: **  NOT this request itself. We also keep the request structures.
                   1542: **  Some requests might be preemptive, for example a SMTP request (when
2.1       frystyk  1543: **  that has been implemented). However, this will be handled internally
                   1544: **  in the load function.
                   1545: */
2.3       frystyk  1546: PUBLIC BOOL HTRequest_killPostWeb (HTRequest *me)
2.1       frystyk  1547: {
                   1548:     if (me && me->source) {
                   1549:        HTRequest *source = me->source;
2.36      frystyk  1550:        if (CORE_TRACE) HTTrace("POSTWeb..... Killing\n");
2.1       frystyk  1551: 
2.23      frystyk  1552:        /*
                   1553:        ** Kill source. The stream tree is now freed so we have to build
                   1554:        ** that again. This is done in HTRequest_linkDestination()
                   1555:        */
                   1556:        if (me != source) {
                   1557:            HTNet_kill(source->net);
                   1558:            source->output_stream = NULL;
                   1559:        }
2.1       frystyk  1560: 
                   1561:        /* Kill all other destinations */
                   1562:        if (source->destinations) {
                   1563:            HTList *cur = source->destinations;
                   1564:            HTRequest *pres;
                   1565:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
2.23      frystyk  1566:                if (me != pres) HTNet_kill(pres->net);
2.1       frystyk  1567:        }
2.23      frystyk  1568: 
                   1569:        /* Kill main destination */
                   1570:        if (source->mainDestination && me != source->mainDestination)
                   1571:            HTNet_kill(source->mainDestination->net);
2.1       frystyk  1572:        return YES;
                   1573:     }
                   1574:     return NO;
2.61      frystyk  1575: }
                   1576: 
                   1577: PUBLIC int HTRequest_forceFlush (HTRequest * request)
                   1578: {
                   1579:     HTHost * host = HTNet_host(request->net);
                   1580:     if (host == NULL) return HT_ERROR;
                   1581:     return HTHost_forceFlush(host);
2.1       frystyk  1582: }
                   1583: 
                   1584: /* --------------------------------------------------------------------------*/
                   1585: /*                             Document Loader                              */
                   1586: /* --------------------------------------------------------------------------*/
                   1587: 
                   1588: /*     Request a resource
                   1589: **     ------------------
                   1590: **     This is an internal routine, which has an address AND a matching
                   1591: **     anchor.  (The public routines are called with one OR the other.)
                   1592: **     Returns:
                   1593: **             YES     if request has been registered (success)
                   1594: **             NO      an error occured
                   1595: */
2.59      frystyk  1596: PUBLIC BOOL HTLoad (HTRequest * me, BOOL recursive)
2.1       frystyk  1597: {
2.59      frystyk  1598:     if (!me || !me->anchor) {
2.36      frystyk  1599:         if (CORE_TRACE) HTTrace("Load Start.. Bad argument\n");
2.1       frystyk  1600:         return NO;
                   1601:     }
2.57      frystyk  1602: 
                   1603:     /* Make sure that we don't carry over any old physical address */
2.63      frystyk  1604:     if (!recursive) HTAnchor_clearPhysical(me->anchor);
2.57      frystyk  1605: 
2.59      frystyk  1606:     /* Set the default method if not already done */
                   1607:     if (me->method == METHOD_INVALID) me->method = METHOD_GET;
2.57      frystyk  1608: 
                   1609:     /* Should we keep the error stack or not? */
2.59      frystyk  1610:     if (!recursive && me->error_stack) {
                   1611:        HTError_deleteAll(me->error_stack);
                   1612:        me->error_stack = NULL;
                   1613:     }
                   1614: 
                   1615:     /* Delete any old Response Object */
                   1616:     if (me->response) {
                   1617:        HTResponse_delete(me->response);
                   1618:        me->response = NULL;
2.16      frystyk  1619:     }
2.57      frystyk  1620: 
                   1621:     /*
                   1622:     **  We set the start point of handling a request to here.
                   1623:     **  This time will be used by the cache
                   1624:     */
2.59      frystyk  1625:     HTRequest_setDate(me, time(NULL));
2.57      frystyk  1626: 
                   1627:     /* Now start the Net Manager */
2.59      frystyk  1628:     return HTNet_newClient(me);
2.1       frystyk  1629: }
                   1630: 

Webmaster