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

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.56    ! frystyk     6: **     @(#) $Id: HTReqMan.c,v 2.55 1996/08/19 18:31:00 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.32      frystyk    32: #include "sysdep.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: /* --------------------------------------------------------------------------*/
                     56: /*                     Management of the HTRequest structure                */
                     57: /* --------------------------------------------------------------------------*/
                     58: 
                     59: /*  Create  a request structure
                     60: **  ---------------------------
                     61: */
2.3       frystyk    62: PUBLIC HTRequest * HTRequest_new (void)
2.1       frystyk    63: {
2.29      frystyk    64:     HTRequest * me;
                     65:     if ((me = (HTRequest *) HT_CALLOC(1, sizeof(HTRequest))) == NULL)
                     66:         HT_OUTOFMEM("HTRequest_new()");
2.1       frystyk    67:     
2.7       frystyk    68:    /* Force Reload */
2.56    ! frystyk    69:     me->reload = HT_CACHE_OK;
2.1       frystyk    70: 
2.40      frystyk    71:     /* Set the default user profile */
                     72:     me->userprofile = HTLib_userProfile();
                     73: 
2.1       frystyk    74:     /* Format of output */
                     75:     me->output_format  = WWW_PRESENT;      /* default it to present to user */
2.21      frystyk    76:     me->debug_format   = WWW_DEBUG;     /* default format of error messages */
2.1       frystyk    77: 
                     78:     /* HTTP headers */
                     79:     me->GenMask                = DEFAULT_GENERAL_HEADERS;
                     80:     me->RequestMask    = DEFAULT_REQUEST_HEADERS;
2.22      frystyk    81:     me->ResponseMask   = DEFAULT_RESPONSE_HEADERS;
2.1       frystyk    82:     me->EntityMask     = DEFAULT_ENTITY_HEADERS;
                     83: 
                     84:     /* Default retry after value */
                     85:     me->retry_after = -1;
2.19      frystyk    86:     me->priority = HT_PRIORITY_MAX;
2.1       frystyk    87: 
2.54      frystyk    88:     /* Default max forward value */
                     89:     me->max_forwards = -1;
                     90: 
2.1       frystyk    91:     /* Content negotiation */
2.45      frystyk    92:     me->ContentNegotiation = YES;                     /* Do this by default */
2.1       frystyk    93: 
2.47      frystyk    94:     if (CORE_TRACE) HTTrace("Request..... Created %p\n", me);
                     95: 
2.38      eric       96: #if 0 /* WWW_WIN_ASYNC */
2.13      frystyk    97:     HTEvent_winHandle(me);
2.1       frystyk    98: #endif
                     99:     return me;
                    100: }
                    101: 
2.28      frystyk   102: /*     HTRequest_clear
                    103: **     ---------------
                    104: **     Clears all protocol specific information so that the request object
                    105: **     can be used for another request.
                    106: **     Returns YES if OK, else NO
                    107: */
                    108: PUBLIC BOOL HTRequest_clear (HTRequest * me)
                    109: {
                    110:     if (me) {
                    111:        me->error_stack = NULL;
                    112:        me->net = NULL;
2.49      frystyk   113:        me->realm = NULL;
2.31      frystyk   114:        me->scheme = NULL;
                    115:        me->challenge = NULL;
                    116:        me->credentials = NULL;
2.47      frystyk   117:        me->connected = NO;
2.28      frystyk   118:        return YES;
                    119:     }
                    120:     return NO;
                    121: }
                    122: 
2.18      frystyk   123: /*     HTRequest_dup
                    124: **     -------------
                    125: **     Creates a new HTRequest object as a duplicate of the src request.
                    126: **     Returns YES if OK, else NO
                    127: */
                    128: PUBLIC HTRequest * HTRequest_dup (HTRequest * src)
                    129: {
                    130:     HTRequest * me;
2.47      frystyk   131:     if (!src) return NULL;
2.29      frystyk   132:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    133:         HT_OUTOFMEM("HTRequest_dup");
2.18      frystyk   134:     memcpy(me, src, sizeof(HTRequest));
2.47      frystyk   135:     if (CORE_TRACE) HTTrace("Request..... Duplicated %p to %p\n", src, me);
2.18      frystyk   136:     return me;
                    137: }
2.1       frystyk   138: 
2.23      frystyk   139: /*     HTRequest_dupInternal
                    140: **     ---------------------
                    141: **     Creates a new HTRequest object as a duplicate of the src request.
                    142: **     The difference to the HTRequest_dup function is that we don't copy the
                    143: **     error_stack and other information that the application keeps in its
                    144: **     copy of the request object. Otherwise it will be freed multiple times
                    145: **     Returns YES if OK, else NO
                    146: */
                    147: PUBLIC HTRequest * HTRequest_dupInternal (HTRequest * src)
                    148: {
                    149:     HTRequest * me;
2.33      eric      150:     if (!src) return 0;
2.29      frystyk   151:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    152:         HT_OUTOFMEM("HTRequest_dup");
2.23      frystyk   153:     memcpy(me, src, sizeof(HTRequest));
2.28      frystyk   154:     HTRequest_clear(me);
2.23      frystyk   155:     return me;
                    156: }
                    157: 
2.1       frystyk   158: /*  Delete a request structure
                    159: **  --------------------------
                    160: */
2.3       frystyk   161: PUBLIC void HTRequest_delete (HTRequest * request)
2.1       frystyk   162: {
                    163:     if (request) {
2.47      frystyk   164:        if (CORE_TRACE) HTTrace("Request..... Delete %p\n", request);
2.48      frystyk   165:        if (request->net) HTNet_setRequest(request->net, NULL);
2.47      frystyk   166: 
                    167:        /* Should we delete the output stream? */
                    168:        if (!request->connected && request->output_stream) {
                    169:            if (CORE_TRACE)
                    170:                HTTrace("Request..... Deleting dangling output stream\n");
                    171:            (*request->output_stream->isa->_free)(request->output_stream);
                    172:            request->output_stream = NULL;
                    173:        }
                    174: 
                    175:        /* Clean up the error stack */
2.11      frystyk   176:        if (request->error_stack) HTError_deleteAll(request->error_stack);
2.13      frystyk   177: 
2.51      frystyk   178:        /* Before and After Filters */
                    179:        if (request->afters) HTList_delete(request->afters);
                    180:        if (request->befores) HTList_delete(request->befores);
                    181: 
2.49      frystyk   182:        /* Access Authentication */
2.31      frystyk   183:        if (request->challenge) HTAssocList_delete(request->challenge);
                    184:        if (request->credentials) HTAssocList_delete(request->credentials);
2.49      frystyk   185:        HT_FREE(request->realm);
                    186:        HT_FREE(request->scheme);
                    187: 
2.56    ! frystyk   188:        /* Cache control headers */
        !           189:        if (request->cache_control) HTAssocList_delete(request->cache_control);
        !           190: 
        !           191:        /* Connection headers */
        !           192:        if (request->connection) HTAssocList_delete(request->connection);
        !           193: 
2.53      frystyk   194:        /* Proxy information */
                    195:        HT_FREE(request->proxy);
                    196: 
2.49      frystyk   197:        /* PEP Information */
                    198: 
                    199:        /* more */
                    200: 
2.55      frystyk   201:        /* Simple extension protocol */
                    202:        if (request->extension) HTAssocList_delete(request->extension);
                    203: 
2.29      frystyk   204:        HT_FREE(request);
2.1       frystyk   205:     }
                    206: }
                    207: 
                    208: /*
                    209: **     Method
                    210: */
2.3       frystyk   211: PUBLIC void HTRequest_setMethod (HTRequest *request, HTMethod method)
2.1       frystyk   212: {
                    213:     if (request) request->method = method;
                    214: }
                    215: 
2.3       frystyk   216: PUBLIC HTMethod HTRequest_method (HTRequest *request)
2.1       frystyk   217: {
                    218:     return request ? request->method : METHOD_INVALID;
                    219: }
                    220: 
                    221: /*
                    222: **     Reload Mode
                    223: */
2.3       frystyk   224: PUBLIC void HTRequest_setReloadMode (HTRequest *request, HTReload mode)
2.1       frystyk   225: {
                    226:     if (request) request->reload = mode;
                    227: }
                    228: 
2.3       frystyk   229: PUBLIC HTReload HTRequest_reloadMode (HTRequest *request)
2.1       frystyk   230: {
2.56    ! frystyk   231:     return request ? request->reload : HT_CACHE_OK;
2.1       frystyk   232: }
                    233: 
                    234: /*
                    235: **     Accept Format Types
                    236: **     list can be NULL
                    237: */
2.6       frystyk   238: PUBLIC void HTRequest_setConversion (HTRequest *request, HTList *type,
                    239:                                     BOOL override)
2.1       frystyk   240: {
                    241:     if (request) {
                    242:        request->conversions = type;
                    243:        request->conv_local = override;
                    244:     }
                    245: }
                    246: 
2.6       frystyk   247: PUBLIC HTList * HTRequest_conversion (HTRequest *request)
2.1       frystyk   248: {
                    249:     return request ? request->conversions : NULL;
                    250: }
                    251: 
                    252: /*
                    253: **     Accept Encoding 
                    254: **     list can be NULL
                    255: */
2.3       frystyk   256: PUBLIC void HTRequest_setEncoding (HTRequest *request, HTList *enc,
                    257:                                   BOOL override)
2.1       frystyk   258: {
                    259:     if (request) {
                    260:        request->encodings = enc;
                    261:        request->enc_local = override;
                    262:     }
                    263: }
                    264: 
2.3       frystyk   265: PUBLIC HTList * HTRequest_encoding (HTRequest *request)
2.1       frystyk   266: {
                    267:     return request ? request->encodings : NULL;
                    268: }
                    269: 
2.37      frystyk   270: /*
                    271: **     Accept Transfer Encoding 
                    272: **     list can be NULL
                    273: */
                    274: PUBLIC void HTRequest_setTransfer (HTRequest * request,
                    275:                                   HTList * cte, BOOL override)
                    276: {
                    277:     if (request) {
                    278:        request->ctes = cte;
                    279:        request->cte_local = override;
                    280:     }
                    281: }
                    282: 
                    283: PUBLIC HTList * HTRequest_transfer (HTRequest * request)
                    284: {
                    285:     return request ? request->ctes : NULL;
                    286: }
                    287: 
2.1       frystyk   288: /*
                    289: **     Accept Language
                    290: **     list can be NULL
                    291: */
2.3       frystyk   292: PUBLIC void HTRequest_setLanguage (HTRequest *request, HTList *lang,
                    293:                                   BOOL override)
2.1       frystyk   294: {
                    295:     if (request) {
                    296:        request->languages = lang;
                    297:        request->lang_local = override;
                    298:     }
                    299: }
                    300: 
2.3       frystyk   301: PUBLIC HTList * HTRequest_language (HTRequest *request)
2.1       frystyk   302: {
                    303:     return request ? request->languages : NULL;
                    304: }
                    305: 
                    306: /*
                    307: **     Accept Charset
                    308: **     list can be NULL
                    309: */
2.3       frystyk   310: PUBLIC void HTRequest_setCharset (HTRequest *request, HTList *charset,
                    311:                                  BOOL override)
2.1       frystyk   312: {
                    313:     if (request) {
                    314:        request->charsets = charset;
                    315:        request->char_local = override;
                    316:     }
                    317: }
                    318: 
2.3       frystyk   319: PUBLIC HTList * HTRequest_charset (HTRequest *request)
2.1       frystyk   320: {
                    321:     return request ? request->charsets : NULL;
                    322: }
                    323: 
                    324: /*
2.9       frystyk   325: **     Extra Header Generators. list can be NULL
                    326: */
                    327: PUBLIC void HTRequest_setGenerator (HTRequest *request, HTList *generator,
                    328:                                    BOOL override)
                    329: {
                    330:     if (request) {
                    331:        request->generators = generator;
                    332:        request->gens_local = override;
                    333:     }
                    334: }
                    335: 
                    336: PUBLIC HTList * HTRequest_generator (HTRequest *request, BOOL *override)
                    337: {
                    338:     if (request) {
                    339:        *override = request->gens_local;
                    340:        return request->generators;
                    341:     }
                    342:     return NULL;
                    343: }
                    344: 
                    345: /*
                    346: **     Extra Header Parsers. list can be NULL
                    347: */
2.43      eric      348: PUBLIC void HTRequest_setMIMEParseSet (HTRequest * me, 
                    349:                                       HTMIMEParseSet * parseSet, BOOL local)
2.9       frystyk   350: {
2.43      eric      351:     if (me) {
                    352:         me->parseSet = parseSet;
                    353:        me->pars_local = local;
2.9       frystyk   354:     }
                    355: }
                    356: 
2.43      eric      357: PUBLIC HTMIMEParseSet * HTRequest_MIMEParseSet (HTRequest * me, BOOL * pLocal)
2.9       frystyk   358: {
2.43      eric      359:     if (me) {
                    360:         if (pLocal) *pLocal = me->pars_local;
                    361:        return me->parseSet;
2.9       frystyk   362:     }
                    363:     return NULL;
2.43      eric      364: }
                    365: 
2.9       frystyk   366: /*
2.1       frystyk   367: **     Set General Headers
                    368: */
2.3       frystyk   369: PUBLIC void HTRequest_setGnHd (HTRequest *request, HTGnHd gnhd)
2.1       frystyk   370: {
                    371:     if (request) request->GenMask = gnhd;
                    372: }
                    373: 
2.3       frystyk   374: PUBLIC void HTRequest_addGnHd (HTRequest *request, HTGnHd gnhd)
2.1       frystyk   375: {
                    376:     if (request) request->GenMask |= gnhd;
                    377: }
                    378: 
2.3       frystyk   379: PUBLIC HTGnHd HTRequest_gnHd (HTRequest *request)
2.1       frystyk   380: {
                    381:     return request ? request->GenMask : 0;
                    382: }
                    383: 
                    384: /*
                    385: **     Set Request Headers
                    386: */
2.3       frystyk   387: PUBLIC void HTRequest_setRqHd (HTRequest *request, HTRqHd rqhd)
2.1       frystyk   388: {
                    389:     if (request) request->RequestMask = rqhd;
                    390: }
                    391: 
2.3       frystyk   392: PUBLIC void HTRequest_addRqHd (HTRequest *request, HTRqHd rqhd)
2.1       frystyk   393: {
                    394:     if (request) request->RequestMask |= rqhd;
                    395: }
                    396: 
2.3       frystyk   397: PUBLIC HTRqHd HTRequest_rqHd (HTRequest *request)
2.1       frystyk   398: {
                    399:     return request ? request->RequestMask : 0;
2.22      frystyk   400: }
                    401: 
                    402: /*
                    403: **     Set Response Headers
                    404: */
                    405: PUBLIC void HTRequest_setRsHd (HTRequest *request, HTRsHd rshd)
                    406: {
                    407:     if (request) request->ResponseMask = rshd;
                    408: }
                    409: 
                    410: PUBLIC void HTRequest_addRsHd (HTRequest *request, HTRsHd rshd)
                    411: {
                    412:     if (request) request->ResponseMask |= rshd;
                    413: }
                    414: 
                    415: PUBLIC HTRsHd HTRequest_rsHd (HTRequest *request)
                    416: {
                    417:     return request ? request->ResponseMask : 0;
2.1       frystyk   418: }
                    419: 
                    420: /*
                    421: **     Set Entity Headers (for the object)
                    422: */
2.3       frystyk   423: PUBLIC void HTRequest_setEnHd (HTRequest *request, HTEnHd enhd)
2.1       frystyk   424: {
                    425:     if (request) request->EntityMask = enhd;
                    426: }
                    427: 
2.3       frystyk   428: PUBLIC void HTRequest_addEnHd (HTRequest *request, HTEnHd enhd)
2.1       frystyk   429: {
                    430:     if (request) request->EntityMask |= enhd;
                    431: }
                    432: 
2.3       frystyk   433: PUBLIC HTEnHd HTRequest_enHd (HTRequest *request)
2.1       frystyk   434: {
                    435:     return request ? request->EntityMask : 0;
                    436: }
                    437: 
2.18      frystyk   438: /*
2.1       frystyk   439: **     Anchor
                    440: */
2.3       frystyk   441: PUBLIC void HTRequest_setAnchor (HTRequest *request, HTAnchor *anchor)
2.1       frystyk   442: {
2.48      frystyk   443:     if (request) {
2.1       frystyk   444:        request->anchor = HTAnchor_parent(anchor);
                    445:        request->childAnchor = ((HTAnchor *) request->anchor != anchor) ?
                    446:            (HTChildAnchor *) anchor : NULL;
                    447:     }
                    448: }
                    449: 
2.3       frystyk   450: PUBLIC HTParentAnchor * HTRequest_anchor (HTRequest *request)
2.1       frystyk   451: {
                    452:     return request ? request->anchor : NULL;
                    453: }
                    454: 
2.56    ! frystyk   455: PUBLIC HTChildAnchor * HTRequest_childAnchor (HTRequest * request)
        !           456: {
        !           457:     return request ? request->childAnchor : NULL;
        !           458: }
        !           459: 
2.1       frystyk   460: /*
2.40      frystyk   461: **     Net
                    462: */
                    463: PUBLIC BOOL HTRequest_setNet (HTRequest * request, HTNet * net)
                    464: {
2.48      frystyk   465:     if (request) {
2.40      frystyk   466:        request->net = net;
                    467:        return YES;
                    468:     }
                    469:     return NO;
                    470: }
                    471: 
                    472: PUBLIC HTNet * HTRequest_net (HTRequest * request)
                    473: {
                    474:     return request ? request->net : NULL;
                    475: }
                    476: 
                    477: /*
                    478: **     User Profile
                    479: */
                    480: PUBLIC BOOL HTRequest_setUserProfile (HTRequest * request, HTUserProfile * up)
                    481: {
2.48      frystyk   482:     if (request) {
2.40      frystyk   483:        request->userprofile = up;
                    484:        return YES;
                    485:     }
                    486:     return NO;
                    487: }
                    488: 
                    489: PUBLIC HTUserProfile * HTRequest_userProfile (HTRequest * request)
                    490: {
                    491:     return request ? request->userprofile : NULL;
                    492: }
                    493: 
                    494: /*
2.1       frystyk   495: **     Parent anchor for Referer field
                    496: */
2.3       frystyk   497: PUBLIC void HTRequest_setParent (HTRequest *request, HTParentAnchor *parent)
2.1       frystyk   498: {
                    499:     if (request) request->parentAnchor = parent;
                    500: }
                    501: 
2.3       frystyk   502: PUBLIC HTParentAnchor * HTRequest_parent (HTRequest *request)
2.1       frystyk   503: {
                    504:     return request ? request->parentAnchor : NULL;
                    505: }
                    506: 
                    507: /*
                    508: **     Output stream
                    509: */
2.3       frystyk   510: PUBLIC void HTRequest_setOutputStream (HTRequest *request, HTStream *output)
2.1       frystyk   511: {
                    512:     if (request) request->output_stream = output;
                    513: }
                    514: 
2.4       frystyk   515: PUBLIC HTStream *HTRequest_outputStream (HTRequest *request)
2.1       frystyk   516: {
                    517:     return request ? request->output_stream : NULL;
                    518: }
                    519: 
                    520: /*
                    521: **     Output format
                    522: */
2.3       frystyk   523: PUBLIC void HTRequest_setOutputFormat (HTRequest *request, HTFormat format)
2.1       frystyk   524: {
                    525:     if (request) request->output_format = format;
                    526: }
                    527: 
2.4       frystyk   528: PUBLIC HTFormat HTRequest_outputFormat (HTRequest *request)
2.1       frystyk   529: {
                    530:     return request ? request->output_format : NULL;
                    531: }
                    532: 
                    533: /*
                    534: **     Debug stream
                    535: */
2.3       frystyk   536: PUBLIC void HTRequest_setDebugStream (HTRequest *request, HTStream *debug)
2.1       frystyk   537: {
                    538:     if (request) request->debug_stream = debug;
                    539: }
                    540: 
2.4       frystyk   541: PUBLIC HTStream *HTRequest_debugStream (HTRequest *request)
2.1       frystyk   542: {
                    543:     return request ? request->debug_stream : NULL;
                    544: }
                    545: 
                    546: /*
                    547: **     Debug Format
                    548: */
2.3       frystyk   549: PUBLIC void HTRequest_setDebugFormat (HTRequest *request, HTFormat format)
2.1       frystyk   550: {
                    551:     if (request) request->debug_format = format;
                    552: }
                    553: 
2.4       frystyk   554: PUBLIC HTFormat HTRequest_debugFormat (HTRequest *request)
2.1       frystyk   555: {
                    556:     return request ? request->debug_format : NULL;
                    557: }
                    558: 
2.35      frystyk   559: /*
                    560: **     Input stream
                    561: */
                    562: PUBLIC void HTRequest_setInputStream (HTRequest *request, HTStream *input)
                    563: {
                    564:     if (request) request->input_stream = input;
                    565: }
                    566: 
                    567: PUBLIC HTStream *HTRequest_inputStream (HTRequest *request)
                    568: {
                    569:     return request ? request->input_stream : NULL;
                    570: }
                    571: 
2.1       frystyk   572: /*
2.51      frystyk   573: **     Net before and after callbacks
2.34      hallam    574: */
2.51      frystyk   575: PUBLIC BOOL HTRequest_addBefore (HTRequest * request, HTNetCallback * filter,
                    576:                                 void * param, int status,
2.34      hallam    577:                                 BOOL override)
                    578: {
                    579:     if (request) {
                    580:        request->befores_local = override;
2.51      frystyk   581:        if (!request->befores) request->befores = HTList_new();
                    582:        return HTNetCall_add(request->befores, filter, param, status);
                    583:     }
                    584:     return NO;
                    585: }
                    586: 
                    587: PUBLIC BOOL HTRequest_deleteBefore (HTRequest * request, HTNetCallback * filter)
                    588: {
                    589:     if (request && request->befores)
                    590:        return HTNetCall_delete(request->befores, filter);
                    591:     return NO;
                    592: }
                    593: 
                    594: PUBLIC BOOL HTRequest_deleteBeforeAll (HTRequest * request)
                    595: {
                    596:     if (request && request->befores) {
                    597:        HTNetCall_deleteAll(request->befores);
                    598:        request->befores = NULL;
                    599:        request->befores_local = NO;
                    600:        return YES;
2.34      hallam    601:     }
2.51      frystyk   602:     return NO;
2.34      hallam    603: }
                    604: 
                    605: PUBLIC HTList * HTRequest_before (HTRequest *request, BOOL *override)
                    606: {
                    607:     if (request) {
                    608:        *override = request->befores_local;
                    609:        return request->befores;
                    610:     }
                    611:     return NULL;
                    612: }
                    613: 
2.51      frystyk   614: PUBLIC BOOL HTRequest_addAfter (HTRequest * request, HTNetCallback * filter,
                    615:                                void * param, int status,
2.34      hallam    616:                                BOOL override)
                    617: {
                    618:     if (request) {
                    619:        request->afters_local = override;
2.51      frystyk   620:        if (!request->afters) request->afters = HTList_new();
                    621:        return HTNetCall_add(request->afters, filter, param, status);
2.34      hallam    622:     }
2.51      frystyk   623:     return NO;
                    624: }
                    625: 
                    626: PUBLIC BOOL HTRequest_deleteAfter (HTRequest * request, HTNetCallback * filter)
                    627: {
                    628:     if (request && request->afters)
                    629:        return HTNetCall_delete(request->afters, filter);
                    630:     return NO;
                    631: }
                    632: 
                    633: PUBLIC BOOL HTRequest_deleteAfterAll (HTRequest * request)
                    634: {
                    635:     if (request && request->afters) {
                    636:        HTNetCall_deleteAll(request->afters);
                    637:        request->afters = NULL;
                    638:        request->afters_local = NO;
                    639:        return YES;
                    640:     }
                    641:     return NO;
2.34      hallam    642: }
                    643: 
                    644: PUBLIC HTList * HTRequest_after (HTRequest *request, BOOL *override)
                    645: {
                    646:     if (request) {
                    647:        *override = request->afters_local;
                    648:        return request->afters;
                    649:     }
                    650:     return NULL;
                    651: }
                    652: 
                    653: /*
2.1       frystyk   654: **     Call back function for context swapping
                    655: */
2.3       frystyk   656: PUBLIC void HTRequest_setCallback (HTRequest *request, HTRequestCallback *cbf)
2.1       frystyk   657: {
2.3       frystyk   658:     if (request) request->callback = cbf;
2.1       frystyk   659: }
                    660: 
2.3       frystyk   661: PUBLIC HTRequestCallback *HTRequest_callback (HTRequest *request)
2.1       frystyk   662: {
                    663:     return request ? request->callback : NULL;
                    664: }
                    665: 
                    666: /*
                    667: **     Context pointer to be used in context call back function
                    668: */
2.3       frystyk   669: PUBLIC void HTRequest_setContext (HTRequest *request, void *context)
2.1       frystyk   670: {
                    671:     if (request) request->context = context;
                    672: }
                    673: 
2.3       frystyk   674: PUBLIC void *HTRequest_context (HTRequest *request)
2.1       frystyk   675: {
                    676:     return request ? request->context : NULL;
                    677: }
                    678: 
                    679: /*
2.23      frystyk   680: **     Socket mode: preemptive or non-preemptive (blocking or non-blocking)
2.1       frystyk   681: */
2.23      frystyk   682: PUBLIC void HTRequest_setPreemptive (HTRequest *request, BOOL mode)
2.1       frystyk   683: {
2.23      frystyk   684:     if (request) request->preemptive = mode;
2.1       frystyk   685: }
                    686: 
2.23      frystyk   687: PUBLIC BOOL HTRequest_preemptive (HTRequest *request)
2.1       frystyk   688: {
2.23      frystyk   689:     return request ? request->preemptive : NO;
2.47      frystyk   690: }
                    691: 
                    692: /*
                    693: **     Has output stream been connected to the channel? If not then we
                    694: **     must free it explicitly when deleting the request object
                    695: */
                    696: PUBLIC void HTRequest_setOutputConnected (HTRequest * request, BOOL mode)
                    697: {
                    698:     if (request) request->connected = mode;
                    699: }
                    700: 
                    701: PUBLIC BOOL HTRequest_outputConnected (HTRequest * request)
                    702: {
                    703:     return request ? request->connected : NO;
2.1       frystyk   704: }
                    705: 
                    706: /*
                    707: **     Should we use content negotiation?
                    708: */
2.3       frystyk   709: PUBLIC void HTRequest_setNegotiation (HTRequest *request, BOOL mode)
2.1       frystyk   710: {
                    711:     if (request) request->ContentNegotiation = mode;
                    712: }
                    713: 
2.3       frystyk   714: PUBLIC BOOL HTRequest_negotiation (HTRequest *request)
2.1       frystyk   715: {
                    716:     return request ? request->ContentNegotiation : NO;
2.40      frystyk   717: }
                    718: 
                    719: /*
2.53      frystyk   720: **     Are we using the full URL in the request or not?
2.40      frystyk   721: */
2.41      frystyk   722: PUBLIC void HTRequest_setFullURI (HTRequest *request, BOOL mode)
2.40      frystyk   723: {
2.53      frystyk   724:     if (request) request->full_uri = mode;
2.40      frystyk   725: }
                    726: 
2.41      frystyk   727: PUBLIC BOOL HTRequest_fullURI (HTRequest *request)
2.40      frystyk   728: {
2.53      frystyk   729:     return request ? request->full_uri : NO;
                    730: }
                    731: 
                    732: /*
                    733: **     Are we using a proxy or not and in that case, which one?
                    734: */
                    735: PUBLIC BOOL HTRequest_setProxy (HTRequest * request, const char * proxy)
                    736: {
                    737:     if (request && proxy) {
                    738:        StrAllocCopy(request->proxy, proxy);
                    739:        return YES;
                    740:     }
                    741:     return NO;
                    742: }
                    743: 
                    744: PUBLIC char * HTRequest_proxy (HTRequest * request)
                    745: {
                    746:     return request ? request->proxy : NULL;
2.1       frystyk   747: }
                    748: 
2.54      frystyk   749: PUBLIC BOOL HTRequest_deleteProxy (HTRequest * request)
                    750: {
                    751:     if (request) {
                    752:        HT_FREE(request->proxy);
                    753:        return YES;
                    754:     }
                    755:     return NO;
                    756: }
                    757: 
2.1       frystyk   758: /*
                    759: **     Bytes read in this request
                    760: */
2.3       frystyk   761: PUBLIC long HTRequest_bytesRead(HTRequest * request)
2.1       frystyk   762: {
                    763:     return request ? HTNet_bytesRead(request->net) : -1;
                    764: }
                    765: 
                    766: /*
2.23      frystyk   767: **     Bytes written in this request
                    768: */
                    769: PUBLIC long HTRequest_bytesWritten (HTRequest * request)
                    770: {
                    771:     return request ? HTNet_bytesWritten(request->net) : -1;
                    772: }
                    773: 
                    774: /*
2.1       frystyk   775: **     Kill this request
                    776: */
2.3       frystyk   777: PUBLIC BOOL HTRequest_kill(HTRequest * request)
2.1       frystyk   778: {
                    779:     return request ? HTNet_kill(request->net) : NO;
                    780: }
                    781: 
2.11      frystyk   782: /*     Error Management
                    783: **     ----------------
2.1       frystyk   784: **     Returns the error stack if a stream is 
                    785: */
2.11      frystyk   786: PUBLIC HTList * HTRequest_error (HTRequest * request)
2.1       frystyk   787: {
                    788:     return request ? request->error_stack : NULL;
                    789: }
                    790: 
2.11      frystyk   791: PUBLIC void HTRequest_setError (HTRequest * request, HTList * list)
                    792: {
                    793:     if (request) request->error_stack = list;
                    794: }
                    795: 
                    796: PUBLIC BOOL HTRequest_addError (HTRequest *    request,
                    797:                                HTSeverity      severity,
                    798:                                BOOL            ignore,
                    799:                                int             element,
                    800:                                void *          par,
                    801:                                unsigned int    length,
                    802:                                char *          where)
                    803: {
                    804:     if (request) {
                    805:        if (!request->error_stack) request->error_stack = HTList_new();
                    806:        return HTError_add(request->error_stack, severity, ignore, element,
                    807:                           par, length, where);
                    808:     }
                    809:     return NO;
                    810: }
                    811: 
                    812: PUBLIC BOOL HTRequest_addSystemError (HTRequest *      request,
                    813:                                      HTSeverity        severity,
                    814:                                      int               errornumber,
                    815:                                      BOOL              ignore,
                    816:                                      char *            syscall)
                    817: {
                    818:     if (request) {
                    819:        if (!request->error_stack) request->error_stack = HTList_new();
                    820:        return HTError_addSystem(request->error_stack, severity, errornumber,
                    821:                                 ignore, syscall);
                    822:     }
                    823:     return NO;
                    824: }
                    825: 
2.1       frystyk   826: /*
                    827: **     When to retry a request if HT_RETRY
                    828: **     Returns -1 if not available
                    829: */
                    830: PUBLIC time_t HTRequest_retryTime (HTRequest * request)
                    831: {
                    832:     return request ? request->retry_after : -1;
                    833: }
                    834: 
                    835: /*
2.23      frystyk   836: **    Redirection informantion
                    837: */
                    838: PUBLIC HTAnchor * HTRequest_redirection (HTRequest * request)
                    839: {
                    840:     return (request ? request->redirectionAnchor : NULL);
2.46      frystyk   841: }
                    842: 
                    843: PUBLIC BOOL HTRequest_setRedirection (HTRequest * request, HTAnchor * anchor)
                    844: {
                    845:     if (request && anchor) {
                    846:        request->redirectionAnchor = (HTAnchor *) HTAnchor_parent(anchor);
                    847:        return YES;
                    848:     }
                    849:     return NO;
2.23      frystyk   850: }
                    851: 
                    852: /*
2.1       frystyk   853: **  Set max number of automatic reload. Default is HT_MAX_RELOADS
                    854: */
2.3       frystyk   855: PUBLIC BOOL HTRequest_setMaxRetry (int newmax)
2.1       frystyk   856: {
                    857:     if (newmax > 0) {
                    858:        HTMaxRetry = newmax;
                    859:        return YES;
                    860:     }
                    861:     return NO;
                    862: }
                    863: 
2.3       frystyk   864: PUBLIC int HTRequest_maxRetry (void)
2.1       frystyk   865: {
                    866:     return HTMaxRetry;
                    867: }
                    868: 
2.52      frystyk   869: PUBLIC int HTRequest_retrys (HTRequest * request)
                    870: {
                    871:     return request ? request->retrys : 0;
                    872: }
                    873: 
2.55      frystyk   874: PUBLIC BOOL HTRequest_addRetry (HTRequest * request)
                    875: {
                    876:     return (request && request->retrys++);
                    877: }
                    878: 
2.1       frystyk   879: /*
                    880: **     Should we try again?
                    881: **     --------------------
                    882: **     Returns YES if we are to retry the load, NO otherwise. We check
                    883: **     this so that we don't go into an infinte loop
                    884: */
2.52      frystyk   885: PUBLIC BOOL HTRequest_doRetry (HTRequest *request)
2.1       frystyk   886: {
                    887:     return (request && request->retrys < HTMaxRetry-1);
2.54      frystyk   888: }
                    889: 
                    890: /*
                    891: **     Handle the max forward header value
                    892: */
                    893: PUBLIC BOOL HTRequest_setMaxForwards (HTRequest * request, int maxforwards)
                    894: {
                    895:     if (request && maxforwards >= 0) {
                    896:        request->max_forwards = maxforwards;
                    897:        HTRequest_addRqHd(request, HT_C_MAX_FORWARDS);         /* Turn it on */
                    898:        return YES;
                    899:     }
                    900:     return NO;
                    901: }
                    902: 
                    903: PUBLIC int HTRequest_maxForwards (HTRequest * request)
                    904: {
                    905:     return request ? request->max_forwards : -1;
2.1       frystyk   906: }
                    907: 
2.9       frystyk   908: /*
                    909: **  Priority to be inherited by all HTNet object hanging off this request
                    910: **  The priority can later be chaned by calling the HTNet object directly
                    911: */
                    912: PUBLIC BOOL HTRequest_setPriority (HTRequest * request, HTPriority priority)
                    913: {
                    914:     if (request) {
                    915:        request->priority = priority;
                    916:        return YES;
                    917:     }
                    918:     return NO;
                    919: }
                    920: 
                    921: PUBLIC HTPriority HTRequest_priority (HTRequest * request)
                    922: {
2.19      frystyk   923:     return (request ? request->priority : HT_PRIORITY_INV);
2.9       frystyk   924: }
                    925: 
2.18      frystyk   926: /*
2.31      frystyk   927: **  Access Authentication Credentials
                    928: */
2.49      frystyk   929: PUBLIC BOOL HTRequest_deleteCredentials (HTRequest * request)
                    930: {
                    931:     if (request && request->credentials) {
                    932:        HTAssocList_delete(request->credentials);
                    933:        request->credentials = NULL;
                    934:        return YES;
                    935:     }
                    936:     return NO;
                    937: }
                    938: 
                    939: PUBLIC BOOL HTRequest_addCredentials (HTRequest * request,
                    940:                                    char * token, char * value)
2.31      frystyk   941: {
                    942:     if (request) {
2.49      frystyk   943:        if (!request->credentials) request->credentials = HTAssocList_new();
                    944:        return HTAssocList_addObject(request->credentials, token, value);
2.31      frystyk   945:     }
                    946:     return NO;
                    947: }
                    948: 
                    949: PUBLIC HTAssocList * HTRequest_credentials (HTRequest * request)
                    950: {
                    951:     return (request ? request->credentials : NULL);
                    952: }
                    953: 
                    954: /*
                    955: **  Access Authentication Challenges
                    956: */
2.49      frystyk   957: PUBLIC BOOL HTRequest_addChallenge (HTRequest * request,
                    958:                                    char * token, char * value)
2.31      frystyk   959: {
                    960:     if (request) {
2.49      frystyk   961:        if (!request->challenge) request->challenge = HTAssocList_new();
                    962:        return HTAssocList_addObject(request->challenge, token, value);
                    963:     }
                    964:     return NO;
                    965: }
                    966: 
                    967: PUBLIC BOOL HTRequest_deleteChallenge (HTRequest * request)
                    968: {
                    969:     if (request && request->challenge) {
                    970:        HTAssocList_delete(request->challenge);
                    971:        request->challenge = NULL;
2.31      frystyk   972:        return YES;
                    973:     }
                    974:     return NO;
                    975: }
                    976: 
                    977: PUBLIC HTAssocList * HTRequest_challenge (HTRequest * request)
                    978: {
                    979:     return (request ? request->challenge : NULL);
                    980: }
                    981: 
                    982: /*
                    983: **  Access Authentication Realms
2.18      frystyk   984: */
2.31      frystyk   985: PUBLIC BOOL HTRequest_setRealm (HTRequest * request, char * realm)
2.18      frystyk   986: {
2.49      frystyk   987:     if (request && realm) {
                    988:        StrAllocCopy(request->realm, realm);
2.18      frystyk   989:        return YES;
                    990:     }
                    991:     return NO;
                    992: }
                    993: 
2.32      frystyk   994: PUBLIC const char * HTRequest_realm (HTRequest * request)
2.18      frystyk   995: {
2.31      frystyk   996:     return (request ? request->realm : NULL);
2.42      frystyk   997: }
                    998: 
                    999: /*
2.49      frystyk  1000: **  Access Authentication Schemes
                   1001: */
                   1002: PUBLIC BOOL HTRequest_setScheme (HTRequest * request, char * scheme)
                   1003: {
                   1004:     if (request && scheme) {
                   1005:        StrAllocCopy(request->scheme, scheme);
                   1006:        return YES;
                   1007:     }
                   1008:     return NO;
                   1009: }
                   1010: 
                   1011: PUBLIC const char * HTRequest_scheme (HTRequest * request)
                   1012: {
                   1013:     return (request ? request->scheme : NULL);
                   1014: }
                   1015: 
                   1016: /*
2.42      frystyk  1017: **  Source request
                   1018: */
                   1019: PUBLIC BOOL HTRequest_setSource (HTRequest * request, HTRequest * source)
                   1020: {
                   1021:     if (request) {
                   1022:        request->source = source;
                   1023:        return YES;
                   1024:     }
                   1025:     return NO;
                   1026: }
                   1027: 
                   1028: PUBLIC HTRequest * HTRequest_source (HTRequest * request)
                   1029: {
                   1030:     return (request ? request->source : NULL);
                   1031: }
                   1032: 
                   1033: PUBLIC BOOL HTRequest_isPostWeb (HTRequest * request)
                   1034: {
2.43      eric     1035:     return (request ? request->source != NULL: NO);
2.42      frystyk  1036: }
                   1037: 
                   1038: /*
                   1039: **  Internal request object
                   1040: */
                   1041: PUBLIC BOOL HTRequest_setInternal (HTRequest * request, BOOL mode)
                   1042: {
                   1043:     if (request) {
                   1044:        request->internal = mode;
                   1045:        return YES;
                   1046:     }
                   1047:     return NO;
                   1048: }
                   1049: 
                   1050: PUBLIC BOOL HTRequest_internal (HTRequest * request)
                   1051: {
                   1052:     return (request ? request->internal : NO);
                   1053: }
                   1054: 
                   1055: /*
                   1056: **     POST Call back function for sending data to the destination
                   1057: */
                   1058: PUBLIC void HTRequest_setPostCallback (HTRequest *request, HTPostCallback *cbf)
                   1059: {
                   1060:     if (request) request->PostCallback = cbf;
                   1061: }
                   1062: 
                   1063: PUBLIC HTPostCallback * HTRequest_postCallback (HTRequest * request)
                   1064: {
                   1065:     return request ? request->PostCallback : NULL;
2.18      frystyk  1066: }
                   1067: 
2.50      frystyk  1068: /*
                   1069: **     Entity Anchor
                   1070: */
                   1071: PUBLIC BOOL HTRequest_setEntityAnchor (HTRequest * request,
                   1072:                                       HTParentAnchor * anchor)
                   1073: {
                   1074:     if (request) {
                   1075:        request->source_anchor = anchor;
                   1076:        return YES;
                   1077:     }
                   1078:     return NO;
                   1079: }
                   1080: 
                   1081: PUBLIC HTParentAnchor * HTRequest_entityAnchor (HTRequest * request)
                   1082: {
                   1083:     return request ? request->source_anchor ? request->source_anchor :
                   1084:        request->anchor : NULL;
2.55      frystyk  1085: }
                   1086: 
                   1087: /*
                   1088: **     Simple Extension Protocol
                   1089: */
                   1090: PUBLIC BOOL HTRequest_addExtension (HTRequest * request,
                   1091:                                    char * token, char * value)
                   1092: {
                   1093:     if (request) {
                   1094:        if (!request->extension) request->extension = HTAssocList_new();
                   1095:        return HTAssocList_addObject(request->extension, token, value);
                   1096:     }
                   1097:     return NO;
                   1098: }
                   1099: 
                   1100: PUBLIC BOOL HTRequest_deleteExtension (HTRequest * request)
                   1101: {
                   1102:     if (request && request->extension) {
                   1103:        HTAssocList_delete(request->extension);
                   1104:        request->extension = NULL;
                   1105:        return YES;
                   1106:     }
                   1107:     return NO;
                   1108: }
                   1109: 
                   1110: PUBLIC HTAssocList * HTRequest_extension (HTRequest * request)
                   1111: {
                   1112:     return (request ? request->extension : NULL);
2.56    ! frystyk  1113: }
        !          1114: 
        !          1115: /*
        !          1116: **     Cache control directives
        !          1117: */
        !          1118: PUBLIC BOOL HTRequest_addCacheControl (HTRequest * request,
        !          1119:                                    char * token, char * value)
        !          1120: {
        !          1121:     if (request) {
        !          1122:        if (!request->cache_control) request->cache_control=HTAssocList_new();
        !          1123:        return HTAssocList_addObject(request->cache_control, token, value);
        !          1124:     }
        !          1125:     return NO;
        !          1126: }
        !          1127: 
        !          1128: PUBLIC BOOL HTRequest_deleteCacheControl (HTRequest * request)
        !          1129: {
        !          1130:     if (request && request->cache_control) {
        !          1131:        HTAssocList_delete(request->cache_control);
        !          1132:        request->cache_control = NULL;
        !          1133:        return YES;
        !          1134:     }
        !          1135:     return NO;
        !          1136: }
        !          1137: 
        !          1138: PUBLIC HTAssocList * HTRequest_cacheControl (HTRequest * request)
        !          1139: {
        !          1140:     return (request ? request->cache_control : NULL);
        !          1141: }
        !          1142: 
        !          1143: /*
        !          1144: **     Connection directives
        !          1145: */
        !          1146: PUBLIC BOOL HTRequest_addConnection (HTRequest * request,
        !          1147:                                    char * token, char * value)
        !          1148: {
        !          1149:     if (request) {
        !          1150:        if (!request->connection) request->connection=HTAssocList_new();
        !          1151:        return HTAssocList_addObject(request->connection, token, value);
        !          1152:     }
        !          1153:     return NO;
        !          1154: }
        !          1155: 
        !          1156: PUBLIC BOOL HTRequest_deleteConnection (HTRequest * request)
        !          1157: {
        !          1158:     if (request && request->connection) {
        !          1159:        HTAssocList_delete(request->connection);
        !          1160:        request->connection = NULL;
        !          1161:        return YES;
        !          1162:     }
        !          1163:     return NO;
        !          1164: }
        !          1165: 
        !          1166: PUBLIC HTAssocList * HTRequest_connection (HTRequest * request)
        !          1167: {
        !          1168:     return (request ? request->connection : NULL);
2.50      frystyk  1169: }
                   1170: 
2.1       frystyk  1171: /* ------------------------------------------------------------------------- */
                   1172: /*                             POST WEB METHODS                             */
                   1173: /* ------------------------------------------------------------------------- */
                   1174: 
                   1175: /*
                   1176: **  Add a destination request to this source request structure so that we
                   1177: **  build the internal request representation of the POST web
                   1178: **  Returns YES if OK, else NO
                   1179: */
2.23      frystyk  1180: PUBLIC BOOL HTRequest_addDestination (HTRequest * src, HTRequest * dest)
2.1       frystyk  1181: {
                   1182:     if (src && dest) {
2.23      frystyk  1183:        dest->source = src->source = src;
2.1       frystyk  1184:        if (!src->mainDestination) {
                   1185:            src->mainDestination = dest;
                   1186:            src->destRequests = 1;
2.36      frystyk  1187:            if (CORE_TRACE)
2.30      eric     1188:                HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk  1189:                         dest, src);
2.1       frystyk  1190:            return YES;
                   1191:        } else {
2.23      frystyk  1192:            if (!src->destinations) src->destinations = HTList_new();
2.1       frystyk  1193:            if (HTList_addObject(src->destinations, (void *) dest)==YES) {
                   1194:                src->destRequests++;
2.36      frystyk  1195:                if (CORE_TRACE)
2.30      eric     1196:                    HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk  1197:                             dest, src);
2.1       frystyk  1198:                return YES;
                   1199:            }
                   1200:        }
                   1201:     }
                   1202:     return NO;
                   1203: }
                   1204: 
                   1205: /*
                   1206: **  Remove a destination request from this source request structure
2.23      frystyk  1207: **  Remember only to delete the internal request objects as the other
                   1208: **  comes from the application!
2.1       frystyk  1209: **  Returns YES if OK, else NO
                   1210: */
