/* Determine a suitable suffix ** --------------------------- ** Use the set of bindings to find a suitable suffix (or index) ** for a certain combination of language, media type and encoding ** given in the anchor. ** ** Returns a pointer to a suitable suffix string that must be freed ** by the caller. If more than one suffix is found they are all ** concatenated using the first delimiter in HTDelimiters. ** If no suffix is found, NULL is returned. */ PUBLIC char * HTBind_getSuffix (HTParentAnchor * anchor) { int cnt; HTList * cur; HTChunk * suffix = HTChunk_new(48); char delimiter = *HTDelimiters; char * ct=NULL, * ce=NULL, * cl=NULL; HTFormat format = HTAnchor_format(anchor); HTList * encoding = HTAnchor_encoding(anchor); HTList * language = HTAnchor_language(anchor); if (!HTBindings) HTBind_init(); if (anchor) { for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) { if ((cur = HTBindings[cnt])) { HTBind *pres; while ((pres = (HTBind *) HTList_nextObject(cur))) { if (!ct && (pres->type && pres->type == format)){ ct = pres->suffix; } else if (!ce && pres->encoding && encoding) { HTList * cur_enc = encoding; HTEncoding pres_enc; while ((pres_enc = (HTEncoding) HTList_nextObject(cur_enc))) { if (pres_enc == pres->encoding) { ce = pres->suffix; break; } } } else if (!cl && pres->language && language) { HTList * cur_lang = language; HTLanguage pres_lang; while ((pres_lang = (HTLanguage) HTList_nextObject(cur_lang))) { if (pres_lang == pres->language) { cl = pres->suffix; break; } } } } } } /* Put the found suffixes together */ if (ct) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ct); } if (ce) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ce); } if (cl) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, cl); } } return HTChunk_toCString(suffix); }
/* Determine the content of an file name ** ------------------------------------- ** Use the set of bindings to find the combination of language, ** media type, encoding, and transfer encoding of a given anchor. ** If more than one suffix is found they are all searched. The last suffix ** has highest priority, the first one lowest. See also HTBind_getBindings() ** Either of format, encoding, or language can be NULL ** Returns the format, encoding, and language found */ PUBLIC BOOL HTBind_getFormat (const char * filename, HTFormat * format, HTEncoding * enc, HTEncoding * cte, HTLanguage * lang, double * quality) { int sufcnt=0; char *file=NULL; #ifdef HT_REENTRANT char *lasts; /* For strtok_r */ #endif if (!HTBindings) HTBind_init(); if (*quality < HT_EPSILON) *quality = 1.0; /* Set to a neutral value */ StrAllocCopy(file, filename); HTUnEscape(file); /* Unescape the file name */ #ifdef HT_REENTRANT if (strtok_r(file, HTDelimiters, &lasts)) { /* Do we have any suffixes? */ #else if (strtok(file, HTDelimiters)) { /* Do we have any suffixes? */ #endif /* HT_REENTRANT */ char *suffix; #ifdef HT_REENTRANT while ((suffix=(char*)strtok_r(NULL, HTDelimiters, &lasts)) != NULL) { #else while ((suffix=strtok(NULL, HTDelimiters)) != NULL) { #endif /* HT_REENTRANT */ HTBind *suff=NULL; int hash; unsigned char * p; HTTRACE(BIND_TRACE, "Get Binding. Look for '%s\' " _ suffix); sufcnt++; /* Select list from hash table */ for (p=suffix, hash=0; *p; p++) { hash = (hash * 3 + TOLOWER(*p)) % HT_L_HASH_SIZE; } /* Now search list for entries (case or non case sensitive) */ if (HTBindings[hash]) { HTList *cur = HTBindings[hash]; while ((suff = (HTBind *) HTList_nextObject(cur))) { if ((HTCaseSen && !strcmp(suff->suffix, suffix)) || !strcasecomp(suff->suffix, suffix)) { HTTRACE(BIND_TRACE, "Found!\n"); if (suff->type && format) *format = suff->type; if (suff->encoding && enc) *enc = suff->encoding; if (suff->transfer && cte) *cte = suff->transfer; if (suff->language && lang) *lang = suff->language; if (suff->quality > HT_EPSILON) *quality *= suff->quality; break; } } } if (!suff) { /* We don't have this suffix - use default */ HTTRACE(BIND_TRACE, "Not found - use default for \'*.*\'\n"); if (format) *format = unknown_suffix.type; if (enc) *enc = unknown_suffix.encoding; if (cte) *cte = unknown_suffix.transfer; if (lang) *lang = unknown_suffix.language; *quality = unknown_suffix.quality; } } /* while we still have suffixes */ } if (!sufcnt) { /* No suffix so use default value */ HTTRACE(BIND_TRACE, "Get Binding. No suffix found - using default '%s\'\n" _ filename); if (format) *format = no_suffix.type; if (enc) *enc = no_suffix.encoding; if (cte) *cte = no_suffix.transfer; if (lang) *lang = no_suffix.language; *quality = no_suffix.quality; } HTTRACE(BIND_TRACE, "Get Binding. Result for '%s\' is: type='%s\', encoding='%s\', cte='%s\', language='%s\' with quality %.2f\n" _ filename _ (format && *format) ? HTAtom_name(*format) : "unknown" _ (enc && *enc) ? HTAtom_name(*enc) : "unknown" _ (cte && *cte) ? HTAtom_name(*cte) : "unknown" _ (lang && *lang) ? HTAtom_name(*lang) : "unknown" _ *quality); HT_FREE(file); return YES; }
PRIVATE void client_profile (const char * AppName, const char * AppVersion, BOOL preemptive, BOOL cache, BOOL HTMLParser) { /* If the Library is not already initialized then do it */ if (!HTLib_isInitialized()) HTLibInit(AppName, AppVersion); /* Register the default set of messages and dialog functions */ HTAlertInit(); HTAlert_setInteractive(YES); if (!converters) { converters = HTList_new(); /* Register the default set of converters */ HTConverterInit(converters); /* Register the default libwww HTML parser */ if (HTMLParser) HTMLInit(converters); /* Set the converters as global converters for all requests */ HTFormat_setConversion(converters); } if (!transfer_encodings) { transfer_encodings = HTList_new(); /* Register the default set of transfer encoders and decoders */ HTTransferEncoderInit(transfer_encodings); HTFormat_setTransferCoding(transfer_encodings); } if (!content_encodings) { content_encodings = HTList_new(); /* Register the default set of content encoders and decoders */ HTContentEncoderInit(content_encodings); if (HTList_count(content_encodings) > 0) HTFormat_setContentCoding(content_encodings); else { HTList_delete(content_encodings); content_encodings = NULL; } } /* Register the default set of transport protocols */ HTTransportInit(); /* Register the default set of application protocol modules */ if (preemptive) HTProtocolPreemptiveInit(); else HTProtocolInit(); /* Initialize suffix bindings for local files */ HTBind_init(); /* Set max number of sockets we want open simultanously */ HTNet_setMaxSocket(32); /* The persistent cache does not work in preemptive mode */ if (cache) HTCacheInit(NULL, 20); /* Register the default set of BEFORE and AFTER filters */ HTNetInit(); /* Set up the default set of Authentication schemes */ HTAAInit(); /* Get any proxy or gateway environment variables */ HTProxy_getEnvVar(); /* Register the default set of MIME header parsers */ HTMIMEInit(); /* Register the default set of file suffix bindings */ HTFileInit(); /* Register the default set of Icons for directory listings */ HTIconInit(NULL); }
PUBLIC BOOL HTBind_add (const char * suffix, const char * representation, const char * encoding, const char * transfer, const char * language, double value) { HTBind * suff; if (!suffix) return NO; if (!strcmp(suffix, "*")) suff = &no_suffix; else if (!strcmp(suffix, "*.*")) suff = &unknown_suffix; else { HTList * suflist; int hash; const unsigned char * p; /* Select list from hash table */ for (p=suffix, hash=0; *p; p++) { hash = (hash * 3 + TOLOWER(*p)) % HT_L_HASH_SIZE; } if (!HTBindings) HTBind_init(); if (!HTBindings[hash]) HTBindings[hash] = HTList_new(); suflist = HTBindings[hash]; /* Look for existing binding */ { HTList *cur = suflist; while ((suff = (HTBind *) HTList_nextObject(cur)) != NULL) { if (!strcmp(suff->suffix, suffix)) break; } } /* If not found -- create a new node */ if (!suff) { if ((suff = (HTBind *) HT_CALLOC(1, sizeof(HTBind))) == NULL) HT_OUTOFMEM("HTBind_add"); HTList_addObject(suflist, (void *) suff); StrAllocCopy(suff->suffix, suffix); } } /* Set the appropriate values */ { HTChunk * chunk = HTChunk_new(32); char *ptr; if (representation) { HTChunk_puts(chunk, representation); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->type = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (encoding) { HTChunk_puts(chunk, encoding); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->encoding = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (transfer) { HTChunk_puts(chunk, transfer); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->transfer = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } if (language) { HTChunk_puts(chunk, language); ptr = HTChunk_data(chunk); for (; *ptr; ptr++) *ptr = TOLOWER(*ptr); suff->language = HTAtom_for(HTChunk_data(chunk)); HTChunk_truncate(chunk,0); } HTChunk_delete(chunk); suff->quality = value; } return YES; }
PRIVATE void robot_profile (const char * AppName, const char * AppVersion) { /* If the Library is not already initialized then do it */ if (!HTLib_isInitialized()) HTLibInit(AppName, AppVersion); if (!converters) { converters = HTList_new(); /* Register the default set of converters including the HTML parser */ HTConverterInit(converters); HTMLInit(converters); /* Set the converters as global converters for all requests */ HTFormat_setConversion(converters); } if (!transfer_encodings) { transfer_encodings = HTList_new(); /* Register the default set of transfer encoders and decoders */ HTTransferEncoderInit(transfer_encodings); HTFormat_setTransferCoding(transfer_encodings); } if (!content_encodings) { content_encodings = HTList_new(); /* Register the default set of content encoders and decoders */ HTContentEncoderInit(content_encodings); if (HTList_count(content_encodings) > 0) HTFormat_setContentCoding(content_encodings); else { HTList_delete(content_encodings); content_encodings = NULL; } } /* Register the default set of transport protocols */ HTTransportInit(); /* Register the default set of application protocol modules */ HTProtocolInit(); /* Initialize suffix bindings for local files */ HTBind_init(); /* Set max number of sockets we want open simultanously */ HTNet_setMaxSocket(32); /* Register some default set of BEFORE and AFTER filters */ HTNet_addBefore(HTRuleFilter, NULL, NULL, HT_FILTER_MIDDLE); HTNet_addBefore(HTProxyFilter, NULL, NULL, HT_FILTER_MIDDLE); HTNet_addAfter(HTInfoFilter, NULL, NULL, HT_ALL, HT_FILTER_LATE); /* Get any proxy or gateway environment variables */ HTProxy_getEnvVar(); /* Register the default set of MIME header parsers */ HTMIMEInit(); /* Register the default set of file suffix bindings */ HTFileInit(); /* Register the default set of Icons for directory listings */ HTIconInit(NULL); /* Register some default messages and dialog functions */ if (HTAlert_interactive()) { HTAlert_add(HTError_print, HT_A_MESSAGE); HTAlert_add(HTConfirm, HT_A_CONFIRM); HTAlert_add(HTPrompt, HT_A_PROMPT); HTAlert_add(HTPromptPassword, HT_A_SECRET); HTAlert_add(HTPromptUsernameAndPassword, HT_A_USER_PW); } HTAlert_setInteractive(YES); }