Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: incorrect parsing for fallback_application_name #2977

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2846, Fix error when requesting `Prefer: count=<type>` and doing null filtering on embedded resources - @laurenceisla
- #2959, Fix setting `default_transaction_isolation` unnecessarily - @steve-chavez
- #2929, Fix arrow filtering on RPC returning dynamic TABLE with composite type - @steve-chavez
- #2970, Fix incorrect URI parsing for adding `fallback_application_name` - @steve-chavez

## [11.2.0] - 2023-08-10

Expand Down
10 changes: 9 additions & 1 deletion nix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ To build PostgREST from your local checkout of the repository, run:

```bash
$ nix-build --attr postgrestPackage

```

This will create a `result` directory that contains the PostgREST binary at
Expand All @@ -22,6 +21,15 @@ build the `postgrestPackage` attribute from the Nix expression it finds in our
`default.nix` (see below for details). Nix will take care of getting the right
GHC version and all the build dependencies.

You can also build a statically linked binary with:

```bash
$ nix-build --attr postgrestStatic

$ ldd result/bin/postgrest
$ not a dynamic executable
```

## Binary cache

We recommend that you use the PostgREST binary cache on
Expand Down
31 changes: 21 additions & 10 deletions src/PostgREST/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ import Data.List.NonEmpty (fromList, toList)
import Data.Maybe (fromJust)
import Data.Scientific (floatingOrInteger)
import Network.URI (escapeURIString,
isUnescapedInURIComponent, parseURI,
uriQuery)
isUnescapedInURIComponent)
import Numeric (readOct, showOct)
import System.Environment (getEnvironment)
import System.Posix.Types (FileMode)
Expand Down Expand Up @@ -472,6 +471,8 @@ readPGRSTEnvironment =
M.map T.pack . M.fromList . filter (isPrefixOf "PGRST_" . fst) <$> getEnvironment

-- | Adds a `fallback_application_name` value to the connection string. This allows querying the PostgREST version on pg_stat_activity.
-- | This follows the same logic as libpq for parsing the URI https://github.com/postgres/postgres/blob/a829b704015104f49a11ea007957ef03a03dc0d4/src/interfaces/libpq/fe-connect.c#L5880-L5921
-- | If there's a postgres URI scheme designator prefix ("postgres://") then the connstring is considered an URI, if not, it's in key/value format.
--
-- >>> let ver = "11.1.0 (5a04ec7)"::ByteString
-- >>> let strangeVer = "11'1&0@#$%,.:\"[]{}?+^()=asdfqwer"::ByteString
Expand All @@ -496,15 +497,25 @@ readPGRSTEnvironment =
--
-- >>> addFallbackAppName strangeVer "postgres:///postgres?host=server&port=5432"
-- "postgres:///postgres?host=server&port=5432&fallback_application_name=PostgREST%2011%271%260%40%23%24%25%2C.%3A%22%5B%5D%7B%7D%3F%2B%5E%28%29%3Dasdfqwer"
--
-- Special chars in password
-- >>> addFallbackAppName ver "postgres:///postgres:pass=()[]&#?host=server&port=5432"
-- "postgres:///postgres:pass=()[]&#?host=server&port=5432&fallback_application_name=PostgREST%2011.1.0%20%285a04ec7%29"
addFallbackAppName :: ByteString -> Text -> Text
addFallbackAppName version dbUri = dbUri <>
case uriQuery <$> parseURI (toS dbUri) of
Nothing -> " " <> keyValFmt -- Assume key/value connection string if the uri is not valid
Just "" -> "?" <> uriFmt
Just "?" -> uriFmt
_ -> "&" <> uriFmt
if isPgURI dbUri
then case snd $ T.breakOn "?" dbUri of
steve-chavez marked this conversation as resolved.
Show resolved Hide resolved
"?" -> fallbackUriFmt
"" -> "?" <> fallbackUriFmt
_ -> "&" <> fallbackUriFmt
else " " <> fallbackKeyValFmt
where
uriFmt = pKeyWord <> toS (escapeURIString isUnescapedInURIComponent $ toS pgrstVer)
keyValFmt = pKeyWord <> "'" <> T.replace "'" "\\'" pgrstVer <> "'"
pKeyWord = "fallback_application_name="
fallbackUriFmt = key <> toS (escapeURIString isUnescapedInURIComponent $ toS pgrstVer)
fallbackKeyValFmt = key <> "'" <> T.replace "'" "\\'" pgrstVer <> "'"
key = "fallback_application_name="
pgrstVer = "PostgREST " <> T.decodeUtf8 version
isPgURI str =
let
uriDesignator = "postgresql://"
shortUriDesignator = "postgres://" in
uriDesignator `T.isPrefixOf` str || shortUriDesignator `T.isPrefixOf` str
Loading