@@ -14,7 +14,11 @@ impl FromStr for PgConnectOptions {
14
14
let mut options = Self :: default ( ) ;
15
15
16
16
if let Some ( host) = url. host_str ( ) {
17
- options = options. host ( host) ;
17
+ let host_decoded = percent_decode_str ( host) ;
18
+ options = match host_decoded. clone ( ) . next ( ) {
19
+ Some ( b'/' ) => options. socket ( & * host_decoded. decode_utf8 ( ) . map_err ( Error :: config) ?) ,
20
+ _ => options. host ( host) ,
21
+ }
18
22
}
19
23
20
24
if let Some ( port) = url. port ( ) {
@@ -174,3 +178,20 @@ fn it_parses_password_with_non_ascii_chars_correctly() {
174
178
175
179
assert_eq ! ( Some ( "p@ssw0rd" . into( ) ) , opts. password) ;
176
180
}
181
+
182
+ #[ test]
183
+ fn it_parses_socket_correctly_percent_encoded ( ) {
184
+ let uri = "postgres://%2Fvar%2Flib%2Fpostgres/database" ;
185
+ let opts = PgConnectOptions :: from_str ( uri) . unwrap ( ) ;
186
+
187
+ assert_eq ! ( Some ( "/var/lib/postgres/" . into( ) ) , opts. socket) ;
188
+ }
189
+ #[ test]
190
+ fn it_parses_socket_correctly_with_username_percent_encoded ( ) {
191
+ let uri = "postgres://some_user@%2Fvar%2Flib%2Fpostgres/database" ;
192
+ let opts = PgConnectOptions :: from_str ( uri) . unwrap ( ) ;
193
+
194
+ assert_eq ! ( "some_user" , opts. username) ;
195
+ assert_eq ! ( Some ( "/var/lib/postgres/" . into( ) ) , opts. socket) ;
196
+ assert_eq ! ( Some ( "database" ) , opts. database. as_deref( ) ) ;
197
+ }
0 commit comments