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; }
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; }
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; }