Skip to content

Commit

Permalink
Fix issue #26 on DB Connection closed in Admin
Browse files Browse the repository at this point in the history
In admin interface, espcially in Responsive mode, the DbConnection sometimes
seems closed and not reopened as it should be.
Since the new model of connections is to not keep the connections opens but to
reopen it as much as we need it (seems not to have big impact, and in particular
for Web Admin interface, it should not have any impact), this fix removes the
database keeping rule replacing by the underlying native pooling connections.

This fix is made for all Admin Interface: R66, GWFTP, ProxyR66.

This is only a fix for #26, not an evolution.
  • Loading branch information
fredericBregier committed May 12, 2020
1 parent ceed1ec commit 8db9e59
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 359 deletions.
Expand Up @@ -91,8 +91,6 @@ public class HttpSslHandler
*/
private static final ConcurrentHashMap<String, FileBasedAuth> sessions =
new ConcurrentHashMap<String, FileBasedAuth>();
private static final ConcurrentHashMap<String, DbSession> dbSessions =
new ConcurrentHashMap<String, DbSession>();
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();

private final FtpSession ftpSession =
Expand Down Expand Up @@ -182,10 +180,6 @@ public String readEnd() {
* session
*/
private DbSession dbSession;
/**
* Does this dbSession is private and so should be closed
*/
private volatile boolean isPrivateDbSession;

private String getTrimValue(String varname) {
String value = params.get(varname).get(0).trim();
Expand Down Expand Up @@ -549,18 +543,21 @@ private void getParams() {
private void clearSession() {
if (admin != null) {
final FileBasedAuth auth = sessions.remove(admin.value());
final DbSession ldbsession = dbSessions.remove(admin.value());
admin = null;
if (auth != null) {
auth.clear();
}
if (ldbsession != null) {
ldbsession.disconnect();
DbAdmin.decHttpSession();
}
}
}

protected void closeConnection() {
if (dbSession != null && dbSession != DbConstantFtp.gatewayAdmin.getSession()) {
DbAdmin.decHttpSession();
dbSession.disconnect();
}
dbSession = null;
}

private void checkAuthent(ChannelHandlerContext ctx) {
newSession = true;
if (request.method() == HttpMethod.GET) {
Expand Down Expand Up @@ -631,18 +628,6 @@ private void checkAuthent(ChannelHandlerContext ctx) {
logger.debug("Still not authenticated: {}", authentHttp);
getMenu = true;
}
// load DbSession
if (dbSession == null) {
try {
dbSession = new DbSession(DbConstantFtp.gatewayAdmin, false);
DbAdmin.incHttpSession();
isPrivateDbSession = true;
} catch (final WaarpDatabaseNoConnectionException e1) {
// Cannot connect so use default connection
logger.warn("Use default database connection");
dbSession = DbConstantFtp.gatewayAdmin.getSession();
}
}
}
} else {
getMenu = true;
Expand All @@ -660,9 +645,6 @@ private void checkAuthent(ChannelHandlerContext ctx) {
.getHostId() +
Long.toHexString(RANDOM.nextLong()));
sessions.put(admin.value(), authentHttp);
if (isPrivateDbSession) {
dbSessions.put(admin.value(), dbSession);
}
logger.debug("CreateSession: " + uriRequest + ":{}", admin);
}
writeResponse(ctx);
Expand All @@ -683,41 +665,45 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg)
return;
}
checkSession(ctx.channel());
if (!authentHttp.isIdentified()) {
logger.debug("Not Authent: " + uriRequest + ":{}", authentHttp);
checkAuthent(ctx);
return;
}
String find = uriRequest;
if (uriRequest.charAt(0) == '/') {
find = uriRequest.substring(1);
}
find = find.substring(0, find.indexOf('.'));
REQUEST req = REQUEST.index;
try {
req = REQUEST.valueOf(find);
} catch (final IllegalArgumentException e1) {
req = REQUEST.index;
logger.debug("NotFound: " + find + ':' + uriRequest);
}
switch (req) {
case System:
responseContent.append(system());
break;
case Rule:
responseContent.append(rule());
break;
case User:
responseContent.append(user());
break;
case Transfer:
responseContent.append(transfer());
break;
default:
responseContent.append(index());
break;
if (!authentHttp.isIdentified()) {
logger.debug("Not Authent: " + uriRequest + ":{}", authentHttp);
checkAuthent(ctx);
return;
}
String find = uriRequest;
if (uriRequest.charAt(0) == '/') {
find = uriRequest.substring(1);
}
find = find.substring(0, find.indexOf('.'));
REQUEST req = REQUEST.index;
try {
req = REQUEST.valueOf(find);
} catch (final IllegalArgumentException e1) {
req = REQUEST.index;
logger.debug("NotFound: " + find + ':' + uriRequest);
}
switch (req) {
case System:
responseContent.append(system());
break;
case Rule:
responseContent.append(rule());
break;
case User:
responseContent.append(user());
break;
case Transfer:
responseContent.append(transfer());
break;
default:
responseContent.append(index());
break;
}
writeResponse(ctx);
} finally {
closeConnection();
}
writeResponse(ctx);
}

