Exemple #1
0
static inline void
call_wsgi_app(client_t *client, picoev_loop* loop)
{
    int ret;
    ret = process_wsgi_app(client);

#ifdef DEBUG
    printf("call_wsgi_app result %d \n", ret);
#endif
    switch(ret){
        case -1:
            //Internal Server Error
            client->bad_request_code = 500;
            send_error_page(client);
            close_conn(client, loop);
            return;
        case 0:
            // suspend
            return;
        default:
            break;
    }
    
    
    if(client->response_closed){
        //closed
        close_conn(client, loop);
        return;
    }
    ret = response_start(client);
#ifdef DEBUG
    printf("response_start result %d \n", ret);
#endif
    switch(ret){
        case -1:
            // Internal Server Error
            client->bad_request_code = 500;
            send_error_page(client);
            close_conn(client, loop);
            return;
        case 0:
            // continue
            // set callback
#ifdef DEBUG
            printf("set write callback %d \n", ret);
#endif
            //clear event
            picoev_del(loop, client->fd);
            picoev_add(loop, client->fd, PICOEV_WRITE, 0, w_callback, (void *)client);
            return;
        default:
            // send OK
            close_conn(client, loop);
    }
    
    
}
static void accept_cb(picoev_loop* loop, int fd, int revents, void* cb_arg)
{
  int newfd;
  assert((revents & PICOEV_READ) != 0);
  if ((newfd = accept(fd, NULL, NULL)) != -1) {
    setup_sock(newfd);
    picoev_add(loop, newfd, PICOEV_READ, 0, read_cb, NULL);
  }
}
Exemple #3
0
static void accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
  int newfd = accept(picoev_w32_fd2sock(fd), NULL, NULL);
  if (newfd != -1) {
    int sock = picoev_w32_sock2fd(newfd);
    printf("connected: %d\n", sock);
    setup_sock(newfd);
    picoev_add(loop, sock, PICOEV_READ, TIMEOUT_SECS, rw_callback, NULL);
  }
}
Exemple #4
0
static inline void 
close_conn(client_t *cli, picoev_loop* loop)
{
    client_t *new_client;
    if(!cli->response_closed){
        close_response(cli);
    }

    picoev_del(loop, cli->fd);
    clean_cli(cli);

#ifdef DEBUG
    printf("start close client:%p fd:%d status_code %d \n", cli, cli->fd, cli->status_code);
    printf("picoev_del client:%p fd:%d \n", cli, cli->fd);
    printf("remain http pipeline size :%d \n", cli->request_queue->size);
#endif
    
    if(cli->request_queue->size > 0){
        if(check_status_code(cli) > 0){
            //process pipeline 
            prepare_call_wsgi(cli);
            call_wsgi_app(cli, loop);
        }
        return ;
    }

    if(cli->http != NULL){
        PyMem_Free(cli->http);
    }

    free_request_queue(cli->request_queue);
    if(!cli->keep_alive){
        close(cli->fd);
#ifdef DEBUG
        printf("close client:%p fd:%d status_code %d \n", cli, cli->fd, cli->status_code);
#endif
    }else{
        disable_cork(cli);
        new_client = new_client_t(cli->fd, cli->remote_addr, cli->remote_port);
        new_client->keep_alive = 1;
        init_parser(new_client, server_name, server_port);
        picoev_add(main_loop, new_client->fd, PICOEV_READ, keep_alive_timeout, r_callback, (void *)new_client);
    }
    //PyMem_Free(cli);
    dealloc_client(cli);
#ifdef DEBUG
    printf("********************\n\n");
#endif

}
Exemple #5
0
int 
main(void)
{
  picoev_loop* loop;
  int listen_sock, flag;
  
  /* listen to port */
  assert((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) != -1);
  flag = 1;
  assert(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) == 0);
  struct sockaddr_in listen_addr;
  listen_addr.sin_family = AF_INET;
  listen_addr.sin_port = htons(PORT);
  listen_addr.sin_addr.s_addr = htonl(HOST);
  assert(bind(listen_sock, (struct sockaddr*)&listen_addr, sizeof(listen_addr)) == 0);
  assert(listen(listen_sock, 5) == 0);
  setup_sock(listen_sock);
  
  /* init picoev */
  picoev_init(MAX_FDS);
  /* create loop */
  loop = picoev_create_loop(60);
  /* add listen socket */
  picoev_add(loop, listen_sock, PICOEV_READ, 0, accept_callback, NULL);

  /* Seccomp sandbox setup */
  sandbox_init();
  sandbox_setup();
  sandbox_lockdown();

  /* loop */
  while (1)
  {
    fputc('.', stdout);
    fflush(stdout);
    picoev_loop_once(loop, 10);
  }
  /* cleanup */
  picoev_destroy_loop(loop);
  picoev_deinit();
  
  return 0;
}
Exemple #6
0
static void
accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
  int client_fd;
  client_t *client;
  struct sockaddr_in client_addr;
  if ((events & PICOEV_TIMEOUT) != 0) {
    // time out
    // next turn or other process
    return;
  }else if ((events & PICOEV_READ) != 0) {
    socklen_t client_len = sizeof(client_addr);
#ifdef linux
    client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
    client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
#endif
    if (client_fd != -1) {
#ifdef DEBUG
      printf("accept fd %d \n", client_fd);
#endif
      setup_sock(client_fd);
      client = new_client_t(client_fd, client_addr);

      client->environ = Qnil;
      rb_gc_register_address(&client->environ);

      init_parser(client, server_name, server_port);

      picoev_add(loop, client_fd, PICOEV_READ, READ_LONG_TIMEOUT_SECS, r_callback, (void *)client);
    }else{
      if (errno != EAGAIN && errno != EWOULDBLOCK) {
	// TODO:
	// raise exception from errno
	/* rb_raise(); */
	/* write_error_log(__FILE__, __LINE__); */
	// die
	loop_done = 0;
      }
    }
  }
}
int main(int argc, char** argv)
{
  int ch, r, flag;
  struct sockaddr_in listen_addr;
  picoev_loop* loop;
  
  while ((ch = getopt(argc, argv, "p:")) != -1) {
    switch (ch) {
    case 'p':
      assert(sscanf(optarg, "%hu", &port) == 1);
      break;
    default:
      exit(1);
    }
  }
  
  listen_sock = socket(AF_INET, SOCK_STREAM, 0);
  assert(listen_sock != -1);
  flag = 1;
  r = setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
  assert(r == 0);
  listen_addr.sin_family = AF_INET;
  listen_addr.sin_port = htons(port);
  listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  r = bind(listen_sock, (struct sockaddr*)&listen_addr, sizeof(listen_addr));
  assert(r == 0);
  setup_sock(listen_sock);
  r = listen(listen_sock, SOMAXCONN);
  assert(r == 0);
  
  picoev_init(1048576 + 10);
  loop = picoev_create_loop(60);
  picoev_add(loop, listen_sock, PICOEV_READ, 0, accept_cb, NULL);
  while (1) {
    picoev_loop_once(loop, 10);
  }
  
  return 0;
}
Exemple #8
0
static void
call_rack_app(client_t *client, picoev_loop* loop)
{
  int ret;
  if(!process_rack_app(client)){
    //Internal Server Error
    client->bad_request_code = 500;
    send_error_page(client);
    close_conn(client, loop);
    return;
  }

  ret = response_start(client);
  /* printf("response_start done: %d\n", ret); */
  switch(ret){
  case -1:
    // Internal Server Error
    client->bad_request_code = 500;
    send_error_page(client);
    close_conn(client, loop);
    return;
  case 0:
    // continue
    // set callback
#ifdef DEBUG
    printf("set write callback %d \n", ret);
#endif
    //clear event
    picoev_del(loop, client->fd);
    picoev_add(loop, client->fd, PICOEV_WRITE, WRITE_TIMEOUT_SECS, w_callback, (void *)client);
    return;
  default:
    // send OK
    close_conn(client, loop);
  }
}
Exemple #9
0
static VALUE
bossan_run_loop(int argc, VALUE *argv, VALUE self)
{
  int ret;
  VALUE args1, args2, args3;

  rb_scan_args(argc, argv, "21", &args1, &args2, &args3);

  if(listen_sock > 0){
    rb_raise(rb_eException, "already set listen socket");
  }

  if (argc == 3){
    server_name = StringValuePtr(args1);
    server_port = NUM2INT(args2);

    long _port = NUM2INT(args2);

    if (_port <= 0 || _port >= 65536) {
      // out of range
      rb_raise(rb_eArgError, "port number outside valid range");
    }

    server_port = (short)_port;

    ret = inet_listen();
    rack_app = args3;
  } else {
    Check_Type(args1, T_STRING);
    ret = unix_listen(StringValuePtr(args1));
    rack_app = args2;
  }

  if(ret < 0){
    //error
    listen_sock = -1;
  }

  if(listen_sock <= 0){
    rb_raise(rb_eTypeError, "not found listen socket");
  }
    
  /* init picoev */
  picoev_init(MAX_FDS);
  /* create loop */
  main_loop = picoev_create_loop(60);
  loop_done = 1;
  
  setsig(SIGPIPE, sigpipe_cb);
  setsig(SIGINT, sigint_cb);
  setsig(SIGTERM, sigint_cb);
    
  picoev_add(main_loop, listen_sock, PICOEV_READ, ACCEPT_TIMEOUT_SECS, accept_callback, NULL);
    
  /* loop */
  while (loop_done) {
    picoev_loop_once(main_loop, 10);
  }
  picoev_destroy_loop(main_loop);
  picoev_deinit();

  printf("Bye.\n");
  return Qnil;
}
int main(int argc, char** argv)
{
  int ch, i, r;
  picoev_loop* loop;
  struct timeval start_at, end_at;
  double elapsed;
  
  host.s_addr = htonl(0x7f000001);
  
  while ((ch = getopt(argc, argv, "a:c:n:fh:p:")) != -1) {
    switch (ch) {
    case 'a':
      assert(sscanf(optarg, "%d", &active_connections) == 1);
      break;
    case 'c':
      assert(sscanf(optarg, "%d", &num_connections) == 1);
      break;
    case 'n':
      assert(sscanf(optarg, "%d", &num_requests) == 1);
      break;
    case 'f':
      fix_clients = 1;
      break;
    case 'h':
      if (inet_aton(optarg, &host) == 0) {
	struct hostent* h = gethostbyname(optarg);
	assert(h != NULL && "host not found");
	assert(h->h_addrtype == AF_INET);
	assert(h->h_length == sizeof(host));
	memcpy(&host, h->h_addr_list[0], sizeof(host));
      }
      break;
    case 'p':
      assert(sscanf(optarg, "%hu", &port) == 1);
      break;
    default:
      exit(1);
    }
  }
  
  picoev_init(num_connections + 10);
  loop = picoev_create_loop(60);
  
  /* setup connections */
  for (i = 0; i < num_connections; ++i) {
    int on;
    struct sockaddr_in addr;
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    assert(fd != -1 && "socket(2) failed");
    on = 1;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    memcpy(&addr.sin_addr, &host, sizeof(host));
    printf("try to connect\n");
    r = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (r == -1) {
      perror("could not connect to server");
      exit(2);
    }
    r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
    assert(r == 0);
    r = fcntl(fd, F_SETFL, O_NONBLOCK);
    assert(r == 0);
    picoev_add(loop, fd, PICOEV_READ, 0, read_cb, NULL);
    fds[i] = fd;
    usleep(1000);
  }
  
  gettimeofday(&start_at, NULL);
  
  /* fire first active_connections */
  printf("fire!\n");
  for (i = 0; i < active_connections; ++i) {
    r = write(fds[next_fd_idx], "hello\n", 6);
    assert(r == 6);
    next_fd_idx = (next_fd_idx + 1) % num_connections;
  }
  /* the main loop */
  while (num_responses < num_requests) {
    picoev_loop_once(loop, 10);
  }
  
  gettimeofday(&end_at, NULL);
  
  elapsed = end_at.tv_sec + end_at.tv_usec / 1000000.0
    - (start_at.tv_sec + start_at.tv_usec / 1000000.0);
  printf("%f reqs./sec. (%d in %f seconds)\n", num_responses / elapsed,
	 num_responses, elapsed);
  
  return 0;
}