Beispiel #1
0
int
query_string_cb (http_parser *p, const char *buf, size_t len, char partial)
{
  client_t *client = get_client(p);
  request *req = client->req;
  buffer_result ret = MEMORY_ERROR;

  if(req->query_string){
    ret = write2buf(req->query_string, buf, len);
  }else{
    req->query_string = new_buffer(1024*2, LIMIT_QUERY_STRING);
    ret = write2buf(req->query_string, buf, len);
  }
  switch(ret){
  case MEMORY_ERROR:
    client->bad_request_code = 500;
    return -1;
  case LIMIT_OVER:
    client->bad_request_code = 400;
    return -1;
  default:
    break;
  }
  return 0;
}
Beispiel #2
0
int
fragment_cb (http_parser *p, const char *buf, size_t len, char partial)
{
  client_t *client = get_client(p);
  register request *req = client->req;
  buffer_result ret = MEMORY_ERROR;
  
  if(req->fragment){
    ret = write2buf(req->fragment, buf, len);
  }else{
    req->fragment = new_buffer(1024, LIMIT_FRAGMENT);
    ret = write2buf(req->fragment, buf, len);
  }
  switch(ret){
  case MEMORY_ERROR:
    client->bad_request_code = 500;
    return -1;
  case LIMIT_OVER:
    client->bad_request_code = 400;
    return -1;
  default:
    break;
  }
  return 0;
}
Beispiel #3
0
static int
url_cb(http_parser *p, const char *buf, size_t len)
{
    request *req = get_current_request(p);
    buffer_result ret = MEMORY_ERROR;

    if(unlikely(req->path)){
        ret = write2buf(req->path, buf, len);
    }else{
        req->path = new_buffer(1024, LIMIT_PATH);
        ret = write2buf(req->path, buf, len);
    }
    switch(ret){
        case MEMORY_ERROR:
            req->bad_request_code = 500;
            return -1;
        case LIMIT_OVER:
            req->bad_request_code = 400;
            return -1;
        default:
            break;
    }


    return 0;
}
Beispiel #4
0
static PyObject*
create_status(PyObject *bytes, int bytelen, int http_minor)
{
    buffer_result r;
    buffer_t *b = new_buffer(256, 0);
    if(b == NULL){
        return NULL;
    }
    
    if(http_minor == 1){
        r = write2buf(b, "HTTP/1.1 ", 9); 
    }else{
        r = write2buf(b, "HTTP/1.0 ", 9); 
    }
    if(r != WRITE_OK){
        goto error;
    }
    r = write2buf(b, PyBytes_AS_STRING(bytes), bytelen);
    if(r != WRITE_OK){
        goto error;
    }
    r = write2buf(b, "\r\n", 2);
    if(r != WRITE_OK){
        goto error;
    }
    return getPyString(b);
error:
    free_buffer(b);
    return NULL;
}
Beispiel #5
0
int
header_value_cb (http_parser *p, const char *buf, size_t len, char partial)
{
  uint32_t i;
  header *h;
  client_t *client = get_client(p);
  request *req = client->req;
    
  buffer_result ret = MEMORY_ERROR;
  i = req->num_headers;
  h = req->headers[i];
  
  if(h){
    ret = write2buf(h->value, buf, len);
  }
  switch(ret){
  case MEMORY_ERROR:
    client->bad_request_code = 500;
    return -1;
  case LIMIT_OVER:
    client->bad_request_code = 400;
    return -1;
  default:
    break;
  }
  req->last_header_element = VAL;
  return 0;
}
Beispiel #6
0
int
header_field_cb (http_parser *p, const char *buf, size_t len, char partial)
{
  uint32_t i;
  header *h;
  client_t *client = get_client(p);
  request *req = client->req;
  char temp[len];
  
  buffer_result ret = MEMORY_ERROR;
  if (req->last_header_element != FIELD){
    if(LIMIT_REQUEST_FIELDS <= req->num_headers){
      client->bad_request_code = 400;
      return -1;
    }
    req->num_headers++;
  }
  i = req->num_headers;
  h = req->headers[i];
  
  key_upper(temp, buf, len);
  if(h){
    ret = write2buf(h->field, temp, len);
  }else{
    req->headers[i] = h = new_header(128, LIMIT_REQUEST_FIELD_SIZE, 1024, LIMIT_REQUEST_FIELD_SIZE);
    rack_header_type type = check_header_type(temp);
    if(type == OTHER){
      ret = write2buf(h->field, "HTTP_", 5);
    }
    ret = write2buf(h->field, temp, len);
    //printf("%s \n", getString(h->field));
  }
  switch(ret){
  case MEMORY_ERROR:
    client->bad_request_code = 500;
    return -1;
  case LIMIT_OVER:
    client->bad_request_code = 400;
    return -1;
  default:
    break;
  }
  req->last_header_element = FIELD;
  return 0;
}
Beispiel #7
0
static int
write_body2mem(request *req, const char *buf, size_t buf_len)
{
    buffer_t *body = (buffer_t*)req->body;
    write2buf(body, buf, buf_len);

    req->body_readed += buf_len;
    DEBUG("write_body2mem %d bytes", (int)buf_len);
    return req->body_readed;
}
Beispiel #8
0
static void
r_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
    client_t *cli = ( client_t *)(cb_arg);
    //PyObject *body = NULL;
    char *key = NULL;
    int finish = 0, nread;

    if ((events & PICOEV_TIMEOUT) != 0) {

#ifdef DEBUG
        printf("** r_callback timeout %d ** \n", fd);
#endif
        //timeout
        cli->keep_alive = 0;
        if(cli->request_queue->size > 0){
            //piplining
            set_bad_request_code(cli, 408);
            finish = 1;
        }else{
            close_conn(cli, loop);
        }
    
    } else if ((events & PICOEV_READ) != 0) {
        char buf[INPUT_BUF_SIZE];
        ssize_t r;
        if(!cli->keep_alive){
            picoev_set_timeout(loop, cli->fd, READ_TIMEOUT_SECS);
        }
        Py_BEGIN_ALLOW_THREADS
        r = read(cli->fd, buf, sizeof(buf));
        Py_END_ALLOW_THREADS
        switch (r) {
            case 0: 
                cli->keep_alive = 0;
                //503??
                if(cli->request_queue->size > 0){
                    //piplining
                    set_bad_request_code(cli, 503);
                    finish = 1;
                }else{
                    cli->status_code = 503;
                    send_error_page(cli);
                    close_conn(cli, loop);
                    return;
                }
            case -1: /* error */
                if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */
                    break;
                } else { /* fatal error */
                    if(cli->request_queue->size > 0){
                        //piplining
                        set_bad_request_code(cli, 500);
                        if(errno != ECONNRESET){
                            PyErr_SetFromErrno(PyExc_IOError);
                            write_error_log(__FILE__, __LINE__); 
                        }
                        finish = 1;
                    }else{
                        if(cli->keep_alive && errno == ECONNRESET){
                        
                            cli->keep_alive = 0;
                            cli->status_code = 500;
                            cli->header_done = 1;
                            cli->response_closed = 1;
                        
                        }else{
                            PyErr_SetFromErrno(PyExc_IOError);
                            write_error_log(__FILE__, __LINE__); 
                            cli->keep_alive = 0;
                            cli->status_code = 500;
                            if(errno != ECONNRESET){
                                send_error_page(cli);
                            }else{
                                cli->header_done = 1;
                                cli->response_closed = 1;
                            }
                        }
                        close_conn(cli, loop);
                        return;
                    }
                }
                break;
            default:
#ifdef DEBUG
                printf("********************\n%s\n", buf);
#endif
                nread = execute_parse(cli, buf, r);
#ifdef DEBUG
                printf("read request fd %d readed %d nread %d \n", cli->fd, r, nread);
#endif
                
                if(cli->bad_request_code > 0){
#ifdef DEBUG
                    printf("fd %d bad_request code %d \n",cli->fd,  cli->bad_request_code);
#endif
                    set_bad_request_code(cli, cli->bad_request_code);
                    ///force end
                    finish = 1;
                    break;
                }

                if(!cli->upgrade && nread != r){
                    // parse error
#ifdef DEBUG
                    printf("fd %d parse error Bad Request %d \n", cli->fd, cli->bad_request_code);
#endif
                    set_bad_request_code(cli, 400);
                    ///force end
                    finish = 1;
                    break;
                }
                
#ifdef DEBUG
                printf("parse ok, fd %d %d nread \n", cli->fd, nread);
#endif
               
                if(parser_finish(cli) > 0){
                    if(cli->upgrade){
                        //WebSocket Key
#ifdef DEBUG
                        printf("upgrade websocket %d \n", cli->fd);
#endif
                        key = buf + nread + 1;
                        buffer *b = new_buffer(r - nread -1, r - nread -1);
                        if(write2buf(b, key, r - nread -1) == WRITE_OK){
                            cli->request_queue->tail->body = b;
                        }else{
                            free_buffer(b);
                        }
                    }
                    finish = 1;
                }
                break;
        }
    }