private void checkSession(Channel channel) {
Expand All @@ -733,15 +719,20 @@ private void checkSession(Channel channel) {
}
}
}
// load DbSession
try {
dbSession = new DbSession(DbConstantFtp.gatewayAdmin, false);
DbAdmin.incHttpSession();
} catch (final WaarpDatabaseNoConnectionException e1) {
// Cannot connect so use default connection
logger.warn("Use default database connection");
dbSession = DbConstantFtp.gatewayAdmin.getSession();
}
if (admin != null) {
final FileBasedAuth auth = sessions.get(admin.value());
if (auth != null) {
authentHttp = auth;
}
final DbSession dbSessionNew = dbSessions.get(admin.value());
if (dbSessionNew != null) {
this.dbSession = dbSessionNew;
}
} else {
logger.debug("NoSession: " + uriRequest + ":{}", admin);
}
Expand Down
Expand Up @@ -20,15 +20,11 @@
package org.waarp.openr66.proxy.protocol.http.adminssl;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.DefaultCookie;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import io.netty.handler.traffic.TrafficCounter;
import org.waarp.common.exception.FileTransferException;
import org.waarp.common.exception.InvalidArgumentException;
Expand All @@ -46,7 +42,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import static org.waarp.openr66.protocol.configuration.Configuration.*;

Expand Down Expand Up @@ -365,7 +360,7 @@ private void getParams() {
}
}

private void clearSession() {
protected void clearSession() {
if (admin != null) {
final R66Session lsession = sessions.remove(admin.value());
admin = null;
Expand Down Expand Up @@ -491,62 +486,37 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg)
return;
}
checkSession(ctx.channel());
if (!authentHttp.isAuthenticated()) {
logger.debug("Not Authent: " + uriRequest + ":{}", authentHttp);
checkAuthent(ctx);
return;
}
String find = uriRequest;
if (uriRequest.charAt(0) == '/') {
find = uriRequest.substring(1);
}
REQUEST req = REQUEST.index;
if (find.length() != 0) {
find = find.substring(0, find.indexOf('.'));
try {
req = REQUEST.valueOf(find);
} catch (final IllegalArgumentException e1) {
req = REQUEST.index;
logger.debug("NotFound: " + find + ':' + uriRequest);
try {
if (!authentHttp.isAuthenticated()) {
logger.debug("Not Authent: " + uriRequest + ":{}", authentHttp);
checkAuthent(ctx);
return;
}
}
switch (req) {
case System:
responseContent.append(System());
break;
default:
responseContent.append(index());
break;
}
writeResponse(ctx);
}

private void checkSession(Channel channel) {
final String cookieString = request.headers().get(HttpHeaderNames.COOKIE);
if (cookieString != null) {
final Set<Cookie> cookies = ServerCookieDecoder.LAX.decode(cookieString);
if (!cookies.isEmpty()) {
for (final Cookie elt : cookies) {
if (elt.name()
.equalsIgnoreCase(R66SESSION + configuration.getHostId())) {
logger.debug("Found session: " + elt);
admin = elt;
final R66Session session = sessions.get(admin.value());
if (session != null) {
authentHttp = session;
authentHttp.setStatus(73);
} else {
admin = null;
}
} else if (elt.name().equalsIgnoreCase(I18NEXT)) {
logger.debug("Found i18next: " + elt);
lang = elt.value();
}
String find = uriRequest;
if (uriRequest.charAt(0) == '/') {
find = uriRequest.substring(1);
}
REQUEST req = REQUEST.index;
if (find.length() != 0) {
find = find.substring(0, find.indexOf('.'));
try {
req = REQUEST.valueOf(find);
} catch (final IllegalArgumentException e1) {
req = REQUEST.index;
logger.debug("NotFound: " + find + ':' + uriRequest);
}
}
}
if (admin == null) {
logger.debug("NoSession: " + uriRequest + ":{}", admin);
switch (req) {
case System:
responseContent.append(System());
break;
default:
responseContent.append(index());
break;
}
writeResponse(ctx);
} finally {
closeConnection();
}
}
}
Expand Up @@ -187,13 +187,11 @@ public R66FiniteDualStates getState() {
}

/**
* Debugging purpose
* Debugging purpose (trace)
*
* @param stat
*
* @deprecated used only for trace
*/
@Deprecated
public void setStatus(int stat) {
final StackTraceElement elt = Thread.currentThread().getStackTrace()[2];
status = '(' + elt.getFileName() + ':' + elt.getLineNumber() + "):" + stat;
Expand Down

0 comments on commit 8db9e59

Please sign in to comment.