Example #1
0
int 
write_access_log(client_t *cli, int log_fd, const char *log_path)
{
  char buf[1024*4];
  if(log_fd > 0){
    VALUE obj;
    char *method, *path, *version, *ua, *referer;
        
    obj = rb_hash_aref(cli->environ, request_method);
    if(obj != Qnil){
      method = StringValuePtr(obj);
    }else{
      method = "-";
    }
                
    obj = rb_hash_aref(cli->environ, path_info);
    if(obj != Qnil){
      path = StringValuePtr(obj);
    }else{
      path = "-";
    }
    
    obj = rb_hash_aref(cli->environ, server_protocol);
    if(obj != Qnil){
      version = StringValuePtr(obj);
    }else{
      version = "-";
    }

    obj = rb_hash_aref(cli->environ, http_user_agent);
    if(obj != Qnil){
      ua = StringValuePtr(obj);
    }else{
      ua = "-";
    }

    obj = rb_hash_aref(cli->environ, http_referer);
    if(obj != Qnil){
      referer = StringValuePtr(obj);
    }else{
      referer = "-";
    }

    //update
    cache_time_update();
        
    sprintf(buf, "%s - - [%s] \"%s %s %s\" %d %d \"%s\" \"%s\"\n",
	    cli->remote_addr,
	    http_log_time,
	    method,
	    path,
	    version,
	    cli->status_code,
	    cli->write_bytes,
	    referer,
	    ua);
    return write_log(log_path, log_fd, buf, strlen(buf));
  }
  return 0;
}
Example #2
0
int picoev_poll_once_internal(picoev_loop* _loop, int max_wait)
{
  picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop;
  struct timespec ts;
  int cl_off = 0, nevents, i;
  
  /* apply pending changes, with last changes stored to loop->changelist */
  cl_off = apply_pending_changes(loop, 0);
  
  ts.tv_sec = max_wait;
  ts.tv_nsec = 0;

  Py_BEGIN_ALLOW_THREADS
  nevents = kevent(loop->kq, loop->changelist, cl_off, loop->events,
		   sizeof(loop->events) / sizeof(loop->events[0]), &ts);
  Py_END_ALLOW_THREADS
  cache_time_update();

  if (nevents == -1) {
    /* the errors we can only rescue */
    assert(errno == EACCES || errno == EFAULT || errno == EINTR);
    return -1;
  }
  for (i = 0; i < nevents; ++i) {
    struct kevent* event = loop->events + i;
    picoev_fd* target = picoev.fds + event->ident;
    assert((event->flags & EV_ERROR) == 0); /* changelist errors are fatal */
    if (loop->loop.loop_id == target->loop_id
	&& (event->filter & (EVFILT_READ | EVFILT_WRITE)) != 0) {
      int revents;
      switch (event->filter) {
      case EVFILT_READ:
	revents = PICOEV_READ;
	break;
      case EVFILT_WRITE:
	revents = PICOEV_WRITE;
	break;
      default:
	assert(0);
	revents = 0; // suppress compiler warning
	break;
      }
      (*target->callback)(&loop->loop, event->ident, revents, target->cb_arg);
    }
  }
  
  return 0;
}
Example #3
0
static int
write_headers(client_t *client)
{
  if(client->header_done){
    return 1;
  }
  write_bucket *bucket;
  uint32_t i = 0, hlen = 0;

  VALUE arr;
  VALUE object;
  char *name = NULL;
  ssize_t namelen;
  char *value = NULL;
  long valuelen;

  if(client->headers){
    if (TYPE(client->headers) != T_HASH) {
      return -1;
    }
    arr = rb_funcall(client->headers, i_keys, 0);
    hlen = RARRAY_LEN(arr);
  }
  bucket = new_write_bucket(client->fd, ( hlen * 4 * 2) + 32 );
  
  object = client->http_status;

  if(TYPE(object) != T_STRING){
    return -1;
  }

  if(object){
    value = StringValuePtr(object);
    valuelen = RSTRING_LEN(object);
    //write status code
    set2bucket(bucket, value, valuelen);

    add_header(bucket, "Server", 6,  SERVER, sizeof(SERVER) -1);
    cache_time_update();
    add_header(bucket, "Date", 4, (char *)http_time, 29);
    if(client->keep_alive == 1){
      // Keep-Alive
      add_header(bucket, "Connection", 10, "Keep-Alive", 10);
    } else {
      add_header(bucket, "Connection", 10, "close", 5);
    }
  }

  VALUE object1, object2;
  
  //write header
  if(client->headers){
    for(i=0; i < hlen; i++){
      object1 = rb_ary_entry(arr, i);
      Check_Type(object1, T_STRING);

      if (TYPE(client->headers)!=T_HASH){
	goto error;
      }
      VALUE tmp = rb_funcall(client->headers, i_key, 1, object1);
      if (tmp == Qfalse){
	goto error;
      }
      object2 = rb_hash_aref(client->headers, object1);

      Check_Type(object2, T_STRING);
      
      name = StringValuePtr(object1);
      namelen = RSTRING_LEN(object1);
  
      value = StringValuePtr(object2);
      valuelen = RSTRING_LEN(object2);

      if (strchr(name, '\n') != 0 || strchr(value, '\n') != 0) {
	rb_raise(rb_eArgError, "embedded newline in response header and value");
      }
      
      if (!strcasecmp(name, "Server") || !strcasecmp(name, "Date")) {
 	continue;
      }
      
      if (!strcasecmp(name, "Content-Length")) {
	char *v = value;
	long l = 0;
	
	errno = 0;
	l = strtol(v, &v, 10);
	if (*v || errno == ERANGE || l < 0) {
	  rb_raise(rb_eArgError, "invalid content length");
	  goto error;
	}
	client->content_length_set = 1;
	client->content_length = l;
      }
    add_header(bucket, name, namelen, value, valuelen);
    }
  }
  set2bucket(bucket, CRLF, 2);

  client->bucket = bucket;
  int ret = writev_bucket(bucket);
  if(ret != 0){
    client->header_done = 1;
    // clear
    free_write_bucket(bucket);
    client->bucket = NULL;
  }
  return ret;
 error:
  /* write_error_log(__FILE__, __LINE__); */
  if(bucket){
    free_write_bucket(bucket);
    client->bucket = NULL;
  }
  return -1;
}