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

📄 http.c

📁 www工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_CONFLICT,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = HT_CONFLICT;	    break;	case 410:						  	     /* Gone */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_GONE,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -410;	    break;	case 411:						  /* Length Required */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_LENGTH_REQUIRED,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = HT_LENGTH_REQUIRED;	    break;	case 412:					      /* Precondition failed */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_PRECON_FAILED,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -412;	    break;	case 413:					 /* Request entity too large */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_TOO_BIG,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -413;	    break;	case 414:					     /* Request-URI too long */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_URI_TOO_BIG,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -414;	    break;	case 415:						      /* Unsupported */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_UNSUPPORTED,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -415;	    break;	case 416:				    /* Request Range not satisfiable */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_BAD_RANGE,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -416;	    break;	case 417:				               /* Expectation Failed */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_EXPECTATION_FAILED,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -417;	    break;	case 418:				        /* Reauthentication required */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_REAUTH,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -418;	    break;	case 419:				  /* Proxy Reauthentication required */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_PROXY_REAUTH,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -419;	    break;	default:	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_BAD_REQUEST,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -400;	    break;	}	break;    case 5:	switch (me->status) {	case 501:	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_NOT_IMPLEMENTED,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -501;	    break;	case 502:	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_BAD_GATE,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -502;	    break;	case 503:	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_DOWN,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    /*	    ** If Retry-After header is found then return HT_RETRY else HT_ERROR.	    ** The caller may want to reissue the request at a later point in time.	    */	    {		HTResponse * response = HTRequest_response(me->request);		if (HTResponse_retryTime(response))		    http->result = HT_RETRY;		else		    http->result = -500;	    }	    break;	case 504:	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_GATE_TIMEOUT,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -504;	    break;	case 505:				     /* Unsupported protocol version */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_BAD_VERSION,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = HT_BAD_VERSION;	    break;	case 506:				   /* Partial update Not Implemented */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_NO_PARTIAL_UPDATE,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = HT_BAD_VERSION;	    break;	default:						       /* bad number */	    HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_INTERNAL,			       me->reason, (int) strlen(me->reason), "HTTPNextState");	    http->next = HTTP_ERROR;	    http->result = -500;	    break;	}	break;    default:	HTRequest_addError(me->request, ERR_FATAL, NO, HTERR_BAD_REPLY,			   (void *) me->buffer, me->buflen, "HTTPNextState");	http->next = HTTP_ERROR;	http->result = -(me->status);	break;    }}/* ------------------------------------------------------------------------- *//* 			    HTTP Status Line Stream			     *//* ------------------------------------------------------------------------- *//***	Analyze the stream we have read. If it is a HTTP 1.0 or higher**	then create a MIME-stream, else create a Guess stream to find out**	what the 0.9 server is sending. We need to copy the buffer as we don't**	know if we can modify the contents or not.****	Stream handling is a function of the status code returned from the **	server:**		200:	 Use `output_stream' in HTRequest structure**		else:	 Use `debug_stream' in HTRequest structure****	Return: YES if buffer should be written out. NO otherwise*/PRIVATE int stream_pipe (HTStream * me, int length){    HTRequest * request = me->request;    HTNet * net = HTRequest_net(request);    HTHost * host = HTNet_host(net);#if 0    {	char * uri = HTAnchor_address((HTAnchor *) HTRequest_anchor(request));	fprintf(stderr, "HTTP header: %s for '%s'\n", me->buffer, uri);	HT_FREE(uri);    }#endif        /*    ** Just check for HTTP and not HTTP/ as NCSA server chokes on 1.1 replies    ** Thanks to Markku Savela <msa@msa.tte.vtt.fi>    */    if (strncasecomp(me->buffer, "http", 4)) {	int status;	HTRequest_addError(request, ERR_INFO, NO, HTERR_HTTP09,		   (void *) me->buffer, me->buflen, "HTTPStatusStream");	me->target = HTStreamStack(WWW_UNKNOWN,				   HTRequest_outputFormat(request),				   HTRequest_outputStream(request),				   request, NO);	me->http->next = HTTP_OK;	if ((status = PUTBLOCK(me->buffer, me->buflen)) == HT_OK)	    me->transparent = YES;	HTHost_setVersion(host, HTTP_09);	if (length > 0) HTHost_setConsumed(host, length);	HTTRACE(PROT_TRACE, "HTTP Status. `%s\' is probably a broken 1.0 server that doesn't understand HEAD\n" _ 		    HTHost_name(host));	return HT_ERROR;    } else {	HTResponse * response = HTRequest_response(request);	char * ptr = me->buffer+5;		       /* Skip the HTTP part */	char * vptr = NULL;	int major = 0;	int minor = 0;	me->version = vptr = HTNextField(&ptr);	if (vptr) {	    major = (int) strtol(me->version, &vptr, 10);	    if (vptr++) minor = strtol(vptr, NULL, 10);	}	/* Here we want to find out when to use persistent connection */	if (major > 1 && major < 100) {	    HTTRACE(PROT_TRACE, "HTTP Status. Major version number is %d\n" _ major);	    me->target = HTErrorStream();	    me->status = 9999;	    HTTPNextState(me);					   /* Get next state */	    return HT_ERROR;	} else if (minor <= 0) {	    if (major > 100) {		HTTRACE(PROT_TRACE, "HTTP Status. This is a *BROKEN* HTTP/1.0 server\n");		me->status = 200;	    } else {		HTTRACE(PROT_TRACE, "HTTP Status. This is an HTTP/1.0 server\n");		me->status = atoi(HTNextField(&ptr));	    }	    HTHost_setVersion(host, HTTP_10);	} else {					/* 1.x, x>0 family */	    HTHost_setVersion(host, HTTP_11);		/* Best we can do */	    if (ConnectionMode & HTTP_11_NO_PIPELINING) {		HTTRACE(PROT_TRACE, "HTTP........ Mode is HTTP/1.1 with NO PIPELINING\n");		HTNet_setPersistent(net, YES, HT_TP_SINGLE);	    } else if (ConnectionMode & HTTP_11_MUX) {		HTTRACE(PROT_TRACE, "HTTP........ Mode is HTTP/1.1 with MUXING\n");		HTNet_setPersistent(net, YES, HT_TP_INTERLEAVE);	    } else if (ConnectionMode & HTTP_FORCE_10) {		HTTRACE(PROT_TRACE, "HTTP........ Mode is FORCE HTTP/1.0\n");		HTHost_setVersion(host, HTTP_10);		HTNet_setPersistent(net, NO, HT_TP_SINGLE);	    } else		HTNet_setPersistent(net, YES, HT_TP_PIPELINE);	    me->status = atoi(HTNextField(&ptr));	}	me->reason = ptr;	if ((ptr = strchr(me->reason, '\r')) != NULL)	  /* Strip \r and \n */	    *ptr = '\0';	else if ((ptr = strchr(me->reason, '\n')) != NULL)	    *ptr = '\0';	/* 	**  If it is a 1xx code then find out what to do and return until we	**  get the next code. In the case of Upgrade we may not get back here	**  at all. If we are uploading an entity then continue doing that	*/	if (me->status/100 == 1) {	    if (HTTPInformation(me) == YES) {		me->buflen = 0;		me->state = EOL_BEGIN;		if (me->info_target) (*me->info_target->isa->_free)(me->info_target);		me->info_target = HTStreamStack(WWW_MIME_CONT,						HTRequest_debugFormat(request),						HTRequest_debugStream(request),						request, NO);		if (length > 0) HTHost_setConsumed(host, length);		return HT_OK;	    }	}	/*	**  As we are getting fresh metainformation in the HTTP response,	**  we clear the old metainfomation in order not to mix it with the new	**  one. This is particularly important for the content-length and the	**  like. The TRACE and OPTIONS method just adds to the current 	**  metainformation so in that case we don't clear the anchor.	*/	if (me->status==200 || me->status==203 || me->status==300) {	    /*	    **  200, 203 and 300 are all fully cacheable responses. No byte 	    **  ranges or anything else make life hard in this case.	    */	    HTAnchor_clearHeader(HTRequest_anchor(request));	    HTResponse_setCachable(response, HT_CACHE_ALL);	    me->target = HTStreamStack(WWW_MIME,				       HTRequest_outputFormat(request),				       HTRequest_outputStream(request),				       request, NO);	} else if (me->status==204) {	    HTResponse_setCachable(response, HT_CACHE_ALL);	    me->target = HTStreamStack(WWW_MIME_HEAD,				       HTRequest_debugFormat(request),				       HTRequest_debugStream(request),				       request, NO);	} else if (me->status==206) {	    /*	    **  We got a partial response and now we must check whether	    **  we issued a cache If-Range request or it was a new 	    **  partial response which we don't have in cache. In the latter	    **  case, we don't cache the object and in the former we append	    **  the result to the already existing cache entry.	    */	    HTReload reload = HTRequest_reloadMode(request);	    if (reload == HT_CACHE_RANGE_VALIDATE) {		HTResponse_setCachable(response, HT_CACHE_ALL);		me->target = HTStreamStack(WWW_MIME_PART,					   HTRequest_outputFormat(request),					   HTRequest_outputStream(request),					   request, NO);	    } else {		HTAnchor_clearHeader(HTRequest_anchor(request));		me->target = HTStreamStack(WWW_MIME,					   HTRequest_outputFormat(request),					   HTRequest_outputStream(request),					   request, NO);	    }	} else if (me->status==304) {	    HTResponse_setCachable(response, HT_CACHE_NOT_MODIFIED);	    me->target = HTStreamStack(WWW_MIME_HEAD,				       HTRequest_debugFormat(request),				       HTRequest_debugStream(request),				       request, NO);	} else if (HTRequest_debugStream(request)) {	    HTResponse_setCachable(response,				   (me->status == 201) ? HT_CACHE_ETAG : HT_NO_CACHE);	    me->target = HTStreamStack(WWW_MIME,				       HTRequest_debugFormat(request),				       HTRequest_debugStream(request),				       request, NO);	} else {	    /*	    **  We still need to parse the MIME part in order to find any	    **  valuable meta information which is needed from the response.	    */	    HTResponse_setCachable(response,				   (me->status == 201) ? HT_CACHE_ETAG : HT_NO_CACHE);	    me->target = HTStreamStack(WWW_MIME,				       HTRequest_debugFormat(request),				       HTRequest_debugStream(request),				       request, NO);	}    }    if (!me->target) me->target = HTErrorStream();    HTTPNextState(me);					   /* Get next state */    me->transparent = YES;    if (length > 0) HTHost_setConsumed(HTNet_host(HTRequest_net(me->request)), length);    return HT_OK;}/***	Searches for HTTP header line until buffer fills up or a CRLF or LF**	is found*/PRIVATE int HTTPStatus_put_block (HTStream * me, const char * b, int l){    int status = HT_OK;    int length = l;    me->startLen = me->buflen;    while (!me->transparent && l-- > 0) {	if (me->info_target) {	    /* Put data down the 1xx return code parser until we are done. */	    status = (*me->info_target->isa->put_block)(me->info_target, b, l+1);	    if (status != HT_CONTINUE) return status;	    /* Now free the info stream */	    (*me->info_target->isa->_free)(me->info_target);	    me->info_target = NULL;			    /* Update where we are in the stream */	    l = HTHost_remainingRead(HTNet_host(HTRequest_net(me->request)));	    b += (length-l);	    	    length = l;	    if (l <= 0) break;	} else {	    *(me->buffer+me->buflen++) = *b;	    if (me->state == EOL_FCR) {		if (*b == LF) {	/* Line found */		    if ((status = stream_pipe(me, length-l)) != HT_OK) return status;		} else {		    me->state = EOL_BEGIN;		}	    } else if (*b == CR) {		me->state = EOL_FCR;	    } else if (*b == LF) {		if ((status = stream_pipe(me, length-l)) != HT_OK) return status;	    } else {		if (me->buflen >= MAX_STATUS_LEN) {		    if ((status = stream_pipe(me, length-l)) != HT_OK) return status;		}	    }	    b++;	}    }    if (!me->transparent && length != l)	HTHost_setConsumed(HTNet_host(HTRequest_net(me->request)), length-l);    if (l > 0) return PUTBLOCK(b, l);    return status;}PRIVATE int HTTPStatus_put_string (HTStream * me, const char * s){    return HTTPStatus_put_block(me, s, (int) strlen(s));}PRIVATE int HTTPStatus_put_character (HTStream * me, char c){    return HTTPStatus_put_block(me, &c, 1);}

⌨️ 快捷键说明

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