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

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

Webmaster