int Dir_serve_file(Dir *dir, Request *req, Connection *conn) { FileRecord *file = NULL; bstring resp = NULL; bstring path = Request_path(req); bstring pattern = req->pattern; int rc = 0; int is_get = biseq(req->request_method, &HTTP_GET); int is_head = is_get ? 0 : biseq(req->request_method, &HTTP_HEAD); check(path, "Request had not path. That's weird."); req->response_size = 0; if(!(is_get || is_head)) { req->status_code = 405; rc = Response_send_status(conn, &HTTP_405); check_debug(rc == blength(&HTTP_405), "Failed to send 405 to client."); return -1; } else { file = Dir_resolve_file(dir, pattern, path); resp = Dir_calculate_response(req, file); if(resp) { rc = Response_send_status(conn, resp); check_debug(rc == blength(resp), "Failed to send error response on file serving."); } else if(is_get) { rc = Dir_stream_file(file, conn); req->response_size = rc; check_debug(rc == file->sb.st_size, "Didn't send all of the file, sent %d of %s.", rc, bdata(path)); } else if(is_head) { rc = Dir_send_header(file, conn); check_debug(rc, "Failed to write header to socket."); } else { sentinel("How the hell did you get to here. Tell Zed."); } FileRecord_release(file); return 0; } sentinel("Invalid code branch, Tell Zed you have magic."); error: FileRecord_release(file); return -1; }
int connection_proxy_failed(Connection *conn) { Response_send_status(conn, &HTTP_502); 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; }