Example #1
0
static int
processs_write(client_t *client)
{
  VALUE iterator;
  VALUE v_body;
  VALUE item;
  char *buf;
  size_t buflen;
  write_bucket *bucket;
  int ret;

  // body
  iterator = client->response_iter;

  if(iterator != Qnil){
    if (TYPE(iterator) != T_ARRAY || RARRAY_LEN(iterator) != 3){
      return -1;
    }

    v_body = rb_ary_entry(iterator, 2);

    if(!rb_respond_to(v_body, i_each)){
      return -1;
    }

    VALUE v_body_str = rb_str_new2("");
    rb_block_call(v_body, i_each, 0, NULL, collect_body, v_body_str);
    if(rb_respond_to(v_body, i_close)) {
      rb_funcall(v_body, i_close, 0);
    }

    buf = StringValuePtr(v_body_str);
    buflen = RSTRING_LEN(v_body_str);

    bucket = new_write_bucket(client->fd, 1);
    set2bucket(bucket, buf, buflen);
    ret = writev_bucket(bucket);
    if(ret <= 0){
      return ret;
    }
    //mark
    client->write_bytes += buflen;
    //check write_bytes/content_length
    if(client->content_length_set){
      if(client->content_length <= client->write_bytes){
	// all done
	/* break; */
      }
    }
    close_response(client);
  }
  return 1;
}
Example #2
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

}
Example #3
0
static response_status
process_sendfile(client_t *client)
{
    PyObject *filelike = NULL;
    FileWrapperObject *filewrap = NULL;
    int in_fd, ret;

    filewrap = (FileWrapperObject *)client->response;
    filelike = filewrap->filelike;

    in_fd = PyObject_AsFileDescriptor(filelike);
    if (in_fd == -1) {
        PyErr_Clear();
        return STATUS_OK;
    }

    while(client->content_length > client->write_bytes){
        ret = write_sendfile(client->fd, in_fd, client->write_bytes, client->content_length);
        DEBUG("process_sendfile send %d", ret);
        switch (ret) {
            case 0:
                break;
            case -1: /* error */
                if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */
                    //next
                    DEBUG("process_sendfile EAGAIN %d", ret);
                    return STATUS_SUSPEND;
                } else { /* fatal error */
                    client->keep_alive = 0;
                    /* client->bad_request_code = 500; */
                    client->status_code = 500;
                    //close
                    return STATUS_ERROR;
                }
            default:
                client->write_bytes += ret;

        }
    }
    //all send
    //disable_cork(client);
    return close_response(client);
}
Example #4
0
 void Response::after_fork_child(STATE) {
   close_response();
 }
Example #5
0
    void Response::stop_thread(STATE) {
      MachineThread::stop_thread(state);

      close_response();
    }
Example #6
0
static response_status
process_write(client_t *client)
{
    PyObject *iterator = NULL;
    PyObject *item, *chunk_data = NULL;
    char *buf = NULL, *lendata = NULL;
    Py_ssize_t buflen, len;
    write_bucket *bucket = NULL;
    response_status ret;
    
    DEBUG("process_write start");
    iterator = client->response_iter;
    if(iterator != NULL){
        while((item =  PyIter_Next(iterator))){
            if(PyBytes_Check(item)){
                //TODO CHECK
                PyBytes_AsStringAndSize(item, &buf, &buflen);
                //write
                if(client->chunked_response){
                    bucket = new_write_bucket(client->fd, 4);
                    if(bucket == NULL){
                        /* write_error_log(__FILE__, __LINE__); */
                        call_error_logger();
                        Py_DECREF(item);
                        return STATUS_ERROR;
                    }
                    lendata  = NULL;
                    len = 0;

                    chunk_data = get_chunk_data(buflen);
                    //TODO CHECK ERROR
                    PyBytes_AsStringAndSize(chunk_data, &lendata, &len);
                    set_chunked_data(bucket, lendata, len, buf, buflen);
                    bucket->chunk_data = chunk_data;
                }else{
                    bucket = new_write_bucket(client->fd, 1);
                    if(bucket == NULL){
                        /* write_error_log(__FILE__, __LINE__); */
                        call_error_logger();
                        Py_DECREF(item);
                        return STATUS_ERROR;
                    }
                    set2bucket(bucket, buf, buflen);
                }
                bucket->temp1 = item;
                ret = writev_bucket(bucket);
                if(ret != STATUS_OK){
                    client->bucket = bucket;
                    /* Py_DECREF(item); */
                    return ret;
                }

                free_write_bucket(bucket);
                //mark
                client->write_bytes += buflen;
                //check write_bytes/content_length
                if(client->content_length_set){
                    if(client->content_length <= client->write_bytes){
                        // all done
                        /* Py_DECREF(item); */
                        break;
                    }
                }
                /* Py_DECREF(item); */
            }else{
                PyErr_SetString(PyExc_TypeError, "response item must be a byte string");
                Py_DECREF(item);
                if (PyErr_Occurred()){
                    /* client->bad_request_code = 500; */
                    client->status_code = 500;
                    /* write_error_log(__FILE__, __LINE__); */
                    call_error_logger();
                    return STATUS_ERROR;
                }
            }
        }
        if(PyErr_Occurred()){
            return STATUS_ERROR;
        }
        if(client->chunked_response){
            DEBUG("write last chunk");
            //last packet
            bucket = new_write_bucket(client->fd, 3);
            if(bucket == NULL){
                /* write_error_log(__FILE__, __LINE__); */
                call_error_logger();
                return STATUS_ERROR;
            }
            set_last_chunked_data(bucket);
            writev_bucket(bucket);
            free_write_bucket(bucket);
        }
        return close_response(client);
    }
    return STATUS_OK;
}