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

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.37    ! frystyk     6: **     @(#) $Id: HTReqMan.c,v 2.36 1996/04/14 01:23:21 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.1       frystyk    33: #include "HTUtils.h"
                     34: #include "HTString.h"
                     35: #include "HTParse.h"
                     36: #include "HTAlert.h"
                     37: #include "HTError.h"
                     38: #include "HTList.h"
                     39: #include "HTCache.h"
2.2       frystyk    40: #include "HTNetMan.h"
2.1       frystyk    41: #include "HTEvntrg.h"
                     42: #include "HTProt.h"
                     43: #include "HTProxy.h"
                     44: #include "HTReqMan.h"                                   /* Implemented here */
                     45: 
2.14      frystyk    46: #include "HTRules.h"
                     47: 
2.1       frystyk    48: #ifndef HT_MAX_RELOADS
                     49: #define HT_MAX_RELOADS 6
                     50: #endif
2.13      frystyk    51: 
2.1       frystyk    52: PRIVATE int HTMaxRetry = HT_MAX_RELOADS;
                     53: 
                     54: struct _HTStream {
                     55:        HTStreamClass * isa;
                     56:        /* ... */
                     57: };
                     58: 
                     59: /* --------------------------------------------------------------------------*/
                     60: /*                     Management of the HTRequest structure                */
                     61: /* --------------------------------------------------------------------------*/
                     62: 
                     63: /*  Create  a request structure
                     64: **  ---------------------------
                     65: */
2.3       frystyk    66: PUBLIC HTRequest * HTRequest_new (void)
2.1       frystyk    67: {
2.29      frystyk    68:     HTRequest * me;
                     69:     if ((me = (HTRequest *) HT_CALLOC(1, sizeof(HTRequest))) == NULL)
                     70:         HT_OUTOFMEM("HTRequest_new()");
2.1       frystyk    71:     
2.7       frystyk    72:    /* Force Reload */
2.1       frystyk    73:     me->reload = HT_ANY_VERSION;
                     74: 
                     75:     /* Format of output */
                     76:     me->output_format  = WWW_PRESENT;      /* default it to present to user */
2.21      frystyk    77:     me->debug_format   = WWW_DEBUG;     /* default format of error messages */
2.1       frystyk    78: 
                     79:     /* HTTP headers */
                     80:     me->GenMask                = DEFAULT_GENERAL_HEADERS;
                     81:     me->RequestMask    = DEFAULT_REQUEST_HEADERS;
2.22      frystyk    82:     me->ResponseMask   = DEFAULT_RESPONSE_HEADERS;
2.1       frystyk    83:     me->EntityMask     = DEFAULT_ENTITY_HEADERS;
                     84: 
                     85:     /* Default retry after value */
                     86:     me->retry_after = -1;
2.19      frystyk    87:     me->priority = HT_PRIORITY_MAX;
2.1       frystyk    88: 
                     89:     /* Content negotiation */
                     90:     me->ContentNegotiation = NO;                      /* Do this by default */
                     91: 
2.13      frystyk    92: #ifdef WWW_WIN_ASYNC
                     93:     HTEvent_winHandle(me);
2.1       frystyk    94: #endif
                     95:     return me;
                     96: }
                     97: 
2.28      frystyk    98: /*     HTRequest_clear
                     99: **     ---------------
                    100: **     Clears all protocol specific information so that the request object
                    101: **     can be used for another request.
                    102: **     Returns YES if OK, else NO
                    103: */
                    104: PUBLIC BOOL HTRequest_clear (HTRequest * me)
                    105: {
                    106:     if (me) {
                    107:        me->boundary = NULL;
                    108:        me->error_stack = NULL;
                    109:        me->net = NULL;
2.31      frystyk   110:        me->scheme = NULL;
                    111:        me->realm = NULL;
                    112:        me->challenge = NULL;
                    113:        me->credentials = NULL;
2.28      frystyk   114:        return YES;
                    115:     }
                    116:     return NO;
                    117: }
                    118: 
2.18      frystyk   119: /*     HTRequest_dup
                    120: **     -------------
                    121: **     Creates a new HTRequest object as a duplicate of the src request.
                    122: **     Returns YES if OK, else NO
                    123: */
                    124: PUBLIC HTRequest * HTRequest_dup (HTRequest * src)
                    125: {
                    126:     HTRequest * me;
2.33      eric      127:     if (!src) return 0;
2.29      frystyk   128:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    129:         HT_OUTOFMEM("HTRequest_dup");
2.18      frystyk   130:     memcpy(me, src, sizeof(HTRequest));
                    131:     return me;
                    132: }
2.1       frystyk   133: 
2.23      frystyk   134: /*     HTRequest_dupInternal
                    135: **     ---------------------
                    136: **     Creates a new HTRequest object as a duplicate of the src request.
                    137: **     The difference to the HTRequest_dup function is that we don't copy the
                    138: **     error_stack and other information that the application keeps in its
                    139: **     copy of the request object. Otherwise it will be freed multiple times
                    140: **     Returns YES if OK, else NO
                    141: */
                    142: PUBLIC HTRequest * HTRequest_dupInternal (HTRequest * src)
                    143: {
                    144:     HTRequest * me;
2.33      eric      145:     if (!src) return 0;
2.29      frystyk   146:     if ((me = (HTRequest  *) HT_MALLOC(sizeof(HTRequest))) == NULL)
                    147:         HT_OUTOFMEM("HTRequest_dup");
2.23      frystyk   148:     memcpy(me, src, sizeof(HTRequest));
2.28      frystyk   149:     HTRequest_clear(me);
2.23      frystyk   150:     return me;
                    151: }
                    152: 
2.1       frystyk   153: /*  Delete a request structure
                    154: **  --------------------------
                    155: */
2.3       frystyk   156: PUBLIC void HTRequest_delete (HTRequest * request)
2.1       frystyk   157: {
                    158:     if (request) {
2.29      frystyk   159:        HT_FREE(request->boundary);
2.11      frystyk   160:        if (request->error_stack) HTError_deleteAll(request->error_stack);
2.31      frystyk   161:        if (request->net) request->net->request = NULL;
2.13      frystyk   162: 
2.31      frystyk   163:        HT_FREE(request->scheme);           /* Current authentication scheme */
                    164:        if (request->challenge) HTAssocList_delete(request->challenge);
                    165:        if (request->credentials) HTAssocList_delete(request->credentials);
2.29      frystyk   166:        HT_FREE(request);
2.1       frystyk   167:     }
                    168: }
                    169: 
                    170: /*
                    171: **     Method
                    172: */
2.3       frystyk   173: PUBLIC void HTRequest_setMethod (HTRequest *request, HTMethod method)
2.1       frystyk   174: {
                    175:     if (request) request->method = method;
                    176: }
                    177: 
2.3       frystyk   178: PUBLIC HTMethod HTRequest_method (HTRequest *request)
2.1       frystyk   179: {
                    180:     return request ? request->method : METHOD_INVALID;
                    181: }
                    182: 
                    183: /*
                    184: **     Reload Mode
                    185: */
2.3       frystyk   186: PUBLIC void HTRequest_setReloadMode (HTRequest *request, HTReload mode)
2.1       frystyk   187: {
                    188:     if (request) request->reload = mode;
                    189: }
                    190: 
2.3       frystyk   191: PUBLIC HTReload HTRequest_reloadMode (HTRequest *request)
2.1       frystyk   192: {
                    193:     return request ? request->reload : HT_ANY_VERSION;
                    194: }
                    195: 
                    196: /*
                    197: **     Accept Format Types
                    198: **     list can be NULL
                    199: */
2.6       frystyk   200: PUBLIC void HTRequest_setConversion (HTRequest *request, HTList *type,
                    201:                                     BOOL override)
2.1       frystyk   202: {
                    203:     if (request) {
                    204:        request->conversions = type;
                    205:        request->conv_local = override;
                    206:     }
                    207: }
                    208: 
2.6       frystyk   209: PUBLIC HTList * HTRequest_conversion (HTRequest *request)
2.1       frystyk   210: {
                    211:     return request ? request->conversions : NULL;
                    212: }
                    213: 
                    214: /*
                    215: **     Accept Encoding 
                    216: **     list can be NULL
                    217: */
2.3       frystyk   218: PUBLIC void HTRequest_setEncoding (HTRequest *request, HTList *enc,
                    219:                                   BOOL override)
2.1       frystyk   220: {
                    221:     if (request) {
                    222:        request->encodings = enc;
                    223:        request->enc_local = override;
                    224:     }
                    225: }
                    226: 
2.3       frystyk   227: PUBLIC HTList * HTRequest_encoding (HTRequest *request)
2.1       frystyk   228: {
                    229:     return request ? request->encodings : NULL;
                    230: }
                    231: 
2.37    ! frystyk   232: /*
        !           233: **     Accept Transfer Encoding 
        !           234: **     list can be NULL
        !           235: */
        !           236: PUBLIC void HTRequest_setTransfer (HTRequest * request,
        !           237:                                   HTList * cte, BOOL override)
        !           238: {
        !           239:     if (request) {
        !           240:        request->ctes = cte;
        !           241:        request->cte_local = override;
        !           242:     }
        !           243: }
        !           244: 
        !           245: PUBLIC HTList * HTRequest_transfer (HTRequest * request)
        !           246: {
        !           247:     return request ? request->ctes : NULL;
        !           248: }
        !           249: 
2.1       frystyk   250: /*
                    251: **     Accept Language
                    252: **     list can be NULL
                    253: */
2.3       frystyk   254: PUBLIC void HTRequest_setLanguage (HTRequest *request, HTList *lang,
                    255:                                   BOOL override)
2.1       frystyk   256: {
                    257:     if (request) {
                    258:        request->languages = lang;
                    259:        request->lang_local = override;
                    260:     }
                    261: }
                    262: 
2.3       frystyk   263: PUBLIC HTList * HTRequest_language (HTRequest *request)
2.1       frystyk   264: {
                    265:     return request ? request->languages : NULL;
                    266: }
                    267: 
                    268: /*
                    269: **     Accept Charset
                    270: **     list can be NULL
                    271: */
2.3       frystyk   272: PUBLIC void HTRequest_setCharset (HTRequest *request, HTList *charset,
                    273:                                  BOOL override)
2.1       frystyk   274: {
                    275:     if (request) {
                    276:        request->charsets = charset;
                    277:        request->char_local = override;
                    278:     }
                    279: }
                    280: 
2.3       frystyk   281: PUBLIC HTList * HTRequest_charset (HTRequest *request)
2.1       frystyk   282: {
                    283:     return request ? request->charsets : NULL;
                    284: }
                    285: 
                    286: /*
2.9       frystyk   287: **     Extra Header Generators. list can be NULL
                    288: */
                    289: PUBLIC void HTRequest_setGenerator (HTRequest *request, HTList *generator,
                    290:                                    BOOL override)
                    291: {
                    292:     if (request) {
                    293:        request->generators = generator;
                    294:        request->gens_local = override;
                    295:     }
                    296: }
                    297: 
                    298: PUBLIC HTList * HTRequest_generator (HTRequest *request, BOOL *override)
                    299: {
                    300:     if (request) {
                    301:        *override = request->gens_local;
                    302:        return request->generators;
                    303:     }
                    304:     return NULL;
                    305: }
                    306: 
                    307: /*
                    308: **     Extra Header Parsers. list can be NULL
                    309: */
                    310: PUBLIC void HTRequest_setParser (HTRequest *request, HTList *parser,
                    311:                                 BOOL override)
                    312: {
                    313:     if (request) {
                    314:        request->parsers = parser;
                    315:        request->pars_local = override;
                    316:     }
                    317: }
                    318: 
                    319: PUBLIC HTList * HTRequest_parser (HTRequest *request, BOOL *override)
                    320: {
                    321:     if (request) {
                    322:        *override = request->pars_local;
                    323:        return request->parsers;
                    324:     }
                    325:     return NULL;
                    326: }
                    327: 
                    328: /*
2.1       frystyk   329: **     Set General Headers
                    330: */
2.3       frystyk   331: PUBLIC void HTRequest_setGnHd (HTRequest *request, HTGnHd gnhd)
2.1       frystyk   332: {
                    333:     if (request) request->GenMask = gnhd;
                    334: }
                    335: 
2.3       frystyk   336: PUBLIC void HTRequest_addGnHd (HTRequest *request, HTGnHd gnhd)
2.1       frystyk   337: {
                    338:     if (request) request->GenMask |= gnhd;
                    339: }
                    340: 
2.3       frystyk   341: PUBLIC HTGnHd HTRequest_gnHd (HTRequest *request)
2.1       frystyk   342: {
                    343:     return request ? request->GenMask : 0;
                    344: }
                    345: 
                    346: /*
                    347: **     Set Request Headers
                    348: */
2.3       frystyk   349: PUBLIC void HTRequest_setRqHd (HTRequest *request, HTRqHd rqhd)
2.1       frystyk   350: {
                    351:     if (request) request->RequestMask = rqhd;
                    352: }
                    353: 
2.3       frystyk   354: PUBLIC void HTRequest_addRqHd (HTRequest *request, HTRqHd rqhd)
2.1       frystyk   355: {
                    356:     if (request) request->RequestMask |= rqhd;
                    357: }
                    358: 
2.3       frystyk   359: PUBLIC HTRqHd HTRequest_rqHd (HTRequest *request)
2.1       frystyk   360: {
                    361:     return request ? request->RequestMask : 0;
2.22      frystyk   362: }
                    363: 
                    364: /*
                    365: **     Set Response Headers
                    366: */
                    367: PUBLIC void HTRequest_setRsHd (HTRequest *request, HTRsHd rshd)
                    368: {
                    369:     if (request) request->ResponseMask = rshd;
                    370: }
                    371: 
                    372: PUBLIC void HTRequest_addRsHd (HTRequest *request, HTRsHd rshd)
                    373: {
                    374:     if (request) request->ResponseMask |= rshd;
                    375: }
                    376: 
                    377: PUBLIC HTRsHd HTRequest_rsHd (HTRequest *request)
                    378: {
                    379:     return request ? request->ResponseMask : 0;
2.1       frystyk   380: }
                    381: 
                    382: /*
                    383: **     Set Entity Headers (for the object)
                    384: */
2.3       frystyk   385: PUBLIC void HTRequest_setEnHd (HTRequest *request, HTEnHd enhd)
2.1       frystyk   386: {
                    387:     if (request) request->EntityMask = enhd;
                    388: }
                    389: 
2.3       frystyk   390: PUBLIC void HTRequest_addEnHd (HTRequest *request, HTEnHd enhd)
2.1       frystyk   391: {
                    392:     if (request) request->EntityMask |= enhd;
                    393: }
                    394: 
2.3       frystyk   395: PUBLIC HTEnHd HTRequest_enHd (HTRequest *request)
2.1       frystyk   396: {
                    397:     return request ? request->EntityMask : 0;
                    398: }
                    399: 
2.18      frystyk   400: /*
2.1       frystyk   401: **     Anchor
                    402: */
2.3       frystyk   403: PUBLIC void HTRequest_setAnchor (HTRequest *request, HTAnchor *anchor)
2.1       frystyk   404: {
                    405:     if (request && anchor) {
                    406:        request->anchor = HTAnchor_parent(anchor);
                    407:        request->childAnchor = ((HTAnchor *) request->anchor != anchor) ?
                    408:            (HTChildAnchor *) anchor : NULL;
                    409:     }
                    410: }
                    411: 
2.3       frystyk   412: PUBLIC HTParentAnchor * HTRequest_anchor (HTRequest *request)
2.1       frystyk   413: {
                    414:     return request ? request->anchor : NULL;
                    415: }
                    416: 
                    417: /*
                    418: **     Parent anchor for Referer field
                    419: */
2.3       frystyk   420: PUBLIC void HTRequest_setParent (HTRequest *request, HTParentAnchor *parent)
2.1       frystyk   421: {
                    422:     if (request) request->parentAnchor = parent;
                    423: }
                    424: 
2.3       frystyk   425: PUBLIC HTParentAnchor * HTRequest_parent (HTRequest *request)
2.1       frystyk   426: {
                    427:     return request ? request->parentAnchor : NULL;
                    428: }
                    429: 
                    430: /*
                    431: **     Output stream
                    432: */
2.3       frystyk   433: PUBLIC void HTRequest_setOutputStream (HTRequest *request, HTStream *output)
2.1       frystyk   434: {
                    435:     if (request) request->output_stream = output;
                    436: }
                    437: 
2.4       frystyk   438: PUBLIC HTStream *HTRequest_outputStream (HTRequest *request)
2.1       frystyk   439: {
                    440:     return request ? request->output_stream : NULL;
                    441: }
                    442: 
                    443: /*
                    444: **     Output format
                    445: */
2.3       frystyk   446: PUBLIC void HTRequest_setOutputFormat (HTRequest *request, HTFormat format)
2.1       frystyk   447: {
                    448:     if (request) request->output_format = format;
                    449: }
                    450: 
2.4       frystyk   451: PUBLIC HTFormat HTRequest_outputFormat (HTRequest *request)
2.1       frystyk   452: {
                    453:     return request ? request->output_format : NULL;
                    454: }
                    455: 
                    456: /*
                    457: **     Debug stream
                    458: */
2.3       frystyk   459: PUBLIC void HTRequest_setDebugStream (HTRequest *request, HTStream *debug)
2.1       frystyk   460: {
                    461:     if (request) request->debug_stream = debug;
                    462: }
                    463: 
2.4       frystyk   464: PUBLIC HTStream *HTRequest_debugStream (HTRequest *request)
2.1       frystyk   465: {
                    466:     return request ? request->debug_stream : NULL;
                    467: }
                    468: 
                    469: /*
                    470: **     Debug Format
                    471: */
2.3       frystyk   472: PUBLIC void HTRequest_setDebugFormat (HTRequest *request, HTFormat format)
2.1       frystyk   473: {
                    474:     if (request) request->debug_format = format;
                    475: }
                    476: 
2.4       frystyk   477: PUBLIC HTFormat HTRequest_debugFormat (HTRequest *request)
2.1       frystyk   478: {
                    479:     return request ? request->debug_format : NULL;
                    480: }
                    481: 
2.35      frystyk   482: /*
                    483: **     Input stream
                    484: */
                    485: PUBLIC void HTRequest_setInputStream (HTRequest *request, HTStream *input)
                    486: {
                    487:     if (request) request->input_stream = input;
                    488: }
                    489: 
                    490: PUBLIC HTStream *HTRequest_inputStream (HTRequest *request)
                    491: {
                    492:     return request ? request->input_stream : NULL;
                    493: }
                    494: 
2.1       frystyk   495: /*
2.34      hallam    496: **     Net before and after callbacks. list can be NULL
                    497: */
                    498: PUBLIC void HTRequest_setBefore (HTRequest *request, HTList *befores,
                    499:                                 BOOL override)
                    500: {
                    501:     if (request) {
                    502:        request->befores = befores;
                    503:        request->befores_local = override;
                    504:     }
                    505: }
                    506: 
                    507: PUBLIC HTList * HTRequest_before (HTRequest *request, BOOL *override)
                    508: {
                    509:     if (request) {
                    510:        *override = request->befores_local;
                    511:        return request->befores;
                    512:     }
                    513:     return NULL;
                    514: }
                    515: 
                    516: PUBLIC void HTRequest_setAfter (HTRequest *request, HTList *afters,
                    517:                                BOOL override)
                    518: {
                    519:     if (request) {
                    520:        request->afters = afters;
                    521:        request->afters_local = override;
                    522:     }
                    523: }
                    524: 
                    525: PUBLIC HTList * HTRequest_after (HTRequest *request, BOOL *override)
                    526: {
                    527:     if (request) {
                    528:        *override = request->afters_local;
                    529:        return request->afters;
                    530:     }
                    531:     return NULL;
                    532: }
                    533: 
                    534: /*
2.1       frystyk   535: **     Call back function for context swapping
                    536: */
2.3       frystyk   537: PUBLIC void HTRequest_setCallback (HTRequest *request, HTRequestCallback *cbf)
2.1       frystyk   538: {
2.3       frystyk   539:     if (request) request->callback = cbf;
2.1       frystyk   540: }
                    541: 
2.3       frystyk   542: PUBLIC HTRequestCallback *HTRequest_callback (HTRequest *request)
2.1       frystyk   543: {
                    544:     return request ? request->callback : NULL;
                    545: }
                    546: 
                    547: /*
2.24      frystyk   548: **     Call back function for proxying
                    549: */
                    550: PUBLIC void HTRequest_setProxying (HTRequest * request, BOOL proxying)
                    551: {
                    552:     if (request) request->using_proxy = proxying;
                    553: }
                    554: 
                    555: PUBLIC BOOL HTRequest_proxying (HTRequest * request)
                    556: {
                    557:     return request ? request->using_proxy : NO;
                    558: }
                    559: 
                    560: /*
2.1       frystyk   561: **     Context pointer to be used in context call back function
                    562: */
2.3       frystyk   563: PUBLIC void HTRequest_setContext (HTRequest *request, void *context)
2.1       frystyk   564: {
                    565:     if (request) request->context = context;
                    566: }
                    567: 
2.3       frystyk   568: PUBLIC void *HTRequest_context (HTRequest *request)
2.1       frystyk   569: {
                    570:     return request ? request->context : NULL;
                    571: }
                    572: 
                    573: /*
2.23      frystyk   574: **     Socket mode: preemptive or non-preemptive (blocking or non-blocking)
2.1       frystyk   575: */
2.23      frystyk   576: PUBLIC void HTRequest_setPreemptive (HTRequest *request, BOOL mode)
2.1       frystyk   577: {
2.23      frystyk   578:     if (request) request->preemptive = mode;
2.1       frystyk   579: }
                    580: 
2.23      frystyk   581: PUBLIC BOOL HTRequest_preemptive (HTRequest *request)
2.1       frystyk   582: {
2.23      frystyk   583:     return request ? request->preemptive : NO;
2.1       frystyk   584: }
                    585: 
                    586: /*
                    587: **     Should we use content negotiation?
                    588: */
2.3       frystyk   589: PUBLIC void HTRequest_setNegotiation (HTRequest *request, BOOL mode)
2.1       frystyk   590: {
                    591:     if (request) request->ContentNegotiation = mode;
                    592: }
                    593: 
2.3       frystyk   594: PUBLIC BOOL HTRequest_negotiation (HTRequest *request)
2.1       frystyk   595: {
                    596:     return request ? request->ContentNegotiation : NO;
                    597: }
                    598: 
                    599: /*
                    600: **     Bytes read in this request
                    601: */
2.3       frystyk   602: PUBLIC long HTRequest_bytesRead(HTRequest * request)
2.1       frystyk   603: {
                    604:     return request ? HTNet_bytesRead(request->net) : -1;
                    605: }
                    606: 
                    607: /*
2.23      frystyk   608: **     Bytes written in this request
                    609: */
                    610: PUBLIC long HTRequest_bytesWritten (HTRequest * request)
                    611: {
                    612:     return request ? HTNet_bytesWritten(request->net) : -1;
                    613: }
                    614: 
                    615: /*
2.1       frystyk   616: **     Kill this request
                    617: */
2.3       frystyk   618: PUBLIC BOOL HTRequest_kill(HTRequest * request)
2.1       frystyk   619: {
                    620:     return request ? HTNet_kill(request->net) : NO;
                    621: }
                    622: 
2.11      frystyk   623: /*     Error Management
                    624: **     ----------------
2.1       frystyk   625: **     Returns the error stack if a stream is 
                    626: */
2.11      frystyk   627: PUBLIC HTList * HTRequest_error (HTRequest * request)
2.1       frystyk   628: {
                    629:     return request ? request->error_stack : NULL;
                    630: }
                    631: 
2.11      frystyk   632: PUBLIC void HTRequest_setError (HTRequest * request, HTList * list)
                    633: {
                    634:     if (request) request->error_stack = list;
                    635: }
                    636: 
                    637: PUBLIC BOOL HTRequest_addError (HTRequest *    request,
                    638:                                HTSeverity      severity,
                    639:                                BOOL            ignore,
                    640:                                int             element,
                    641:                                void *          par,
                    642:                                unsigned int    length,
                    643:                                char *          where)
                    644: {
                    645:     if (request) {
                    646:        if (!request->error_stack) request->error_stack = HTList_new();
                    647:        return HTError_add(request->error_stack, severity, ignore, element,
                    648:                           par, length, where);
                    649:     }
                    650:     return NO;
                    651: }
                    652: 
                    653: PUBLIC BOOL HTRequest_addSystemError (HTRequest *      request,
                    654:                                      HTSeverity        severity,
                    655:                                      int               errornumber,
                    656:                                      BOOL              ignore,
                    657:                                      char *            syscall)
                    658: {
                    659:     if (request) {
                    660:        if (!request->error_stack) request->error_stack = HTList_new();
                    661:        return HTError_addSystem(request->error_stack, severity, errornumber,
                    662:                                 ignore, syscall);
                    663:     }
                    664:     return NO;
                    665: }
                    666: 
2.1       frystyk   667: /*
                    668: **     When to retry a request if HT_RETRY
                    669: **     Returns -1 if not available
                    670: */
                    671: PUBLIC time_t HTRequest_retryTime (HTRequest * request)
                    672: {
                    673:     return request ? request->retry_after : -1;
                    674: }
                    675: 
                    676: /*
2.23      frystyk   677: **    Redirection informantion
                    678: */
                    679: PUBLIC HTAnchor * HTRequest_redirection (HTRequest * request)
                    680: {
                    681:     return (request ? request->redirectionAnchor : NULL);
                    682: }
                    683: 
                    684: /*
2.1       frystyk   685: **  Set max number of automatic reload. Default is HT_MAX_RELOADS
                    686: */
2.3       frystyk   687: PUBLIC BOOL HTRequest_setMaxRetry (int newmax)
2.1       frystyk   688: {
                    689:     if (newmax > 0) {
                    690:        HTMaxRetry = newmax;
                    691:        return YES;
                    692:     }
                    693:     return NO;
                    694: }
                    695: 
2.3       frystyk   696: PUBLIC int HTRequest_maxRetry (void)
2.1       frystyk   697: {
                    698:     return HTMaxRetry;
                    699: }
                    700: 
                    701: /*
                    702: **     Should we try again?
                    703: **     --------------------
                    704: **     Returns YES if we are to retry the load, NO otherwise. We check
                    705: **     this so that we don't go into an infinte loop
                    706: */
2.3       frystyk   707: PUBLIC BOOL HTRequest_retry (HTRequest *request)
2.1       frystyk   708: {
                    709:     return (request && request->retrys < HTMaxRetry-1);
                    710: }
                    711: 
2.9       frystyk   712: /*
                    713: **  Priority to be inherited by all HTNet object hanging off this request
                    714: **  The priority can later be chaned by calling the HTNet object directly
                    715: */
                    716: PUBLIC BOOL HTRequest_setPriority (HTRequest * request, HTPriority priority)
                    717: {
                    718:     if (request) {
                    719:        request->priority = priority;
                    720:        return YES;
                    721:     }
                    722:     return NO;
                    723: }
                    724: 
                    725: PUBLIC HTPriority HTRequest_priority (HTRequest * request)
                    726: {
2.19      frystyk   727:     return (request ? request->priority : HT_PRIORITY_INV);
2.9       frystyk   728: }
                    729: 
2.18      frystyk   730: /*
2.31      frystyk   731: **  Access Authentication Credentials
                    732: */
                    733: PUBLIC BOOL HTRequest_setCredentials (HTRequest * request, HTAssocList * list)
                    734: {
                    735:     if (request) {
                    736:        request->credentials = list;
                    737:        return YES;
                    738:     }
                    739:     return NO;
                    740: }
                    741: 
                    742: PUBLIC HTAssocList * HTRequest_credentials (HTRequest * request)
                    743: {
                    744:     return (request ? request->credentials : NULL);
                    745: }
                    746: 
                    747: /*
                    748: **  Access Authentication Challenges
                    749: */
                    750: PUBLIC BOOL HTRequest_setChallenge (HTRequest * request, HTAssocList * list)
                    751: {
                    752:     if (request) {
                    753:        request->challenge = list;
                    754:        return YES;
                    755:     }
                    756:     return NO;
                    757: }
                    758: 
                    759: PUBLIC HTAssocList * HTRequest_challenge (HTRequest * request)
                    760: {
                    761:     return (request ? request->challenge : NULL);
                    762: }
                    763: 
                    764: /*
                    765: **  Access Authentication Realms
2.18      frystyk   766: */
2.31      frystyk   767: PUBLIC BOOL HTRequest_setRealm (HTRequest * request, char * realm)
2.18      frystyk   768: {
                    769:     if (request) {
2.31      frystyk   770:        request->realm = realm;
2.18      frystyk   771:        return YES;
                    772:     }
                    773:     return NO;
                    774: }
                    775: 
2.32      frystyk   776: PUBLIC const char * HTRequest_realm (HTRequest * request)
2.18      frystyk   777: {
2.31      frystyk   778:     return (request ? request->realm : NULL);
2.18      frystyk   779: }
                    780: 
2.1       frystyk   781: /* ------------------------------------------------------------------------- */
                    782: /*                             POST WEB METHODS                             */
                    783: /* ------------------------------------------------------------------------- */
                    784: 
                    785: /*
                    786: **  Add a destination request to this source request structure so that we
                    787: **  build the internal request representation of the POST web
                    788: **  Returns YES if OK, else NO
                    789: */
2.23      frystyk   790: PUBLIC BOOL HTRequest_addDestination (HTRequest * src, HTRequest * dest)
2.1       frystyk   791: {
                    792:     if (src && dest) {
2.23      frystyk   793:        dest->source = src->source = src;
2.1       frystyk   794:        if (!src->mainDestination) {
                    795:            src->mainDestination = dest;
                    796:            src->destRequests = 1;
2.36      frystyk   797:            if (CORE_TRACE)
2.30      eric      798:                HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk   799:                         dest, src);
2.1       frystyk   800:            return YES;
                    801:        } else {
2.23      frystyk   802:            if (!src->destinations) src->destinations = HTList_new();
2.1       frystyk   803:            if (HTList_addObject(src->destinations, (void *) dest)==YES) {
                    804:                src->destRequests++;
2.36      frystyk   805:                if (CORE_TRACE)
2.30      eric      806:                    HTTrace("POSTWeb..... Adding dest %p to src %p\n",
2.23      frystyk   807:                             dest, src);
2.1       frystyk   808:                return YES;
                    809:            }
                    810:        }
                    811:     }
                    812:     return NO;
                    813: }
                    814: 
                    815: /*
                    816: **  Remove a destination request from this source request structure
2.23      frystyk   817: **  Remember only to delete the internal request objects as the other
                    818: **  comes from the application!
2.1       frystyk   819: **  Returns YES if OK, else NO
                    820: */