Beispiel #9
0
buffer_t*
get_converted_query(char *query, size_t len, PyObject *args)
{
    buffer_t *qbuf;
    char *buf, *st;
    size_t buflen;
    int c, qlen, ret;
    buffer_result bret;
    PyObject *iter = NULL, *item = NULL;


    qbuf = new_buffer(1024 * 4, 0);
    if ( qbuf == NULL) {
        return NULL;
    }
    buf = st = query;
    buflen = len; 
    
    if (args != NULL) {
        iter = PyObject_GetIter(args);
        if (iter == NULL || PyErr_Occurred()) {
            free_buffer(qbuf);
            return NULL;
        }
    }

    while(buflen > 0){
        c = *buf++;
        if (c == '?'){
            qlen = buf - st - 1;
            bret = write2buf(qbuf, st, qlen);
            if (bret != WRITE_OK) {
                goto error;
            }
            if (iter) {
                item =  PyIter_Next(iter);
                if (item == NULL) {
                    //TODO Set Error
                    goto error;
                }
                //ret = convert_object(item);
                if (ret == -1) {
                    goto error;
                }


            }

            st = buf;
        }
        buflen--;

    }
    DEBUG("%s", query);
    qlen = buf - st;
    bret = write2buf(qbuf, st, qlen);
    if (bret != WRITE_OK) {
        goto error;
    }
    
    return qbuf;
error:
    free_buffer(qbuf);
    Py_XDECREF(item);
    Py_XDECREF(iter);
    return NULL;

}