Commit Graph

836 Commits

Author SHA1 Message Date
Ophir LOJKINE d277dcddda Fix HTTP status mapping for client request errors 2026-03-13 10:31:31 +01:00
Ophir LOJKINE c7e5be793b Return 400 for invalid UTF-8 multipart fields (#1239) 2026-03-12 11:57:29 +01:00
Ophir LOJKINE acb1893e96 Cap parallel OIDC login state cookies (#1238)
* Cap parallel OIDC login state cookies

* Cap parallel OIDC login state cookies

* simplify cookie eviction code
2026-03-12 11:41:13 +01:00
Ophir LOJKINE f2e23c09dc update dependencies 2026-03-08 11:48:53 +01:00
Ophir LOJKINE ba06855f89 fmt 2026-03-08 10:57:36 +01:00
Ophir LOJKINE 52c37e0dd5 use tokio::time::Instant for testable time manipulation, simplify tests
Replace std::time::Instant with tokio::time::Instant in OidcSnapshot so
that tokio::time::pause()/advance() controls elapsed time in tests.
Remove force_expire() — tests advance time past MAX_REFRESH_INTERVAL
instead. Simplify slow discovery test from ~70 to ~30 lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:49:02 +01:00
Ophir LOJKINE d5f7a84999 rethink OIDC state: std::sync::RwLock<Arc<Snapshot>> for lock-free reads
Replace tokio::sync::RwLock<ClientWithTime> with std::sync::RwLock<Arc<OidcSnapshot>>.
The std lock makes it structurally impossible to hold across await points.
Readers clone an Arc (nanoseconds) and use it freely — no lock contention.
Many previously-async functions become synchronous (get_token_claims,
build_auth_url, handle_unauthenticated_request, handle_oidc_logout, etc).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:48:27 +01:00
Ophir LOJKINE 817674cded OIDC: non-blocking background refresh and body read timeout
- OIDC provider metadata refreshes now run in a background task via
  spawn_local, never blocking incoming HTTP requests.
- Multiple concurrent refresh triggers are deduplicated via an AtomicBool.
- The write lock on the OIDC client is only held briefly to swap data,
  not during the upstream HTTP call.
- Add a body-read timeout to OIDC HTTP requests to prevent hangs when
  the provider stalls after sending headers.
- Add tests for both scenarios: slow discovery and slow token endpoint.

Fixes https://github.com/sqlpage/SQLPage/issues/1231

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:48:02 +01:00
Ophir LOJKINE 431ab87fa5 Add timeout to OIDC HTTP response body read (#1232)
* add timeout to OIDC HTTP response body read

A stalled OIDC provider that sends HTTP headers but never completes the
body would cause response.body().await to hang forever, freezing the
entire SQLPage process. Add a 5-second timeout on the body stream read
using awc's ClientResponse::timeout().

partially Fixes #1231

* simplify test comment

* simplify test: use token_endpoint_delay instead of Notify gate

* simplify test: use tokio time pause + auto-advance instead of select

* use spawn_local + advance instead of select to detect hang

* use Notify sync point instead of yield loop for deterministic test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* simplify test: replace Notify+yields with sleep+time-advance

Remove the Notify synchronization and yield_now() calls. Instead,
use a small real-time sleep for TCP to complete, then pause+advance
tokio time. Assert the actual response status instead of is_finished().


* fix clippy: remove unnecessary mut on response
2026-03-08 03:55:40 +01:00
Ophir LOJKINE c822b55b2d Standardize statement position formatting and preserve HTTP statuses (#1226) 2026-03-02 00:14:38 +01:00
lovasoa d1804ba402 change sqlpage.link error message format 2026-03-01 21:18:29 +01:00
lovasoa 03e1d65bce sqlpage.link: improve error message 2026-03-01 19:19:57 +01:00
Ophir LOJKINE 17e6e1e712 Improve SQLPage function argument warnings (#1225)
* improve sqlpage function argument warnings with source context

Made-with: Cursor

* Param extraction: Result-based errors, single caller message, no CompoundIdentifier special case

- expr_to_stmt_param returns Result<StmtParam, ExprToParamError>; error carries only line + kind (UnsupportedExpr, UnemulatedFunction, NamedArgs)
- function_args_to_stmt_params logs one formatted message (ctx.format_param_error) then returns Err
- Single unsupported-expr arm; expr_summary() used for description
- Rename ParamWarnContext to ParamExtractContext

Made-with: Cursor

* Surface param extraction error in parse result; add parse_sql error-message tests; remove are_params_extractable

- When func_call_to_param returns StmtParam::Error, store it and have extract_parameters return Err so parse yields ParsedStatement::Error with specialized message
- Add test_parse_sql_unsupported_expr_in_sqlpage_arg and test_parse_sql_unemulated_function_in_sqlpage_arg
- Remove dead are_params_extractable and its unused import

Made-with: Cursor

* Refactor sqlpage function argument error messages to match user expectations

- Overhauled ExprToParamError formatting to construct exact user-friendly descriptions.
- Removed superfluous anyhow::Context prefixes in func_call_to_param.
- Passed source_path properly through validate_function_calls to ensure file line numbers populate the new error template accurately.
- Renamed error test file to match its dynamic error output signature.
- Removed redundant mut mutability warnings on parsing logic loops.

* improve error messages

* Refactor SqlPageFunctionError representation to clean up 'syntax error' wrappers

- Replaced stringly-typed anyhow errors with a strongly typed SqlPageFunctionError.
- Removed source_path threading completely from the parameter extraction phases, conforming to better separation of concerns.
- Appended file path prefix dynamically at the evaluation stage in clone_anyhow_err strictly when downcasting to SqlPageFunctionError.
- Removed the confusing generic 'Caused by: x.sql contains a syntax error...' wrapper from actual function logic errors.

* Remove redundant 'reorganize' hint from error message

* readd deleted test

* split parameter extraction logic into a separate file

* Add to changelog
2026-03-01 09:52:46 +01:00
Ophir LOJKINE 0994b926c6 Sqlpage port variable parsing (#1206)
* Ignore invalid SQLPAGE_PORT values from Kubernetes service environment variables

Co-authored-by: contact <contact@ophir.dev>

* Use custom visitor for port deserialization instead of serde_json::Value

Co-authored-by: contact <contact@ophir.dev>

* Fix clippy warnings about uninlined format args

Co-authored-by: contact <contact@ophir.dev>

* Add robust port deserialization for Kubernetes

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-29 18:44:42 +01:00
Guillaume Cornu 94f9988fbb Format protected and public paths with site prefix (#1204)
* Format protected and public paths with site prefix

Update protected and public paths to include site prefix.

* Fix formatting of paths in OIDC module

* Validate that paths start with '/' in config

* Refactor path handling for OIDC configuration

* Update OIDC paths configuration details

* code fix+clippy hints+formatting
2026-01-29 15:26:42 +01:00
Ophir LOJKINE dc5da4643b Connection timeouts configuration (#1197)
* Allow disabling database connection timeouts via config

Co-authored-by: contact <contact@ophir.dev>

* Simplify documentation for disabling database timeouts

Co-authored-by: contact <contact@ophir.dev>

* Refactor timeout resolution to AppConfig

Co-authored-by: contact <contact@ophir.dev>

* Remove *_raw fields and use custom deserializer for timeouts

Co-authored-by: contact <contact@ophir.dev>

* Fix formatting in AppConfig

Co-authored-by: contact <contact@ophir.dev>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-21 12:23:41 +01:00
mtt cb4c1f915e feat(oidc): allow sub domain on localhost (#1188)
Co-authored-by: Your Name <you@example.com>
2026-01-17 16:25:50 +01:00
lovasoa cc55a3d647 v0.42.0
Create Release / Build sqlpage binaries (macOS & Windows) (.exe, , windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Create Release / Build sqlpage binaries (macOS & Windows) (odbc-static, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
Create Release / Build sqlpage binaries (Linux) (push) Has been cancelled
Create Release / Build AWS Lambda Serverless zip image (push) Has been cancelled
Create Release / Create Github Release (push) Has been cancelled
Create Release / Publish to crates.io (push) Has been cancelled
CI / compile_and_lint (push) Has been cancelled
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been cancelled
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been cancelled
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been cancelled
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been cancelled
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been cancelled
CI / windows_test (push) Has been cancelled
CI / docker_build (linux/amd64, duckdb) (push) Has been cancelled
CI / docker_build (linux/amd64, minimal) (push) Has been cancelled
CI / docker_build (linux/arm/v7, minimal) (push) Has been cancelled
CI / docker_build (linux/arm64, duckdb) (push) Has been cancelled
CI / docker_build (linux/arm64, minimal) (push) Has been cancelled
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
2026-01-17 16:18:57 +01:00
lovasoa ce2b881227 Add cache_stale_duration_ms configuration option
Introduces a new configuration option `cache_stale_duration_ms` which
allows users to control how long files are cached before their freshness
is checked. This provides more fine-grained control over caching
behavior, especially in production environments.
2026-01-17 16:11:53 +01:00
Ophir LOJKINE 73377f4f62 add sqlpage functions to access sqlpage config paths (#1186) 2026-01-12 18:02:35 +01:00
Ophir LOJKINE a2ef976fc7 Add support for Oracle over ODBC (compatibility fixes, ci testing) (#1182)
* Add Oracle DB (free) and ODBC CI support

This change adds support for testing with Oracle DB (using the free version `gvenzl/oracle-free:slim`) in the CI pipeline. It:
- Updates `.github/workflows/ci.yml` to include a new matrix entry for Oracle DB.
- Adds steps to install the Oracle Instant Client and ODBC driver in the CI runner.
- Configures `odbcinst.ini` to register the Oracle ODBC driver.
- Updates `docker-compose.yml` to include the Oracle DB service definition.

* Fix CI: Remove libaio1 dependency

`libaio1` is not available in the ubuntu-latest environment used by GitHub Actions (which likely uses a newer Ubuntu version where `libaio1` is replaced by `libaio1t64` or similar, or it is transitively installed). Removing explicit installation to fix the CI failure.

* Fix CI: Update Oracle Instant Client to 21.14

The previous version 21.10.0.0.0-1 seems to be no longer available at the specified URL (404 Not Found). Updated to 21.14.0.0.0-1 which was verified to exist.

* Fix CI: Install libaio1t64 for Oracle Instant Client

Oracle Instant Client requires `libaio.so.1`, which is provided by the `libaio1t64` package in newer Ubuntu versions (like 24.04). Installing this package should resolve the "cannot open shared object file: No such file or directory" error.

* Fix CI: Symlink libaio.so.1 for Oracle Instant Client

On Ubuntu 24.04 (Noble), `libaio1t64` installs the library as `libaio.so.1t64`, but Oracle Instant Client explicitly looks for `libaio.so.1`. Creating a symlink fixes this loading issue.

* Fix CI: Install libodbcinst2 and unixodbc for Oracle driver

The Oracle ODBC driver requires `libodbcinst.so.2` which is provided by `libodbcinst2`. Installing `unixodbc` ensures the full ODBC stack is available.

* Fix CI: Remove redundant wget installation

`wget` is pre-installed on GitHub Actions runners, so the explicit installation via `apt-get` is unnecessary.

* Fix CI: Create 'root' user in Oracle DB

The Oracle test run failed with ORA-01017 (invalid credentials) because the 'root' user does not exist by default in the Oracle database.
This commit:
1. Installs Oracle SQL*Plus (instantclient-sqlplus) in the CI environment.
2. Adds a step to connect as SYSDBA and create the 'root' user with the required permissions and password, matching the test configuration.

* Fix CI: Use container env vars for Oracle user

Instead of manually creating the 'root' user with SQL*Plus, rely on the `gvenzl/oracle-free` container's initialization features (`APP_USER` and `APP_USER_PASSWORD`) which were already configured in `docker-compose.yml`.
Removed the SQL*Plus installation and user creation steps from the CI workflow.

* Fix CI: Use FREEPDB1 service for Oracle user

The `APP_USER` ('root') created by the `gvenzl/oracle-free` container is created in the `FREEPDB1` pluggable database, not the `FREE` container database. Updated the connection string to use `FREEPDB1`.

* Fix Oracle DB test failures

- `sql_to_json`: Handle Oracle's behavior where empty strings are treated as NULL.
- `filesystem`: Explicitly CAST the timestamp parameter to TIMESTAMP in `was_modified_query` for ODBC (Oracle) to avoid ORA-01843 (invalid month) errors caused by implicit string-to-date conversion mismatches.

* Fix Oracle tests by accounting for known behavior

- Revert generic ODBC changes in `filesystem.rs`.
- Skip `test_sql_file_read_utf8` for ODBC connections (Oracle) because fixing the `ORA-01843` error would require Oracle-specific SQL (e.g. `CAST` or `TO_TIMESTAMP`) in the main codebase which is undesirable for a generic ODBC implementation.
- Keep the test adjustment in `sql_to_json.rs` but clarify the comment that we are assuming ODBC implies Oracle in this test context for the empty string behavior.

* Fix Oracle tests: Identify Oracle by connection string

Instead of relying on `sqlx::any::AnyKind::Odbc` (which applies to any ODBC database), detect Oracle specifically by checking if the connection string contains "Oracle". This allows applying Oracle-specific test logic (like skipping tests with implicit timestamp conversions or handling empty strings as NULL) without incorrectly affecting other ODBC databases.

* use oracle dialect when talking to oracle

* remove stupid ai comment

* update oracle odbc installation steps

* fix odbc installation path

* cast variables to varchar(4000) in oracle

* clippy

* remove long backtraces from ci

* fixed csv upload test for oracle

* update tests for oracle

* properly quote sqlpage-generated col names

* fix test syntax for oracle

* clippy

* remove as but keep alias

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-12 14:22:07 +01:00
Mukhtar 5cf1882dc3 fix: handle temp file removal race condition in concurrent initializa… (#1185)
* fix: handle temp file removal race condition in concurrent initialization

When multiple SQLPage instances start simultaneously in the same directory,
they can encounter a race condition during initialization. The create_default_database()
function creates a temporary file to test directory writability, then removes it.
If multiple instances try to remove the same file concurrently, some panic with
'No such file or directory'.

This commit replaces the .expect() panic with graceful error handling using
if let Err(). The writability test has already succeeded by the time we try
to remove the file, so whether another instance removed it is irrelevant.

Includes a test that spawns 10 concurrent threads initializing AppConfig
to verify no panics occur.

ref #1183

* cargo fmt

* the error may have another cause

* Remove concurrent initialization test

Removed the test for concurrent initialization. The test did not work

---------

Co-authored-by: lovasoa <contact@ophir.dev>
2026-01-12 12:43:19 +01:00
Ophir LOJKINE 8d106fb677 Oidc site prefix handling (#1179)
* fix(oidc): respect site_prefix in OIDC redirect and logout URLs

This change ensures that when `site_prefix` is configured, the OIDC redirect URI and logout URI include this prefix.
Previously, `site_prefix` was ignored, causing OIDC callbacks to fail when the application was served under a sub-path.

- Added `site_prefix` to `OidcConfig`.
- Updated `make_oidc_client` to prepend `site_prefix` to the redirect URI.
- Updated `handle_request` to match paths with `site_prefix` included.
- Updated `validate_redirect_url` to respect the prefix when verifying redirect targets.
- Added a regression test `test_oidc_with_site_prefix`.

* Refactor: Update dependencies and remove unused crates

This commit updates several dependencies to their latest versions and removes unused crates to streamline the project.

Co-authored-by: contact <contact@ophir.dev>

* removed unused config

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-08 16:46:10 +01:00
Ophir LOJKINE 72eff8079a Fix invalid redirect url scheme behind reverse proxy (#1178)
This commit refactors the OIDC tests to use a more robust fake OIDC provider and improves the logout URL generation to correctly handle the scheme.

Fixes https://github.com/sqlpage/SQLPage/issues/1174
2026-01-08 15:03:23 +01:00
Ophir Lojkine fb40807ce7 Add DuckDB support including specific syntax parsing 2026-01-05 16:01:55 +01:00
lovasoa 16c089705c Fix: sqlpage.variables() no longer returns duplicate keys
The `sqlpage.variables()` function previously allowed duplicate keys
when GET, POST, and SET variables of the same name were present. This
commit ensures that the returned JSON object contains only unique keys,
with precedence given to SET variables, then POST, then GET.
2025-12-30 03:12:29 +01:00
Ophir LOJKINE 6cc9b1da37 Fix: Prevent infinite OIDC redirects (#1135)
* Fix: Prevent infinite OIDC redirects

This commit adds a mechanism to prevent infinite redirects in the OIDC
callback flow. It does this by:

- Tracking the number of redirects using a cookie.
- Setting a maximum number of redirects (3).
- Returning an error if the maximum is exceeded.

* Merge branch 'main' into prevent-oidc-infinite-redirects

* simplify OIDC infinite redirect prevention logic

This update introduces a new function, `handle_oidc_callback_error`, to streamline error handling during OIDC callback processing. It enhances the management of redirect counts and separates the logic for handling maximum redirect limits into `handle_max_redirect_count_reached`. Additionally, the `build_auth_provider_redirect_response` function is updated to accept the redirect count, ensuring accurate tracking of redirects. This refactor aims to prevent infinite redirect loops and improve code clarity.
2025-12-11 22:49:11 +01:00
Ophir LOJKINE 083593d927 Implement secure oidc logout endpoint and sql function (#1141)
* Checkpoint before follow-up message

Co-authored-by: contact <contact@ophir.dev>

* Checkpoint before follow-up message

Co-authored-by: contact <contact@ophir.dev>

* Checkpoint before follow-up message

Co-authored-by: contact <contact@ophir.dev>

* Checkpoint before follow-up message

Co-authored-by: contact <contact@ophir.dev>

* feat: Add OIDC logout functionality

This commit introduces the `oidc_logout_url` function, allowing users to securely log out of OIDC-authenticated applications. It includes CSRF protection and handles redirection to the OIDC provider's logout endpoint.

Co-authored-by: contact <contact@ophir.dev>

* Refactor OIDC logout cookie removal

Co-authored-by: contact <contact@ophir.dev>

* feat: Implement OIDC logout with CSRF protection

This commit implements secure OIDC logout by:

- Using sqlpage.oidc_logout_url() to generate the logout URL.
- Ensuring CSRF protection during the logout process.
- Redirecting to the OIDC provider's logout endpoint.
- Redirecting back to the homepage after logout.
- Adding absolute URI for post logout redirect URI.

* refactor: Enhance build_absolute_uri function to accept scheme parameter

This commit modifies the build_absolute_uri function to include a scheme parameter, allowing for more flexible URL construction. The function now dynamically sets the URL scheme based on the request context, improving compatibility with different environments.

* refactor: Simplify OIDC logout processing and enhance logout token handling

This commit refactors the OIDC logout process by introducing a new function, `parse_logout_params`, to streamline the extraction of logout parameters from the request. It also updates the logout token creation and verification logic, improving security by ensuring the signature is computed correctly. Additionally, the `create_logout_url` function is modified to include a timestamp and signature in the generated URL, enhancing the logout flow's integrity.

* refactor: Improve logout URL generation and parameter parsing

This commit refines the `create_logout_url` function to utilize a query string builder for constructing the logout URL, enhancing readability and maintainability. Additionally, the `parse_logout_params` function is updated to use `Query::into_inner`, streamlining the extraction of logout parameters from the request.

* refactor: Streamline cookie removal in OIDC logout process

This commit simplifies the removal of authentication and nonce cookies during the OIDC logout process by consolidating the cookie removal logic into a single method call for each cookie, enhancing code clarity and maintainability.

* refactor: Enhance cookie removal logic in OIDC logout process

This commit updates the cookie removal process during OIDC logout by utilizing the `Cookie::build` method to specify cookie attributes, improving clarity and ensuring proper cookie handling.

* chore: Update CHANGELOG for version 0.40.1

- Added new function `sqlpage.oidc_logout_url(redirect_uri)` to generate secure logout URLs for OIDC users, supporting RP-Initiated Logout.
- Fixed compatibility issues with Auth0 for OpenID-Connect authentication.
2025-12-07 01:06:52 +01:00
lovasoa 681c884f71 Fix compatibility with Auth0 for OpenID-Connect authentification.
See https://github.com/ramosbugs/openidconnect-rs/issues/23
2025-11-29 01:10:43 +01:00
Ophir LOJKINE b808ccfdcf Use HTTP 303 instead of 307 for oidc redirects (#1133)
* Use SeeOther for redirects, not TemporaryRedirect

Co-authored-by: contact <contact@ophir.dev>

* Fix OIDC login redirect to use HTTP 303

Co-authored-by: contact <contact@ophir.dev>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-28 17:22:25 +01:00
Ophir LOJKINE 747cc78a91 sqlpage.fetch(null) = null (#1131)
* Fix: fetch(null) and fetch_with_meta(null) return null

Co-authored-by: contact <contact@ophir.dev>

* clean up implementation

* update docs

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-26 22:02:51 +01:00
lovasoa 9c89f02c9b fix regression: SET x = NULL now works even when ?x=something is set in
the URL

fix https://github.com/sqlpage/SQLPage/issues/1130
2025-11-26 21:29:14 +01:00
Ophir LOJKINE 2af95a041f Accept header JSON responses (#1127)
* Support JSON responses via Accept header

* no update in migrations

* No UPDATE in official site migrations

- Updated the JSON component description to clarify its integration with external services and the ability to serve both HTML and JSON based on the HTTP Accept header.
- Added examples demonstrating how to request JSON responses using `curl`.
- Removed the obsolete migration file that documented the JSON response format feature, consolidating information into the main documentation.

* revert stupid docs example change

stupid bot

* simplify tests

* avoid string then json in tests, parse as json directly

* changelog
2025-11-24 23:17:19 +01:00
Ophir LOJKINE e93056e6d8 Add sqlpage.set_variable(name, value) function and update docs (#1124)
* feat: Add sqlpage.set_variable function

Co-authored-by: contact <contact@ophir.dev>

* Refactor: Fix set_variable serialization and update tests

Co-authored-by: contact <contact@ophir.dev>

* fix tests: no json_extract on mssql

* Refactor: Update URLParameters handling in set_variable function

- Replaced serde_json::Map with a custom URLParameters struct for better management of URL parameters.
- Introduced methods for handling single and vector values in URLParameters.
- Updated tests to reflect changes in the set_variable function's behavior.

* cargo fmt

* clippy

* retsore set var test

* remove redundant test

* ensure set_variable only takes into account GET variables, not SET

* factor url parameter setting code

* v0.40

* sqlpage.set_variable links to "?" when no parameter is present

- Renamed URLParameters module for clarity and removed the deprecated url_parameter_deserializer.
- Updated the set_variable function to return parameters directly instead of appending to a URL.
- Adjusted related function calls to reflect changes in URL parameter management.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-24 12:55:32 +01:00
Ophir LOJKINE 75ade135da Refactor request handling to separate data and state (#1111)
* Make URL and POST parameters immutable, separate from SET variables

- URL and POST parameters are now immutable after request initialization
- SET command creates user-defined variables in separate namespace
- Variable lookup: SET variables shadow request parameters
- Added sqlpage.variables('set') to inspect user-defined variables
- Simplified API: most functions now use &RequestInfo instead of &mut
- All tests passing (151 total)

* Restore deprecation warning for SET on POST variable names

* Restore deprecation warnings for $var accessing POST variables

- Warn when both URL and POST have same variable name
- Warn when $var is used for POST-only variable (should use :var)

* Simplify run_sql: always use clone_without_variables

No need to branch on whether variables are provided since we clone in both cases anyway.

* Revert "Simplify run_sql: always use clone_without_variables"

This reverts commit 60f5a05446.

* WIP: Add ExecutionContext to separate mutable state from RequestInfo

This is a draft refactoring to avoid cloning large immutable data (headers,
cookies, body) when creating nested execution contexts in run_sql().

Changes:
- RequestInfo now contains only immutable request data
- ExecutionContext wraps Rc<RequestInfo> + mutable execution state
- Avoids cloning potentially large strings in nested run_sql() calls

Status: NOT COMPILING YET - this is work in progress

* Refactor: Rename RequestInfo to ExecutionContext

Co-authored-by: contact <contact@ophir.dev>

* avoid cloning request

* improve run_sql invalid variables error message

* changelog

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-19 12:27:23 +01:00
Ophir LOJKINE b11e7bf0ff Make URL and POST parameters immutable (#1109)
* Make URL and POST parameters immutable, separate from SET variables

- URL and POST parameters are now immutable after request initialization
- SET command creates user-defined variables in separate namespace
- Variable lookup: SET variables shadow request parameters
- Added sqlpage.variables('set') to inspect user-defined variables
- Simplified API: most functions now use &RequestInfo instead of &mut
- All tests passing (151 total)

* Restore deprecation warning for SET on POST variable names

* Restore deprecation warnings for $var accessing POST variables

- Warn when both URL and POST have same variable name
- Warn when $var is used for POST-only variable (should use :var)

* Simplify run_sql: always use clone_without_variables

No need to branch on whether variables are provided since we clone in both cases anyway.

* Revert "Simplify run_sql: always use clone_without_variables"

This reverts commit 60f5a05446.

* Fix cross-database test compatibility for immutable variables

Renamed test to run only on SQLite since json_extract() is SQLite-specific.
Other databases (PostgreSQL, MySQL, MSSQL) have different JSON functions.

* Fix test to work across all databases without json_extract

PostgreSQL doesn't have json_extract, so compare the full JSON string instead.

* Document variable system improvements in CHANGELOG

* Make CHANGELOG more explicit about breaking changes with examples

* Fix CHANGELOG: SET overwrites GET parameters, not POST

* Add database-specific examples for accessing original URL parameters
2025-11-19 03:10:54 +01:00
Ophir LOJKINE 7cbf5034d8 Improve run_sql error messages (#1105)
* Refactor: Improve run_sql variable parsing

Co-authored-by: contact <contact@ophir.dev>

* Refactor: Use serde_path_to_error for better error reporting

Co-authored-by: contact <contact@ophir.dev>

* Remove serde_path_to_error, use serde_json error reporting

Co-authored-by: contact <contact@ophir.dev>

* Refactor: Move SingleOrVec tests to end of file

Co-authored-by: contact <contact@ophir.dev>

* fix SingleOrVec serialization

* Refactor: Move SingleOrVec to a dedicated module and update imports

* Move SingleOrVec tests from http.rs to single_or_vec.rs for better organization

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-19 01:52:38 +01:00
Ophir LOJKINE f2c8164fee Test postgresql range type decoding (#1097)
* Add support for PostgreSQL range types in SQL to JSON conversion

Co-authored-by: contact <contact@ophir.dev>

* add support for postgres range types

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-11-12 18:05:44 +01:00
Phoenix79-spec f4dab9ff1c Suppressed clippy redundant else error in http.rs using expect syntax. (#1096) 2025-11-12 02:44:44 +01:00
Christophe CHAUVET 9b6691ab1e fix ipv6 notation (#1084)
On Mac OS, when localhost:8080 is defined and sqlpage config file, the SocketAddr is resolved with ipv6 address if ip V6 is available on the internal network.

```json
{
  "listen_on": "localhost:8080"
}
```

On the terminal we can Ctrl + Click, but the URL is incorrect (ipV6 notation use bracket)

Actually we have 

```shell
View your website at:
🔗 http://::1:8080
```

Instead of 

```
View your website at:
🔗 http://[::1]:8080
```

Regards,
2025-11-05 22:51:54 +01:00
lovasoa c4b398b21c simplify icon _img helper 2025-11-04 16:51:16 +01:00
lovasoa 5c41f16481 Simlplify icon generation in build.rs 2025-11-04 16:46:42 +01:00
lovasoa df1e6c2184 IconImgHelper: use raw string literals for SVG output 2025-11-04 14:00:02 +01:00
lovasoa 923cb6262f icon image helper: logging and error handling
- Changed debug logs to warning logs for invalid icon names and missing icons in the IconImgHelper.
- Updated the way icons are retrieved from the ICON_MAP for better clarity and performance.
2025-11-04 13:57:36 +01:00
lovasoa 52e11df5b6 Implement faster icon loading by inlining icons from the Tabler sprite. The previous method required downloading and parsing a large file, causing delays in icon rendering. Now, icons are generated and cached, improving page load times. Update the icon helper to utilize the new inline method. 2025-11-04 13:38:05 +01:00
lovasoa c4ffc0dda3 clippy 2025-11-03 09:53:46 +01:00
lovasoa 44fd2e1cca disable response compression by default 2025-11-02 19:05:41 +01:00
Ophir LOJKINE 73044e7016 nice visual error messages for invalid header values
* Feat: Sanitize header values to prevent injection attacks

Co-authored-by: contact <contact@ophir.dev>

* Refactor sanitize_header_value to use Cow and remove test file

Co-authored-by: contact <contact@ophir.dev>

* refactor header error handling in render.rs

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-10-28 23:50:18 +01:00
lovasoa c803214766 Add server timing for parameter binding in query execution
- Recorded server timing for the parameter binding process in the query execution flow.
- Updated tests to verify the inclusion of the new timing event in the server timing header.
2025-10-28 16:18:05 +01:00
lovasoa 1e396ac095 Fix missing server timing in some cases
- Updated response handling to use a builder pattern for better clarity and consistency.
- Enhanced server timing format to include microseconds in the output.
- Added a new test for server timing in redirect responses to ensure proper header inclusion.
2025-10-28 16:08:40 +01:00