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

📄 parse.c

📁 WSP is an HTTP to WSP proxy that can be used to forward HTTP requests to WSP, which is used in WAP 1
💻 C
字号:
/*Copyright (c) 2002-2003 Nicolas Jombart - HSCRedistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright   notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright   notice, this list of conditions and the following disclaimer in the   documentation and/or other materials provided with the distribution.3. The name of the author may not be used to endorse or promote products   derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUTNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OFTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//*  * parsing functions : *   - decode WSP packet (almost only interesting fields *                        for us) *   - make the HTTP reply * * $Id: parse.c,v 1.22 2004/09/08 09:33:56 jombart Exp $  * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "wspp.h"/*  * Parse proxy request */int parse_req (request *req, char *line) {int i, k;char tmp[16]; /* houuu */	if(req->parse_state == PARSE_TODO) {		/* init */		req->content_length = 0;		req->data_length = 0;		req->headers = NULL;		req->data = NULL;		/* extract METHOD */		if( !strncmp(line, "GET ", 4) ) {			req->method = WSP_GET; k = 4;		}		else if( !strncmp(line, "DELETE ", 7) ) {			req->method = WSP_DELETE; k = 7;		}		else if( !strncmp(line, "OPTIONS ", 8) ) {			req->method = WSP_OPTIONS; k = 8;		}		else if( !strncmp(line, "PUT ", 4) ) {			req->method = WSP_PUT; k = 4;		}		else if( !strncmp(line, "HEAD ", 5) ) {			req->method = WSP_HEAD; k = 5;		}		else if( !strncmp(line, "POST ", 5) ) {			req->method = WSP_POST; k = 5;		}		else if( !strncmp(line, "TRACE ", 6) ) {			req->method = WSP_TRACE; k = 6;		} else { 			req->parse_state = PARSE_ERROR;			return -1;		}			/* extract URI */		for(i = k; line[i] != '\x20' && i < strlen(line); i++);		req->uri = (char *) malloc(i-k+1);		memset(req->uri, 0, i-k+1);		memcpy(req->uri, line + k, i - k);		/* FIXME: We ignore HTTP Version */		req->parse_state = PARSE_HEADER_TODO;		return 1;	}	if(req->parse_state == PARSE_HEADER_TODO) {		/* Skip hardcoded ignored headers */		if( !strncasecmp(line, "User-Agent:", 11) ) {#ifdef DEBUG			printf("Ignored header (replaced) : %s \n", line);#endif			return 1;		}		if( !strncasecmp(line, "Content-Length:", 15) ) {			k = 0;			for(i = 16; line[i] && isdigit(line[i]) && k<16; tmp[k++] = line[i++]);			tmp[k] = '\0';			req->content_length = atoi(tmp);			return 1;		}		/* header to transmit to gateway */		req->headers = restrcat(req->headers, line);		return 1;	}	return 0;}/* * Parse WSP reply packet and fill in structure */int parse_wsp (wsp_reply *reply, unsigned char *packet, int size) {int p, e, offset, i, head, textual, ctype_length, c;char header_tmp[256];char header_name[256];char header_value[256];	memset((void *)reply, 0, sizeof(reply));	head = 0;	offset = 0;	reply->headers = NULL;	/* reply ? */	if(packet[1] != PDU_REPLY) {		reply->status = HTTP_ERROR_CODE;		reply->header_length = 0;		reply->data_length = 0;		reply->contenttype = 0x02;		return -1;	}	++head;	/* status code */	reply->status = http_code(packet[2]);/*	if(packet[2] != WSP_OK) {		return 0;	}*/	++head;	reply->header_length = from_uintvar(packet, 3, 8);#ifdef DEBUG	printf("Header length from packet : %d\n", reply->header_length);#endif	/* Content-Type code */	offset = uintvar_len(reply->header_length);	head += offset;	c = packet[offset+3];	if((c > 40) && (c < 0x7f)) {		//printf("Textual content-type\n");		reply->contenttype = 0xFF;  /* internal value because conversion is done later */		reply->contenttype_string = strdup(packet + offset + 3);		for(i = offset+3; packet[i]; i++) /*{ printf("%c", packet[i])*/;/* }*/		head += i - (offset + 3) + 1/*- 1*/ ;		ctype_length= strlen(reply->contenttype_string) + 1;	}	else if (c >= 0x80) {		//printf("one char content-type\n");		reply->contenttype = c & 0x7f;		ctype_length = 1; head += 1;	}	else if (c<= 40) {		/* first byte = len */		//printf("content-type coded with %d bytes\n", c);		ctype_length = c; head += c + 1;		reply->contenttype = packet[offset+4] & 0x7f;		if((c == 3) && (packet[offset+5] == 0x81)) { /* charset */			reply->charset = packet[offset+6] & 0x7f;		}	}	else {		/* should never occur */		ctype_length = 0;	}#ifdef DEBUG	printf("Content-type : 0x%x (%s)", reply->contenttype, contentt(reply->contenttype));	if(reply->contenttype == 0xFF) { printf(" (%s) \n", reply->contenttype_string); }	else { printf("\n"); }#endif	i = head + 1;	//printf("limite = %d\n", head + (reply->header_length - ctype_length));	while(i < head + (reply->header_length - ctype_length)) {			e = packet[i] & 0x7f; /* field name */			textual = 0;		if((e >= 0x42) && (e <= 0x7f)) { /* XXX */			/* textual name */			strlcpy(header_name, packet + i, 256);			offset = strlen(packet+i) + 1;			textual = 1; /* textual names MUST be followed by textual value */		} else {			strlcpy(header_name, header(e), 256);			offset = 1;		}#ifdef DEBUG		printf("parsing header %s\n", header_name);#endif		i += offset;		p = (int) packet[i]; /* first octet of field value */		//printf("First octet of value : 0x%x ... ", p);		/* endodings */		if((textual == 1) || ((p >= 32) && (p <= 127))) { /* Null terminated text string */			//printf("textual\n");			strlcpy(header_value, packet+i, 256);			i += 1 + strlen(packet+i);		}		if(p <= 30) { /* followed by indicated number of data octets */			//printf("followed by indicated number of data octets \n");			if((e == 0x12) || (e == 0x1d) || (e == 0x14)) {				/* date */				snprintf(header_value, 256, "%s", extime(packet + i + 1, p));				} else if (e == 0x0d) {				/* Content-Length : we recompute it later */				i += 1 + p;				continue;			} else {				strlcpy(header_value, packet+i, p); /* always < 256 */			}			i += 1 + p;		}		if(p == 31) { /* uintvar */			//printf("unintvar\n");			snprintf(header_value, 256, "%d", from_uintvar(packet, i+1, 8));			i += 1 + (from_uintvar(packet, i+1, 8) / 0x7f) + 1;		}		if(p > 127) { /* encoded 7bit value, no more data*/			//printf("Encoded 7-bit value\n");			/* Ignore Content-Length */			if(e == 0x0d) {				i += 1;				continue;			}			/* common headers which spec gives specific encoding info (8.4.2.X) */			switch(e) { /* common headers */				case 0x04: /* Accept-Range */					switch(p) {						case 128: strlcpy(header_value, "None", 256); break;						case 129: strlcpy(header_value, "bytes", 256); break;						default:  strlcpy(header_value, "Unknown", 256);					}					break;				case 0x08: /* Cache-Control */					switch(p) {						case 128: strlcpy(header_value, "no-cache", 256); break;						case 129: strlcpy(header_value, "no-store", 256); break;						case 130: strlcpy(header_value, "max-age", 256); break;						case 131: strlcpy(header_value, "max-stale", 256); break;						case 132: strlcpy(header_value, "min-fresh", 256); break;						case 133: strlcpy(header_value, "only-if-cached", 256); break;						case 134: strlcpy(header_value, "public", 256); break;						case 135: strlcpy(header_value, "private", 256); break;						case 136: strlcpy(header_value, "no-transform", 256); break;						case 137: strlcpy(header_value, "must-revalidate", 256); break;						case 138: strlcpy(header_value, "proxy-revalidate", 256); break;						case 139: strlcpy(header_value, "s-maxage", 256); break;						default:  strlcpy(header_value, "Unknown", 256);					}					break;				case 0x0c: /* Content-Language */					switch(p) {						/* FIXME : arbitrary langages, should implement ISO 639 */						case 0x19: strlcpy(header_value, "en", 256); break;						case 0x1B: strlcpy(header_value, "es", 256); break;						case 0x22: strlcpy(header_value, "fr", 256); break;						case 0x5F: strlcpy(header_value, "ru", 256); break;						case 0x16: strlcpy(header_value, "de", 256); break;						case 0x36: strlcpy(header_value, "ja", 256); break;						case 0x70: strlcpy(header_value, "sv", 256); break;						case 0x12: strlcpy(header_value, "co", 256); break;						default:   strlcpy(header_value, "en", 256);					}					break;				case 0x2a: /* Vary */					switch(p) {						case 0xa9: strlcpy(header_value, "User-Agent", 256); break;						default:   strlcpy(header_value, "Unknown", 256);					}					break;				default: /* fall-back */					snprintf(header_value, 256, "%d", p & 0x7f);			}			i += 1;		}		/* store Name: Value */		snprintf(header_tmp, 256, "%s: %s", header_name, header_value);		reply->headers = restrcat(reply->headers, header_tmp);}	/* datas */	reply->data_length = size - i;	reply->data = (char *) malloc(reply->data_length);	memcpy(reply->data, packet + i, reply->data_length);	return 0;}/* * WSP to HTTP structure */void wsp_to_http (http *body, const wsp_reply *wsp_packet) {	char tmp[69];	body->headers = NULL;	strlcpy(tmp, expand_http_code(wsp_packet->status), 69); 	body->headers = restrcat(body->headers, tmp);	/* Content-Type */	sprintf(tmp, "Content-Type: %s", 		wsp_packet->contenttype == 0xFF ? wsp_packet->contenttype_string 		                                : contentt(wsp_packet->contenttype));	body->headers = restrcat(body->headers, tmp);	/* Content-Length */	sprintf(tmp, "Content-Length: %d", wsp_packet->data_length);	body->headers = restrcat(body->headers, tmp);	/* Our Via: */	body->headers = restrcat(body->headers, HEADER_VIA);	/* headers from gateway */	body->headers = restrcat(body->headers, wsp_packet->headers);	/* \n */	body->headers = restrcat(body->headers, "\n");	/* Body */	body->data_length = wsp_packet->data_length;	body->data = (char *) malloc(wsp_packet->data_length * sizeof(char));	memcpy(body->data, wsp_packet->data, wsp_packet->data_length);}

⌨️ 快捷键说明

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