2.23      frystyk   821: PUBLIC BOOL HTRequest_removeDestination (HTRequest * dest)
2.1       frystyk   822: {
                    823:     BOOL found=NO;
                    824:     if (dest && dest->source) {
                    825:        HTRequest *src = dest->source;
                    826:        if (src->mainDestination == dest) {
                    827:            dest->source = NULL;
                    828:            src->mainDestination = NULL;
                    829:            src->destRequests--;
                    830:            found = YES;
2.23      frystyk   831:        } else if (src->destinations) {
2.1       frystyk   832:            if (HTList_removeObject(src->destinations, (void *) dest)) {
                    833:                src->destRequests--;
                    834:                found = YES;
                    835:            }
                    836:        }
                    837:        if (found) {
2.23      frystyk   838:            if (dest->internal) HTRequest_delete(dest);
2.36      frystyk   839:            if (CORE_TRACE)
2.30      eric      840:                HTTrace("POSTWeb..... Deleting dest %p from src %p\n",
2.23      frystyk   841:                         dest, src);
2.1       frystyk   842:        }
2.23      frystyk   843:        if (src->destRequests <= 0) {
2.36      frystyk   844:            if (CORE_TRACE)
2.30      eric      845:                HTTrace("POSTWeb..... terminated\n");
2.23      frystyk   846:            if (src->internal) HTRequest_delete(src);
2.1       frystyk   847:        }
                    848:     }
                    849:     return found;
                    850: }
                    851: 
                    852: /*
2.23      frystyk   853: **  Check to see whether all destinations are ready. If so then enable the
                    854: **  source as ready for reading.
                    855: **  Returns YES if all dests are ready, NO otherwise
                    856: */
                    857: PUBLIC BOOL HTRequest_destinationsReady (HTRequest * me)
                    858: {
                    859:     HTRequest * source = me ? me->source : NULL;
                    860:     if (source) {
                    861:        if (source->destStreams == source->destRequests) {
                    862:            HTNet * net = source->net;
2.36      frystyk   863:            if (CORE_TRACE)
2.30      eric      864:                HTTrace("POSTWeb..... All destinations are ready!\n");
2.23      frystyk   865:            if (net)                          /* Might already have finished */
                    866:                HTEvent_Register(net->sockfd, source, (SockOps) FD_READ,
                    867:                                 net->cbf, net->priority);
                    868:            return YES;
                    869:        }
                    870:     }
                    871:     return NO;
                    872: }
                    873: 
                    874: /*
                    875: **  Find the source request object and make the link between the 
2.1       frystyk   876: **  source output stream and the destination input stream. There can be
                    877: **  a conversion between the two streams!
                    878: **  Returns YES if link is made, NO otherwise
                    879: */
