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

📄 httchunk.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
字号:
/***	CHUNKED TRANSFER CODING****	(c) COPYRIGHT MIT 1995.**	Please first read the full copyright statement in the file COPYRIGH.**	@(#) $Id: HTTChunk.c,v 2.16 1999/02/22 22:10:12 frystyk Exp $****	This stream parses a chunked transfer encoding using multiple chunks.**** Authors**	HF	Henrik Frystyk <frystyk@w3.org>**** History:**	Apr 96	Written from scratch***//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"#include "HTTChunk.h"					 /* Implemented here */#define PUTBLOCK(b, l)	(*me->target->isa->put_block)(me->target, b, l)#define PUTC(c)		(*me->target->isa->put_character)(me->target, c)struct _HTStream {    const HTStreamClass *	isa;    HTEncoding			coding;    HTStream *			target;    HTRequest *			request;    char * 			param;	    /* Extra parameters for encoding */    long			left;	    /* Remaining bytes in this chunk */    long			total;			      /* Full length */    BOOL			lastchunk;	  /* Is this the last chunk? */    BOOL			trailer;	    /* Do we have a trailer? */    HTEOLState			state;        HTChunk *			buf;    int				status;	     /* return code from down stream */};/* ------------------------------------------------------------------------- *//***	Chunked Decoder stream*/PRIVATE BOOL HTChunkDecode_header (HTStream * me) {    char * line = HTChunk_data(me->buf);    if (line) {	char *errstr = NULL;	me->left = strtol(line, &errstr, 16);    /* hex! */	HTTRACE(STREAM_TRACE, "Chunked..... `%s\' chunk size: %X\n" _ line _ me->left);	if (errstr == line)	    HTDEBUGBREAK("Chunk decoder received illigal chunk size: `%s\'\n" _ line);	if (me->left > 0) {	    me->total += me->left;	    /* Look for arguments */		    HTChunk_clear(me->buf);	} else if (me->left == 0)	       		      /* Last chunk */	    me->lastchunk = YES;	else if (me->left < 0)	    return NO;	return YES;    }    return NO;}PRIVATE int HTChunkDecode_block (HTStream * me, const char * b, int l){    while (l > 0) {	int length = l;	if (me->left <= 0 && !me->trailer) {	    while (l > 0) {		if (me->state == EOL_FLF) {		    if (HTChunkDecode_header(me) == NO) return HT_ERROR;		    if (me->lastchunk) if (*b != CR && *b != LF) me->trailer = YES;		    me->state = EOL_DOT;		    break;		} else if (me->state == EOL_SLF) {		    if (me->lastchunk) break;		    me->state = EOL_BEGIN;		    HTChunk_putc(me->buf, *b);		} else if (*b == CR) {		    me->state = me->state == EOL_DOT ? EOL_SCR : EOL_FCR;		} else if (*b == LF) {		    me->state = me->state == EOL_SCR ? EOL_SLF : EOL_FLF;		} else		    HTChunk_putc(me->buf, *b);		b++, l--;	    }	}	/*	** Account for the parts we read in the chunk header +	** the chunk that we are reading.	*/	if (length != l)	    HTHost_setConsumed(HTNet_host(HTRequest_net(me->request)), length - l);	/*	** If we have to read trailers. Otherwise we are done.	*/	if (me->trailer) {	    me->target = HTStreamStack(WWW_MIME_FOOT, WWW_SOURCE,				       me->target, me->request, NO);	} else if (me->state == EOL_SLF) {            if (me->lastchunk) {                HTAlertCallback * cbf = HTAlert_find(HT_PROG_DONE);                if (cbf) (*cbf)(me->request, HT_PROG_DONE, HT_MSG_NULL,                                NULL, NULL, NULL);                return HT_LOADED;            }	    me->state = EOL_BEGIN;	}	/*	**  Handle the rest of the data including trailers	*/	if (l > 0 && me->left) {	    int bytes = HTMIN(l, me->left);	    int status = (*me->target->isa->put_block)(me->target, b, bytes);	    if (status != HT_OK) return status;	    HTHost_setConsumed(HTNet_host(HTRequest_net(me->request)), bytes);	    me->left -= bytes;	    l -= bytes, b+= bytes;	}    }    return HT_OK;}PRIVATE int HTChunkDecode_string (HTStream * me, const char * s){    return HTChunkDecode_block(me, s, (int) strlen(s));}PRIVATE int HTChunkDecode_character (HTStream * me, char c){    return HTChunkDecode_block(me, &c, 1);}PRIVATE int HTChunkDecode_flush (HTStream * me){    return (*me->target->isa->flush)(me->target);}PRIVATE int HTChunkDecode_free (HTStream * me){    int status = HT_OK;    HTParentAnchor * anchor = HTRequest_anchor(me->request);    /*    **  Update the amount of data that we read in all.    */    HTAnchor_setLength(anchor, me->total);    if (me->target) {	if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)	    return HT_WOULD_BLOCK;    }    HTTRACE(PROT_TRACE, "Chunked..... FREEING....\n");    HTChunk_delete(me->buf);    HT_FREE(me);    return status;}PRIVATE int HTChunkDecode_abort (HTStream * me, HTList * e){    int status = HT_ERROR;    if (me->target) status = (*me->target->isa->abort)(me->target, e);    HTTRACE(PROT_TRACE, "Chunked..... ABORTING...\n");    HTChunk_delete(me->buf);    HT_FREE(me);    return status;}PRIVATE const HTStreamClass HTChunkDecodeClass ={    "ChunkDecoder",    HTChunkDecode_flush,    HTChunkDecode_free,    HTChunkDecode_abort,    HTChunkDecode_character,    HTChunkDecode_string,    HTChunkDecode_block};PUBLIC HTStream * HTChunkedDecoder   (HTRequest *	request,				      void *		param,				      HTEncoding	coding,				      HTStream *	target){    HTStream * me;    HTParentAnchor * anchor = HTRequest_anchor(request);    if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)        HT_OUTOFMEM("HTChunkDecoder");    me->isa = &HTChunkDecodeClass;    me->coding = coding;    me->target = target;    me->request = request;    me->state = EOL_BEGIN;    me->buf = HTChunk_new(64);    me->status = HT_ERROR;        /* Adjust information in anchor */    HTAnchor_setLength(anchor, -1);    HTTRACE(STREAM_TRACE, "Chunked..... Decoder stream created\n");    return me;}/***	Chunked Encoder Stream*/PRIVATE int HTChunkEncode_block (HTStream * me, const char * b, int l){    char * chunky = HTChunk_data(me->buf);    if (me->lastchunk) return HT_LOADED;    if (me->param) {	if (me->total)	    sprintf(chunky, "%c%c%x %s %c%c", CR, LF, l, me->param, CR, LF);	else	    sprintf(chunky, "%x %s %c%c", l, me->param, CR, LF);    } else {	if (me->total)	    sprintf(chunky, "%c%c%x%c%c", CR, LF, l, CR, LF);	else	    sprintf(chunky, "%x%c%c", l, CR, LF);    }    me->total += l;    PUTBLOCK(chunky, (int) strlen(chunky));    HTTRACE(STREAM_TRACE, "Chunked..... chunk size 0x%X\n" _ l);    if (l > 0) return PUTBLOCK(b, l);    /* Here we should provide a footer */    PUTC(CR);    PUTC(LF);    me->lastchunk = YES;    (*me->target->isa->flush)(me->target);    return HT_LOADED;}PRIVATE int HTChunkEncode_string (HTStream * me, const char * s){    return HTChunkEncode_block(me, s, (int) strlen(s));}PRIVATE int HTChunkEncode_character (HTStream * me, char c){    return HTChunkEncode_block(me, &c, 1);}PRIVATE int HTChunkEncode_flush (HTStream * me){    return (*me->target->isa->flush)(me->target);}PRIVATE int HTChunkEncode_free (HTStream * me){#if 0    int status = HTChunkEncode_block(me, NULL, 0);    if (status != HT_WOULD_BLOCK) {	if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)	    return HT_WOULD_BLOCK;	HT_FREE(me);    }    return status;#else    int status = me->target ? (*me->target->isa->_free)(me->target) : HT_OK;    HT_FREE(me);    return status;#endif}PRIVATE int HTChunkEncode_abort (HTStream * me, HTList * e){    int status = HT_ERROR;    if (me->target) status = (*me->target->isa->_free)(me->target);    HTTRACE(PROT_TRACE, "Chunked..... ABORTING...\n");    HT_FREE(me);    return status;}PRIVATE const HTStreamClass HTChunkEncoderClass ={    "ChunkEncoder",    HTChunkEncode_flush,    HTChunkEncode_free,    HTChunkEncode_abort,    HTChunkEncode_character,    HTChunkEncode_string,    HTChunkEncode_block};PUBLIC HTStream * HTChunkedEncoder   (HTRequest *	request,				      void *		param,				      HTEncoding	coding,				      HTStream *	target){    HTStream * me;    if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)        HT_OUTOFMEM("HTChunkEncoder");    me->isa = &HTChunkEncoderClass;    me->coding = coding;    me->target = target;    me->request = request;    me->param = (char *) param;    me->state = EOL_BEGIN;    me->status = HT_ERROR;    {	int length = me->param ? strlen(me->param)+20 : 20;	me->buf = HTChunk_new(length);	HTChunk_ensure(me->buf, length);    }    HTTRACE(STREAM_TRACE, "Chunked..... Encoder stream created\n");    return me;}

⌨️ 快捷键说明

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