2.23      frystyk  1211: PUBLIC BOOL HTRequest_removeDestination (HTRequest * dest)
2.1       frystyk  1212: {
                   1213:     BOOL found=NO;
                   1214:     if (dest && dest->source) {
                   1215:        HTRequest *src = dest->source;
                   1216:        if (src->mainDestination == dest) {
                   1217:            dest->source = NULL;
                   1218:            src->mainDestination = NULL;
                   1219:            src->destRequests--;
                   1220:            found = YES;
2.23      frystyk  1221:        } else if (src->destinations) {
2.1       frystyk  1222:            if (HTList_removeObject(src->destinations, (void *) dest)) {
                   1223:                src->destRequests--;
                   1224:                found = YES;
                   1225:            }
                   1226:        }
                   1227:        if (found) {
2.23      frystyk  1228:            if (dest->internal) HTRequest_delete(dest);
2.36      frystyk  1229:            if (CORE_TRACE)
2.30      eric     1230:                HTTrace("POSTWeb..... Deleting dest %p from src %p\n",
2.23      frystyk  1231:                         dest, src);
2.1       frystyk  1232:        }
2.23      frystyk  1233:        if (src->destRequests <= 0) {
2.36      frystyk  1234:            if (CORE_TRACE)
2.30      eric     1235:                HTTrace("POSTWeb..... terminated\n");
2.23      frystyk  1236:            if (src->internal) HTRequest_delete(src);
2.1       frystyk  1237:        }
                   1238:     }
                   1239:     return found;
                   1240: }
                   1241: 
                   1242: /*
2.23      frystyk  1243: **  Check to see whether all destinations are ready. If so then enable the
                   1244: **  source as ready for reading.
                   1245: **  Returns YES if all dests are ready, NO otherwise
                   1246: */
                   1247: PUBLIC BOOL HTRequest_destinationsReady (HTRequest * me)
                   1248: {
                   1249:     HTRequest * source = me ? me->source : NULL;
                   1250:     if (source) {
                   1251:        if (source->destStreams == source->destRequests) {
                   1252:            HTNet * net = source->net;
2.36      frystyk  1253:            if (CORE_TRACE)
2.30      eric     1254:                HTTrace("POSTWeb..... All destinations are ready!\n");
2.23      frystyk  1255:            if (net)                          /* Might already have finished */
2.38      eric     1256:                HTEvent_register(net->sockfd, source, (SockOps) FD_READ,
2.23      frystyk  1257:                                 net->cbf, net->priority);
                   1258:            return YES;
                   1259:        }
                   1260:     }
                   1261:     return NO;
                   1262: }
                   1263: 
                   1264: /*
                   1265: **  Find the source request object and make the link between the 
2.1       frystyk  1266: **  source output stream and the destination input stream. There can be
                   1267: **  a conversion between the two streams!
                   1268: **  Returns YES if link is made, NO otherwise
                   1269: */
