📄 http_proxy.c
字号:
*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 + -