2.3       frystyk   880: PUBLIC BOOL HTRequest_linkDestination (HTRequest *dest)
2.1       frystyk   881: {
                    882:     if (dest && dest->input_stream && dest->source && dest!=dest->source) {
                    883:        HTRequest *source = dest->source;
                    884:        HTStream *pipe = HTStreamStack(source->output_format,
                    885:                                       dest->input_format,
                    886:                                       dest->input_stream,
                    887:                                       dest, YES);
                    888: 
                    889:        /* Check if we are the only one - else spawn off T streams */
                    890:        /* @@@ We don't do this yet @@@ */
                    891: 
2.23      frystyk   892:        /* Now set up output stream of the source */
                    893:        if (source->output_stream)
                    894:            (*source->output_stream->isa->_free)(source->output_stream);
2.1       frystyk   895:        source->output_stream = pipe ? pipe : dest->input_stream;
                    896: 
2.36      frystyk   897:        if (CORE_TRACE)
2.30      eric      898:            HTTrace("POSTWeb..... Linking dest %p to src %p\n",
2.23      frystyk   899:                     dest, source);
2.1       frystyk   900:        if (++source->destStreams == source->destRequests) {
                    901:            HTNet *net = source->net;
2.36      frystyk   902:            if (CORE_TRACE)
2.30      eric      903:                HTTrace("POSTWeb..... All destinations ready!\n");
2.1       frystyk   904:            if (net)                          /* Might already have finished */
                    905:                HTEvent_Register(net->sockfd, source, (SockOps) FD_READ,
                    906:                                 net->cbf, net->priority);
                    907:            return YES;
                    908:        }
                    909:     }
                    910:     return NO;
                    911: }
                    912: 
                    913: /*
                    914: **  Remove a feed stream to a destination request from this source
                    915: **  request structure. When all feeds are removed the request tree is
                    916: **  ready to take down and the operation can be terminated.
                    917: **  Returns YES if removed, else NO
                    918: */
