static int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { // mark a route request wsgi_req->via = UWSGI_VIA_ROUTE; // get the http address from the route char *addr = ur->data; struct uwsgi_buffer *ub_url = NULL; if (ur->data3_len) { char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); ub_url = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data3, ur->data3_len); if (!ub_url) return UWSGI_ROUTE_BREAK; } // convert the wsgi_request to an http proxy request struct uwsgi_buffer *ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len, ub_url ? ub_url->buf : NULL, ub_url ? ub_url->pos : 0); if (!ub) { if (ub_url) uwsgi_buffer_destroy(ub_url); uwsgi_log("unable to generate http request for %s\n", addr); return UWSGI_ROUTE_NEXT; } if (ub_url) uwsgi_buffer_destroy(ub_url); // amount of body to send size_t remains = wsgi_req->post_cl - wsgi_req->proto_parser_remains; // append remaining body... if (wsgi_req->proto_parser_remains > 0) { if (uwsgi_buffer_append(ub, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains)) { uwsgi_buffer_destroy(ub); uwsgi_log("unable to generate http request for %s\n", addr); return UWSGI_ROUTE_NEXT; } wsgi_req->proto_parser_remains = 0; } // ok now if have offload threads, directly use them if (!wsgi_req->post_file && !ur->custom && wsgi_req->socket->can_offload) { // append buffered body if (uwsgi.post_buffering > 0 && wsgi_req->post_cl > 0) { if (uwsgi_buffer_append(ub, wsgi_req->post_buffering_buf, wsgi_req->post_cl)) { uwsgi_buffer_destroy(ub); uwsgi_log("unable to generate http request for %s\n", addr); return UWSGI_ROUTE_NEXT; } } if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) { wsgi_req->via = UWSGI_VIA_OFFLOAD; wsgi_req->status = 202; return UWSGI_ROUTE_BREAK; } } if (uwsgi_proxy_nb(wsgi_req, addr, ub, remains, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { uwsgi_log("error routing request to http server %s\n", addr); } uwsgi_buffer_destroy(ub); return UWSGI_ROUTE_BREAK; }
static int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { struct uwsgi_buffer *ub = NULL; // mark a route request wsgi_req->via = UWSGI_VIA_ROUTE; char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); struct uwsgi_buffer *ub_addr = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len); if (!ub_addr) return UWSGI_ROUTE_BREAK; struct uwsgi_buffer *ub_url = NULL; if (ur->data3_len) { ub_url = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data3, ur->data3_len); if (!ub_url) { uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_BREAK; } } // convert the wsgi_request to an http proxy request if (ur->custom & 0x02) { ub = uwsgi_buffer_new(uwsgi.page_size); } else if (ur->custom & 0x04) { ub = uwsgi_to_http_dumb(wsgi_req, ur->data2, ur->data2_len, ub_url ? ub_url->buf : NULL, ub_url ? ub_url->pos : 0); } else { ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len, ub_url ? ub_url->buf : NULL, ub_url ? ub_url->pos : 0); } if (!ub) { if (ub_url) uwsgi_buffer_destroy(ub_url); uwsgi_log("unable to generate http request for %s\n", ub_addr->buf); uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_NEXT; } if (ub_url) uwsgi_buffer_destroy(ub_url); // amount of body to send size_t remains = wsgi_req->post_cl - wsgi_req->proto_parser_remains; // append remaining body... if (wsgi_req->proto_parser_remains > 0) { if (uwsgi_buffer_append(ub, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains)) { uwsgi_buffer_destroy(ub); uwsgi_log("unable to generate http request for %s\n", ub_addr->buf); uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_NEXT; } wsgi_req->post_pos += wsgi_req->proto_parser_remains; wsgi_req->proto_parser_remains = 0; } // ok now if have offload threads, directly use them if (!wsgi_req->post_file && !(ur->custom & 0x01) && wsgi_req->socket->can_offload) { // append buffered body if (uwsgi.post_buffering > 0 && wsgi_req->post_cl > 0) { if (uwsgi_buffer_append(ub, wsgi_req->post_buffering_buf, wsgi_req->post_cl)) { uwsgi_buffer_destroy(ub); uwsgi_log("unable to generate http request for %s\n", ub_addr->buf); uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_NEXT; } } // if we have a CONNECT request, let's confirm it to the client if (ur->custom & 0x02) { if (uwsgi_response_prepare_headers(wsgi_req, "200 Connection established", 26)) goto end; // no need to check for return value uwsgi_response_write_headers_do(wsgi_req); } if (!uwsgi_offload_request_net_do(wsgi_req, ub_addr->buf, ub)) { wsgi_req->via = UWSGI_VIA_OFFLOAD; wsgi_req->status = 202; uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_BREAK; } } if (uwsgi_proxy_nb(wsgi_req, ub_addr->buf, ub, remains, uwsgi.socket_timeout)) { uwsgi_log("error routing request to http server %s\n", ub_addr->buf); } end: uwsgi_buffer_destroy(ub); uwsgi_buffer_destroy(ub_addr); return UWSGI_ROUTE_BREAK; }