int connection_msg_to_handler(Connection *conn) { Handler *handler = Request_get_action(conn->req, handler); int rc = 0; int header_len = Request_header_length(conn->req); // body_len will include \0 int body_len = Request_content_length(conn->req); check(handler, "JSON request doesn't match any handler: %s", bdata(Request_path(conn->req))); if(pattern_match(IOBuf_start(conn->iob), header_len + body_len, bdata(&PING_PATTERN))) { Register_ping(IOBuf_fd(conn->iob)); } else { check(body_len >= 0, "Parsing error, body length ended up being: %d", body_len); bstring payload = Request_to_payload(conn->req, handler->send_ident, IOBuf_fd(conn->iob), IOBuf_start(conn->iob) + header_len, body_len - 1); // drop \0 on payloads rc = Handler_deliver(handler->send_socket, bdata(payload), blength(payload)); bdestroy(payload); check(rc == 0, "Failed to deliver to handler: %s", bdata(Request_path(conn->req))); } // consumes \0 from body_len IOBuf_read_commit(conn->iob, header_len + body_len); return REQ_SENT; error: return CLOSE; }
int connection_proxy_deliver(Connection *conn) { int rc = 0; int total_len = Request_header_length(conn->req) + Request_content_length(conn->req); char *buf = IOBuf_read_all(conn->iob, total_len, CLIENT_READ_RETRIES); check(buf != NULL, "Failed to read from the client socket to proxy."); rc = IOBuf_send(conn->proxy_iob, IOBuf_start(conn->iob), total_len); check(rc > 0, "Failed to send to proxy."); return REQ_SENT; error: return REMOTE_CLOSE; }
int connection_msg_to_handler(Connection *conn) { Handler *handler = Request_get_action(conn->req, handler); int rc = 0; int header_len = Request_header_length(conn->req); // body_len will include \0 int body_len = Request_content_length(conn->req); check(handler, "JSON request doesn't match any handler: %s", bdata(Request_path(conn->req))); if(pattern_match(IOBuf_start(conn->iob), header_len + body_len, bdata(&PING_PATTERN))) { Register_ping(IOBuf_fd(conn->iob)); } else { check(body_len >= 0, "Parsing error, body length ended up being: %d", body_len); bstring payload = NULL; if(handler->protocol == HANDLER_PROTO_TNET) { payload = Request_to_tnetstring(conn->req, handler->send_ident, IOBuf_fd(conn->iob), IOBuf_start(conn->iob) + header_len, body_len - 1); // drop \0 on payloads } else if(handler->protocol == HANDLER_PROTO_JSON) { payload = Request_to_payload(conn->req, handler->send_ident, IOBuf_fd(conn->iob), IOBuf_start(conn->iob) + header_len, body_len - 1); // drop \0 on payloads } else { sentinel("Invalid protocol type: %d", handler->protocol); } debug("SENT: %s", bdata(payload)); check(payload != NULL, "Failed to generate payload."); check(handler->send_socket != NULL, "Handler socket is NULL, tell Zed."); rc = Handler_deliver(handler->send_socket, bdata(payload), blength(payload)); free(payload); check(rc == 0, "Failed to deliver to handler: %s", bdata(Request_path(conn->req))); } // consumes \0 from body_len check(IOBuf_read_commit(conn->iob, header_len + body_len) != -1, "Final commit failed."); return REQ_SENT; error: return CLOSE; }
int connection_http_to_handler(Connection *conn) { int content_len = Request_content_length(conn->req); int rc = 0; char *body = NULL; Handler *handler = Request_get_action(conn->req, handler); error_unless(handler, conn, 404, "No action for request: %s", bdata(Request_path(conn->req))); // we don't need the header anymore, so commit the buffer and deal with the body IOBuf_read_commit(conn->iob, Request_header_length(conn->req)); if(content_len == 0) { body = ""; rc = Connection_send_to_handler(conn, handler, body, content_len); check_debug(rc == 0, "Failed to deliver to the handler."); } else if(content_len > MAX_CONTENT_LENGTH) { rc = Upload_file(conn, handler, content_len); check(rc == 0, "Failed to upload file."); } else { if(content_len > conn->iob->len) { // temporarily grow the buffer IOBuf_resize(conn->iob, content_len); } debug("READ ALL CALLED with content_len: %d, and MAX_CONTENT_LENGTH: %d", content_len, MAX_CONTENT_LENGTH); body = IOBuf_read_all(conn->iob, content_len, CLIENT_READ_RETRIES); check(body != NULL, "Client closed the connection during upload."); rc = Connection_send_to_handler(conn, handler, body, content_len); check_debug(rc == 0, "Failed to deliver to the handler."); } Log_request(conn, 200, content_len); return REQ_SENT; error: return CLOSE; }
int connection_http_to_directory(Connection *conn) { Dir *dir = Request_get_action(conn->req, dir); int rc = Dir_serve_file(dir, conn->req, conn); check_debug(rc == 0, "Failed to serve file: %s", bdata(Request_path(conn->req))); IOBuf_read_commit(conn->iob, Request_header_length(conn->req) + Request_content_length(conn->req)); Log_request(conn, conn->req->status_code, conn->req->response_size); if(conn->close) { return CLOSE; } else { return RESP_SENT; } error: return CLOSE; }
int connection_http_to_handler(Connection *conn) { int content_len = Request_content_length(conn->req); int rc = 0; char *body = NULL; Handler *handler = Request_get_action(conn->req, handler); error_unless(handler, conn, 404, "No action for request: %s", bdata(Request_path(conn->req))); bstring expects = Request_get(conn->req, &HTTP_EXPECT); if (expects != NULL) { if (biseqcstr(expects, "100-continue")) { Response_send_status(conn, &HTTP_100); } else { Response_send_status(conn, &HTTP_417); log_info("Client requested unsupported expectation: %s.", bdata(expects)); goto error; } } // we don't need the header anymore, so commit the buffer and deal with the body check(IOBuf_read_commit(conn->iob, Request_header_length(conn->req)) != -1, "Finaly commit failed streaming the connection to http handlers."); if(is_websocket(conn)) { bstring wsKey = Request_get(conn->req, &WS_SEC_WS_KEY); bstring response= websocket_challenge(wsKey); conn->handler = handler; //Response_send_status(conn,response); bdestroy(conn->req->request_method); conn->req->request_method=bfromcstr("WEBSOCKET_HANDSHAKE"); Connection_send_to_handler(conn, handler, bdata(response), blength(response)); bdestroy(response); bdestroy(conn->req->request_method); conn->req->request_method=bfromcstr("WEBSOCKET"); return REQ_SENT; } if(content_len == 0) { body = ""; rc = Connection_send_to_handler(conn, handler, body, content_len); check_debug(rc == 0, "Failed to deliver to the handler."); } else if(content_len > MAX_CONTENT_LENGTH) { rc = Upload_file(conn, handler, content_len); check(rc == 0, "Failed to upload file."); } else { debug("READ ALL CALLED with content_len: %d, and MAX_CONTENT_LENGTH: %d", content_len, MAX_CONTENT_LENGTH); body = IOBuf_read_all(conn->iob, content_len, CLIENT_READ_RETRIES); check(body != NULL, "Client closed the connection during upload."); rc = Connection_send_to_handler(conn, handler, body, content_len); check_debug(rc == 0, "Failed to deliver to the handler."); } Log_request(conn, 200, content_len); return REQ_SENT; error: return CLOSE; }