📄 htreqman.c
字号:
/* HTReqMan.c** REQUEST MANAGER**** (c) COPYRIGHT MIT 1995.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTReqMan.c,v 2.83 2002/05/29 16:09:13 kirschpi Exp $**** Authors** TBL Tim Berners-Lee timbl@w3.org** JFG Jean-Francois Groff jfg@dxcern.cern.ch** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>** HFN Henrik Frystyk, frystyk@w3.org** Contribution** MKP Manuele Kirsch, Manuele.Kirsch_Pinheiro@inrialpes.fr or manuele@inf.ufrgs.br** History** 8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG** 6 Oct 92 Moved HTClientHost and HTlogfile into here. TBL** 17 Dec 92 Tn3270 added, bug fix. DD** 4 Feb 93 Access registration, Search escapes bad chars TBL** PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED** 28 May 93 WAIS gateway explicit if no WAIS library linked in.** Dec 93 Bug change around, more reentrant, etc** 09 May 94 logfile renamed to HTlogfile to avoid clash with WAIS** 8 Jul 94 Insulate free() from _free structure element.** 02 Sep 95 Rewritten and spawned from HTAccess.c, HFN** 14 Fev 02 Message body added to HTRequest*/#if !defined(HT_DIRECT_WAIS) && !defined(HT_DEFAULT_WAIS_GATEWAY)#define HT_DEFAULT_WAIS_GATEWAY "http://www.w3.org:8001/"#endif/* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "HTParse.h"#include "HTNoFree.h"#include "HTAlert.h"#include "HTError.h"#include "HTNetMan.h"#include "HTEvent.h"#include "HTProt.h"#include "HTHeader.h"#include "HTLib.h"#include "HTReqMan.h" /* Implemented here */#ifndef HT_MAX_RELOADS#define HT_MAX_RELOADS 6#endifPRIVATE int HTMaxRetry = HT_MAX_RELOADS;struct _HTStream { HTStreamClass * isa; /* ... */};/* --------------------------------------------------------------------------*//* Create and delete the HTRequest Object *//* --------------------------------------------------------------------------*/PUBLIC HTRequest * HTRequest_new (void){ HTRequest * me; if ((me = (HTRequest *) HT_CALLOC(1, sizeof(HTRequest))) == NULL) HT_OUTOFMEM("HTRequest_new()"); /* Force Reload */ me->reload = HT_CACHE_OK; /* no default PUT name */ me->default_put_name = NULL; /* Set the default user profile */ me->userprofile = HTLib_userProfile(); /* Format of output */ me->output_format = WWW_PRESENT; /* default it to present to user */ me->debug_format = WWW_DEBUG; /* default format of error messages */ /* HTTP headers */ me->GenMask = DEFAULT_GENERAL_HEADERS; me->RequestMask = DEFAULT_REQUEST_HEADERS; me->ResponseMask = DEFAULT_RESPONSE_HEADERS; me->EntityMask = DEFAULT_ENTITY_HEADERS; /* Default retry after value */ me->priority = HT_PRIORITY_MAX; /* Default max forward value */ me->max_forwards = -1; /* Content negotiation */ me->ContentNegotiation = YES; /* Do this by default */#ifdef HT_EXT /* Message Body */ me->messageBody = NULL; /* MKP: default value is NULL - no message body set */ me->messageBodyLength = -1; /* MKP: default value is -1 */ me->messageBodyFormat = NULL; /* MKP: default value is NULL */#endif HTTRACE(CORE_TRACE, "Request..... Created %p\n" _ me); return me;}/* HTRequest_clear** ---------------** Clears all protocol specific information so that the request object** can be used for another request.** Returns YES if OK, else NO*/PUBLIC BOOL HTRequest_clear (HTRequest * me){ if (me) { me->error_stack = NULL; me->net = NULL; me->realm = NULL; me->credentials = NULL; me->connected = NO; if (me->default_put_name) HTRequest_deleteDefaultPutName (me); if (me->response) { HTResponse_delete(me->response); me->response = NULL; } #ifdef HT_EXT if (me->messageBody) /* MKP: clear message body */ HTRequest_deleteMessageBody(me); me->messageBodyFormat = NULL; me->messageBodyLength = -1; #endif return YES; } return NO;}/* HTRequest_dup** -------------** Creates a new HTRequest object as a duplicate of the src request.** Returns YES if OK, else NO*/PUBLIC HTRequest * HTRequest_dup (HTRequest * src){ HTRequest * me; if (!src) return NULL; if ((me = (HTRequest *) HT_MALLOC(sizeof(HTRequest))) == NULL) HT_OUTOFMEM("HTRequest_dup"); memcpy(me, src, sizeof(HTRequest)); HTTRACE(CORE_TRACE, "Request..... Duplicated %p to %p\n" _ src _ me); return me;}/* HTRequest_dupInternal** ---------------------** Creates a new HTRequest object as a duplicate of the src request.** The difference to the HTRequest_dup function is that we don't copy the** error_stack and other information that the application keeps in its** copy of the request object. Otherwise it will be freed multiple times** Returns YES if OK, else NO*/PUBLIC HTRequest * HTRequest_dupInternal (HTRequest * src){ HTRequest * me; if (!src) return 0; if ((me = (HTRequest *) HT_MALLOC(sizeof(HTRequest))) == NULL) HT_OUTOFMEM("HTRequest_dup"); memcpy(me, src, sizeof(HTRequest)); HTRequest_clear(me); return me;}PUBLIC void HTRequest_delete (HTRequest * me){ if (me) { HTTRACE(CORE_TRACE, "Request..... Delete %p\n" _ me); if (me->net) HTNet_setRequest(me->net, NULL); /* ** Make sure we don't delete the same stream twice, when the output ** stream and the debug stream are the same. */ if (me->orig_output_stream == me->orig_debug_stream) { me->orig_debug_stream = NULL; } /* Should we delete the output stream? */ if (me->orig_output_stream) { HTTRACE(CORE_TRACE, "Request..... Deleting dangling output stream\n"); (*me->orig_output_stream->isa->_free)(me->orig_output_stream); me->orig_output_stream = NULL; HTNoFreeStream_delete(me->output_stream); me->output_stream = NULL; } /* Should we delete the debug stream? */ if (me->orig_debug_stream) { HTTRACE(CORE_TRACE, "Request..... Deleting dangling debug stream\n"); (*me->orig_debug_stream->isa->_free)(me->orig_debug_stream); me->orig_debug_stream = NULL; HTNoFreeStream_delete(me->debug_stream); me->debug_stream = NULL; } /* Clean up the error stack */ if (me->error_stack) HTError_deleteAll(me->error_stack); /* Before and After Filters */ if (me->afters) HTNetCall_deleteAfterAll(me->afters); if (me->befores) HTNetCall_deleteBeforeAll(me->befores); /* default PUT name */ if (me->default_put_name) HTRequest_deleteDefaultPutName (me); /* Access Authentication */ HT_FREE(me->realm); if (me->credentials) HTAssocList_delete(me->credentials); /* Cache control headers */ if (me->cache_control) HTAssocList_delete(me->cache_control); /* Byte ranges */ if (me->byte_ranges) HTAssocList_delete(me->byte_ranges); /* Connection headers */ if (me->connection) HTAssocList_delete(me->connection); /* Connection headers */ if (me->expect) HTAssocList_delete(me->expect); /* Proxy information */ HT_FREE(me->proxy); /* Extra header fields */ if (me->extra_headers) HTAssocList_delete(me->extra_headers); /* HTTP Extension Information */ if (me->optional) HTAssocList_delete(me->optional); if (me->mandatory) HTAssocList_delete(me->mandatory); /* Any response object */ if (me->response) HTResponse_delete(me->response);#ifdef HT_EXT if (me->messageBody) HTRequest_deleteMessageBody(me); /* MKP: clear message body*/ me->messageBodyFormat = NULL; me->messageBodyLength = -1; #endif HT_FREE(me); }}/*** Kill this request*/PUBLIC BOOL HTRequest_kill(HTRequest * me){ return me ? HTNet_kill(me->net) : NO;}/* --------------------------------------------------------------------------*//* Methods on the HTRequest Object *//* --------------------------------------------------------------------------*//*** Internal request object*/PUBLIC BOOL HTRequest_setInternal (HTRequest * me, BOOL mode){ if (me) { me->internal = mode; return YES; } return NO;}PUBLIC BOOL HTRequest_internal (HTRequest * me){ return (me ? me->internal : NO);}/*** Should we flush immediately?*/PUBLIC BOOL HTRequest_setFlush (HTRequest * me, BOOL mode){ if (me) { me->flush = mode; return YES; } return NO;}PUBLIC BOOL HTRequest_flush (HTRequest * me){ return (me ? me->flush : NO);}/*** Date/time stamp when then request was issued** This is normally set when generating the request headers.*/PUBLIC time_t HTRequest_date (HTRequest * me){ return me ? me->date : -1;}PUBLIC BOOL HTRequest_setDate (HTRequest * me, time_t date){ if (me) { me->date = date; return YES; } return NO;}/*** Method*/PUBLIC void HTRequest_setMethod (HTRequest * me, HTMethod method){ if (me) me->method = method;}PUBLIC HTMethod HTRequest_method (HTRequest * me){ return me ? me->method : METHOD_INVALID;}/*** Priority to be inherited by all HTNet object hanging off this request** The priority can later be chaned by calling the HTNet object directly*/PUBLIC BOOL HTRequest_setPriority (HTRequest * me, HTPriority priority){ if (me) { me->priority = priority; return YES; } return NO;}PUBLIC HTPriority HTRequest_priority (HTRequest * me){ return (me ? me->priority : HT_PRIORITY_INV);}/*** User Profile*/PUBLIC BOOL HTRequest_setUserProfile (HTRequest * me, HTUserProfile * up){ if (me) { me->userprofile = up; return YES; } return NO;}PUBLIC HTUserProfile * HTRequest_userProfile (HTRequest * me){ return me ? me->userprofile : NULL;}/*** Net Object*/PUBLIC BOOL HTRequest_setNet (HTRequest * me, HTNet * net){ if (me) { me->net = net; return YES; } return NO;}PUBLIC HTNet * HTRequest_net (HTRequest * me){ return me ? me->net : NULL;}/*** Response Object. If the object does not exist then create it at the** same time it is asked for.*/PUBLIC HTResponse * HTRequest_response (HTRequest * me){ if (me) { if (!me->response) me->response = HTResponse_new(); return me->response; } return NULL;}PUBLIC BOOL HTRequest_setResponse (HTRequest * me, HTResponse * response){ if (me) { if (me->response) HTResponse_delete(me->response); me->response = response; return YES; } return NO;}/* Error Management** ----------------** Returns the error stack if a stream is */PUBLIC HTList * HTRequest_error (HTRequest * me){ return me ? me->error_stack : NULL;}PUBLIC void HTRequest_setError (HTRequest * me, HTList * list){ if (me) me->error_stack = list;}/* begin _GM_ *//* Note: libwww bug ID: GM11 */PUBLIC void HTRequest_deleteAllErrors (HTRequest * request){ HTError_deleteAll(request->error_stack); HTRequest_setError(request, NULL);}/* end _GM_ */PUBLIC BOOL HTRequest_addError (HTRequest * me, HTSeverity severity, BOOL ignore, int element, void * par, unsigned int length, char * where){ if (me) { if (!me->error_stack) me->error_stack = HTList_new(); return HTError_add(me->error_stack, severity, ignore, element, par, length, where); } return NO;}PUBLIC BOOL HTRequest_addSystemError (HTRequest * me, HTSeverity severity, int errornumber, BOOL ignore, char * syscall){ if (me) { if (!me->error_stack) me->error_stack = HTList_new(); return HTError_addSystem(me->error_stack, severity, errornumber, ignore, syscall); } return NO;}/*** Set max number of automatic reload. Default is HT_MAX_RELOADS*/PUBLIC BOOL HTRequest_setMaxRetry (int newmax){ if (newmax > 0) { HTMaxRetry = newmax; return YES; } return NO;}PUBLIC int HTRequest_maxRetry (void){ return HTMaxRetry;}PUBLIC int HTRequest_retrys (HTRequest * me){ return me ? me->retrys : 0;}PUBLIC BOOL HTRequest_addRetry (HTRequest * me){ return (me && me->retrys++);}PUBLIC int HTRequest_AAretrys (HTRequest * me){ return me ? me->AAretrys : 0;}PUBLIC BOOL HTRequest_addAARetry (HTRequest * me){ return (me && me->AAretrys++);}/*** Should we try again?** --------------------** Returns YES if we are to retry the load, NO otherwise. We check** this so that we don't go into an infinte loop*/PUBLIC BOOL HTRequest_doRetry (HTRequest * me){ return (me && me->retrys < HTMaxRetry-1);}/*** Socket mode: preemptive or non-preemptive (blocking or non-blocking)*/PUBLIC void HTRequest_setPreemptive (HTRequest * me, BOOL mode){ if (me) me->preemptive = mode;}PUBLIC BOOL HTRequest_preemptive (HTRequest * me){ return me ? me->preemptive : NO;}/*** Should we use content negotiation?*/PUBLIC void HTRequest_setNegotiation (HTRequest * me, BOOL mode){ if (me) me->ContentNegotiation = mode;}PUBLIC BOOL HTRequest_negotiation (HTRequest * me){ return me ? me->ContentNegotiation : NO;}/*** Use preconditions when doing a PUT or a POST. These are the** if-* header fields that can be used to avoid version conflicts** etc.*/PUBLIC void HTRequest_setPreconditions (HTRequest * me, HTPreconditions mode){ if (me) me->preconditions = mode;}PUBLIC HTPreconditions HTRequest_preconditions (HTRequest * me){ return me ? me->preconditions : NO;}/*** Set General Headers*/PUBLIC void HTRequest_setGnHd (HTRequest * me, HTGnHd gnhd){ if (me) me->GenMask = gnhd;}PUBLIC void HTRequest_addGnHd (HTRequest * me, HTGnHd gnhd){ if (me) me->GenMask |= gnhd;}PUBLIC HTGnHd HTRequest_gnHd (HTRequest * me){ return me ? me->GenMask : 0;}/*** Set Request Headers*/PUBLIC void HTRequest_setRqHd (HTRequest * me, HTRqHd rqhd){ if (me) me->RequestMask = rqhd;}PUBLIC void HTRequest_addRqHd (HTRequest * me, HTRqHd rqhd){ if (me) me->RequestMask |= rqhd;}PUBLIC HTRqHd HTRequest_rqHd (HTRequest * me){ return me ? me->RequestMask : 0;}/*** Set Response Headers*/PUBLIC void HTRequest_setRsHd (HTRequest * me, HTRsHd rshd){ if (me) me->ResponseMask = rshd;}PUBLIC void HTRequest_addRsHd (HTRequest * me, HTRsHd rshd){ if (me) me->ResponseMask |= rshd;}PUBLIC HTRsHd HTRequest_rsHd (HTRequest * me){ return me ? me->ResponseMask : 0;}/*** Set Entity Headers (for the object)*/PUBLIC void HTRequest_setEnHd (HTRequest * me, HTEnHd enhd){ if (me) me->EntityMask = enhd;}PUBLIC void HTRequest_addEnHd (HTRequest * me, HTEnHd enhd){ if (me) me->EntityMask |= enhd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -