📄 browser_conn.c
字号:
}/** * Prints data to the browser buffer. */voidbrowser_print(browser_t *browser, char *data){ char *buf; if (browser->cout_offset >= browser->cout_length) { browser->cout_offset = 0; browser->cout_length = 0; } buf = browser->cout_buf + browser->cout_length; while ((*buf++ = *data++)) { } browser->cout_length = buf - browser->cout_buf + 1; /* XXX: this isn't quite right. */ if (browser->iov_index == 0) { browser->iov_index = 1; browser->iov[0].iov_base = browser->cout_buf + browser->cout_offset; } browser->iov[0].iov_len = browser->cout_length - browser->cout_offset;}/** * Prints data to the browser buffer. */voidbrowser_printf(browser_t *browser, char *fmt, ...){ char *buf = 0; va_list args; if (browser->cout_offset >= browser->cout_length) { browser->cout_offset = 0; browser->cout_length = 0; } buf = browser->cout_buf + browser->cout_length; va_start(args, fmt); browser->cout_length += vsprintf(buf, fmt, args); va_end(args); if (browser->iov_index == 0) { browser->iov_index = 1; browser->iov[0].iov_base = browser->cout_buf + browser->cout_offset; } browser->iov[0].iov_len = browser->cout_length - browser->cout_offset;}/** * Write data to the browser * * @param browser The browser object which is sending */intbrowser_write_iov(browser_t *browser){ mm_segment_t oldfs; struct iovec *iov = browser->iov; int iov_len = browser->iov_index; struct msghdr msg; struct sock *sock = browser->browser_sock; int len; int sent_len; int i; int delta = 0; if (! sock) return -1; if (iov_len <= 0) { LOG(("iov-len messup\n")); return -1; } LOG(("iov_len(%d)\n",iov_len)); len = 0; for (i = 0; i < iov_len; i++) { LOG(("iov(buf:%p,len:%d)\n", iov[i].iov_base, iov[i].iov_len)); ((char *) iov[i].iov_base)[iov[i].iov_len] = 0; len += iov[i].iov_len; /* if (iov[i].iov_len == 0) delta++; */ } msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = iov + delta; msg.msg_iovlen = iov_len - delta; msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL; LOG(("sending %p %p %d %d\n", sock, iov, iov_len, len)); // These are needed to make the copy right oldfs = get_fs(); set_fs(KERNEL_DS); sent_len = sock->prot->sendmsg(sock, &msg, len); set_fs(oldfs); LOG(("post send %d\n", sent_len)); if (sent_len == len) { browser->state = browser->write_state; return 1; } else if (sent_len == -EAGAIN) return 0; else if (sent_len < 0) { browser_close(browser); return -1; } else { // partial write for (i = 0; sent_len > 0 && i < iov_len; i++) { if (iov[i].iov_len <= sent_len) { sent_len -= iov[i].iov_len; iov[i].iov_len = 0; } else { iov[i].iov_len -= sent_len; iov[i].iov_base += sent_len; sent_len = 0; } } return 0; }}/** * free the browser structure */static voidbrowser_free(browser_t *browser){ browser_t *next = browser->next_browser; browser_t *prev = browser->prev_browser; if (browser->browser_sock) browser_close(browser); if (next) next->prev_browser = prev; if (prev) prev->next_browser = next; else g_browser_list = next; kfree(browser);}/* * Create accept socket */intaccept_socket_create(struct sockaddr_in *sin, resin_t *resin){ struct socket *sock; int error; LOG(("resin: create_socket(%u.%u.%u.%u:%d)\n", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port))); error = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); if (error < 0) return error; error = sock->ops->bind(sock, (struct sockaddr *) sin, sizeof(*sin)); if (error < 0) goto error; error = sock->ops->listen(sock, 5); if (error < 0) goto error; resin->accept_socket = sock; sock->sk->user_data = resin; LOG(("created -> %x:%x(%x,%x,%d,%x)\n", sock, resin->accept_socket, sock->sk, sock->sk->socket, sock->sk->state, sock->sk->user_data)); if (sock->sk->state == TCP_LISTEN) LOG(("setting up TCP socket for listening\n")); resin->old_state_change = sock->sk->state_change; sock->sk->state_change = accept_state_change; return 0; error: sock_release(sock); return error;}/** * Accept new connections * * No lock is needed on g_has_accept because it's cleared before * calling browser_accept in a loop. Even if an accept_state_change * appears between the test and the set, we'll still run through * all the accepts using browser_accept. */static voidaccept_execute(){ if (g_has_accept) { g_has_accept = 0; LOG(("accept\n")); while (browser_accept(&g_resin)) { } }}/** * Executes all the active browser */voidbrowser_execute(){ if (g_has_accept) accept_execute(); while (g_browser_ready) { browser_t *browser; spin_lock_irq(&g_ready_lock); browser = g_browser_ready; g_browser_ready = g_browser_ready->next; browser->is_active = 0; spin_unlock_irq(&g_ready_lock); browser->next = 0; if (browser->is_dead) browser->state = RHC_BROWSER_QUIT; LOG(("browser %p %s\n", browser, browser_state_name(browser))); switch (browser->state) { case RHC_IDLE: case RHC_BROWSER_QUIT: browser_close(browser); break; case RHC_BROWSER_START: case RHC_BROWSER_SPACE: case RHC_BROWSER_METHOD: case RHC_BROWSER_URL: case RHC_BROWSER_PROTOCOL: case RHC_BROWSER_KEY: case RHC_BROWSER_VALUE: case RHC_BROWSER_EOL: case RHC_BROWSER_HEADER_DONE: browser_recv(browser); browser->in_header = 1; request_parse(browser); if (browser->state == RHC_BROWSER_BODY) browser_wake(browser); break; case RHC_BROWSER_BODY: browser->in_header = 0; if (! strcmp(browser->method, "GET") && cache_lookup(browser)) { } else { srun_connect(&g_resin.srun_list[0], browser); } break; case RHC_BROWSER_READ: if (browser_recv(browser) > 0) { browser->state = browser->next_state; browser_wake(browser); } break; case RHC_SRUN_START: browser->in_header = 0; resin_srun(browser); if (browser->state == RHC_SRUN_SEND) srun_send(browser); break; case RHC_SRUN_SEND: srun_send(browser); break; case RHC_SRUN_RECV_HEADER: case RHC_SRUN_RECV_STATUS: case RHC_SRUN_RECV_KEY: case RHC_SRUN_RECV_VALUE: case RHC_SRUN_RECV_SKIP: case RHC_SRUN_BODY: case RHC_SRUN_RECV_DATA: if (srun_recv(browser) > 0) { if (srun_read_header(browser)) browser_wake(browser); } break; case RHC_SRUN_POST: if (browser_recv(browser) > 0) { browser->state = browser->next_state; srun_send_post(browser); } break; case RHC_CACHE_WRITE: if (cache_read(browser)) browser_wake(browser); break; case RHC_BROWSER_WRITE: if (browser_write_iov(browser) > 0) browser_wake(browser); break; } if (g_has_accept) accept_execute(); }}/** * Initialize the main socket stuff. */static voidresin_init_socket(resin_t *resin){ struct sockaddr_in sin; int error; int i; sin.sin_family = 0; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(resin->accept_port); for (i = 0; i < 16; i++) browser_create(); error = accept_socket_create(&sin, resin); if (error < 0) { LOG(("error %d\n", error)); }}/** * Initialize the browser structures */voidbrowser_init(resin_t *resin){ srun_init(resin); resin_init_socket(resin);}static voidresin_cleanup_socket(resin_t *resin){ if (resin->accept_socket) { struct socket *sock = resin->accept_socket; resin->accept_socket = 0; sock->sk->user_data = 0; sock->sk->state_change = resin->old_state_change; LOG(("closing server\n")); sock_release(sock); LOG(("closed server\n")); }}/** * Clean up the browser structures */voidbrowser_cleanup(resin_t *resin){ resin_cleanup_socket(resin); srun_cleanup(resin); LOG(("free\n")); while (g_browser_list) browser_free(g_browser_list); LOG(("browser done\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -