📄 htaccess.c
字号:
full_url = HTParse(relative, base_url, PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION); status = HTSearchAbsolute(keywords, full_url, request); HT_FREE(full_url); HT_FREE(base_url); } return status;}/*** Search a string** ---------------** This is the same as HTSearchAbsolute but instead of using a chunk** you can pass a string.*/PUBLIC BOOL HTSearchString (const char * keywords, HTAnchor * anchor, HTRequest * request){ BOOL status = NO; if (keywords && anchor && request) { char * base_url = HTAnchor_address((HTAnchor *) anchor); HTChunk * chunk = HTChunk_new(strlen(keywords)+2); HTChunk_puts(chunk, keywords); status = HTSearchAbsolute(chunk, base_url, request); HT_FREE(base_url); HTChunk_delete(chunk); } return status;} /* Search an Anchor** ----------------** Performs a keyword search on word given by the user. Adds the keyword** to the end of the current address and attempts to open the new address.** The list of keywords must be a space-separated list and spaces will** be converted to '+' before the request is issued.** Search can also be performed by HTLoadAbsolute() etc.** Returns YES if request accepted, else NO*/PUBLIC BOOL HTSearchAnchor (HTChunk * keywords, HTAnchor * anchor, HTRequest * request){ BOOL status = NO; if (keywords && anchor && request) { char * base_url = HTAnchor_address(anchor); status = HTSearchAbsolute(keywords, base_url, request); HT_FREE(base_url); } return status;}/* --------------------------------------------------------------------------*//* HANDLING FORMS USING GET AND POST *//* --------------------------------------------------------------------------*//* Send a Form request using GET from absolute name** ------------------------------------------------** Request a document referencd by an absolute URL appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.** Returns YES if request accepted, else NO*/PUBLIC BOOL HTGetFormAbsolute (HTAssocList * formdata, const char * base, HTRequest * request){ if (formdata && base && request) { char * full = form_url_encode(base, formdata); if (full) { HTAnchor * anchor = HTAnchor_findAddress(full); HTRequest_setAnchor(request, anchor); HT_FREE(full); return launch_request(request, NO); } } return NO;}/* Send a Form request using GET from relative name** ------------------------------------------------** Request a document referencd by a relative URL appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.** Returns YES if request accepted, else NO*/PUBLIC BOOL HTGetFormRelative (HTAssocList * formdata, const char * relative, HTParentAnchor * base, HTRequest * request){ BOOL status = NO; if (formdata && relative && base && request) { char * full_url = NULL; char * base_url = HTAnchor_address((HTAnchor *) base); full_url=HTParse(relative, base_url, PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION); status = HTGetFormAbsolute(formdata, full_url, request); HT_FREE(full_url); HT_FREE(base_url); } return status;}/* Send a Form request using GET from an anchor** --------------------------------------------** Request a document referencd by an anchor object appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.** Returns YES if request accepted, else NO*/PUBLIC BOOL HTGetFormAnchor (HTAssocList * formdata, HTAnchor * anchor, HTRequest * request){ BOOL status = NO; if (formdata && anchor && request) { char * base_url = HTAnchor_address((HTAnchor *) anchor); status = HTGetFormAbsolute(formdata, base_url, request); HT_FREE(base_url); } return status;}PRIVATE int HTEntity_callback (HTRequest * request, HTStream * target){ HTParentAnchor * entity = HTRequest_entityAnchor(request); HTTRACE(APP_TRACE, "Posting Data from callback function\n"); if (!request || !entity || !target) return HT_ERROR; { BOOL chunking = NO; int status; char * document = (char *) HTAnchor_document(entity); int len = HTAnchor_length(entity); if (!document) { HTTRACE(PROT_TRACE, "Posting Data No document\n"); return HT_ERROR; } /* ** If the length is unknown (-1) then see if the document is a text ** type and in that case take the strlen. If not then we don't know ** how much data we can write and must stop */ if (len < 0) { HTFormat actual = HTAnchor_format(entity); HTFormat tmplate = HTAtom_for("text/*"); if (HTMIMEMatch(tmplate, actual)) { len = strlen(document); /* Naive! */ chunking = YES; } else { HTTRACE(PROT_TRACE, "Posting Data Must know the length of document %p\n" _ document); return HT_ERROR; } } /* Send the data down the pipe */ status = (*target->isa->put_block)(target, document, len); if (status == HT_WOULD_BLOCK) { HTTRACE(PROT_TRACE, "Posting Data Target WOULD BLOCK\n"); return HT_WOULD_BLOCK; } else if (status == HT_PAUSE) { HTTRACE(PROT_TRACE, "Posting Data Target PAUSED\n"); return HT_PAUSE; } else if (chunking && status == HT_OK) { HTTRACE(PROT_TRACE, "Posting Data Target is SAVED using chunked\n"); return (*target->isa->put_block)(target, "", 0); } else if (status == HT_LOADED || status == HT_OK) { HTTRACE(PROT_TRACE, "Posting Data Target is SAVED\n"); (*target->isa->flush)(target); return HT_LOADED; } else if (status > 0) { /* Stream specific return code */ HTTRACE(PROT_TRACE, "Posting Data. Target returns %d\n" _ status); return status; } else { /* we have a real error */ HTTRACE(PROT_TRACE, "Posting Data Target ERROR %d\n" _ status); return status; } }}/* Send a Form request using POST from absolute name** -------------------------------------------------** Request a document referencd by an absolute URL appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.*/PUBLIC HTParentAnchor * HTPostFormAbsolute (HTAssocList * formdata, const char * base, HTRequest * request){ if (formdata && base && request) { HTAnchor * anchor = HTAnchor_findAddress(base); return HTPostFormAnchor(formdata, anchor, request); } return NULL;}/* Send a Form request using POST from relative name** -------------------------------------------------** Request a document referencd by a relative URL appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.*/PUBLIC HTParentAnchor * HTPostFormRelative (HTAssocList * formdata, const char * relative, HTParentAnchor * base, HTRequest * request){ HTParentAnchor * postanchor = NULL; if (formdata && relative && base && request) { char * full_url = NULL; char * base_url = HTAnchor_address((HTAnchor *) base); full_url=HTParse(relative, base_url, PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION); postanchor = HTPostFormAbsolute(formdata, full_url, request); HT_FREE(full_url); HT_FREE(base_url); } return postanchor;}/* Send a Form request using POST from an anchor** ---------------------------------------------** Request a document referencd by an anchor object appended with the** formdata given. The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.*/PUBLIC HTParentAnchor * HTPostFormAnchor (HTAssocList * formdata, HTAnchor * anchor, HTRequest * request){ HTParentAnchor * postanchor = NULL; if (formdata && anchor && request) { HTUserProfile * up = HTRequest_userProfile(request); char * tmpfile = HTGetTmpFileName(HTUserProfile_tmp(up)); char * tmpurl = HTParse(tmpfile, "file:", PARSE_ALL); char * form_encoded = form_url_encode(NULL, formdata); if (form_encoded) { /* ** Now create a new anchor for the post data and set up ** the rest of the metainformation we know about this anchor. The ** tmp anchor may actually already exist from previous postings. */ postanchor = (HTParentAnchor *) HTAnchor_findAddress(tmpurl); HTAnchor_clearHeader(postanchor); HTAnchor_setDocument(postanchor, form_encoded); HTAnchor_setLength(postanchor, strlen(form_encoded)); HTAnchor_setFormat(postanchor, WWW_FORM); /* ** Bind the temporary anchor to the anchor that will contain the ** response */ HTLink_removeAll((HTAnchor *) postanchor); HTLink_add((HTAnchor *) postanchor, (HTAnchor *) anchor, NULL, METHOD_POST); /* Set up the request object */ HTRequest_addGnHd(request, HT_G_DATE); /* Send date header */ HTRequest_setAnchor(request, anchor); HTRequest_setEntityAnchor(request, postanchor); HTRequest_setMethod(request, METHOD_POST); /* Add the post form callback function to provide the form data */ HTRequest_setPostCallback(request, HTEntity_callback); /* Now start the load normally */ launch_request(request, NO); } HT_FREE(tmpfile); HT_FREE(tmpurl); } return postanchor;}/*** POST a URL and save the response in a mem buffer** ------------------------------------------------** Returns chunk if OK - else NULL*/PUBLIC HTChunk * HTPostFormAnchorToChunk (HTAssocList * formdata, HTAnchor * anchor, HTRequest * request){ if (formdata && anchor && request) { HTChunk * chunk = NULL; HTStream * target = HTStreamToChunk(request, &chunk, 0); HTRequest_setOutputStream(request, target); if (HTPostFormAnchor(formdata, anchor, request) != NULL) return chunk; else { HTChunk_delete(chunk); return NULL; } } return NULL;}/* --------------------------------------------------------------------------*//* PUT A DOCUMENT *//* --------------------------------------------------------------------------*/ /* ** If we use our persistent cache then we can protect** against the lost update problem by saving the etag** or last modified date in the cache and use it on all** our PUT operations.*/PRIVATE BOOL set_preconditions (HTRequest * request){ if (request) { HTPreconditions precons = HTRequest_preconditions(request); HTRqHd if_headers = HTRequest_rqHd (request); HTRqHd all_if_headers = (HT_C_IF_MATCH | HT_C_IF_MATCH_ANY | HT_C_IF_NONE_MATCH | HT_C_IF_NONE_MATCH_ANY | HT_C_IMS | HT_C_IF_UNMOD_SINCE); switch (precons) { case HT_NO_MATCH: if_headers &= ~(all_if_headers); break; case HT_MATCH_THIS: if_headers &= ~(all_if_headers); if_headers |= (HT_C_IF_MATCH | HT_C_IF_UNMOD_SINCE); break; case HT_MATCH_ANY: if_headers &= ~(all_if_headers); if_headers |= (HT_C_IF_MATCH_ANY); break; case HT_DONT_MATCH_THIS: if_headers &= ~(all_if_headers); if_headers |= (HT_C_IF_NONE_MATCH | HT_C_IMS); break; case HT_DONT_MATCH_ANY: if_headers &= ~(all_if_headers); if_headers |= (HT_C_IF_NONE_MATCH_ANY); break; default: HTTRACE(APP_TRACE, "Precondition %d not understood\n" _ precons); } /* Set the if-* bit flag */ HTRequest_setRqHd(request, if_headers); return YES; } return NO;}PRIVATE BOOL setup_anchors (HTRequest * request, HTParentAnchor * source, HTParentAnchor * dest, HTMethod method){ if (!(method & (METHOD_PUT | METHOD_POST))) { HTTRACE(APP_TRACE, "Posting..... Bad method\n"); return NO; } /* ** Check whether we know if it is possible to PUT to this destination. ** We both check the local set of allowed methods in the anchor and any ** site information that we may have about the location of the origin ** server. */ { char * addr = HTAnchor_address((HTAnchor *) source); char * hostname = HTParse(addr, "", PARSE_HOST);#if 0 HTHost * host = HTHost_find(hostname); HTMethod public_methods = HTHost_publicMethods(host); HTMethod private_methods = HTAnchor_allow(dest);#endif HT_FREE(hostname); HT_FREE(addr);#if 0 /* ** Again, this may be too cautios for normal operations */ if (!(method & (private_methods | public_methods))) { HTAlertCallback * prompt = HTAlert_find(HT_A_CONFIRM); if (prompt) { if ((*prompt)(request, HT_A_CONFIRM, HT_MSG_METHOD, NULL, NULL, NULL) != YES) return NO; } }#endif } /* ** Bind the source anchor to the dest anchor that will contain the ** response. If link already exists then ask is we should do it again. ** If so then remove the old link and replace it with a new one. */ { HTLink *link = HTLink_find((HTAnchor *) source, (HTAnchor *) dest); if (link && HTLink_method(link) == METHOD_PUT) { HTAlertCallback * prompt = HTAlert_find(HT_A_CONFIRM); if (prompt) { if ((*prompt)(request, HT_A_CONFIRM, HT_MSG_REDO, NULL, NULL, NULL) != YES) return NO; } HTLink_remove((HTAnchor *) source, (HTAnchor *) dest); } HTLink_add((HTAnchor*) source, (HTAnchor*) dest, NULL, METHOD_PUT); } return YES;}/* Send an Anchor using PUT from absolute name** -------------------------------------------** Upload a document referenced by an absolute URL appended.** The URL can NOT contain any fragment identifier!** The list of form data must be given as an association list where ** the name is the field name and the value is the value of the field.*/PUBLIC BOOL HTPutAbsolute (HTParentAnchor * source, const char * destination, HTRequest * request){ if (source && destination && request) { HTAnchor * dest = HTAnchor_findAddress(destination); return HTPutAnchor(source, dest, request); } return NO;}/* Send an Anchor using PUT from relative name
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -