View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2024 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.mysql;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.net.Socket;
23  
24  import org.newsclub.net.unix.AFUNIXSocket;
25  import org.newsclub.net.unix.AFUNIXSocketAddress;
26  
27  import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
28  import com.mysql.cj.conf.PropertyKey;
29  import com.mysql.cj.conf.PropertySet;
30  import com.mysql.cj.conf.RuntimeProperty;
31  import com.mysql.cj.protocol.ExportControlled;
32  import com.mysql.cj.protocol.ServerSession;
33  import com.mysql.cj.protocol.SocketConnection;
34  import com.mysql.cj.protocol.SocketFactory;
35  
36  /**
37   * Connect to mysql databases (and compatibles) using UNIX domain sockets.
38   */
39  public class AFUNIXDatabaseSocketFactoryCJ implements SocketFactory {
40    private AFUNIXSocket rawSocket;
41  
42    /**
43     * Creates a new instance.
44     */
45    public AFUNIXDatabaseSocketFactoryCJ() {
46    }
47  
48    @SuppressWarnings({"unchecked"})
49    @SuppressFBWarnings("EI_EXPOSE_REP")
50    @Override
51    public Socket connect(String hostname, int portNumber,
52        @SuppressWarnings("exports") PropertySet props, int loginTimeout) throws IOException {
53      // Adjust the path to your MySQL socket by setting the
54      // "junixsocket.file" property
55      // If no socket path is given, use the default: /tmp/mysql.sock
56      RuntimeProperty<String> prop = props.getStringProperty("junixsocket.file");
57      String sock;
58      if (prop != null && !prop.isExplicitlySet()) {
59        sock = prop.getStringValue();
60      } else {
61        sock = "/tmp/mysql.sock";
62      }
63      final File socketFile = new File(sock);
64  
65      AFUNIXSocket socket = AFUNIXSocket.newInstance();
66  
67      int connectTimeout = props.getIntegerProperty(PropertyKey.connectTimeout).getValue();
68      int timeout = MysqlHelper.shorterTimeout(connectTimeout, loginTimeout);
69  
70      socket.connect(AFUNIXSocketAddress.of(socketFile), timeout);
71  
72      return (this.rawSocket = socket);
73    }
74  
75    @SuppressWarnings({"unchecked"})
76    @SuppressFBWarnings("EI_EXPOSE_REP")
77    @Override
78    public Socket performTlsHandshake(@SuppressWarnings("exports") SocketConnection socketConnection,
79        @SuppressWarnings("exports") ServerSession serverSession) throws IOException {
80      return ExportControlled.performTlsHandshake(this.rawSocket, socketConnection,
81          serverSession == null ? null : serverSession.getServerVersion(), null);
82    }
83  }