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