2.3       frystyk  1270: PUBLIC BOOL HTRequest_linkDestination (HTRequest *dest)
2.1       frystyk  1271: {
                   1272:     if (dest && dest->input_stream && dest->source && dest!=dest->source) {
                   1273:        HTRequest *source = dest->source;
                   1274:        HTStream *pipe = HTStreamStack(source->output_format,
                   1275:                                       dest->input_format,
                   1276:                                       dest->input_stream,
                   1277:                                       dest, YES);
                   1278: 
                   1279:        /* Check if we are the only one - else spawn off T streams */
                   1280:        /* @@@ We don't do this yet @@@ */
                   1281: 
2.23      frystyk  1282:        /* Now set up output stream of the source */
                   1283:        if (source->output_stream)
                   1284:            (*source->output_stream->isa->_free)(source->output_stream);
2.1       frystyk  1285:        source->output_stream = pipe ? pipe : dest->input_stream;
                   1286: 
2.36      frystyk  1287:        if (CORE_TRACE)
2.30      eric     1288:            HTTrace("POSTWeb..... Linking dest %p to src %p\n",
2.23      frystyk  1289:                     dest, source);
2.1       frystyk  1290:        if (++source->destStreams == source->destRequests) {
                   1291:            HTNet *net = source->net;
2.36      frystyk  1292:            if (CORE_TRACE)
2.30      eric     1293:                HTTrace("POSTWeb..... All destinations ready!\n");
2.1       frystyk  1294:            if (net)                          /* Might already have finished */
2.38      eric     1295:                HTEvent_register(net->sockfd, source, (SockOps) FD_READ,
2.1       frystyk  1296:                                 net->cbf, net->priority);
                   1297:            return YES;
                   1298:        }
                   1299:     }
                   1300:     return NO;
                   1301: }
                   1302: 
                   1303: /*
                   1304: **  Remove a feed stream to a destination request from this source
                   1305: **  request structure. When all feeds are removed the request tree is
                   1306: **  ready to take down and the operation can be terminated.
                   1307: **  Returns YES if removed, else NO
                   1308: */
