HttpFormattedHandlerProxyR66.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.proxy.protocol.http;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.traffic.TrafficCounter;
import org.waarp.common.exception.FileTransferException;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.common.utility.ParametersChecker;
import org.waarp.common.utility.WaarpStringUtils;
import org.waarp.gateway.kernel.http.HttpWriteCacheEnable;
import org.waarp.openr66.context.R66Session;
import org.waarp.openr66.protocol.exception.OpenR66Exception;
import org.waarp.openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
import org.waarp.openr66.protocol.http.HttpFormattedHandler;
import java.io.IOException;
import java.util.Date;
import static org.waarp.openr66.protocol.configuration.Configuration.*;
/**
* Handler for HTTP information support
*/
public class HttpFormattedHandlerProxyR66 extends HttpFormattedHandler {
/**
* Internal Logger
*/
private static final WaarpLogger logger =
WaarpLoggerFactory.getLogger(HttpFormattedHandlerProxyR66.class);
private enum REQUEST {
index("index.html"), error("monitoring_header.html", "monitoring_end.html"),
statusxml("");
private static final String MONITOR = "monitor/";
private final String header;
private final String end;
/**
* Constructor for a unique file
*
* @param uniquefile
*/
REQUEST(final String uniquefile) {
header = uniquefile;
end = uniquefile;
}
/**
* @param header
* @param end
*/
REQUEST(final String header, final String end) {
this.header = header;
this.end = end;
}
/**
* Reader for a unique file
*
* @return the content of the unique file
*/
public final String readFileUnique(
final HttpFormattedHandlerProxyR66 handler) {
return handler.readFileHeaderInternal(
configuration.getHttpBasePath() + MONITOR + header);
}
public final String readHeader(final HttpFormattedHandlerProxyR66 handler) {
return handler.readFileHeaderInternal(
configuration.getHttpBasePath() + MONITOR + header);
}
public final String readEnd() {
return WaarpStringUtils.readFile(
configuration.getHttpBasePath() + MONITOR + end);
}
}
final R66Session authentHttp = new R66Session(false);
private String readFileHeaderInternal(final String filename) {
final String value;
try {
value = WaarpStringUtils.readFileException(filename);
} catch (final FileTransferException e) {
logger.error("Error while trying to read: " + filename + ": {}",
e.getMessage());
return "";
}
final StringBuilder builder = new StringBuilder(value);
WaarpStringUtils.replace(builder, REPLACEMENT.XXXDATEXXX.toString(),
new Date().toString());
WaarpStringUtils.replace(builder, REPLACEMENT.XXXLOCACTIVEXXX.toString(),
Integer.toString(
configuration.getLocalTransaction()
.getNumberLocalChannel()));
WaarpStringUtils.replace(builder, REPLACEMENT.XXXNETACTIVEXXX.toString(),
Integer.toString(
configuration.getLocalTransaction()
.getNumberLocalChannel()));
WaarpStringUtils.replace(builder, REPLACEMENT.XXXHOSTIDXXX.toString(),
configuration.getHostId());
final TrafficCounter trafficCounter =
configuration.getGlobalTrafficShapingHandler().trafficCounter();
WaarpStringUtils.replace(builder, REPLACEMENT.XXXBANDWIDTHXXX.toString(),
"IN:" +
trafficCounter.lastReadThroughput() / 131072 +
"Mbits OUT:" +
trafficCounter.lastWriteThroughput() / 131072 +
"Mbits");
WaarpStringUtils.replace(builder, REPLACEMENT.XXXLANGXXX.toString(), lang);
return builder.toString();
}
@Override
protected void channelRead0(final ChannelHandlerContext ctx,
final FullHttpRequest msg) {
isCurrentRequestXml = false;
isCurrentRequestJson = false;
status = HttpResponseStatus.OK;
final FullHttpRequest request = this.request = msg;
final QueryStringDecoder queryStringDecoder =
new QueryStringDecoder(request.uri());
uriRequest = queryStringDecoder.path();
logger.debug("Msg: {}", uriRequest);
if (uriRequest.contains("gre/") || uriRequest.contains("img/") ||
uriRequest.contains("res/") || uriRequest.contains("favicon.ico")) {
HttpWriteCacheEnable.writeFile(request, ctx,
configuration.getHttpBasePath() +
uriRequest, "XYZR66NOSESSION");
return;
}
char cval = 'z';
long nb = LIMITROW;
// check the URI
if ("/statusxml".equalsIgnoreCase(uriRequest)) {
cval = '5';
nb = 0; // since it could be the default or setup by request
isCurrentRequestXml = true;
} else if ("/statusjson".equalsIgnoreCase(uriRequest)) {
cval = '7';
nb = 0; // since it could be the default or setup by request
isCurrentRequestJson = true;
}
if (request.method() == HttpMethod.GET) {
params = queryStringDecoder.parameters();
}
final boolean getMenu = cval == 'z';
final boolean extraBoolean = false;
if (!params.isEmpty()) {
final String langarg = getTrimValue("setLng");
if (ParametersChecker.isNotEmpty(langarg)) {
lang = langarg;
}
}
if (getMenu) {
responseContent.append(REQUEST.index.readFileUnique(this));
} else {
// Use value 0=Active 1=Error 2=Done 3=All
switch (cval) {
case '5':
statusxml(ctx, nb, extraBoolean);
break;
case '7':
statusjson(ctx, nb, extraBoolean);
break;
default:
responseContent.append(REQUEST.index.readFileUnique(this));
}
}
writeResponse(ctx);
}
@Override
public void exceptionCaught(final ChannelHandlerContext ctx,
final Throwable cause) {
final OpenR66Exception exception =
OpenR66ExceptionTrappedFactory.getExceptionFromTrappedException(
ctx.channel(), cause);
if (exception != null) {
if (!(exception instanceof OpenR66ProtocolBusinessNoWriteBackException)) {
if (cause instanceof IOException) {
// Nothing to do
return;
}
logger.warn("Exception in HttpHandler {}", exception.getMessage());
}
if (ctx.channel().isActive()) {
sendError(ctx, HttpResponseStatus.BAD_REQUEST);
}
} else {
// Nothing to do
}
}
@Override
public void channelInactive(final ChannelHandlerContext ctx)
throws Exception {
super.channelInactive(ctx);
logger.debug("Closed");
}
@Override
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
logger.debug("Connected");
authentHttp.getAuth()
.specialNoSessionAuth(false, configuration.getHostId());
super.channelActive(ctx);
final ChannelGroup group = configuration.getHttpChannelGroup();
if (group != null) {
group.add(ctx.channel());
}
}
}