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

📄 browser_conn.c

📁 解压在c盘
💻 C
📖 第 1 页 / 共 2 页
字号:
}/** * 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 + -