Connecting to Postgres Via database_url and Unix Socket in Rails - rails-activerecord

I've hunted around for this and just can't find a solution.
Currently I have a database.yml connected to a local pgbouncer server on a Unix socket successfully. However, I'm transitioning to setting this to a database_url environment variable and cannot work out at all how to connect to a local Postgres server via a Unix socket. localhost obviously works OK.
I was looking at a URL that looks like this as apparently you can use this with Postgres (http://www.postgresql.org/docs/9.2/interactive/libpq-connect.html):
export DATABASE_URL="postgresql://username#%Fvar%Frun%Fpostgresql%F.s.PGSQL.6432/dbname"
However, this will not get past the URI police:
rubies/ruby-2.1.5/lib/ruby/2.1.0/uri/common.rb:176:in `split': bad URI(is not URI?): postgresql://username#%Fvar%Frun%Fpostgresql%F.s.PGSQL.6432/dbname
Does anyone have any idea about the secret sauce needed for this? I've Googles endlessly and haven't found anything. It must be possible since the application currently connects over a socket now.
Thanks in advance,

31.1.1.2. Connection URIs
The general form for a connection URI is:
postgresql://[user[:password]#][netloc][:port][/dbname][?param1=value1&...]`
The URI scheme designator can be either postgresql:// or postgres://.
Each of the URI parts is optional. The following examples illustrate
valid URI syntax uses:
postgresql://
postgresql://localhost
postgresql://localhost:5433
postgresql://localhost/mydb
postgresql://user#localhost
postgresql://user:secret#localhost
postgresql://other#localhost/otherdb?connect_timeout=10&application_name=myapp
Components of the hierarchical part of the URI can also be given as
parameters. For example:
postgresql:///mydb?host=localhost&port=5433
Percent-encoding may be used to include symbols with special meaning
in any of the URI parts.
Any connection parameters not corresponding to key words listed in
Section 31.1.2 are ignored and a warning message about them is sent to
stderr.
For improved compatibility with JDBC connection URIs, instances of
parameter ssl=true are translated into sslmode=require.
The host part may be either host name or an IP address. To specify an
IPv6 host address, enclose it in square brackets:
postgresql://[2001:db8::1234]/database
The host component is interpreted as described for the parameter host.
In particular, a Unix-domain socket connection is chosen if the host
part is either empty or starts with a slash, otherwise a TCP/IP
connection is initiated. Note, however, that the slash is a reserved
character in the hierarchical part of the URI. So, to specify a
non-standard Unix-domain socket directory, either omit the host
specification in the URI and specify the host as a parameter, or
percent-encode the path in the host component of the URI:
postgresql:///dbname?host=/var/lib/postgresql
postgresql://%2Fvar%2Flib%2Fpostgresql/dbname

You must omit the host to use unix socket, like so:
postgres://username#/dbname
or simply
postgres:///dbname
This works with psql > 9.2.
I am not sure it works with the rails handling of the database URL.

You can pass the socket as a query parameter:
postgresql://user#host/database?socket=/path/to/socket

The answer provided by #blnc is correct if using libpq in general. However, if you are using Activerecord or RubyonRails, at least in version 3.2.21, that module parses the URI to Ruby's URI.parse, instead of directly handing it to libpq. URI.parse cannot handle an empty hostname here.
irb(main):020:0> URI.parse "postgresql://user:pass#host/dbname"
=> #<URI::Generic:0x7f72b17f04d8 URL:postgresql://user:pass#host/dbname>
But, without host:
irb(main):021:0> URI.parse "postgresql://user:pass#/dbname"
URI::InvalidURIError: the scheme postgresql does not accept registry part: user:pass# (or bad hostname?)
from /usr/lib/ruby/1.8/uri/generic.rb:195:in `initialize'
from /usr/lib/ruby/1.8/uri/common.rb:492:in `new'
from /usr/lib/ruby/1.8/uri/common.rb:492:in `parse'
from (irb):21
from /usr/lib/ruby/1.8/uri/generic.rb:556
There appears to be no way to fix this without adding custom URI-parsing code (or altering activerecord).

On Archlinux with default path for unix_socket_directories:
postgres:///<dbname>?host=/run/postgresql/

Related

Using winhttp for client with non default SSL server name indication (sni)

I'm using winhttp in order to establish https connection on port 443 with my remote. However, the server running this service also contains more services on the same https port (443), so it uses SNI in order to resolve the requested session.
However, the server doesn't expect to get the hostname as SNI, since it uses single URL for all services. instead, the SNI address is chosen not according to the URL but according to some other string notation (i.e. service_api or service_web_if ...)
In my client connection flow, I set the URL in method WinHttpConnect which also set the SNI accordingly, and the actual SSL/TLS handshake is made when calling WinHttpSentRequest.
I wonder how can I change the SNI value from the default URL value after calling WinHttpConnect.
So far, while investigating possible solutions, I've learned about HTTP_SERVICE_CONFIG_SSL_SNI_KEY structure which is set by method HttpSetServiceConfiguration along with the matching certificate for this SNI, but this seems to be related to the server side configuration. Besides that, I haven't found any references for such action unfortunately.
Perhaps anybody ever used non-default SNI using winhttp API and can tell me how to do so ? is the only option to do so is doing the SSL handshake using some lower level API such as schannel, and than switching back to winhttp ?
if it's not possible, perhaps there's an option to use extended hostname with directory tree in order to get multiple sni on a single url...

Camel Route sending files from file endpoint to FTP server

Being new to Apache Camel, I have been following the examples all over the internet. Near on every book/forum/bog post has an example on how to create a simple route that will consume/produce files to/from an FTP server.
My issue is that the host that I am trying to connect to using the suggested connection
from("ftp://someone#someserver.com?password=secret&localWorkDirectory=/tmp")
OR
<from uri="ftp://someone#someserver/public/reports?password=password"/>
Doesn't work for me when I use the credentials my host supplies me:
For the sake of this example, lets call the FTP details:
FTP username: username#ftpserverhost.com
Password: password
So when I replace the advised URI with my servers credentials it fails to connect. I am assuming this is because it has two # symbols and this is causing the route some confusion.
from("ftp://username#ftpserverhost.com#ftpserverhost.com?password=secret&localWorkDirectory=/tmp")
OR
<from uri="ftp://username#ftpserverhost.com#ftpserverhost.com/public/reports?password=password"/>
Is there a way to escape the # or get this working? I have asked my host if its possible to leave the #ftpserverhost.com but they have advised me that it will not work.
Any ideas?
Use the username option:
from("ftp://ftpserverhost.com?password=secret&localWorkDirectory=/tmp&username=username#ftpserverhost.com")
If this does not work and if you use Camel 2.11 or above, you may use the RAW syntax:
from("ftp://ftpserverhost.com?password=secret&localWorkDirectory=/tmp&username=RAW(username#ftpserverhost.com)")
The RAW syntax also comes in handy if your options contains &, + or other special characters that must not be encoded.

UWSGI specify socket location

I am trying to locate all my sockets logically and I am having a hard time understanding.
Say, for example that I want them in this directory: /var/run/<app>/
I should specify uWSGI this in a command line parameter
--socket </var/run/<app>/>
However in my uwsgi.ini I have this:
socket = 127.0.0.1:3031
In order to get the effect I want, should I be doing
socket = /var/run/uwsgi
I am just confused, because one is an IP and one is a directory.
As documented you can use either network or Unix domain sockets.

Ruby: force dns resolution through custom dns server

I want to resolve the DNS requests issued from within a Ruby script through a DNS server, different from the ones in resolv.conf. While I could do that manualy by using Resolv::DNS or something like that, I'd like to do that for all the requests (like the ones issued by RestClient, for example). Any ideas?
RestClient uses net/http and uses the host name part of the provided URL to open a TCP socket:
https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb?source=cc#L879
The simplest way to change which host is accessed is to manually change the URL to use an IP address by performing the lookup yourself.
Alternatively, you can replace the resolver of the various *Socket classes, and there is actually an example of how to do this here: https://github.com/ruby/ruby/blob/4c2304f0004e9f1784540f3d36976aad9eab1f68/lib/resolv-replace.rb

Fault Tolerance JMS URL in Java

I am doing a JMS connection using Java. The command I am using to establish connection is
QueueConnectionFactory factory =
new com.tibco.tibjms.TibjmsQueueConnectionFactory(JMSserverUrl);
Where JMSServerUrl is the varible which stores my JMS URL.
Now the problem is that I need to add the fault tolerance URL i.e two different URL's. So can any one tell me how can I specify two URLs together in the above code sample such that if first URL is not accessible it should try connecting to the other URL.
Put all URLs in a single string with a comma between them.
new TibjmsQueueConnectionFactory("ssl://host01:20302,ssl://host02:20302");
Caution, I am a Tibco EMS newbie, but this seems to work, as evidenced by the error I can get ...
javax.jms.JMSSecurityException: Failed to connect to any server at:
ssl://host01:20302,ssl://host02:20302
[Error: Can not initialize SSL client: no trusted certificates are set:
url that returned this exception = SSL://host01:20302 ]
The .NET documentation for tibco(I know your using java) suggests that you can provide a comma delimited list of server URL's for messaging connections. Bear in mind that I don't have any real tibco experience, but this is a common way to handle initial connection fault tolerance(i.e. prior to establishing a connection and receiving information about the cluster, after which failover is typically handled by the connection). It may be worth a try. Another solution that I have seen to this problem is creating a virtual IP and handling fault tolerance at the Network Level.

Resources