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

📄 parsers.c

📁 一个不错的服务代理器
💻 C
字号:
char *parsers_rcs = "$Id: parsers.c,v 1.26 1998/10/23 01:54:12 ACJC Exp $";/* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation. * Distributed under the GNU General Public License; see the README file. * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html */#include <stdio.h>#include <sys/types.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#ifndef _WIN32#include <unistd.h>#endif#ifdef REGEX#include <gnu_regex.h>#endif#include "jcc.h"struct parsers client_patterns[] = {	{ "referer:", /* sic */	 8,	client_referrer		},	{ "user-agent:",	11,	client_uagent		},	{ "ua-",		 3,	client_ua		},	{ "from:",		 5,	client_from		},	{ "cookie:",		 7,	client_send_cookie	},	{ "x-forwarded-for:",	16,	client_x_forwarded	},	{ "proxy-connection:",	17,	crumble			},/*	{ "if-modified-since:", 18,	crumble			}, */	{ NULL,			 0,	NULL			}};struct interceptors intercept_patterns[] = {	{ "show-proxy-args",	14,	show_proxy_args		},	{ "ij-blocked-url",	14,	ij_blocked_url		},	{ "ij-untrusted-url",	14,	ij_untrusted_url	},	{ NULL,			 0,	NULL			}};struct parsers server_patterns[] = {	{ "set-cookie:",	11,	server_set_cookie	},	{ "connection:",	11,	crumble			},	{ NULL,			 0,	NULL			}};void (*add_client_headers[])() = {	client_cookie_adder,	client_x_forwarded_adder,	client_xtra_adder,	NULL};void (*add_server_headers[])() = {	NULL};struct parsers *match(char *buf, struct parsers *pats){	struct parsers *v;	if(buf == NULL) {		/* hit me */		fprintf(logfp, "bingo!\n");		return(NULL);	}	for(v = pats; v->str ; v++) {		if(strncmpic(buf, v->str, v->len) == 0) {			return(v);		}	}	return(NULL);}intflush_socket(int fd, struct client_state *csp){	struct iob *iob = csp->iob;	int n = iob->eod - iob->cur;	if(n <= 0) return(0);	n = write_socket(fd, iob->cur, n);	iob->eod = iob->cur = iob->buf;	return(n);}intadd_to_iob(struct client_state *csp, char *buf, int n){	struct iob *iob = csp->iob;	int have, need;	char *p;	have = iob->eod - iob->cur;	if(n <= 0) return(have);	need = have + n;	if((p = malloc(need + 1)) == NULL) {			fprintf(logfp, "%s: malloc() iob failed\n", prog);			fperror(logfp, "");			return(-1);	}	if(have) {		/* there is something in the buffer - save it */		memcpy(p, iob->cur, have);		/* replace the buffer with the new space */		freez(iob->buf);		iob->buf = p;		/* point to the end of the data */		p += have;	} else {		/* the buffer is empty, free it and reinitialize */		freez(iob->buf);		iob->buf = p;	}	/* copy the new data into the iob buffer */	memcpy(p, buf, n);	/* point to the end of the data */	 p +=   n ;	/* null terminate == cheap insurance */	*p  = '\0';	/* set the pointers to the new values */	iob->cur = iob->buf;	iob->eod = p;	return(need);}/* this (odd) routine will parse the csp->iob and return one of the following: * * 1) a pointer to a dynamically allocated string that contains a header line * 2) NULL  indicating that the end of the header was reached * 3) ""    indicating that the end of the iob was reached before finding *          a complete header line. */char *get_header(struct client_state *csp){	struct iob *iob = csp->iob;	char *p, *q, *ret;	if((iob->cur == NULL)	|| ((p = strchr(iob->cur, '\n')) == NULL)) {		return("");	/* couldn't find a complete header */	}	*p = '\0';	ret = strdup(iob->cur);	iob->cur = p+1;	if((q = strchr(ret, '\r'))) *q = '\0';	/* is this a blank linke (i.e. the end of the header) ? */	if(*ret == '\0') {		freez(ret);		return(NULL);	}	return(ret);}/* h = pointer to list 'dummy' header * s = string to add to the list */voidenlist(struct list *h, char *s){	struct list *n = (struct list *)malloc(sizeof(*n));	struct list *l;	if(n) {		n->str  = strdup(s);		n->next = NULL;		if((l = h->last)) {			l->next = n;		} else {			h->next = n;		}		h->last = n;	}}voiddestroy_list(struct list *h){	struct list *p, *n;	for(p = h->next; p ; p = n) {		n = p->next;		freez(p->str);		freez(p);	}	memset(h, '\0', sizeof(*h));}char *list_to_text(struct list *h){	struct list *p;	char *ret = NULL;	char *s;	int size;	size = 0;	for(p = h->next; p ; p = p->next) {		if(p->str) {			size += strlen(p->str) + 2;		}	}	if((ret = malloc(size + 1)) == NULL) {		return(NULL);	}	ret[size] = '\0';	s = ret;	for(p = h->next; p ; p = p->next) {		if(p->str) {			strcpy(s, p->str);			s += strlen(s);			*s++ = '\r'; *s++ = '\n';		}	}	return(ret);}/* sed(): add, delete or modify lines in the HTTP header streams. * on entry, it receives a linked list of headers space that was * allocated dynamically (both the list nodes and the header contents). * * it returns a single pointer to a fully formed header. * * as a side effect it frees the space used by the original header lines. * */char *sed(pats, more_headers, csp)struct parsers pats[];int (*more_headers[])();struct client_state *csp;{	struct list *p;	struct parsers *v;	char *hdr;	int (**f)();	for(p = csp->headers->next; p ; p = p->next) {		if(DEBUG(HDR)) fprintf(logfp, "scan: %s", p->str);		if((v = match(p->str, pats))) {			hdr = v->parser(v, p->str, csp);			freez(p->str);			p->str = hdr;		}		if(DEBUG(HDR)) fprintf(logfp, "\n");	}	/* place any additional headers on the csp->headers list */	for(f = more_headers; *f ; f++) {		(*f)(csp);	}	/* add the blank line at the end of the header */	enlist(csp->headers, "");	hdr = list_to_text(csp->headers);	return(hdr);}voidfree_http_request(struct http_request *http){	freez(http->cmd);	freez(http->gpc);	freez(http->host);	freez(http->hostport);	freez(http->path);	freez(http->ver);}/* parse out the host and port from the URL */voidparse_http_request(char *req, struct http_request *http, struct client_state *csp){	char *buf, *v[10], *url, *p;	int n;	memset(http, '\0', sizeof(*http));	http->cmd = strdup(req);	buf = strdup(req);	n = ssplit(buf, " \r\n", v, SZ(v), 1, 1);	if(n == 3) {		/* this could be a CONNECT request */		if(strcmpic(v[0], "connect") == 0) {			http->ssl      = 1;			http->gpc      = strdup(v[0]);			http->hostport = strdup(v[1]);			http->ver      = strdup(v[2]);		}		/* or it could be a GET or a POST */		if((strcmpic(v[0], "get")  == 0)		|| (strcmpic(v[0], "head") == 0)		|| (strcmpic(v[0], "post") == 0)) {			http->ssl      = 0;			http->gpc      = strdup(v[0]);			url            =        v[1] ;			http->ver      = strdup(v[2]);			if(strncmpic(url, "http://",  7) == 0) {				url += 7;			} else if(strncmpic(url, "https://", 8) == 0) {				url += 8;			} else {				url = NULL;			}			if(url && (p = strchr(url, '/'))) {				http->path = strdup(p);				*p = '\0';				http->hostport = strdup(url);			}		}	}	freez(buf);	if(http->hostport == NULL) {		free_http_request(http);		return;	}	buf = strdup(http->hostport);	n = ssplit(buf, ":", v, SZ(v), 1, 1);	if(n == 1) {		http->host = strdup(v[0]);		http->port = 80;	}	if(n == 2) {		http->host = strdup(v[0]);		http->port = atoi(v[1]);	}	freez(buf);	if(http->host == NULL) {		free_http_request(http);	}	if(http->path == NULL) {		http->path = strdup("");	}}/* here begins the family of parser functions that reformat header lines */char *crumble(struct parsers *v, char *s, struct client_state *csp){	if(DEBUG(HDR)) fprintf(logfp, " crunch!");	return(NULL);}char *client_referrer(struct parsers *v, char *s, struct client_state *csp){	csp->referrer = strdup(s);	if(referrer == NULL) {		if(DEBUG(HDR)) fprintf(logfp, " crunch!");		return(NULL);	}	if(*referrer == '.') {		return(strdup(s));	}	if(*referrer == '@') {		if(csp->send_user_cookie) {			return(strdup(s));		} else {			if(DEBUG(HDR)) fprintf(logfp, " crunch!");			return(NULL);		}	}	if(DEBUG(HDR)) fprintf(logfp, " modified");	s = strsav(NULL, "Referer: ");	s = strsav(s,     referrer  );	return(s);}char *client_uagent(struct parsers *v, char *s, struct client_state *csp){	if(uagent == NULL) {		if(DEBUG(HDR)) fprintf(logfp, " default");		return(strdup(DEFAULT_USER_AGENT));	}	if(*uagent == '.') {		return(strdup(s));	}	if(*uagent == '@') {		if(csp->send_user_cookie) {			return(strdup(s));		} else {			if(DEBUG(HDR)) fprintf(logfp, " default");			return(strdup(DEFAULT_USER_AGENT));		}	}	if(DEBUG(HDR)) fprintf(logfp, " modified");	s = strsav(NULL, "User-Agent: ");	s = strsav(s,     uagent   );	return(s);}char *client_ua(struct parsers *v, char *s, struct client_state *csp){	if(uagent == NULL) {		if(DEBUG(HDR)) fprintf(logfp, " crunch!");		return(NULL);	}	if(*uagent == '.') {		return(strdup(s));	}	if(*uagent == '@') {		if(csp->send_user_cookie) {			return(strdup(s));		} else {			if(DEBUG(HDR)) fprintf(logfp, " crunch!");			return(NULL);		}	}	if(DEBUG(HDR)) fprintf(logfp, " crunch!");	return(NULL);}char *client_from(struct parsers *v, char *s, struct client_state *csp){	/* if not set, zap it */	if(from == NULL) {		if(DEBUG(HDR)) fprintf(logfp, " crunch!");		return(NULL);	}	if(*from == '.') {		return(strdup(s));	}	if(DEBUG(HDR)) fprintf(logfp, " modified");	s = strsav(NULL, "From: ");	s = strsav(s,     from   );	return(s);}char *client_send_cookie(struct parsers *v, char *s, struct client_state *csp){	if(csp->send_user_cookie) {		enlist(csp->cookie_list, s + v->len + 1);	} else {		if(DEBUG(HDR)) fprintf(logfp, " crunch!");	}	/* always return NULL here.  the cookie header will be sent	 * at the end of the header.	 */	return(NULL);}char *client_x_forwarded(struct parsers *v, char *s, struct client_state *csp){	if(add_forwarded) {		csp->x_forwarded = strdup(s);	}	/* always return NULL, since this information	 * will be sent at the end of the header.	 */	return(NULL);}/* the following functions add headers directly to the header list */void client_cookie_adder(struct client_state *csp){	struct list *l;	char *tmp = NULL;	char *e;	for(l = csp->cookie_list->next; l ; l = l->next) {		if(tmp) {			tmp = strsav(tmp, "; ");		}		tmp = strsav(tmp, l->str);	}	for(l = wafer_list->next;  l ; l = l->next) {		if(tmp) {			tmp = strsav(tmp, "; ");		}		if((e = url_encode(cookie_code_map, l->str))) {			tmp = strsav(tmp, e);			freez(e);		}	}	if(tmp) {		char *ret;		ret = strdup("Cookie: ");		ret = strsav(ret, tmp);		if(DEBUG(HDR)) fprintf(logfp, "addh: %s\r\n", ret);		enlist(csp->headers, ret);		freez(tmp);		freez(ret);	}}void client_xtra_adder(struct client_state *csp){	struct list *l;	for(l = xtra_list->next; l ; l = l->next) {		if(DEBUG(HDR)) fprintf(logfp, "addh: %s\r\n", l->str);		enlist(csp->headers, l->str);	}}void client_x_forwarded_adder(struct client_state *csp){	char *p = NULL;	if(add_forwarded == 0) return;	if(csp->x_forwarded) {		p = strsav(p, csp->x_forwarded);		p = strsav(p, ", ");		p = strsav(p, csp->ip_addr_str);	} else {		p = strsav(p, "X-Forwarded-For: ");		p = strsav(p, csp->ip_addr_str);	}	if(DEBUG(HDR)) fprintf(logfp, "addh: %s\r\n", p);	enlist(csp->headers, p);}char *server_set_cookie(struct parsers *v, char *s, struct client_state *csp){	if(jar) fprintf(jar, "%s\t%s\n", csp->http->host, (s + v->len + 1));	if(csp->accept_server_cookie == 0) return(crumble(v, s, csp));	return(strdup(s));}/* case insensitive string comparison */int strcmpic(char *s1, char *s2){	while(*s1 && *s2) {		if((        *s1  !=         *s2)		&& (tolower(*s1) != tolower(*s2))) {			break;		}		s1++, s2++;	}	return(tolower(*s1) - tolower(*s2));}int strncmpic(char *s1, char *s2, size_t n){	if(n <= 0) return(0);	while(*s1 && *s2) {		if((        *s1  !=         *s2)		&& (tolower(*s1) != tolower(*s2))) {			break;		}		if(--n <= 0) break;		s1++, s2++;	}	return(tolower(*s1) - tolower(*s2));}

⌨️ 快捷键说明

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