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