2.3       frystyk  1309: PUBLIC BOOL HTRequest_unlinkDestination (HTRequest *dest)
2.1       frystyk  1310: {
                   1311:     BOOL found = NO;
                   1312:     if (dest && dest->source && dest != dest->source) {
                   1313:        HTRequest *src = dest->source;
                   1314:        if (src->mainDestination == dest) {
                   1315:            src->output_stream = NULL;
                   1316:            if (dest->input_stream)
                   1317:                (*dest->input_stream->isa->_free)(dest->input_stream);
                   1318:            found = YES;
                   1319:        } else if (src->destinations) {
                   1320: 
                   1321:            /* LOOK THROUGH THE LIST AND FIND THE RIGHT ONE */
                   1322: 
                   1323:        }       
                   1324:        if (found) {
                   1325:            src->destStreams--;
2.36      frystyk  1326:            if (CORE_TRACE)
2.30      eric     1327:                HTTrace("POSTWeb..... Unlinking dest %p from src %p\n",
2.23      frystyk  1328:                         dest, src);
2.1       frystyk  1329:            return YES;
                   1330:        }
                   1331:     }
                   1332:     return NO;
                   1333: }
                   1334: 
                   1335: /*
                   1336: **  Removes all request structures in this PostWeb.
                   1337: */
