I recently installed seafile/seahub 11.0.12 on Freebsd 14.3 with MySQL 8.4 database.
Although I use the Seadrive client for Windows and Android, I had the need to enable WebDAV for one purpose and subsequently discovered this problem. I filed a bug report on FreeBSD Bugzilla (295624), which contains the following.
Testing discovered issues with the WebDAV extension SeafDAV failing to connect to the database if the MySQL option require_secure_transport is enabled. This option enforces connection using SSL/TLS for TCP or a local Unix socket.
SeafDAV uses SQLAlchemy and PyMySQL to connect to the database, but the application code is incorrect. It ignores the unix_socket setting in the configuration files, forcing connection via TCP, but there is no provision for SSL, so the connection is refused. The following error appears in the seafdav.log file:
WARNING : Failed to init seahub db: (pymysql.err.OperationalError) (3159, ‘Connections using insecure transport are prohibited while --require_secure_transport=ON.’)
Database connections should use unix_socket if the database host is localhost, but it does not.
The file /usr/local/www/haiwen/seafile-server/seahub/thirdpart/wsgidav/dc/seahub_db.py contains:
if db_passwd and not db_host.startswith(‘/’):
db_url = f"mysql+pymysql://{db_user}:{quote_plus(db_passwd)}@{db_host}:{db_port}/{db_name}?charset=utf8"
if not db_passwd and db_host.startswith(‘/’):
db_url = f"mysql+pymysql://{db_user}:@localhost:{db_port}/{db_name}?unix_socket={db_host}&charset=utf8"
This code/logic is plain wrong. In the case of localhost it will ignore the password and expect the host to be the socket file. If the config file is changed to suit the code above it would break normal Seafile connectivity. These lines were replaced with the following to fix the problem:
db_options = db_infos.get(‘OPTIONS’, {})
db_socket = db_options.get(‘unix_socket’, ‘/tmp/mysql.sock’)
db_charset = db_options.get(‘charset’, ‘utf8’)
if db_host == ‘localhost’:
db_url = f"mysql+pymysql://{db_user}:{quote_plus(db_passwd)}@localhost/{db_name}?unix_socket={db_socket}&charset={db_charset}"
else:
db_url = f"mysql+pymysql://{db_user}:{quote_plus(db_passwd)}@{db_host}:{db_port}/{db_name}?charset={db_charset}"
Similarly, the file /usr/local/www/haiwen/seafile-server/seahub/thirdpart/seafobj/db.py contains:
db_url = “mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8” % (username, quote_plus(passwd), host, port, dbname)
This was replaced with:
if config.has_option(‘database’, ‘unix_socket’):
socket = config.get(‘database’, ‘unix_socket’)
else:
socket = ‘/tmp/mysql.sock’
if config.has_option(‘database’, ‘connection_charset’):
charset = config.get(‘database’, ‘connection_charset’)
else:
charset = ‘utf8’
if host == ‘localhost’:
db_url = “mysql+pymysql://%s:%s@localhost/%s?unix_socket=%s&charset=%s” % (username, quote_plus(passwd), dbname, socket, charset)
else:
db_url = “mysql+pymysql://%s:%s@%s:%s/%s?charset=%s” % (username, quote_plus(passwd), host, port, dbname, charset)
The edits also apply connection characterset from the config files, as utf8 is deprecated since MySQL 8.
This fixes the problem in allowing proper expected use of socket connections. A broader fix should also allow for SSL use.