2.3       frystyk   919: PUBLIC BOOL HTRequest_unlinkDestination (HTRequest *dest)
2.1       frystyk   920: {
                    921:     BOOL found = NO;
                    922:     if (dest && dest->source && dest != dest->source) {
                    923:        HTRequest *src = dest->source;
                    924:        if (src->mainDestination == dest) {
                    925:            src->output_stream = NULL;
                    926:            if (dest->input_stream)
                    927:                (*dest->input_stream->isa->_free)(dest->input_stream);
                    928:            found = YES;
                    929:        } else if (src->destinations) {
                    930: 
                    931:            /* LOOK THROUGH THE LIST AND FIND THE RIGHT ONE */
                    932: 
                    933:        }       
                    934:        if (found) {
                    935:            src->destStreams--;
2.36      frystyk   936:            if (CORE_TRACE)
2.30      eric      937:                HTTrace("POSTWeb..... Unlinking dest %p from src %p\n",
2.23      frystyk   938:                         dest, src);
2.1       frystyk   939:            return YES;
                    940:        }
                    941:     }
                    942:     return NO;
                    943: }
                    944: 
                    945: /*
                    946: **  Removes all request structures in this PostWeb.
                    947: */
2.3       frystyk   948: PUBLIC BOOL HTRequest_removePostWeb (HTRequest *me)
2.1       frystyk   949: {
                    950:     if (me && me->source) {
                    951:        HTRequest *source = me->source;
                    952: 
                    953:        /* Kill main destination */
                    954:        if (source->mainDestination)
                    955:            HTRequest_removeDestination(source->mainDestination);
                    956: 
                    957:        /* Kill all other destinations */
                    958:        if (source->destinations) {
                    959:            HTList *cur = source->destinations;
                    960:            HTRequest *pres;
                    961:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
                    962:                HTRequest_removeDestination(pres);
                    963:        }
                    964: 
                    965:        /* Remove source request */
                    966:        HTRequest_removeDestination(source);
                    967:        return YES;
                    968:     }
                    969:     return NO;
                    970: }
                    971: 
                    972: /*
                    973: **  Kills all threads in a POST WEB connected to this request but
2.23      frystyk   974: **  NOT this request itself. We also keep the request structures.
                    975: **  Some requests might be preemptive, for example a SMTP request (when
2.1       frystyk   976: **  that has been implemented). However, this will be handled internally
                    977: **  in the load function.
                    978: */
