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

📄 http_proxy.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			*bp++ = '\0';			port = bp;			while (*bp && isdigit(*bp))				++bp;			if (*bp == 0) {				url = (char *) 0;				goto gotit;			}		}		*bp++ = '\0';		url = bp;	}  gotit:#ifdef  OSKIT_UNIX	osenv_intr_disable();#endif	if (connect_to_host(host, port, &server_sock)) {		/*		 * Send back a connection message		 */		sprintf(str, "HTTP/1.0 204 Connection Failed\n\n");		send(client_sock, str, strlen(str), 0);		return 1;	}#ifdef	OSKIT_UNIX	osenv_intr_enable();#endif	if ((connp = (connection_t *) malloc(sizeof(connection_t))) == NULL) {		printf("setup_connection: Out of memory\n");		return 1;	}	bzero(connp, sizeof(*connp));	connp->client_sock = client_sock;	connp->server_sock = server_sock;	pthread_mutex_init(&connp->mutex, 0);	pthread_cond_init(&connp->condvar, 0);	if (tunneling) {		/*		 * Send back a connection message		 */		sprintf(str, "HTTP/1.0 200 Connection established\n\n");		len = strlen(str);				if ((c = send(client_sock, str, len, 0)) != len) {			printf("Unexpected close on client side\n");			close(server_sock);			free(connp);			return 1;		}	}	else {		/*		 * Okay, send the initial data block off.		 */		sprintf(str, "%s /%s %s", method, url, rest);		len = strlen(str);		/* printf("%s\n", str); */		if ((c = send(server_sock, str, len, 0)) != len) {			printf("Unexpected close on server side\n");			close(server_sock);			free(connp);			return 1;		}	}	*return_connp = connp;	return 0;}void *connection_manager(void *arg){	void		*client_side(void *connp);	void		*server_side(void *connp);	pthread_t	client_tid, server_tid;	int		status, client_sock = (int) arg;	connection_t	*connp;	printf("Connection accepted. tid=%d\n", (int) pthread_self());	if (setup_connection(client_sock, &connp)) {		close(client_sock);		pthread_exit((void *) 1);	}	pthread_mutex_lock(&connp->mutex);	/*	 * Create a thread to manage the client side.	 */	pthread_create(&client_tid, 0, client_side, (void *) connp);	/*	 * Create a thread to manage the server side.	 */	pthread_create(&server_tid, 0, server_side, (void *) connp);	/*	 * Lets wait for them to change status.	 */	while (! connp->died) {		pthread_cond_wait(&connp->condvar, &connp->mutex);	}	pthread_mutex_unlock(&connp->mutex);	pthread_cancel(client_tid);	pthread_cancel(server_tid);	pthread_join(client_tid, (void *) &status);	pthread_join(server_tid, (void *) &status);	printf("Manager: tid=%d "	       "Client(%d) and server(%d) side threads have exited\n",	       (int) pthread_self(), (int) client_tid, (int) server_tid);	shutdown(connp->client_sock, 2);	shutdown(connp->server_sock, 2);	close(connp->client_sock);	close(connp->server_sock);	free(connp);	return 0;}/* * Since the POSIX library does not implement cancelation points at * all the necessary spots, need to do this ourselves. */voidcleanup_handler(void *arg){	connection_t	*connp = (connection_t *) arg;	pthread_mutex_lock(&connp->mutex);	connp->died++;	pthread_mutex_unlock(&connp->mutex);	pthread_cond_signal(&connp->condvar);}/* * Read from the client side of the connection and send to the server * side. */void *client_side(void *arg){	connection_t	*connp = (connection_t *) arg;	char		buf[4096];	int		c;	printf("client_side starting: tid=%d\n", (int) pthread_self());	pthread_mutex_lock(&connp->mutex);	pthread_mutex_unlock(&connp->mutex);	pthread_cleanup_push(cleanup_handler, connp);		while (1) {		pthread_testcancel();		if ((c = recv(connp->client_sock, buf, 4096, 0)) <= 0) {			if (c == 0) {				printf("Read: Closing Client side\n");				goto done;			}			else if (errno == EAGAIN || errno == EINTR) {				/*				 * On client side, a read timeout means no				 * data available. Thats okay.				 */				continue;			}			else {				perror("read on client side");				goto done;			}		}		/*printf("Client %d\n%s\n", c, buf);*/		if ((c = send(connp->server_sock, buf, c, 0)) != c) {			if (c == 0) {				printf("Write: Closing Client side\n");				goto done;			}			else if (c < 0) {				perror("write syscall on client side");				goto done;			}			else {				printf("write data on client side\n");				goto done;			}		}	}   done:	pthread_cleanup_pop(1);	return 0;}/* * Read from the server side of the connection and send to the client * side. */void *server_side(void *arg){	connection_t	*connp = (connection_t *) arg;	char		buf[4096];	int		c;		printf("server_side starting: tid=%d\n", (int) pthread_self());	pthread_mutex_lock(&connp->mutex);	pthread_mutex_unlock(&connp->mutex);	pthread_cleanup_push(cleanup_handler, connp);		while (1) {		pthread_testcancel();		if ((c = recv(connp->server_sock, buf, 4096, 0)) <= 0) {			if (c == 0) {				printf("Read: Closing Server side\n");				goto done;			}			else if (errno == EAGAIN) {				/*				 * On client side, a read timeout means no				 * data available. Thats okay.				 */				printf("Read: EAGAIN on server side: tid=%d\n",				       (int) pthread_self());				goto done;			}			else {				perror("read on server side");				goto done;			}		}		/*printf("Server %d\n%s\n", c, buf);*/		if ((c = send(connp->client_sock, buf, c, 0)) != c) {			if (c == 0) {				printf("Send: Closing Server side\n");				goto done;			}			else if (c < 0) {				perror("send syscall on server side");				goto done;			}			else {				printf("send data on server side\n");				goto done;			}		}	}   done:	pthread_cleanup_pop(1);	return 0;}void *deathwatch(void *arg){	char		buf[4096];	int		c, sock;	struct sockaddr client;	while (1) {		sock = accept(death_socket, &client, &c);		/*		 * UNIX implementation uses non-blocking I/O.		 * OSKIT version of accept will call osenv_sleep.		 */		if (sock < 0) {			perror("accept");			exit(1);		}		while (1) {			if ((c = recv(sock, buf, 4096, 0)) <= 0) {				if (c == 0) {					printf("Read: Closing Death Socket\n");					goto done;				}				else {					perror("read on death side");					goto done;				}			}			buf[c-1] = 0;			printf("Death Watch: %d %s\n", c, buf);			if (strncmp(buf, "reboot", 6) == 0)				exit(1);#if !defined(OSKIT_UNIX) && defined(OSKIT_X86)			if (strncmp(buf, "gdb", 3) == 0) {				asm("int $3");				base_gdt_load();			}#endif			if (strncmp(buf, "bta", 3) == 0) {				int i;				for (i = 0; i < 100; i++) {					threads_stack_back_trace(i, 16);				}			}			else if (strncmp(buf, "bt", 2) == 0) {				buf[4] = 0;				threads_stack_back_trace(atoi(buf), 24);			}		}           done:	}	return 0;}/* * Case insensitive search of an hlen character array for a substring. */char *strnstr(char *haystack, int hlen, char *needle){	int nlen = strlen(needle);	while (hlen >= nlen)	{		if (!strncasecmp(haystack, needle, nlen))			return (char *)haystack;		haystack++;		hlen--;	}	return 0;}/* * Search for a particular header, returning a string copy of the value. */char *getheader(char *buf, int n, char *header){	char	*bp, *ep, *str;	int	len;		if ((bp = strnstr(buf, n, header)) == NULL)		return 0;	/* skip the header */	while (! isspace(*bp))		bp++;	/* and the following spaces */	while (isspace(*bp))		bp++;	/* Skip to the end of the value */	ep = bp;	while (! iscntrl(*ep))		ep++;	len = ep - bp;	str = malloc(len + 1);	if (str) {		strncpy(str, bp, len);		str[len] = 0;	}	return str;}#include <syslog.h>#include <stdarg.h>voidmy_syslog(int pri, const char *fmt, ...){        va_list args;        va_start(args, fmt);        osenv_log(pri, fmt, args);        va_end(args);}oskit_syslogger_t oskit_libc_syslogger = my_syslog;

⌨️ 快捷键说明

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