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