2.3       frystyk  1338: PUBLIC BOOL HTRequest_removePostWeb (HTRequest *me)
2.1       frystyk  1339: {
                   1340:     if (me && me->source) {
                   1341:        HTRequest *source = me->source;
                   1342: 
                   1343:        /* Kill main destination */
                   1344:        if (source->mainDestination)
                   1345:            HTRequest_removeDestination(source->mainDestination);
                   1346: 
                   1347:        /* Kill all other destinations */
                   1348:        if (source->destinations) {
                   1349:            HTList *cur = source->destinations;
                   1350:            HTRequest *pres;
                   1351:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
                   1352:                HTRequest_removeDestination(pres);
                   1353:        }
                   1354: 
                   1355:        /* Remove source request */
                   1356:        HTRequest_removeDestination(source);
                   1357:        return YES;
                   1358:     }
                   1359:     return NO;
                   1360: }
                   1361: 
                   1362: /*
                   1363: **  Kills all threads in a POST WEB connected to this request but
2.23      frystyk  1364: **  NOT this request itself. We also keep the request structures.
                   1365: **  Some requests might be preemptive, for example a SMTP request (when
2.1       frystyk  1366: **  that has been implemented). However, this will be handled internally
                   1367: **  in the load function.
                   1368: */
2.3       frystyk  1369: PUBLIC BOOL HTRequest_killPostWeb (HTRequest *me)
2.1       frystyk  1370: {
                   1371:     if (me && me->source) {
                   1372:        HTRequest *source = me->source;
2.36      frystyk  1373:        if (CORE_TRACE) HTTrace("POSTWeb..... Killing\n");
2.1       frystyk  1374: 
2.23      frystyk  1375:        /*
                   1376:        ** Kill source. The stream tree is now freed so we have to build
                   1377:        ** that again. This is done in HTRequest_linkDestination()
                   1378:        */
                   1379:        if (me != source) {
                   1380:            HTNet_kill(source->net);
                   1381:            source->output_stream = NULL;
                   1382:        }
2.1       frystyk  1383: 
                   1384:        /* Kill all other destinations */
                   1385:        if (source->destinations) {
                   1386:            HTList *cur = source->destinations;
                   1387:            HTRequest *pres;
                   1388:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
2.23      frystyk  1389:                if (me != pres) HTNet_kill(pres->net);
2.1       frystyk  1390:        }
2.23      frystyk  1391: 
                   1392:        /* Kill main destination */
                   1393:        if (source->mainDestination && me != source->mainDestination)
                   1394:            HTNet_kill(source->mainDestination->net);
2.1       frystyk  1395:        return YES;
                   1396:     }
                   1397:     return NO;
                   1398: }
                   1399: 
                   1400: /* --------------------------------------------------------------------------*/
                   1401: /*                             Document Loader                              */
                   1402: /* --------------------------------------------------------------------------*/
                   1403: 
                   1404: /*     Request a resource
                   1405: **     ------------------
                   1406: **     This is an internal routine, which has an address AND a matching
                   1407: **     anchor.  (The public routines are called with one OR the other.)
                   1408: **     Returns:
                   1409: **             YES     if request has been registered (success)
                   1410: **             NO      an error occured
                   1411: */
2.9       frystyk  1412: PUBLIC BOOL HTLoad (HTRequest * request, BOOL recursive)
2.1       frystyk  1413: {
                   1414:     if (!request || !request->anchor) {
2.36      frystyk  1415:         if (CORE_TRACE) HTTrace("Load Start.. Bad argument\n");
2.1       frystyk  1416:         return NO;
                   1417:     }
2.50      frystyk  1418:     HTAnchor_clearPhysical(request->anchor);
2.14      frystyk  1419:     if (request->method == METHOD_INVALID) request->method = METHOD_GET;
2.16      frystyk  1420:     if (!recursive && request->error_stack) {
                   1421:        HTError_deleteAll(request->error_stack);
                   1422:        request->error_stack = NULL;
                   1423:     }
2.18      frystyk  1424:     return HTNet_newClient(request);
2.1       frystyk  1425: }
                   1426: 

Webmaster