2.3       frystyk   979: PUBLIC BOOL HTRequest_killPostWeb (HTRequest *me)
2.1       frystyk   980: {
                    981:     if (me && me->source) {
                    982:        HTRequest *source = me->source;
2.36      frystyk   983:        if (CORE_TRACE) HTTrace("POSTWeb..... Killing\n");
2.1       frystyk   984: 
2.23      frystyk   985:        /*
                    986:        ** Kill source. The stream tree is now freed so we have to build
                    987:        ** that again. This is done in HTRequest_linkDestination()
                    988:        */
                    989:        if (me != source) {
                    990:            HTNet_kill(source->net);
                    991:            source->output_stream = NULL;
                    992:        }
2.1       frystyk   993: 
                    994:        /* Kill all other destinations */
                    995:        if (source->destinations) {
                    996:            HTList *cur = source->destinations;
                    997:            HTRequest *pres;
                    998:            while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL)
2.23      frystyk   999:                if (me != pres) HTNet_kill(pres->net);
2.1       frystyk  1000:        }
2.23      frystyk  1001: 
                   1002:        /* Kill main destination */
                   1003:        if (source->mainDestination && me != source->mainDestination)
                   1004:            HTNet_kill(source->mainDestination->net);
2.1       frystyk  1005:        return YES;
                   1006:     }
                   1007:     return NO;
                   1008: }
                   1009: 
                   1010: /* --------------------------------------------------------------------------*/
                   1011: /*                     Physical Anchor Address Manager                      */
                   1012: /* --------------------------------------------------------------------------*/
