📄 httpreq.c
字号:
if ((!list && ((cur = HTFormat_language()) != NULL)) || (list && ((cur = HTRequest_language(request)) != NULL))) { HTAcceptNode *pres; while ((pres = (HTAcceptNode *) HTList_nextObject(cur))) { if (first) { PUTS("Accept-Language: "); first=NO; } else PUTC(','); PUTS(HTAtom_name(pres->atom)); if (pres->quality < 1.0 && pres->quality >= 0.0) { sprintf(qstr, ";q=%1.1f", pres->quality); PUTS(qstr); } } } } if (!first) PUTBLOCK(crlf, 2); } if (request_mask & HT_C_AUTH) { HTAssocList * cur = HTRequest_credentials(request); if (cur) { /* Access authentication */ HTAssoc * pres; while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) { PUTS(HTAssoc_name(pres)); PUTS(": "); PUTS(HTAssoc_value(pres)); PUTBLOCK(crlf, 2); } } } if (request_mask & HT_C_EXPECT) { HTAssocList * cur = HTRequest_expect(request); if (cur) { BOOL first=YES; HTAssoc * pres; while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) { char * value = HTAssoc_value(pres); if (first) { PUTS("Expect: "); first = NO; } else PUTC(','); /* Output the name */ PUTS(HTAssoc_name(pres)); /* Only output the value if not empty string */ if (*value) { PUTS("="); PUTS(value); } } PUTBLOCK(crlf, 2); } } if (request_mask & HT_C_FROM) { HTUserProfile * up = HTRequest_userProfile(request); const char * mailaddress = HTUserProfile_email(up); if (mailaddress) { PUTS("From: "); PUTS(mailaddress); PUTBLOCK(crlf, 2); } } if (request_mask & HT_C_HOST) { char *orig = HTAnchor_address((HTAnchor *) anchor); char *host = HTParse(orig, "", PARSE_HOST);#if 0 /* Keep the port number for HTTP/1.1 compliance */ char *ptr = strchr(host, ':'); /* Chop off port number */ if (ptr) *ptr = '\0';#endif PUTS("Host: "); PUTS(host); PUTBLOCK(crlf, 2); HT_FREE(orig); HT_FREE(host); } /* ** In the "If-*" series of headers, the ones related to etags have higher ** priority than the date relates ones. That is, if we have a etag then ** use that, otherwise use the date. First we check for range, match, and ** unmodified-since. */ if (request_mask & HT_C_IF_RANGE && etag) { PUTS("If-Range: \""); PUTS(etag); PUTC('"'); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-Range using etag `%s\'\n" _ etag); } else if (request_mask & HT_C_IF_MATCH_ANY) { PUTS("If-Match: *"); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-Match using `*\'\n"); } else if (request_mask & HT_C_IF_MATCH && etag) { PUTS("If-Match: \""); PUTS(etag); PUTC('"'); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-Match using etag `%s\'\n" _ etag); } else if (request_mask & HT_C_IF_UNMOD_SINCE) { time_t lm = HTAnchor_lastModified(anchor); if (lm > 0) { PUTS("If-Unmodified-Since: "); PUTS(HTDateTimeStr(&lm, NO)); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-Unmodified-Since `%s\'\n" _ HTDateTimeStr(&lm, NO)); } } /* ** If-None-Match and If-Modified-Since are equivalent except that the ** first uses etags and the second uses dates. Etags have precedence over ** dates. */ if (request_mask & HT_C_IF_NONE_MATCH_ANY) { PUTS("If-None-Match: *"); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-None-Match using `*\'\n"); } else if (request_mask & HT_C_IF_NONE_MATCH && etag) { PUTS("If-None-Match: \""); PUTS(etag); PUTC('"'); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-None-Match `%s\'\n" _ etag); } if (request_mask & HT_C_IMS) { time_t lm = HTAnchor_lastModified(anchor); if (lm > 0) { PUTS("If-Modified-Since: "); PUTS(HTDateTimeStr(&lm, NO)); PUTBLOCK(crlf, 2); HTTRACE(PROT_TRACE, "HTTP........ If-Modified-Since `%s\'\n" _ HTDateTimeStr(&lm, NO)); } } /* ** Max forwards is mainly for TRACE where we want to be able to stop the ** TRACE at a specific location un the message path. */ if (request_mask & HT_C_MAX_FORWARDS) { int hops = HTRequest_maxForwards(request); if (hops >= 0) { sprintf(qstr, "%d", hops); PUTS("Max-Forwards: "); PUTS(qstr); PUTBLOCK(crlf, 2); } } /* ** Range requests. For now, we only take the first entry registered for ** this request. This means that you can only send a single "unit" and ** then a set of range within this unit. This is in accordance with ** HTTP/1.1. Multiple units will go on multiple lines. */ if (request_mask & HT_C_RANGE) { HTAssocList * cur = HTRequest_range(request); if (cur) { /* Range requests */ HTAssoc * pres; while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) { PUTS("Range: "); PUTS(HTAssoc_name(pres)); /* Unit */ PUTS("="); PUTS(HTAssoc_value(pres)); /* Ranges within this unit */ PUTBLOCK(crlf, 2); } } } if (request_mask & HT_C_REFERER) { HTParentAnchor * parent_anchor = HTRequest_parent(request); if (parent_anchor) { char * act = HTAnchor_address((HTAnchor *) anchor); char * parent = HTAnchor_address((HTAnchor *) parent_anchor);#if 1 char * relative = HTRelative(parent, act);#else char * relative = HTParse(parent, act, PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);#endif if (relative && *relative) { PUTS("Referer: "); PUTS(relative); PUTBLOCK(crlf, 2); } HT_FREE(act); HT_FREE(parent); HT_FREE(relative); } } if (request_mask & HT_C_USER_AGENT) { PUTS("User-Agent: "); PUTS(HTLib_appName()); PUTC('/'); PUTS(HTLib_appVersion()); PUTC(' '); PUTS(HTLib_name()); PUTC('/'); PUTS(HTLib_version()); PUTBLOCK(crlf, 2); } HTTRACE(PROT_TRACE, "HTTP........ Generating HTTP/1.x Request Headers\n"); return HT_OK;}PRIVATE int HTTPRequest_put_block (HTStream * me, const char * b, int l){ if (!me->target) { return HT_WOULD_BLOCK; } else if (me->transparent) return b ? PUTBLOCK(b, l) : HT_OK; else { int status = HT_OK; if (me->version == HTTP_09) { status = HTTP09Request(me, me->request); if (status != HT_OK) return status; } else { status = HTTPMakeRequest(me, me->request); if (status != HT_OK) return status; me->transparent = YES; return b ? PUTBLOCK(b, l) : HT_OK; } return status; }}PRIVATE int HTTPRequest_put_character (HTStream * me, char c){ return HTTPRequest_put_block(me, &c, 1);}PRIVATE int HTTPRequest_put_string (HTStream * me, const char * s){ return HTTPRequest_put_block(me, s, strlen(s));}/*** Flushes data but doesn't free stream object*/PRIVATE int HTTPRequest_flush (HTStream * me){ int status = HTTPRequest_put_block(me, NULL, 0); return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;}/*** Flushes data and frees stream object*/PRIVATE int HTTPRequest_free (HTStream * me){ int status = HTTPRequest_flush(me); if (status != HT_WOULD_BLOCK) { if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK) return HT_WOULD_BLOCK; HT_FREE(me->url); HT_FREE(me); } return status;}PRIVATE int HTTPRequest_abort (HTStream * me, HTList * e){ HTTRACE(PROT_TRACE, "HTTPRequest. ABORTING...\n"); /* JK: Added protection against NULL pointers */ if (me) { if (me->target && me->target->isa) (*me->target->isa->abort)(me->target, e); if (me->url) HT_FREE(me->url); HT_FREE(me); } return HT_ERROR;}/* HTTPRequest Stream** -----------------*/PRIVATE const HTStreamClass HTTPRequestClass ={ "HTTPRequest", HTTPRequest_flush, HTTPRequest_free, HTTPRequest_abort, HTTPRequest_put_character, HTTPRequest_put_string, HTTPRequest_put_block};PUBLIC HTStream * HTTPRequest_new (HTRequest * request, HTStream * target, BOOL endHeader, int version){ HTStream * me; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTTPRequest_new"); me->isa = &HTTPRequestClass; me->target = target; me->request = request; me->version = version; me->transparent = NO; /* ** If sending a body in the request then we want a 100 code! */ if (HTMethod_hasEntity(HTRequest_method(request))) HTRequest_addExpect(request, "100-continue", ""); /* Return general HTTP header stream */ return HTTPGen_new(request, me, endHeader, version);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -