Beispiel #1
0
static void nxweb_http_server_connection_connect(nxweb_http_server_connection* conn, nxe_loop* loop, int fd) {
  conn->sock.fs.fd=fd;
  nxe_register_fd_source(loop, &conn->sock.fs);
  nxe_subscribe(loop, &conn->sock.fs.data_error, &conn->hsp.data_error);
  nxe_subscribe(loop, &conn->hsp.events_pub, &conn->events_sub);
  nxe_connect_streams(loop, &conn->sock.fs.data_is, &conn->hsp.data_in);
  nxe_connect_streams(loop, &conn->hsp.data_out, &conn->sock.fs.data_os);
  conn->uid=nxweb_generate_unique_id();
  conn->connected_time=loop->current_time;
  nxd_http_server_proto_connect(&conn->hsp, loop);
  //__sync_add_and_fetch(&num_connections, 1);
}
Beispiel #2
0
void nxd_http_client_proto_start_request(nxd_http_client_proto* hcp, nxweb_http_request* req) {
  //nxweb_http_request* resp=&hcp->resp;
  hcp->nxb=nxp_alloc(hcp->nxb_pool);
  nxb_init(hcp->nxb, NXWEB_CONN_NXB_SIZE);

  hcp->req=req;
  if (!req->nxb) req->nxb=hcp->nxb;
  if (!req->host) req->host=hcp->host;

  nxe_loop* loop=hcp->data_in.super.loop;
  hcp->req_headers_ptr=_nxweb_prepare_client_request_headers(req);
  //nxweb_log_error("REQ: %s", hcp->req_headers_ptr);
  if (!hcp->req_body_in.pair && req->content && req->content_length>0) {
    nxd_obuffer_init(&hcp->ob, req->content, req->content_length);
    nxe_connect_streams(loop, &hcp->ob.data_out, &hcp->req_body_in);
  }
  if (hcp->state==HCP_IDLE) hcp->state=HCP_SENDING_HEADERS;
  nxe_unset_timer(loop, NXWEB_TIMER_KEEP_ALIVE, &hcp->timer_keep_alive);
  hcp->req_body_sending_started=0;
  hcp->receiving_100_continue=0;
  hcp->request_complete=0;
  hcp->response_body_complete=0;
  hcp->queued_error_message.l=0;
  nxe_istream_set_ready(loop, &hcp->data_out);
}
Beispiel #3
0
static nxweb_result ssi_do_filter(nxweb_filter* filter, nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp, nxweb_filter_data* fdata) {
  ssi_filter_data* sfdata=(ssi_filter_data*)fdata;
  if (resp->status_code && resp->status_code!=200 && resp->status_code!=404) return NXWEB_OK;
  if (!resp->content_length) return NXWEB_OK;

  if (resp->gzip_encoded) {
    fdata->bypass=1;
    return NXWEB_NEXT;
  }

  if (!resp->ssi_on) {
    if (!resp->mtype && resp->content_type) {
      resp->mtype=nxweb_get_mime_type(resp->content_type);
    }
    if (!resp->mtype || !resp->mtype->ssi_on) {
      fdata->bypass=1;
      return NXWEB_NEXT;
    }
  }

  nxd_http_server_proto_setup_content_out(&conn->hsp, resp);

  // attach content_out to ssi_buffer
  ssi_buffer_init(&sfdata->ssib, conn, req);
  if (resp->content_length>0) ssi_buffer_make_room(&sfdata->ssib, min(MAX_SSI_SIZE, resp->content_length));
  nxe_connect_streams(conn->tdata->loop, resp->content_out, &sfdata->ssib.data_in);

  nxweb_set_request_data(req, SSIB_REQ_KEY, (nxe_data)(void*)&sfdata->ssib, 0); // will be used for variable lookups in parent requests

  // replace content_out with composite stream
  nxweb_composite_stream* cs=nxweb_composite_stream_init(conn, req);

  nxweb_composite_stream_start(cs, resp);

  // reset previous response content
  resp->content=0;
  resp->sendfile_path=0;
  if (resp->sendfile_fd) {
    // save it to close on finalize
    sfdata->input_fd=resp->sendfile_fd;
    resp->sendfile_fd=0;
  }
  resp->last_modified=0;

  sfdata->ssib.cs=cs;

  return NXWEB_OK;
}
Beispiel #4
0
static nxweb_result start_proxy_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_proxy_request_data* rdata) {

  nxweb_log_debug("start_proxy_request");

  nxe_loop* loop=conn->tdata->loop;
  nxweb_handler* handler=conn->handler;
  assert(handler->idx>=0 && handler->idx<NXWEB_MAX_PROXY_POOLS);
  nxd_http_proxy* hpx=nxd_http_proxy_pool_connect(&conn->tdata->proxy_pool[handler->idx]);
  rdata->proxy_request_complete=0;
  rdata->proxy_request_error=0;
  rdata->response_sending_started=0;
  if (hpx) {
    rdata->hpx=hpx;
    nxweb_http_request* preq=nxd_http_proxy_prepare(hpx);
    if (handler->proxy_copy_host) preq->host=req->host;
    preq->method=req->method;
    preq->head_method=req->head_method;
    preq->content_length=req->content_length;
    preq->content_type=req->content_type;
    /// Do not forward Accept-Encoding header if you want to process results (eg SSI)
    // preq->accept_encoding=req->accept_encoding;
    preq->expect_100_continue=!!req->content_length;
    if (handler->uri) {
      const char* path_info=req->path_info? req->path_info : req->uri;
      if (*handler->uri) {
        char* uri=nxb_alloc_obj(conn->hsp.nxb, strlen(handler->uri)+strlen(path_info)+1);
        strcat(strcpy(uri, handler->uri), path_info);
        preq->uri=uri;
      }
      else {
        preq->uri=path_info;
      }
    }
    else {
      preq->uri=req->uri;
    }
    preq->http11=1;
    preq->keep_alive=1;
    preq->user_agent=req->user_agent;
    preq->cookie=req->cookie;
    preq->if_modified_since=req->if_modified_since + nxd_http_proxy_pool_get_backend_time_delta(hpx->pool);
    preq->x_forwarded_for=conn->remote_addr;
    preq->x_forwarded_host=req->host;
    preq->x_forwarded_ssl=nxweb_server_config.listen_config[conn->lconf_idx].secure;
    preq->uid=req->uid;
    preq->parent_req=req->parent_req;
    preq->headers=req->headers; // need to filter these???
    nxd_http_proxy_start_request(hpx, preq);
    nxe_init_subscriber(&rdata->proxy_events_sub, &nxweb_http_server_proxy_events_sub_class);
    nxe_subscribe(loop, &hpx->hcp.events_pub, &rdata->proxy_events_sub);
    nxd_rbuffer_init(&rdata->rb_resp, rdata->rbuf, NXWEB_RBUF_SIZE);
    nxe_connect_streams(loop, &hpx->hcp.resp_body_out, &rdata->rb_resp.data_in);

    if (req->content_length) { // receive body
      nxd_rbuffer_init(&rdata->rb_req, rdata->rbuf, NXWEB_RBUF_SIZE); // use same buffer area for request and response bodies, as they do not overlap in time
      conn->hsp.cls->connect_request_body_out(&conn->hsp, &rdata->rb_req.data_in);
      nxe_connect_streams(loop, &rdata->rb_req.data_out, &hpx->hcp.req_body_in);
      req->cdstate.monitor_only=1;

      conn->hsp.cls->start_receiving_request_body(&conn->hsp);
    }
    nxe_set_timer(loop, NXWEB_TIMER_BACKEND, &rdata->timer_backend);
    return NXWEB_OK;
  }
  else {
    nxweb_http_response* resp=&conn->hsp._resp;
    nxweb_send_http_error(resp, 502, "Bad Gateway");
    return NXWEB_ERROR;
  }
}