2.16      frystyk  1013: #if 0
2.1       frystyk  1014: /*             Find physical name and access protocol
                   1015: **             --------------------------------------
                   1016: **
                   1017: **     Checks for Cache, proxy, and gateway (in that order)
                   1018: **
                   1019: ** On exit,    
                   1020: **     returns         HT_NO_ACCESS            no protocol module found
                   1021: **                     HT_FORBIDDEN            Error has occured.
                   1022: **                     HT_OK                   Success
                   1023: **
                   1024: */
                   1025: PRIVATE int get_physical (HTRequest *req)
                   1026: {    
                   1027:     char * addr = HTAnchor_address((HTAnchor*)req->anchor);    /* free me */
2.14      frystyk  1028:     HTList *list = HTRule_global();
                   1029:     char * physical = HTRule_translate(list, addr, NO);
                   1030:     if (!physical) {
2.29      frystyk  1031:        HT_FREE(addr);
2.14      frystyk  1032:        return HT_FORBIDDEN;
2.1       frystyk  1033:     }
2.14      frystyk  1034:     HTAnchor_setPhysical(req->anchor, physical);
2.29      frystyk  1035:     HT_FREE(physical);
2.1       frystyk  1036: 
                   1037:     /*
                   1038:     ** Check local Disk Cache (if we are not forced to reload), then
                   1039:     ** for proxy, and finally gateways
                   1040:     */
                   1041:     {
                   1042:        char *newaddr=NULL;
                   1043:        if (req->reload != HT_FORCE_RELOAD &&
                   1044:            (newaddr = HTCache_getReference(addr))) {
                   1045:            if (req->reload != HT_CACHE_REFRESH) {
                   1046:                HTAnchor_setPhysical(req->anchor, newaddr);
                   1047:                HTAnchor_setCacheHit(req->anchor, YES);
                   1048:            } else {                     /* If refresh version in file cache */
                   1049:                req->RequestMask |= (HT_IMS + HT_NO_CACHE);
                   1050:            }
2.8       frystyk  1051:        } else if ((newaddr = HTProxy_find(addr))) {
2.1       frystyk  1052:            StrAllocCat(newaddr, addr);
                   1053:            req->using_proxy = YES;
                   1054:            HTAnchor_setPhysical(req->anchor, newaddr);
2.8       frystyk  1055:        } else if ((newaddr = HTGateway_find(addr))) {
2.1       frystyk  1056:            char * path = HTParse(addr, "",
                   1057:                                  PARSE_HOST + PARSE_PATH + PARSE_PUNCTUATION);
                   1058:                /* Chop leading / off to make host into part of path */
                   1059:            char * gatewayed = HTParse(path+1, newaddr, PARSE_ALL);
                   1060:             HTAnchor_setPhysical(req->anchor, gatewayed);
2.29      frystyk  1061:            HT_FREE(path);
                   1062:            HT_FREE(gatewayed);
2.1       frystyk  1063:        } else {
                   1064:            req->using_proxy = NO;          /* We don't use proxy or gateway */
                   1065:        }
2.29      frystyk  1066:        HT_FREE(newaddr);
2.1       frystyk  1067:     }
2.29      frystyk  1068:     HT_FREE(addr);
2.1       frystyk  1069: 
                   1070:     /* Set the access scheme on our way out */
2.12      frystyk  1071:     return (HTProtocol_find(req, req->anchor)==YES) ? HT_OK : HT_NO_ACCESS;
2.1       frystyk  1072: }
2.16      frystyk  1073: #endif
2.1       frystyk  1074: 
                   1075: /* --------------------------------------------------------------------------*/
                   1076: /*                             Document Loader                              */
                   1077: /* --------------------------------------------------------------------------*/
                   1078: 
                   1079: /*     Request a resource
                   1080: **     ------------------
                   1081: **     This is an internal routine, which has an address AND a matching
                   1082: **     anchor.  (The public routines are called with one OR the other.)
                   1083: **     Returns:
                   1084: **             YES     if request has been registered (success)
                   1085: **             NO      an error occured
                   1086: */
2.9       frystyk  1087: PUBLIC BOOL HTLoad (HTRequest * request, BOOL recursive)
2.1       frystyk  1088: {
                   1089:     if (!request || !request->anchor) {
2.36      frystyk  1090:         if (CORE_TRACE) HTTrace("Load Start.. Bad argument\n");
2.1       frystyk  1091:         return NO;
                   1092:     }
2.14      frystyk  1093:     if (request->method == METHOD_INVALID) request->method = METHOD_GET;
2.16      frystyk  1094:     if (!recursive && request->error_stack) {
                   1095:        HTError_deleteAll(request->error_stack);
                   1096:        request->error_stack = NULL;
                   1097:     }
2.18      frystyk  1098:     return HTNet_newClient(request);
2.1       frystyk  1099: }
                   1100: 

Webmaster