⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpreq.c

📁 www工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*								      HTTPReq.c**	HTTP REQUEST GENERATION****	(c) COPYRIGHT MIT 1995.**	Please first read the full copyright statement in the file COPYRIGH.**	@(#) $Id: HTTPReq.c,v 2.61 1999/02/22 22:10:12 frystyk Exp $****	This module implements the output stream for HTTP used for sending**	requests with or without a entity body.**** History:**	Jan 95 HFN	Written from scratch*//* Library Includes */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"#include "HTTPGen.h"#include "HTTPUtil.h"#include "HTTPReq.h"					       /* Implements */#define PUTC(c)		(*me->target->isa->put_character)(me->target, c)#define PUTS(s)		(*me->target->isa->put_string)(me->target, s)#define PUTBLOCK(b, l)	(*me->target->isa->put_block)(me->target, b, l)struct _HTStream {    const HTStreamClass *	isa;    HTStream *		  	target;    HTRequest *			request;    SOCKET			sockfd;    int				version;    int 			state;        char *			url;    BOOL			transparent;};/* ------------------------------------------------------------------------- *//* 			    HTTP Output Request Stream			     *//* ------------------------------------------------------------------------- *//*	HTTP09Request**	-------------**	Makes a HTTP/0.9 request*/PRIVATE int HTTP09Request (HTStream * me, HTRequest * request){    HTParentAnchor * anchor = HTRequest_anchor(request);    char * addr = HTAnchor_physical(anchor);    if (!me->url) me->url = HTParse(addr, "", PARSE_PATH|PARSE_PUNCTUATION);    if (me->state == 0) {	int status = PUTS("GET ");	if (status != HT_OK) return status;	me->state++;    }    if (me->state == 1) {	int status = PUTS(me->url);	if (status != HT_OK) return status;	me->state++;    }    PUTC(CR);    PUTC(LF);    HTTRACE(PROT_TRACE, "HTTP........ Generating HTTP/0.9 Request\n");    return HT_OK;}/*	HTTPMakeRequest**	---------------**	Makes a HTTP/1.0-1.1 request header.*/PRIVATE int HTTPMakeRequest (HTStream * me, HTRequest * request){    HTMethod method = HTRequest_method(request);    HTRqHd request_mask = HTRequest_rqHd(request);    HTParentAnchor * anchor = HTRequest_anchor(request);    char * etag = HTAnchor_etag(anchor);    char crlf[3];    char qstr[10];    *crlf = CR; *(crlf+1) = LF; *(crlf+2) = '\0';    /* Generate the HTTP/1.x RequestLine */    if (me->state == 0) {	if (method != METHOD_INVALID) {	    PUTS(HTMethod_name(method));	    PUTC(' ');	} else	    PUTS("GET ");	me->state++;    }    /*    **  Generate the Request URI. If we are using full request URI then it's    **  easy. Otherwise we must filter out the path part of the URI.    **  In case it's a OPTIONS request then if there is no pathinfo then use    **  a * instead. If we use a method different from GET or HEAD then use    **  the content-location if available.    */    if (me->state == 1) {	char * abs_location = NULL;	char * addr = HTAnchor_physical(anchor);#if 0	/*	**  We don't use the content-location any more as it is superseeded	**  by etags and the combination of the two might do more harm than	**  good (The etag is not guaranteed to be unique over multiple URIs)	*/	/*	**  If we are using a method different from HEAD and GET then use	**  the Content-Location if available, else the Request-URI.	*/	if (!HTMethod_isSafe(method)) {	    char * location = HTAnchor_location(anchor);	    if (location) {		if (HTURL_isAbsolute(location))		    addr = location;		else {		    /*		    **  We have a content-location but it is relative and		    **  must expand it either to the content-base or to		    **  the Request-URI itself.		    */		    char * base = HTAnchor_base(anchor);		    abs_location = HTParse(location, base, PARSE_ALL);		    addr = abs_location;		}	    }	}#endif	/*	**  If we are using a proxy or newer versions of HTTP then we can	**  send the full URL. Otherwise we only send the path.	*/	if (HTRequest_fullURI(request))	    StrAllocCopy(me->url, addr);	else {	    me->url = HTParse(addr, "", PARSE_PATH | PARSE_PUNCTUATION);	    if (method == METHOD_OPTIONS) {		/*		** We don't preserve the final slash or lack of same through		** out the code. This is mainly for optimization reasons		** but it gives a problem OPTIONS. We can either send a "*"		** or a "/" but not both. For now we send a "*".		*/		if (!strcmp(me->url, "/")) *me->url = '*';	    }	}	HT_FREE(abs_location);	me->state++;    }    /*    **  Now send the URL that we have put together    */    if (me->state == 2) {	int status = HT_OK;	if ((status = PUTS(me->url)) != HT_OK) return status;	me->state++;#if 0	fprintf(stderr, "Requesting '%s'\n", me->url);#endif    }    PUTC(' ');    /*    **  Send out the version number. If we know it is a HTTP/1.0 server we    **  are talking to then use HTTP/1.0, else use HTTP/1.1 as default version    **  number    */    if (me->version == HTTP_10)	PUTS(HTTP_VERSION_10);    else	PUTS(HTTP_VERSION);    PUTBLOCK(crlf, 2);    /* Request Headers */    if (request_mask & HT_C_ACCEPT_TYPE) {	HTFormat format = HTRequest_outputFormat(request);		/*	** If caller has specified a specific output format then use this.	** Otherwise use all the registered converters to generate the 	** accept header	*/	if (format == WWW_PRESENT) {	    int list;	    HTList *cur;	    BOOL first=YES;	    for (list=0; list<2; list++) {		if ((!list && ((cur = HTFormat_conversion()) != NULL)) ||		    (list && ((cur = HTRequest_conversion(request))!=NULL))) {		    HTPresentation * pres;		    while ((pres=(HTPresentation *) HTList_nextObject(cur))) {			if (pres->rep_out==WWW_PRESENT && pres->quality<=1.0) {			    if (first) {				PUTS("Accept: ");				first=NO;			    } else				PUTC(',');			    PUTS(HTAtom_name(pres->rep));			    if (pres->quality < 1.0 && pres->quality >= 0.0) {				sprintf(qstr, ";q=%1.1f", pres->quality);				PUTS(qstr);			    }			}		    }		}	    }	    if (!first) PUTBLOCK(crlf, 2);	} else {	    /*	    **  If we have an explicit output format then only send	    **  this one if not this is an internal libwww format	    **	of type www/<star>	    */	    if (!HTMIMEMatch(WWW_INTERNAL, format)) {		PUTS("Accept: ");		PUTS(HTAtom_name(format));		PUTBLOCK(crlf, 2);	    }	}	    }    if (request_mask & HT_C_ACCEPT_CHAR) {	int list;	HTList *cur;	BOOL first=YES;	for (list=0; list<2; list++) {	    if ((!list && ((cur = HTFormat_charset()) != NULL)) ||		(list && ((cur = HTRequest_charset(request)) != NULL))) {		HTAcceptNode *pres;		while ((pres = (HTAcceptNode *) HTList_nextObject(cur))) {		    if (first) {			PUTS("Accept-Charset: ");			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_ACCEPT_ENC) {	int list;	HTList *cur;	BOOL first=YES;	for (list=0; list<2; list++) {	    if ((!list && ((cur = HTFormat_contentCoding()) != NULL)) ||		(list && ((cur = HTRequest_encoding(request)) != NULL))) {		HTCoding * pres;		while ((pres = (HTCoding *) HTList_nextObject(cur))) {		    double quality = HTCoding_quality(pres);		    if (first) {			PUTS("Accept-Encoding: ");			first = NO;		    } else			PUTC(',');		    PUTS(HTCoding_name(pres));		    if (quality < 1.0 && quality >= 0.0) {			sprintf(qstr, ";q=%1.1f", quality);			PUTS(qstr);		    }		}	    }	}	if (!first) PUTBLOCK(crlf, 2);    }    if (request_mask & HT_C_ACCEPT_TE) {	int list;	HTList *cur;	BOOL first=YES;	for (list=0; list<2; list++) {	    if ((!list && ((cur = HTFormat_transferCoding()) != NULL)) ||		(list && ((cur = HTRequest_transfer(request)) != NULL))) {		HTCoding * pres;		while ((pres = (HTCoding *) HTList_nextObject(cur))) {		    double quality = HTCoding_quality(pres);		    const char * coding = HTCoding_name(pres);		    if (first) {			PUTS("TE: ");			first = NO;		    } else			PUTC(',');		    /* Special check for "chunked" which is translated to "trailers" */		    if (!strcasecomp(coding, "chunked"))			PUTS("trailers");		    else			PUTS(coding);		    if (quality < 1.0 && quality >= 0.0) {			sprintf(qstr, ";q=%1.1f", quality);			PUTS(qstr);		    }		}	    }	}	if (!first) PUTBLOCK(crlf, 2);    }    if (request_mask & HT_C_ACCEPT_LAN) {	int list;	HTList *cur;	BOOL first=YES;	for (list=0; list<2; list++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -