Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
int connection_proxy_failed(Connection *conn)
{
    Response_send_status(conn, &HTTP_502);

    return CLOSE;
}
Ejemplo n.º 3
0
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;
}