View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.protocol.http.adminssl;
22  
23  import goldengate.common.database.DbAdmin;
24  import goldengate.common.database.DbPreparedStatement;
25  import goldengate.common.database.DbSession;
26  import goldengate.common.database.exception.GoldenGateDatabaseException;
27  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
28  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
29  import goldengate.common.exception.FileTransferException;
30  import goldengate.common.exception.InvalidArgumentException;
31  import goldengate.common.logging.GgInternalLogger;
32  import goldengate.common.logging.GgInternalLoggerFactory;
33  import goldengate.common.utility.GgStringUtils;
34  
35  import java.io.IOException;
36  import java.net.SocketAddress;
37  import java.sql.Timestamp;
38  import java.util.Arrays;
39  import java.util.List;
40  import java.util.Map;
41  import java.util.Random;
42  import java.util.Set;
43  import java.util.concurrent.ConcurrentHashMap;
44  
45  import openr66.client.Message;
46  import openr66.configuration.AuthenticationFileBasedConfiguration;
47  import openr66.configuration.RuleFileBasedConfiguration;
48  import openr66.context.ErrorCode;
49  import openr66.context.R66FiniteDualStates;
50  import openr66.context.R66Result;
51  import openr66.context.R66Session;
52  import openr66.context.filesystem.R66Dir;
53  import openr66.database.DbConstant;
54  import openr66.database.data.DbHostAuth;
55  import openr66.database.data.DbRule;
56  import openr66.database.data.DbTaskRunner;
57  import openr66.protocol.configuration.Configuration;
58  import openr66.protocol.exception.OpenR66Exception;
59  import openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
60  import openr66.protocol.exception.OpenR66ProtocolBusinessException;
61  import openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
62  import openr66.protocol.exception.OpenR66ProtocolSystemException;
63  import openr66.protocol.http.HttpWriteCacheEnable;
64  import openr66.protocol.localhandler.LocalChannelReference;
65  import openr66.protocol.localhandler.packet.ErrorPacket;
66  import openr66.protocol.localhandler.packet.RequestPacket;
67  import openr66.protocol.localhandler.packet.RequestPacket.TRANSFERMODE;
68  import openr66.protocol.localhandler.packet.TestPacket;
69  import openr66.protocol.networkhandler.NetworkTransaction;
70  import openr66.protocol.utils.ChannelUtils;
71  import openr66.protocol.utils.NbAndSpecialId;
72  import openr66.protocol.utils.R66Future;
73  import openr66.protocol.utils.TransferUtils;
74  import openr66.protocol.utils.Version;
75  
76  import org.jboss.netty.buffer.ChannelBuffer;
77  import org.jboss.netty.buffer.ChannelBuffers;
78  import org.jboss.netty.channel.Channel;
79  import org.jboss.netty.channel.ChannelFuture;
80  import org.jboss.netty.channel.ChannelFutureListener;
81  import org.jboss.netty.channel.ChannelHandlerContext;
82  import org.jboss.netty.channel.ChannelStateEvent;
83  import org.jboss.netty.channel.ExceptionEvent;
84  import org.jboss.netty.channel.MessageEvent;
85  import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
86  import org.jboss.netty.channel.group.ChannelGroup;
87  import org.jboss.netty.handler.codec.http.Cookie;
88  import org.jboss.netty.handler.codec.http.CookieDecoder;
89  import org.jboss.netty.handler.codec.http.CookieEncoder;
90  import org.jboss.netty.handler.codec.http.DefaultCookie;
91  import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
92  import org.jboss.netty.handler.codec.http.HttpHeaders;
93  import org.jboss.netty.handler.codec.http.HttpMethod;
94  import org.jboss.netty.handler.codec.http.HttpRequest;
95  import org.jboss.netty.handler.codec.http.HttpResponse;
96  import org.jboss.netty.handler.codec.http.HttpResponseStatus;
97  import org.jboss.netty.handler.codec.http.HttpVersion;
98  import org.jboss.netty.handler.codec.http.QueryStringDecoder;
99  import org.jboss.netty.handler.ssl.SslHandler;
100 import org.jboss.netty.handler.traffic.TrafficCounter;
101 
102 /**
103  * @author Frederic Bregier
104  *
105  */
106 public class HttpSslHandler extends SimpleChannelUpstreamHandler {
107     /**
108      * Internal Logger
109      */
110     private static final GgInternalLogger logger = GgInternalLoggerFactory
111             .getLogger(HttpSslHandler.class);
112     /**
113      * Waiter for SSL handshake is finished
114      */
115     private static final ConcurrentHashMap<Integer, R66Future> waitForSsl
116         = new ConcurrentHashMap<Integer, R66Future>();
117     /**
118      * Session Management
119      */
120     private static final ConcurrentHashMap<String, R66Session> sessions
121         = new ConcurrentHashMap<String, R66Session>();
122     private static final ConcurrentHashMap<String, DbSession> dbSessions
123         = new ConcurrentHashMap<String, DbSession>();
124     private volatile R66Session authentHttp = new R66Session();
125 
126     private volatile HttpRequest request;
127     private volatile boolean newSession = false;
128     private volatile Cookie admin = null;
129     private final StringBuilder responseContent = new StringBuilder();
130     private volatile String uriRequest;
131     private volatile Map<String, List<String>> params;
132     private volatile QueryStringDecoder queryStringDecoder;
133     private volatile boolean forceClose = false;
134     private volatile boolean shutdown = false;
135 
136     private static final String R66SESSION = "R66SESSION";
137     private static enum REQUEST {
138         Logon("Logon.html"), 
139         index("index.html"),
140         error("error.html"),
141         Transfers("Transfers.html"), 
142         Listing("Listing_head.html","Listing_body0.html","Listing_body.html","Listing_body1.html","Listing_end.html"), 
143         CancelRestart("CancelRestart_head.html","CancelRestart_body0.html","CancelRestart_body.html","CancelRestart_body1.html","CancelRestart_end.html"), 
144         Export("Export.html"),
145         Hosts("Hosts_head.html","Hosts_body0.html","Hosts_body.html","Hosts_body1.html","Hosts_end.html"), 
146         Rules("Rules_head.html","Rules_body0.html","Rules_body.html","Rules_body1.html","Rules_end.html"), 
147         System("System.html");
148         
149         private String header;
150         private String headerBody;
151         private String body;
152         private String endBody;
153         private String end;
154         /**
155          * Constructor for a unique file
156          * @param uniquefile
157          */
158         private REQUEST(String uniquefile) {
159             this.header = uniquefile;
160             this.headerBody = null;
161             this.body = null;
162             this.endBody = null;
163             this.end = null;
164         }
165         /**
166          * @param header
167          * @param headerBody
168          * @param body
169          * @param endBody
170          * @param end
171          */
172         private REQUEST(String header, String headerBody, String body,
173                 String endBody, String end) {
174             this.header = header;
175             this.headerBody = headerBody;
176             this.body = body;
177             this.endBody = endBody;
178             this.end = end;
179         }
180         
181         /**
182          * Reader for a unique file
183          * @return the content of the unique file
184          */
185         public String readFileUnique(HttpSslHandler handler) {
186             return handler.readFileHeader(Configuration.configuration.httpBasePath+this.header);
187         }
188         
189         public String readHeader(HttpSslHandler handler) {
190             return handler.readFileHeader(Configuration.configuration.httpBasePath+this.header);
191         }
192         public String readBodyHeader() {
193             return GgStringUtils.readFile(Configuration.configuration.httpBasePath+this.headerBody);
194         }
195         public String readBody() {
196             return GgStringUtils.readFile(Configuration.configuration.httpBasePath+this.body);
197         }
198         public String readBodyEnd() {
199             return GgStringUtils.readFile(Configuration.configuration.httpBasePath+this.endBody);
200         }
201         public String readEnd() {
202             return GgStringUtils.readFile(Configuration.configuration.httpBasePath+this.end);
203         }
204     }
205     
206     private static enum REPLACEMENT {
207         XXXHOSTIDXXX, XXXADMINXXX, XXXVERSIONXXX, XXXBANDWIDTHXXX,
208         XXXXSESSIONLIMITRXXX, XXXXSESSIONLIMITWXXX,
209         XXXXCHANNELLIMITRXXX, XXXXCHANNELLIMITWXXX,
210         XXXXDELAYCOMMDXXX, XXXXDELAYRETRYXXX,
211         XXXLOCALXXX, XXXNETWORKXXX,
212         XXXERRORMESGXXX;
213     }
214     public static final int LIMITROW = 48;// better if it can be divided by 4
215 
216     /**
217      * The Database connection attached to this NetworkChannel
218      * shared among all associated LocalChannels in the session
219      */
220     private volatile DbSession dbSession = null;
221     /**
222      * Does this dbSession is private and so should be closed
223      */
224     private volatile boolean isPrivateDbSession = false;
225 
226     /**
227      * Remover from SSL HashMap
228      */
229     private static final ChannelFutureListener remover = new ChannelFutureListener() {
230         public void operationComplete(ChannelFuture future) {
231             logger.debug("SSL remover");
232             waitForSsl.remove(future.getChannel().getId());
233         }
234     };
235 
236     private String readFileHeader(String filename) {
237         String value;
238         try {
239             value = GgStringUtils.readFileException(filename);
240         } catch (InvalidArgumentException e) {
241             logger.error("Error while trying to open: "+filename,e);
242             return "";
243         } catch (FileTransferException e) {
244             logger.error("Error while trying to read: "+filename,e);
245             return "";
246         }
247         StringBuilder builder = new StringBuilder(value);
248         GgStringUtils.replace(builder, REPLACEMENT.XXXLOCALXXX.toString(),
249                 Integer.toString(
250                         Configuration.configuration.getLocalTransaction().
251                         getNumberLocalChannel())+" "+Thread.activeCount());
252         GgStringUtils.replace(builder, REPLACEMENT.XXXNETWORKXXX.toString(),
253                 Integer.toString(
254                         DbAdmin.getNbConnection()));
255         GgStringUtils.replace(builder, REPLACEMENT.XXXHOSTIDXXX.toString(),
256                 Configuration.configuration.HOST_ID);
257         if (authentHttp.isAuthenticated()) {
258             GgStringUtils.replace(builder, REPLACEMENT.XXXADMINXXX.toString(),
259                 "Connected");
260         } else {
261             GgStringUtils.replace(builder, REPLACEMENT.XXXADMINXXX.toString(),
262                     "Not authenticated");
263         }
264         TrafficCounter trafficCounter =
265             Configuration.configuration.getGlobalTrafficShapingHandler().getTrafficCounter();
266         GgStringUtils.replace(builder, REPLACEMENT.XXXBANDWIDTHXXX.toString(),
267                 "IN:"+(trafficCounter.getLastReadThroughput()>>17)+
268                 "Mbits&nbsp;<br>&nbsp;OUT:"+
269                 (trafficCounter.getLastWriteThroughput()>>17)+"Mbits");
270         return builder.toString();
271     }
272 
273     private String getTrimValue(String varname) {
274         String value = params.get(varname).get(0).trim();
275         if (value.length() == 0) {
276             value = null;
277         }
278         return value;
279     }
280     private String getValue(String varname) {
281         return params.get(varname).get(0);
282     }
283     /**
284      * Add the Channel as SSL handshake is over
285      * @param channel
286      */
287     private static void addSslConnectedChannel(Channel channel) {
288         R66Future futureSSL = new R66Future(true);
289         waitForSsl.put(channel.getId(),futureSSL);
290         channel.getCloseFuture().addListener(remover);
291     }
292     /**
293      * Set the future of SSL handshake to status
294      * @param channel
295      * @param status
296      */
297     private static void setStatusSslConnectedChannel(Channel channel, boolean status) {
298         R66Future futureSSL = waitForSsl.get(channel.getId());
299         if (futureSSL != null) {
300             if (status) {
301                 futureSSL.setSuccess();
302             } else {
303                 futureSSL.cancel();
304             }
305         }
306     }
307 
308     /* (non-Javadoc)
309      * @see org.jboss.netty.channel.SimpleChannelUpstreamHandler#channelOpen(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent)
310      */
311     @Override
312     public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
313             throws Exception {
314         Channel channel = e.getChannel();
315         logger.debug("Add channel to ssl");
316         addSslConnectedChannel(channel);
317         Configuration.configuration.getHttpChannelGroup().add(channel);
318         super.channelOpen(ctx, e);
319     }
320 
321     
322 
323     private String index() {
324         String index = REQUEST.index.readFileUnique(this);
325         StringBuilder builder = new StringBuilder(index);
326         GgStringUtils.replaceAll(builder, REPLACEMENT.XXXHOSTIDXXX.toString(),
327                 Configuration.configuration.HOST_ID);
328         GgStringUtils.replaceAll(builder, REPLACEMENT.XXXADMINXXX.toString(),
329                 "Administrator Connected");
330         GgStringUtils.replace(builder, REPLACEMENT.XXXVERSIONXXX.toString(),
331                 Version.ID);
332         return builder.toString();
333     }
334     private String error(String mesg) {
335         String index = REQUEST.error.readFileUnique(this);
336         return index.replaceAll(REPLACEMENT.XXXERRORMESGXXX.toString(),
337                 mesg);
338     }
339     private String Logon() {
340         return REQUEST.Logon.readFileUnique(this);
341     }
342     private String Transfers() {
343         return REQUEST.Transfers.readFileUnique(this);
344     }
345 
346     private String resetOptionTransfer(String header, String startid, String stopid,
347             String start, String stop, String rule, String req,
348             boolean pending, boolean transfer, boolean error, boolean done, boolean all) {
349         StringBuilder builder = new StringBuilder(header);
350         GgStringUtils.replace(builder, "XXXSTARTIDXXX", startid);
351         GgStringUtils.replace(builder, "XXXSTOPIDXXX", stopid);
352         GgStringUtils.replace(builder, "XXXSTARTXXX", start);
353         GgStringUtils.replace(builder, "XXXSTOPXXX", stop);
354         GgStringUtils.replace(builder, "XXXRULEXXX", rule);
355         GgStringUtils.replace(builder, "XXXREQXXX", req);
356         GgStringUtils.replace(builder, "XXXPENDXXX", pending ? "checked":"");
357         GgStringUtils.replace(builder, "XXXTRANSXXX", transfer ? "checked":"");
358         GgStringUtils.replace(builder, "XXXERRXXX", error ? "checked":"");
359         GgStringUtils.replace(builder, "XXXDONEXXX", done ? "checked":"");
360         GgStringUtils.replace(builder, "XXXALLXXX", all ? "checked":"");
361         return builder.toString();
362     }
363     private String Listing() {
364         getParams();
365         if (params == null) {
366             String head = REQUEST.Listing.readHeader(this);
367             head = resetOptionTransfer(head, "", "", "", "", "", "",
368                     false, false, false, false, true);
369             String end = REQUEST.Listing.readEnd();
370             return head+end;
371         }
372         String head = REQUEST.Listing.readHeader(this);
373         String body0, body, body1;
374         body0 = body1 = body = "";
375         List<String> parms = params.get("ACTION");
376         if (parms != null) {
377             body0 = REQUEST.Listing.readBodyHeader();
378             String parm = parms.get(0);
379             if ("Filter".equalsIgnoreCase(parm)) {
380                 String startid = getTrimValue("startid");
381                 String stopid = getTrimValue("stopid");
382                 if (startid != null && stopid == null) {
383                     stopid = Long.toString(Long.parseLong(startid)+(LIMITROW/2));
384                 }
385                 if (stopid != null && startid == null) {
386                     startid = Long.toString(Long.parseLong(stopid)-(LIMITROW/2));
387                 }
388                 String start = getValue("start");
389                 String stop = getValue("stop");
390                 String rule = getTrimValue("rule");
391                 String req = getTrimValue("req");
392                 boolean pending, transfer, error, done, all;
393                 pending = params.containsKey("pending");
394                 transfer = params.containsKey("transfer");
395                 error = params.containsKey("error");
396                 done = params.containsKey("done");
397                 all = params.containsKey("all");
398                 if (pending && transfer && error && done) {
399                     all = true;
400                 } else if (!(pending || transfer || error || done)) {
401                     all = true;
402                 }
403                 Timestamp tstart = GgStringUtils.fixDate(start);
404                 if (tstart != null) {
405                     start = tstart.toString();
406                 }
407                 Timestamp tstop = GgStringUtils.fixDate(stop, tstart);
408                 if (tstop != null) {
409                     stop = tstop.toString();
410                 }
411                 head = resetOptionTransfer(head, startid == null ? "":startid,
412                         stopid == null ? "":stopid, start, stop,
413                         rule == null ? "":rule, req == null ? "":req,
414                         pending, transfer, error, done, all);
415                 body = REQUEST.Listing.readBody();
416                 DbPreparedStatement preparedStatement = null;
417                 try {
418                     preparedStatement =
419                         DbTaskRunner.getFilterPrepareStatement(dbSession, LIMITROW, false,
420                                 startid, stopid, tstart, tstop, rule, req,
421                                 pending, transfer, error, done, all);
422                     preparedStatement.executeQuery();
423                     StringBuilder builder = new StringBuilder();
424                     int i = 0;
425                     while (preparedStatement.getNext()) {
426                         try {
427                             i++;
428                             DbTaskRunner taskRunner = DbTaskRunner.getFromStatement(preparedStatement);
429                             LocalChannelReference lcr =
430                                 Configuration.configuration.getLocalTransaction().
431                                 getFromRequest(taskRunner.getKey());
432                             builder.append(taskRunner.toSpecializedHtml(authentHttp, body,
433                                     lcr != null ? "Active" : "NotActive"));
434                             if (i > LIMITROW) {
435                                 break;
436                             }
437                         } catch (GoldenGateDatabaseException e) {
438                             // try to continue if possible
439                             logger.warn("An error occurs while accessing a Runner: {}",
440                                     e.getMessage());
441                             continue;
442                         }
443                     }
444                     preparedStatement.realClose();
445                     body = builder.toString();
446                 } catch (GoldenGateDatabaseException e) {
447                     if (preparedStatement != null) {
448                         preparedStatement.realClose();
449                     }
450                     logger.warn("OpenR66 Web Error {}",e.getMessage());
451                 }
452             } else {
453                 head = resetOptionTransfer(head, "", "", "", "", "", "",
454                         false, false, false, false, true);
455             }
456             body1 = REQUEST.Listing.readBodyEnd();
457         } else {
458             head = resetOptionTransfer(head, "", "", "", "", "", "",
459                     false, false, false, false, true);
460         }
461         String end;
462         end = REQUEST.Listing.readEnd();
463         return head+body0+body+body1+end;
464     }
465 
466     private String CancelRestart() {
467         getParams();
468         if (params == null) {
469             String head = REQUEST.CancelRestart.readHeader(this);
470             head = resetOptionTransfer(head, "", "", "", "", "", "",
471                     false, false, false, false, true);
472             String end;
473             end = REQUEST.CancelRestart.readEnd();
474             return head+end;
475         }
476         String head = REQUEST.CancelRestart.readHeader(this);
477         String body0, body, body1;
478         body0 = body1 = body = "";
479         List<String> parms = params.get("ACTION");
480         if (parms != null) {
481             body0 = REQUEST.CancelRestart.readBodyHeader();
482             String parm = parms.get(0);
483             if ("Filter".equalsIgnoreCase(parm)) {
484                 String startid = getTrimValue("startid");
485                 String stopid = getTrimValue("stopid");
486                 if (startid != null && stopid == null) {
487                     stopid = Long.toString(Long.parseLong(startid)+(LIMITROW/2));
488                 }
489                 if (stopid != null && startid == null) {
490                     startid = Long.toString(Long.parseLong(stopid)-(LIMITROW/2));
491                 }
492                 String start = getValue("start");
493                 String stop = getValue("stop");
494                 String rule = getTrimValue("rule");
495                 String req = getTrimValue("req");
496                 boolean pending, transfer, error, done, all;
497                 pending = params.containsKey("pending");
498                 transfer = params.containsKey("transfer");
499                 error = params.containsKey("error");
500                 done = params.containsKey("done");
501                 all = params.containsKey("all");
502                 if (pending && transfer && error && done) {
503                     all = true;
504                 } else if (!(pending || transfer || error || done)) {
505                     all = true;
506                 }
507                 Timestamp tstart = GgStringUtils.fixDate(start);
508                 if (tstart != null) {
509                     start = tstart.toString();
510                 }
511                 Timestamp tstop = GgStringUtils.fixDate(stop, tstart);
512                 if (tstop != null) {
513                     stop = tstop.toString();
514                 }
515                 head = resetOptionTransfer(head, startid == null ? "":startid,
516                         stopid == null ? "":stopid, start, stop,
517                         rule == null ? "":rule, req == null ? "":req,
518                         pending, transfer, error, done, all);
519                 body = REQUEST.CancelRestart.readBody();
520                 DbPreparedStatement preparedStatement = null;
521                 try {
522                     preparedStatement =
523                         DbTaskRunner.getFilterPrepareStatement(dbSession, LIMITROW, false,
524                                 startid, stopid, tstart, tstop, rule, req,
525                                 pending, transfer, error, done, all);
526                     preparedStatement.executeQuery();
527                     StringBuilder builder = new StringBuilder();
528                     int i = 0;
529                     while (preparedStatement.getNext()) {
530                         try {
531                             i++;
532                             DbTaskRunner taskRunner = DbTaskRunner.getFromStatement(preparedStatement);
533                             LocalChannelReference lcr =
534                                 Configuration.configuration.getLocalTransaction().
535                                 getFromRequest(taskRunner.getKey());
536                             builder.append(taskRunner.toSpecializedHtml(authentHttp, body,
537                                     lcr != null ? "Active" : "NotActive"));
538                             if (i > LIMITROW) {
539                                 break;
540                             }
541                         } catch (GoldenGateDatabaseException e) {
542                             // try to continue if possible
543                             logger.warn("An error occurs while accessing a Runner: {}",
544                                     e.getMessage());
545                             continue;
546                         }
547                     }
548                     preparedStatement.realClose();
549                     body = builder.toString();
550                 } catch (GoldenGateDatabaseException e) {
551                     if (preparedStatement != null) {
552                         preparedStatement.realClose();
553                     }
554                     logger.warn("OpenR66 Web Error {}",e.getMessage());
555                 }
556                 body1 = REQUEST.CancelRestart.readBodyEnd();
557             } else if ("RestartAll".equalsIgnoreCase(parm) ||
558                     "StopAll".equalsIgnoreCase(parm)) {
559                 boolean stopcommand = "StopAll".equalsIgnoreCase(parm);
560                 String startid = getTrimValue("startid");
561                 String stopid = getTrimValue("stopid");
562                 String start = getValue("start");
563                 String stop = getValue("stop");
564                 String rule = getTrimValue("rule");
565                 String req = getTrimValue("req");
566                 boolean pending, transfer, error, done, all;
567                 pending = params.containsKey("pending");
568                 transfer = params.containsKey("transfer");
569                 error = params.containsKey("error");
570                 done = false;
571                 all = false;
572                 if (pending && transfer && error && done) {
573                     all = true;
574                 } else if (!(pending || transfer || error || done)) {
575                     all = true;
576                     pending = true;
577                     transfer = true;
578                     error = true;
579                 }
580                 Timestamp tstart = GgStringUtils.fixDate(start);
581                 if (tstart != null) {
582                     start = tstart.toString();
583                 }
584                 Timestamp tstop = GgStringUtils.fixDate(stop, tstart);
585                 if (tstop != null) {
586                     stop = tstop.toString();
587                 }
588                 head = resetOptionTransfer(head, startid == null ? "":startid,
589                         stopid == null ? "":stopid, start, stop,
590                         rule == null ? "":rule, req == null ? "":req,
591                         pending, transfer, error, done, all);
592                 body = REQUEST.CancelRestart.readBody();
593                 StringBuilder builder = new StringBuilder();
594                 if (stopcommand) {
595                     builder = TransferUtils.stopSelectedTransfers(dbSession, LIMITROW, builder,
596                             authentHttp, body, startid, stopid, tstart, tstop, rule, req,
597                             pending, transfer, error);
598                 } else {
599                     DbPreparedStatement preparedStatement = null;
600                     try {
601                         preparedStatement =
602                             DbTaskRunner.getFilterPrepareStatement(dbSession, LIMITROW, false,
603                                     startid, stopid, tstart, tstop, rule, req,
604                                     pending, transfer, error, done, all);
605                         preparedStatement.executeQuery();
606                         int i = 0;
607                         while (preparedStatement.getNext()) {
608                             try {
609                                 i++;
610                                 DbTaskRunner taskRunner = DbTaskRunner.getFromStatement(preparedStatement);
611                                 LocalChannelReference lcr =
612                                     Configuration.configuration.getLocalTransaction().
613                                     getFromRequest(taskRunner.getKey());
614                                 R66Result finalResult = TransferUtils.restartTransfer(taskRunner, lcr);
615                                 ErrorCode result = finalResult.code;
616                                 ErrorCode last = taskRunner.getErrorInfo();
617                                 taskRunner.setErrorExecutionStatus(result);
618                                 builder.append(taskRunner.toSpecializedHtml(authentHttp, body,
619                                         lcr != null ? "Active" : "NotActive"));
620                                 taskRunner.setErrorExecutionStatus(last);
621                                 if (i > LIMITROW) {
622                                     break;
623                                 }
624                             } catch (GoldenGateDatabaseException e) {
625                                 // try to continue if possible
626                                 logger.warn("An error occurs while accessing a Runner: {}",
627                                         e.getMessage());
628                                 continue;
629                             }                        }
630                         preparedStatement.realClose();
631                     } catch (GoldenGateDatabaseException e) {
632                         if (preparedStatement != null) {
633                             preparedStatement.realClose();
634                         }
635                         logger.warn("OpenR66 Web Error {}",e.getMessage());
636                     }
637                 }
638                 if (builder != null) {
639                     body = builder.toString();
640                 } else {
641                     body = "";
642                 }
643                 body1 = REQUEST.CancelRestart.readBodyEnd();
644             } else if ("Cancel".equalsIgnoreCase(parm) || "Stop".equalsIgnoreCase(parm)) {
645                 // Cancel or Stop
646                 boolean stop = "Stop".equalsIgnoreCase(parm);
647                 String specid = getValue("specid");
648                 String reqd = getValue("reqd");
649                 String reqr = getValue("reqr");
650                 LocalChannelReference lcr =
651                     Configuration.configuration.getLocalTransaction().
652                     getFromRequest(reqd+" "+reqr+" "+specid);
653                 // stop the current transfer
654                 ErrorCode result;
655                 long lspecid = Long.parseLong(specid);
656                 DbTaskRunner taskRunner = null;
657                 try {
658                     taskRunner = new DbTaskRunner(dbSession, authentHttp, null,
659                             lspecid, reqr, reqd);
660                 } catch (GoldenGateDatabaseException e) {
661                 }
662                 if (taskRunner == null) {
663                     body = "";
664                     body1 = REQUEST.CancelRestart.readBodyEnd();
665                     body1 += "<br><b>"+parm+" aborted since Transfer is not found</b>";
666                     String end;
667                     end = REQUEST.CancelRestart.readEnd();
668                     return head+body0+body+body1+end;
669                 }
670                 ErrorCode code = (stop) ?
671                         ErrorCode.StoppedTransfer : ErrorCode.CanceledTransfer;
672                 if (lcr != null) {
673                     int rank = taskRunner.getRank();
674                     lcr.sessionNewState(R66FiniteDualStates.ERROR);
675                     ErrorPacket error = new ErrorPacket("Transfer "+parm+" "+rank,
676                             code.getCode(), ErrorPacket.FORWARDCLOSECODE);
677                     try {
678                         //XXX ChannelUtils.writeAbstractLocalPacket(lcr, error);
679                         // inform local instead of remote
680                         ChannelUtils.writeAbstractLocalPacketToLocal(lcr, error);
681                     } catch (Exception e) {
682                     }
683                     result = ErrorCode.CompleteOk;
684                 } else {
685                     // Transfer is not running
686                     // But is the database saying the contrary
687                     result = ErrorCode.TransferOk;
688                     if (taskRunner != null) {
689                         if (taskRunner.stopOrCancelRunner(code)) {
690                             result = ErrorCode.CompleteOk;
691                         }
692                     }
693                 }
694                 if (taskRunner != null) {
695                     body = REQUEST.CancelRestart.readBody();
696                     body = taskRunner.toSpecializedHtml(authentHttp, body,
697                             lcr != null ? "Active" : "NotActive");
698                     String tstart = taskRunner.getStart().toString();
699                     tstart = tstart.substring(0, tstart.length());
700                     String tstop = taskRunner.getStop().toString();
701                     tstop = tstop.substring(0, tstop.length());
702                     head = resetOptionTransfer(head, (taskRunner.getSpecialId()-1)+"",
703                             (taskRunner.getSpecialId()+1)+"", tstart, tstop,
704                             taskRunner.getRuleId(), taskRunner.getRequested(),
705                             false, false, false, false, true);
706                 }
707                 body1 = REQUEST.CancelRestart.readBodyEnd();
708                 body1 += "<br><b>"+(result == ErrorCode.CompleteOk ? parm+" transmitted":
709                     parm+" aborted since Transfer is not running")+"</b>";
710             } else if ("Restart".equalsIgnoreCase(parm)) {
711                 // Restart
712                 String specid = getValue("specid");
713                 String reqd = getValue("reqd");
714                 String reqr = getValue("reqr");
715                 long lspecid = Long.parseLong(specid);
716                 DbTaskRunner taskRunner;
717                 String comment;
718                 try {
719                     taskRunner = new DbTaskRunner(dbSession, authentHttp, null,
720                             lspecid, reqr, reqd);
721                     LocalChannelReference lcr =
722                         Configuration.configuration.getLocalTransaction().
723                         getFromRequest(taskRunner.getKey());
724                     R66Result finalResult = TransferUtils.restartTransfer(taskRunner, lcr);
725                     comment = (String) finalResult.other;
726                     body = REQUEST.CancelRestart.readBody();
727                     body = taskRunner.toSpecializedHtml(authentHttp, body,
728                             lcr != null ? "Active" : "NotActive");
729                     String tstart = taskRunner.getStart().toString();
730                     tstart = tstart.substring(0, tstart.length());
731                     String tstop = taskRunner.getStop().toString();
732                     tstop = tstop.substring(0, tstop.length());
733                     head = resetOptionTransfer(head, (taskRunner.getSpecialId()-1)+"",
734                             (taskRunner.getSpecialId()+1)+"", tstart, tstop,
735                             taskRunner.getRuleId(), taskRunner.getRequested(),
736                             false, false, false, false, true);
737                 } catch (GoldenGateDatabaseException e) {
738                     body = "";
739                     comment = "Internal error";
740                 }
741                 body1 = REQUEST.CancelRestart.readBodyEnd();
742                 body1 += "<br><b>"+comment+"</b>";
743             } else {
744                 head = resetOptionTransfer(head, "", "", "", "", "", "",
745                         false, false, false, false, true);
746             }
747         } else {
748             head = resetOptionTransfer(head, "", "", "", "", "", "",
749                     false, false, false, false, true);
750         }
751         String end;
752         end = REQUEST.CancelRestart.readEnd();
753         return head+body0+body+body1+end;
754     }
755     private String Export() {
756         getParams();
757         if (params == null) {
758             String body = REQUEST.Export.readFileUnique(this);
759             body = resetOptionTransfer(body, "", "", "", "", "", "",
760                     false, false, false, true, false);
761             return body.replace("XXXRESULTXXX", "");
762         }
763         String body = REQUEST.Export.readFileUnique(this);
764         String start = getValue("start");
765         String stop = getValue("stop");
766         String rule = getTrimValue("rule");
767         String req = getTrimValue("req");
768         boolean pending, transfer, error, done, all;
769         pending = params.containsKey("pending");
770         transfer = params.containsKey("transfer");
771         error = params.containsKey("error");
772         done = params.containsKey("done");
773         all = params.containsKey("all");
774         boolean toPurge = params.containsKey("purge");
775         if (toPurge) {
776             transfer = false;
777         }
778         if (pending && transfer && error && done) {
779             all = true;
780         } else if (!(pending || transfer || error || done)) {
781             all = true;
782         }
783         Timestamp tstart = GgStringUtils.fixDate(start);
784         if (tstart != null) {
785             start = tstart.toString();
786         }
787         Timestamp tstop = GgStringUtils.fixDate(stop, tstart);
788         if (tstop != null) {
789             stop = tstop.toString();
790         }
791         body = resetOptionTransfer(body, "", "", start, stop,
792                 rule == null ? "":rule, req == null ? "":req,
793                 pending, transfer, error, done, all);
794         boolean isexported = true;
795         // clean a bit the database before exporting
796         try {
797             DbTaskRunner.changeFinishedToDone(dbSession);
798         } catch (GoldenGateDatabaseNoConnectionException e2) {
799             // should not be
800         }
801         // create export of log and optionally purge them from database
802         DbPreparedStatement getValid = null;
803         NbAndSpecialId nbAndSpecialId = null;
804         String filename = Configuration.configuration.baseDirectory+
805             Configuration.configuration.archivePath+R66Dir.SEPARATOR+
806             Configuration.configuration.HOST_ID+"_"+System.currentTimeMillis()+
807             "_runners.xml";
808         try {
809             getValid =
810                 DbTaskRunner.getFilterPrepareStatement(dbSession, 0,// 0 means no limit
811                         true, null, null, tstart, tstop, rule, req,
812                         pending, transfer, error, done, all);
813             nbAndSpecialId = DbTaskRunner.writeXMLWriter(getValid, filename);
814         } catch (GoldenGateDatabaseNoConnectionException e1) {
815             isexported = false;
816             toPurge = false;
817         } catch (GoldenGateDatabaseSqlException e1) {
818             isexported = false;
819             toPurge = false;
820         } catch (OpenR66ProtocolBusinessException e) {
821             isexported = false;
822             toPurge = false;
823         } finally {
824             if (getValid != null) {
825                 getValid.realClose();
826             }
827         }
828         int purge = 0;
829         if (isexported && nbAndSpecialId != null) {
830             if (nbAndSpecialId.nb <= 0) {
831                 return body.replace("XXXRESULTXXX",
832                         "Export unsuccessful since no records were found");
833             }
834             // in case of purge
835             if (isexported && toPurge) {
836                 // purge with same filter all runners where globallasttep
837                 // is ALLDONE or ERROR
838                 // but getting the higher Special first
839                 String stopId = Long.toString(nbAndSpecialId.higherSpecialId);
840                 try {
841                     purge =
842                         DbTaskRunner.purgeLogPrepareStatement(dbSession,
843                                 null,stopId, tstart, tstop, rule, req,
844                                 pending, transfer, error, done, all);
845                 } catch (GoldenGateDatabaseNoConnectionException e) {
846                 } catch (GoldenGateDatabaseSqlException e) {
847                 }
848             }
849         }
850         return body.replace("XXXRESULTXXX", "Export "+(isexported?"successful into "+
851                 filename+" with "+nbAndSpecialId.nb+" exported and "+purge+" purged records":
852                     "in error"));
853     }
854     private String resetOptionHosts(String header,
855             String host, String addr, boolean ssl) {
856         StringBuilder builder = new StringBuilder(header);
857         GgStringUtils.replace(builder, "XXXFHOSTXXX", host);
858         GgStringUtils.replace(builder, "XXXFADDRXXX", addr);
859         GgStringUtils.replace(builder, "XXXFSSLXXX", ssl ? "checked":"");
860         return builder.toString();
861     }
862     private String Hosts() {
863         getParams();
864         String head = REQUEST.Hosts.readHeader(this);
865         String end;
866         end = REQUEST.Hosts.readEnd();
867         if (params == null) {
868             head = resetOptionHosts(head, "", "", false);
869             return head+end;
870         }
871         String body0, body, body1;
872         body0 = body1 = body = "";
873         List<String> parms = params.get("ACTION");
874         if (parms != null) {
875             body0 = REQUEST.Hosts.readBodyHeader();
876             String parm = parms.get(0);
877             if ("Create".equalsIgnoreCase(parm)) {
878                 String host = getTrimValue("host");
879                 String addr = getTrimValue("address");
880                 String port = getTrimValue("port");
881                 String key = getTrimValue("hostkey");
882                 boolean ssl, admin, isclient;
883                 ssl = params.containsKey("ssl");
884                 admin = params.containsKey("admin");
885                 isclient = params.containsKey("isclient");
886                 if (host == null || addr == null || port == null || key == null) {
887                     body0 = body1 = body = "";
888                     body = "<p><center><b>Not enough data to create a Host</b></center></p>";
889                     head = resetOptionHosts(head, "", "", false);
890                     return head+body0+body+body1+end;
891                 }
892                 head = resetOptionHosts(head, host, addr, ssl);
893                 int iport = Integer.parseInt(port);
894                 DbHostAuth dbhost = new DbHostAuth(dbSession, host, addr, iport,
895                         ssl, key.getBytes(), admin, isclient);
896                 try {
897                     dbhost.insert();
898                 } catch (GoldenGateDatabaseException e) {
899                     body0 = body1 = body = "";
900                     body = "<p><center><b>Cannot create a Host: "+e.getMessage()+"</b></center></p>";
901                     head = resetOptionHosts(head, "", "", false);
902                     return head+body0+body+body1+end;
903                 }
904                 body = REQUEST.Hosts.readBody();
905                 body = dbhost.toSpecializedHtml(authentHttp, body, false);
906             } else if ("Filter".equalsIgnoreCase(parm)) {
907                 String host = getTrimValue("host");
908                 String addr = getTrimValue("address");
909                 boolean ssl = params.containsKey("ssl");
910                 head = resetOptionHosts(head, host == null ? "":host,
911                         addr == null ? "":addr, ssl);
912                 body = REQUEST.Hosts.readBody();
913                 DbPreparedStatement preparedStatement = null;
914                 try {
915                     preparedStatement =
916                         DbHostAuth.getFilterPrepareStament(dbSession,
917                                 host, addr, ssl);
918                     preparedStatement.executeQuery();
919                     StringBuilder builder = new StringBuilder();
920                     int i = 0;
921                     while (preparedStatement.getNext()) {
922                         i++;
923                         DbHostAuth dbhost = DbHostAuth.getFromStatement(preparedStatement);
924                         builder.append(dbhost.toSpecializedHtml(authentHttp, body, false));
925                         if (i > LIMITROW) {
926                             break;
927                         }
928                     }
929                     preparedStatement.realClose();
930                     body = builder.toString();
931                 } catch (GoldenGateDatabaseException e) {
932                     if (preparedStatement != null) {
933                         preparedStatement.realClose();
934                     }
935                     logger.warn("OpenR66 Web Error {}",e.getMessage());
936                 }
937                 body1 = REQUEST.Hosts.readBodyEnd();
938             } else if ("Update".equalsIgnoreCase(parm)) {
939                 String host = getTrimValue("host");
940                 String addr = getTrimValue("address");
941                 String port = getTrimValue("port");
942                 String key = getTrimValue("hostkey");
943                 boolean ssl, admin, isclient;
944                 ssl = params.containsKey("ssl");
945                 admin = params.containsKey("admin");
946                 isclient = params.containsKey("isclient");
947                 if (host == null || addr == null || port == null || key == null) {
948                     body0 = body1 = body = "";
949                     body = "<p><center><b>Not enough data to update a Host</b></center></p>";
950                     head = resetOptionHosts(head, "", "", false);
951                     return head+body0+body+body1+end;
952                 }
953                 head = resetOptionHosts(head, host, addr, ssl);
954                 int iport = Integer.parseInt(port);
955                 DbHostAuth dbhost = new DbHostAuth(dbSession, host, addr, iport,
956                         ssl, key.getBytes(), admin, isclient);
957                 try {
958                     if (dbhost.exist()) {
959                         dbhost.update();
960                     } else {
961                         dbhost.insert();
962                     }
963                 } catch (GoldenGateDatabaseException e) {
964                     body0 = body1 = body = "";
965                     body = "<p><center><b>Cannot update a Host: "+e.getMessage()+"</b></center></p>";
966                     head = resetOptionHosts(head, "", "", false);
967                     return head+body0+body+body1+end;
968                 }
969                 body = REQUEST.Hosts.readBody();
970                 body = dbhost.toSpecializedHtml(authentHttp, body, false);
971             } else if ("TestConn".equalsIgnoreCase(parm)) {
972                 String host = getTrimValue("host");
973                 String addr = getTrimValue("address");
974                 String port = getTrimValue("port");
975                 String key = getTrimValue("hostkey");
976                 boolean ssl, admin, isclient;
977                 ssl = params.containsKey("ssl");
978                 admin = params.containsKey("admin");
979                 isclient = params.containsKey("isclient");
980                 head = resetOptionHosts(head, host, addr, ssl);
981                 int iport = Integer.parseInt(port);
982                 DbHostAuth dbhost = new DbHostAuth(dbSession, host, addr, iport,
983                         ssl, key.getBytes(), admin, isclient);
984                 R66Future result = new R66Future(true);
985                 TestPacket packet = new TestPacket("MSG", "CheckConnection", 100);
986                 Message transaction = new Message(
987                         Configuration.configuration.getInternalRunner().getNetworkTransaction(),
988                         result, dbhost, packet);
989                 transaction.run();
990                 result.awaitUninterruptibly(Configuration.configuration.TIMEOUTCON);
991                 body = REQUEST.Hosts.readBody();
992                 if (result.isSuccess()) {
993                     body = dbhost.toSpecializedHtml(authentHttp, body, false);
994                     body += "<p><center><b>Connection SUCCESSFUL</b></center></p>";
995                 } else {
996                     boolean resultShutDown = false;
997                     if (!dbhost.isClient()) {
998                         SocketAddress socketAddress = dbhost.getSocketAddress();
999                         resultShutDown =
1000                             NetworkTransaction.shuttingdownNetworkChannel(socketAddress, null);
1001                     }
1002                     resultShutDown = resultShutDown ||
1003                         NetworkTransaction.shuttingdownNetworkChannels(host);
1004                     if (resultShutDown) {
1005                         body = dbhost.toSpecializedHtml(authentHttp, body, false);
1006                         body += "<p><center><b>Connection FAILURE: Disconnection is on going due to "+
1007                         result.getResult().code.mesg+"</b></center></p>";
1008                     } else {
1009                         body = dbhost.toSpecializedHtml(authentHttp, body, false);
1010                         body += "<p><center><b>Connection FAILURE: "+
1011                         result.getResult().code.mesg+"</b></center></p>";
1012                     }
1013                 }
1014             } else if ("CloseConn".equalsIgnoreCase(parm)) {
1015                 String host = getTrimValue("host");
1016                 String addr = getTrimValue("address");
1017                 String port = getTrimValue("port");
1018                 String key = getTrimValue("hostkey");
1019                 boolean ssl, admin, isclient;
1020                 ssl = params.containsKey("ssl");
1021                 admin = params.containsKey("admin");
1022                 isclient = params.containsKey("isclient");
1023                 head = resetOptionHosts(head, host, addr, ssl);
1024                 int iport = Integer.parseInt(port);
1025                 DbHostAuth dbhost = new DbHostAuth(dbSession, host, addr, iport,
1026                         ssl, key.getBytes(), admin, isclient);
1027                 body = REQUEST.Hosts.readBody();
1028                 boolean resultShutDown = false;
1029                 if (!dbhost.isClient()) {
1030                     SocketAddress socketAddress = dbhost.getSocketAddress();
1031                     resultShutDown =
1032                         NetworkTransaction.shuttingdownNetworkChannel(socketAddress, null);
1033                 }
1034                 resultShutDown = resultShutDown ||
1035                     NetworkTransaction.shuttingdownNetworkChannels(host);
1036                 if (resultShutDown) {
1037                     body = dbhost.toSpecializedHtml(authentHttp, body, false);
1038                     body += "<p><center><b>Disconnection on going SUCCESSFUL</b></center></p>";
1039                 } else {
1040                     body = dbhost.toSpecializedHtml(authentHttp, body, false);
1041                     body += "<p><center><b>Disconnection cannot be done</b></center></p>";
1042                 }
1043             } else if ("Delete".equalsIgnoreCase(parm)) {
1044                 String host = getTrimValue("host");
1045                 if (host == null || host.length() == 0) {
1046                     body0 = body1 = body = "";
1047                     body = "<p><center><b>Not enough data to delete a Host</b></center></p>";
1048                     head = resetOptionHosts(head, "", "", false);
1049                     return head+body0+body+body1+end;
1050                 }
1051                 DbHostAuth dbhost;
1052                 try {
1053                     dbhost = new DbHostAuth(dbSession, host);
1054                 } catch (GoldenGateDatabaseException e) {
1055                     body0 = body1 = body = "";
1056                     body = "<p><center><b>Cannot delete a Host: "+e.getMessage()+"</b></center></p>";
1057                     head = resetOptionHosts(head, "", "", false);
1058                     return head+body0+body+body1+end;
1059                 }
1060                 try {
1061                     dbhost.delete();
1062                 } catch (GoldenGateDatabaseException e) {
1063                     body0 = body1 = body = "";
1064                     body = "<p><center><b>Cannot delete a Host: "+e.getMessage()+"</b></center></p>";
1065                     head = resetOptionHosts(head, "", "", false);
1066                     return head+body0+body+body1+end;
1067                 }
1068                 body0 = body1 = body = "";
1069                 body = "<p><center><b>Deleted Host: "+host+"</b></center></p>";
1070                 head = resetOptionHosts(head, "", "", false);
1071                 return head+body0+body+body1+end;
1072             } else {
1073                 head = resetOptionHosts(head, "", "", false);
1074             }
1075             body1 = REQUEST.Hosts.readBodyEnd();
1076         } else {
1077             head = resetOptionHosts(head, "", "", false);
1078         }
1079         return head+body0+body+body1+end;
1080     }
1081     private void createExport(String body, StringBuilder builder, String rule, int mode, int limit) {
1082         DbPreparedStatement preparedStatement = null;
1083         try {
1084             preparedStatement =
1085                 DbRule.getFilterPrepareStament(dbSession,
1086                         rule, mode);
1087             preparedStatement.executeQuery();
1088             int i = 0;
1089             while (preparedStatement.getNext()) {
1090                 i++;
1091                 DbRule dbrule = DbRule.getFromStatement(preparedStatement);
1092                 builder.append(dbrule.toSpecializedHtml(authentHttp, body));
1093                 if (i > limit) {
1094                     break;
1095                 }
1096             }
1097             preparedStatement.realClose();
1098         } catch (GoldenGateDatabaseException e) {
1099             if (preparedStatement != null) {
1100                 preparedStatement.realClose();
1101             }
1102             logger.warn("OpenR66 Web Error {}",e.getMessage());
1103         }
1104     }
1105     private String resetOptionRules(String header,
1106             String rule, RequestPacket.TRANSFERMODE mode, int gmode) {
1107         StringBuilder builder = new StringBuilder(header);
1108         GgStringUtils.replace(builder, "XXXRULEXXX", rule);
1109         if (mode != null) {
1110             switch (mode) {
1111             case RECVMODE:
1112                 GgStringUtils.replace(builder, "XXXRECVXXX", "checked");
1113                 break;
1114             case SENDMODE:
1115                 GgStringUtils.replace(builder, "XXXSENDXXX", "checked");
1116                 break;
1117             case RECVMD5MODE:
1118                 GgStringUtils.replace(builder, "XXXRECVMXXX", "checked");
1119                 break;
1120             case SENDMD5MODE:
1121                 GgStringUtils.replace(builder, "XXXSENDMXXX", "checked");
1122                 break;
1123             case RECVTHROUGHMODE:
1124                 GgStringUtils.replace(builder, "XXXRECVTXXX", "checked");
1125                 break;
1126             case SENDTHROUGHMODE:
1127                 GgStringUtils.replace(builder, "XXXSENDTXXX", "checked");
1128                 break;
1129             case RECVMD5THROUGHMODE:
1130                 GgStringUtils.replace(builder, "XXXRECVMTXXX", "checked");
1131                 break;
1132             case SENDMD5THROUGHMODE:
1133                 GgStringUtils.replace(builder, "XXXSENDMTXXX", "checked");
1134                 break;
1135             }
1136         }
1137         if (gmode == -1) {// All Recv
1138             GgStringUtils.replace(builder, "XXXARECVXXX", "checked");
1139         } else if (gmode == -2) {// All Send
1140             GgStringUtils.replace(builder, "XXXASENDXXX", "checked");
1141         } else if (gmode == -3) {// All
1142             GgStringUtils.replace(builder, "XXXALLXXX", "checked");
1143         }
1144         return builder.toString();
1145     }
1146     private String Rules() {
1147         getParams();
1148         String head = REQUEST.Rules.readHeader(this);
1149         String end;
1150         end = REQUEST.Rules.readEnd();
1151         if (params == null) {
1152             head = resetOptionRules(head, "", null, -3);
1153             return head+end;
1154         }
1155         String body0, body, body1;
1156         body0 = body1 = body = "";
1157         List<String> parms = params.get("ACTION");
1158         if (parms != null) {
1159             body0 = REQUEST.Rules.readBodyHeader();
1160             String parm = parms.get(0);
1161             if ("Create".equalsIgnoreCase(parm) || "Update".equalsIgnoreCase(parm)) {
1162                 String rule = getTrimValue("rule");
1163                 String hostids = getTrimValue("hostids");
1164                 String recvp = getTrimValue("recvp");
1165                 String sendp = getTrimValue("sendp");
1166                 String archp = getTrimValue("archp");
1167                 String workp = getTrimValue("workp");
1168                 String rpre = getTrimValue("rpre");
1169                 String rpost = getTrimValue("rpost");
1170                 String rerr = getTrimValue("rerr");
1171                 String spre = getTrimValue("spre");
1172                 String spost = getTrimValue("spost");
1173                 String serr = getTrimValue("serr");
1174                 String mode = getTrimValue("mode");
1175                 if (rule == null || mode == null) {
1176                     body0 = body1 = body = "";
1177                     body = "<p><center><b>Not enough data to "+parm+" a Rule</b></center></p>";
1178                     head = resetOptionRules(head, "", null, -3);
1179                     return head+body0+body+body1+end;
1180                 }
1181                 int gmode = 0;
1182 
1183                 TRANSFERMODE tmode = null;
1184                 if (mode.equals("send")) {
1185                     tmode = RequestPacket.TRANSFERMODE.SENDMODE;
1186                     gmode= -2;
1187                 } else if (mode.equals("recv")) {
1188                     tmode = RequestPacket.TRANSFERMODE.RECVMODE;
1189                     gmode= -1;
1190                 } else if (mode.equals("sendmd5")) {
1191                     tmode = RequestPacket.TRANSFERMODE.SENDMD5MODE;
1192                     gmode= -2;
1193                 } else if (mode.equals("recvmd5")) {
1194                     tmode = RequestPacket.TRANSFERMODE.RECVMD5MODE;
1195                     gmode= -1;
1196                 } else if (mode.equals("sendth")) {
1197                     tmode = RequestPacket.TRANSFERMODE.SENDTHROUGHMODE;
1198                     gmode= -2;
1199                 } else if (mode.equals("recvth")) {
1200                     tmode = RequestPacket.TRANSFERMODE.RECVTHROUGHMODE;
1201                     gmode= -1;
1202                 } else if (mode.equals("sendthmd5")) {
1203                     tmode = RequestPacket.TRANSFERMODE.SENDMD5THROUGHMODE;
1204                     gmode= -2;
1205                 } else if (mode.equals("recvthmd5")) {
1206                     tmode = RequestPacket.TRANSFERMODE.RECVMD5THROUGHMODE;
1207                     gmode= -1;
1208                 }
1209                 head = resetOptionRules(head, rule, tmode, gmode);
1210                 DbRule dbrule = new DbRule(dbSession,rule,hostids,tmode.ordinal(),
1211                         recvp,sendp,archp,workp,rpre,rpost,rerr,spre,spost,serr);
1212                 try {
1213                     if ("Create".equalsIgnoreCase(parm)) {
1214                         dbrule.insert();
1215                     } else {
1216                         if (dbrule.exist()) {
1217                             dbrule.update();
1218                         } else {
1219                             dbrule.insert();
1220                         }
1221                     }
1222                 } catch (GoldenGateDatabaseException e) {
1223                     body0 = body1 = body = "";
1224                     body = "<p><center><b>Cannot create a Rule: "+e.getMessage()+"</b></center></p>";
1225                     head = resetOptionRules(head, "", null, -3);
1226                     return head+body0+body+body1+end;
1227                 }
1228                 body = REQUEST.Rules.readBody();
1229                 body = dbrule.toSpecializedHtml(authentHttp, body);
1230             } else if ("Filter".equalsIgnoreCase(parm)) {
1231                 String rule = getTrimValue("rule");
1232                 String mode = getTrimValue("mode");
1233                 TRANSFERMODE tmode;
1234                 int gmode = 0;
1235                 if (mode.equals("all")) {
1236                     gmode = -3;
1237                 } else if (mode.equals("send")) {
1238                     gmode = -2;
1239                 } else if (mode.equals("recv")) {
1240                     gmode = -1;
1241                 }
1242                 head = resetOptionRules(head, rule == null ? "":rule,
1243                         null, gmode);
1244                 body = REQUEST.Rules.readBody();
1245                 StringBuilder builder = new StringBuilder();
1246                 boolean specific = false;
1247                 if (params.containsKey("send")) {
1248                     tmode = RequestPacket.TRANSFERMODE.SENDMODE;
1249                     head = resetOptionRules(head, rule == null ? "":rule,
1250                             tmode, gmode);
1251                     specific = true;
1252                     createExport(body, builder, rule,
1253                             RequestPacket.TRANSFERMODE.SENDMODE.ordinal(), LIMITROW/4);
1254                 }
1255                 if (params.containsKey("recv")) {
1256                     tmode = RequestPacket.TRANSFERMODE.RECVMODE;
1257                     head = resetOptionRules(head, rule == null ? "":rule,
1258                             tmode, gmode);
1259                     specific = true;
1260                     createExport(body, builder, rule,
1261                             RequestPacket.TRANSFERMODE.RECVMODE.ordinal(), LIMITROW/4);
1262                 }
1263                 if (params.containsKey("sendmd5")) {
1264                     tmode = RequestPacket.TRANSFERMODE.SENDMD5MODE;
1265                     head = resetOptionRules(head, rule == null ? "":rule,
1266                             tmode, gmode);
1267                     specific = true;
1268                     createExport(body, builder, rule,
1269                             RequestPacket.TRANSFERMODE.SENDMD5MODE.ordinal(), LIMITROW/4);
1270                 }
1271                 if (params.containsKey("recvmd5")) {
1272                     tmode = RequestPacket.TRANSFERMODE.RECVMD5MODE;
1273                     head = resetOptionRules(head, rule == null ? "":rule,
1274                             tmode, gmode);
1275                     specific = true;
1276                     createExport(body, builder, rule,
1277                             RequestPacket.TRANSFERMODE.RECVMD5MODE.ordinal(), LIMITROW/4);
1278                 }
1279                 if (params.containsKey("sendth")) {
1280                     tmode = RequestPacket.TRANSFERMODE.SENDTHROUGHMODE;
1281                     head = resetOptionRules(head, rule == null ? "":rule,
1282                             tmode, gmode);
1283                     specific = true;
1284                     createExport(body, builder, rule,
1285                             RequestPacket.TRANSFERMODE.SENDTHROUGHMODE.ordinal(), LIMITROW/4);
1286                 }
1287                 if (params.containsKey("recvth")) {
1288                     tmode = RequestPacket.TRANSFERMODE.RECVTHROUGHMODE;
1289                     head = resetOptionRules(head, rule == null ? "":rule,
1290                             tmode, gmode);
1291                     specific = true;
1292                     createExport(body, builder, rule,
1293                             RequestPacket.TRANSFERMODE.RECVTHROUGHMODE.ordinal(), LIMITROW/4);
1294                 }
1295                 if (params.containsKey("sendthmd5")) {
1296                     tmode = RequestPacket.TRANSFERMODE.SENDMD5THROUGHMODE;
1297                     head = resetOptionRules(head, rule == null ? "":rule,
1298                             tmode, gmode);
1299                     specific = true;
1300                     createExport(body, builder, rule,
1301                             RequestPacket.TRANSFERMODE.SENDMD5THROUGHMODE.ordinal(), LIMITROW/4);
1302                 }
1303                 if (params.containsKey("recvthmd5")) {
1304                     tmode = RequestPacket.TRANSFERMODE.RECVMD5THROUGHMODE;
1305                     head = resetOptionRules(head, rule == null ? "":rule,
1306                             tmode, gmode);
1307                     specific = true;
1308                     createExport(body, builder, rule,
1309                             RequestPacket.TRANSFERMODE.RECVMD5THROUGHMODE.ordinal(), LIMITROW/4);
1310                 }
1311                 if (!specific) {
1312                     if (gmode == -1) {
1313                         //recv
1314                         createExport(body, builder, rule,
1315                                 RequestPacket.TRANSFERMODE.RECVMODE.ordinal(), LIMITROW/4);
1316                         createExport(body, builder, rule,
1317                                 RequestPacket.TRANSFERMODE.RECVMD5MODE.ordinal(), LIMITROW/4);
1318                         createExport(body, builder, rule,
1319                                 RequestPacket.TRANSFERMODE.RECVTHROUGHMODE.ordinal(), LIMITROW/4);
1320                         createExport(body, builder, rule,
1321                                 RequestPacket.TRANSFERMODE.RECVMD5THROUGHMODE.ordinal(), LIMITROW/4);
1322                     } else if (gmode == -2) {
1323                         //send
1324                         createExport(body, builder, rule,
1325                                 RequestPacket.TRANSFERMODE.SENDMODE.ordinal(), LIMITROW/4);
1326                         createExport(body, builder, rule,
1327                                 RequestPacket.TRANSFERMODE.SENDMD5MODE.ordinal(), LIMITROW/4);
1328                         createExport(body, builder, rule,
1329                                 RequestPacket.TRANSFERMODE.SENDTHROUGHMODE.ordinal(), LIMITROW/4);
1330                         createExport(body, builder, rule,
1331                                 RequestPacket.TRANSFERMODE.SENDMD5THROUGHMODE.ordinal(), LIMITROW/4);
1332                     } else {
1333                         // all
1334                         createExport(body, builder, rule,
1335                                 -1, LIMITROW);
1336                     }
1337                 }
1338                 body = builder.toString();
1339                 body1 = REQUEST.Rules.readBodyEnd();
1340             } else if ("Delete".equalsIgnoreCase(parm)) {
1341                 String rule = getTrimValue("rule");
1342                 if (rule == null || rule.length() == 0) {
1343                     body0 = body1 = body = "";
1344                     body = "<p><center><b>Not enough data to delete a Rule</b></center></p>";
1345                     head = resetOptionRules(head, "", null, -3);
1346                     return head+body0+body+body1+end;
1347                 }
1348                 DbRule dbrule;
1349                 try {
1350                     dbrule = new DbRule(dbSession,rule);
1351                 } catch (GoldenGateDatabaseException e) {
1352                     body0 = body1 = body = "";
1353                     body = "<p><center><b>Cannot delete a Rule: "+e.getMessage()+"</b></center></p>";
1354                     head = resetOptionRules(head, "", null, -3);
1355                     return head+body0+body+body1+end;
1356                 }
1357                 try {
1358                     dbrule.delete();
1359                 } catch (GoldenGateDatabaseException e) {
1360                     body0 = body1 = body = "";
1361                     body = "<p><center><b>Cannot delete a Rule: "+e.getMessage()+"</b></center></p>";
1362                     head = resetOptionRules(head, "", null, -3);
1363                     return head+body0+body+body1+end;
1364                 }
1365                 body0 = body1 = body = "";
1366                 body = "<p><center><b>Deleted Rule: "+rule+"</b></center></p>";
1367                 head = resetOptionRules(head, "", null, -3);
1368                 return head+body0+body+body1+end;
1369             } else {
1370                 head = resetOptionRules(head, "", null, -3);
1371             }
1372             body1 = REQUEST.Rules.readBodyEnd();
1373         } else {
1374             head = resetOptionRules(head, "", null, -3);
1375         }
1376         return head+body0+body+body1+end;
1377     }
1378 
1379     private String System() {
1380         getParams();
1381         if (params == null) {
1382             String system = REQUEST.System.readFileUnique(this);
1383             StringBuilder builder = new StringBuilder(system);
1384             GgStringUtils.replace(builder, REPLACEMENT.XXXXSESSIONLIMITWXXX.toString(),
1385                     Long.toString(Configuration.configuration.serverChannelWriteLimit));
1386             GgStringUtils.replace(builder, REPLACEMENT.XXXXSESSIONLIMITRXXX.toString(),
1387                     Long.toString(Configuration.configuration.serverChannelReadLimit));
1388             GgStringUtils.replace(builder, REPLACEMENT.XXXXDELAYCOMMDXXX.toString(),
1389                     Long.toString(Configuration.configuration.delayCommander));
1390             GgStringUtils.replace(builder, REPLACEMENT.XXXXDELAYRETRYXXX.toString(),
1391                     Long.toString(Configuration.configuration.delayRetry));
1392             GgStringUtils.replace(builder, REPLACEMENT.XXXXCHANNELLIMITWXXX.toString(),
1393                     Long.toString(Configuration.configuration.serverGlobalWriteLimit));
1394             GgStringUtils.replace(builder, REPLACEMENT.XXXXCHANNELLIMITRXXX.toString(),
1395                     Long.toString(Configuration.configuration.serverGlobalReadLimit));
1396             return builder.toString();
1397         }
1398         String extraInformation = null;
1399         if (params.containsKey("ACTION")) {
1400             List<String> action = params.get("ACTION");
1401             for (String act : action) {
1402                 if (act.equalsIgnoreCase("ExportConfig")) {
1403                     String directory = Configuration.configuration.baseDirectory+
1404                         R66Dir.SEPARATOR+Configuration.configuration.archivePath;
1405                     extraInformation = "Export Directory: "+directory+"<br>";
1406                     try {
1407                         RuleFileBasedConfiguration.writeXml(directory,
1408                             Configuration.configuration.HOST_ID);
1409                         extraInformation += "-Rule are exported.<br>";
1410                     } catch (GoldenGateDatabaseNoConnectionException e1) {
1411                     } catch (GoldenGateDatabaseSqlException e1) {
1412                     } catch (OpenR66ProtocolSystemException e1) {
1413                     }
1414                     String filename =
1415                         directory+R66Dir.SEPARATOR+Configuration.configuration.HOST_ID+
1416                             "_Authentications.xml";
1417                     extraInformation += "-Authent are exported.<br>";
1418                     try {
1419                         AuthenticationFileBasedConfiguration.writeXML(Configuration.configuration, 
1420                                 filename);
1421                     } catch (GoldenGateDatabaseNoConnectionException e) {
1422                     } catch (GoldenGateDatabaseSqlException e) {
1423                     } catch (OpenR66ProtocolSystemException e) {
1424                     }
1425                 } else if (act.equalsIgnoreCase("Disconnect")) {
1426                     String logon = Logon();
1427                     newSession = true;
1428                     clearSession();
1429                     forceClose = true;
1430                     return logon;
1431                 } else if (act.equalsIgnoreCase("Shutdown")) {
1432                     String error = error("Shutdown in progress");
1433                     newSession = true;
1434                     clearSession();
1435                     forceClose = true;
1436                     shutdown = true;
1437                     return error;
1438                 } else if (act.equalsIgnoreCase("Validate")) {
1439                     String bsessionr = getTrimValue("BSESSR");
1440                     long lsessionr = Configuration.configuration.serverChannelReadLimit;
1441                     if (bsessionr != null) {
1442                         lsessionr = (Long.parseLong(bsessionr)/10)*10;
1443                     }
1444                     String bglobalr = getTrimValue("BGLOBR");
1445                     long lglobalr = Configuration.configuration.serverGlobalReadLimit;
1446                     if (bglobalr != null) {
1447                         lglobalr = (Long.parseLong(bglobalr)/10)*10;
1448                     }
1449                     String bsessionw = getTrimValue("BSESSW");
1450                     long lsessionw = Configuration.configuration.serverChannelWriteLimit;
1451                     if (bsessionw !=null) {
1452                         lsessionw = (Long.parseLong(bsessionw)/10)*10;
1453                     }
1454                     String bglobalw = getTrimValue("BGLOBW");
1455                     long lglobalw = Configuration.configuration.serverGlobalWriteLimit;
1456                     if (bglobalw != null) {
1457                         lglobalw = (Long.parseLong(bglobalw)/10)*10;
1458                     }
1459                     Configuration.configuration.changeNetworkLimit(
1460                             lglobalw, lglobalr, lsessionw, lsessionr,
1461                             Configuration.configuration.delayLimit);
1462                     String dcomm = getTrimValue("DCOM");
1463                     if (dcomm != null) {
1464                         Configuration.configuration.delayCommander = Long.parseLong(dcomm);
1465                         if (Configuration.configuration.delayCommander <= 100) {
1466                             Configuration.configuration.delayCommander = 100;
1467                         }
1468                         Configuration.configuration.reloadCommanderDelay();
1469                     }
1470                     String dret = getTrimValue("DRET");
1471                     if (dret != null) {
1472                         Configuration.configuration.delayRetry = Long.parseLong(dret);
1473                         if (Configuration.configuration.delayRetry <= 1000) {
1474                             Configuration.configuration.delayRetry = 1000;
1475                         }
1476                     }
1477                     extraInformation = "Configuration Saved";
1478                 }
1479             }
1480         }
1481         String system = REQUEST.System.readFileUnique(this);
1482         StringBuilder builder = new StringBuilder(system);
1483         GgStringUtils.replace(builder, REPLACEMENT.XXXXSESSIONLIMITWXXX.toString(),
1484                 Long.toString(Configuration.configuration.serverChannelWriteLimit));
1485         GgStringUtils.replace(builder, REPLACEMENT.XXXXSESSIONLIMITRXXX.toString(),
1486                 Long.toString(Configuration.configuration.serverChannelReadLimit));
1487         GgStringUtils.replace(builder, REPLACEMENT.XXXXDELAYCOMMDXXX.toString(),
1488                 Long.toString(Configuration.configuration.delayCommander));
1489         GgStringUtils.replace(builder, REPLACEMENT.XXXXDELAYRETRYXXX.toString(),
1490                 Long.toString(Configuration.configuration.delayRetry));
1491         GgStringUtils.replace(builder, REPLACEMENT.XXXXCHANNELLIMITWXXX.toString(),
1492                 Long.toString(Configuration.configuration.serverGlobalWriteLimit));
1493         GgStringUtils.replace(builder, REPLACEMENT.XXXXCHANNELLIMITRXXX.toString(),
1494                 Long.toString(Configuration.configuration.serverGlobalReadLimit));
1495         if (extraInformation != null) {
1496             builder.append(extraInformation);
1497         }
1498         return builder.toString();
1499     }
1500 
1501     private void getParams() {
1502         if (request.getMethod() == HttpMethod.GET) {
1503             params = null;
1504         } else if (request.getMethod() == HttpMethod.POST) {
1505             ChannelBuffer content = request.getContent();
1506             if (content.readable()) {
1507                 String param = content.toString(GgStringUtils.UTF8);
1508                 QueryStringDecoder queryStringDecoder2 = new QueryStringDecoder("/?"+param);
1509                 params = queryStringDecoder2.getParameters();
1510             } else {
1511                 params = null;
1512             }
1513         }
1514     }
1515     private void clearSession() {
1516         if (admin != null) {
1517             R66Session lsession = sessions.remove(admin.getValue());
1518             DbSession ldbsession = dbSessions.remove(admin.getValue());
1519             admin = null;
1520             if (lsession != null) {
1521                 lsession.setStatus(75);
1522                 lsession.clear();
1523             }
1524             if (ldbsession != null) {
1525                 ldbsession.disconnect();
1526                 DbAdmin.nbHttpSession--;
1527             }
1528         }
1529     }
1530     private void checkAuthent(MessageEvent e) {
1531         newSession = true;
1532         if (request.getMethod() == HttpMethod.GET) {
1533             String logon = Logon();
1534             responseContent.append(logon);
1535             clearSession();
1536             writeResponse(e.getChannel());
1537             return;
1538         } else if (request.getMethod() == HttpMethod.POST) {
1539             getParams();
1540             if (params == null) {
1541                 String logon = Logon();
1542                 responseContent.append(logon);
1543                 clearSession();
1544                 writeResponse(e.getChannel());
1545                 return;
1546             }
1547         }
1548         boolean getMenu = false;
1549         if (params.containsKey("Logon")) {
1550             String name = null, password = null;
1551             List<String> values = null;
1552             if (!params.isEmpty()) {
1553                 // get values
1554                 if (params.containsKey("name")) {
1555                     values = params.get("name");
1556                     if (values != null) {
1557                         name = values.get(0);
1558                         if (name == null || name.length() == 0) {
1559                             getMenu = true;
1560                         }
1561                     }
1562                 } else {
1563                     getMenu = true;
1564                 }
1565                 // search the nb param
1566                 if ((!getMenu) && params.containsKey("passwd")) {
1567                     values = params.get("passwd");
1568                     if (values != null) {
1569                         password = values.get(0);
1570                         if (password == null || password.length() == 0) {
1571                             getMenu = true;
1572                         } else {
1573                             getMenu = false;
1574                         }
1575                     } else {
1576                         getMenu = true;
1577                     }
1578                 } else {
1579                     getMenu = true;
1580                 }
1581             } else {
1582                 getMenu = true;
1583             }
1584             if (! getMenu) {
1585                 logger.debug("Name="+name+" vs "+name.equals(Configuration.configuration.ADMINNAME)+
1586                         " Passwd="+password+" vs "+Arrays.equals(password.getBytes(),
1587                                 Configuration.configuration.getSERVERADMINKEY()));
1588                 if (name.equals(Configuration.configuration.ADMINNAME) &&
1589                         Arrays.equals(password.getBytes(),
1590                                 Configuration.configuration.getSERVERADMINKEY())) {
1591                     authentHttp.getAuth().specialNoSessionAuth(true, Configuration.configuration.HOST_ID);
1592                     authentHttp.setStatus(70);
1593                 } else {
1594                     getMenu = true;
1595                 }
1596                 if (! authentHttp.isAuthenticated()) {
1597                     authentHttp.setStatus(71);
1598                     logger.debug("Still not authenticated: {}",authentHttp);
1599                     getMenu = true;
1600                 }
1601                 // load DbSession
1602                 if (this.dbSession == null) {
1603                     try {
1604                         if (DbConstant.admin.isConnected) {
1605                             this.dbSession = new DbSession(DbConstant.admin, false);
1606                             DbAdmin.nbHttpSession++;
1607                             this.isPrivateDbSession = true;
1608                         }
1609                     } catch (GoldenGateDatabaseNoConnectionException e1) {
1610                         // Cannot connect so use default connection
1611                         logger.warn("Use default database connection");
1612                         this.dbSession = DbConstant.admin.session;
1613                     }
1614                 }
1615             }
1616         } else {
1617             getMenu = true;
1618         }
1619         if (getMenu) {
1620             String logon = Logon();
1621             responseContent.append(logon);
1622             clearSession();
1623             writeResponse(e.getChannel());
1624         } else {
1625             String index = index();
1626             responseContent.append(index);
1627             clearSession();
1628             admin = new DefaultCookie(R66SESSION, Configuration.configuration.HOST_ID+
1629                     Long.toHexString(new Random().nextLong()));
1630             sessions.put(admin.getValue(), this.authentHttp);
1631             authentHttp.setStatus(72);
1632             if (this.isPrivateDbSession) {
1633                 dbSessions.put(admin.getValue(), dbSession);
1634             }
1635             logger.debug("CreateSession: "+uriRequest+":{}",admin);
1636             writeResponse(e.getChannel());
1637         }
1638     }
1639 
1640     @Override
1641     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
1642             HttpRequest request = this.request = (HttpRequest) e.getMessage();
1643             queryStringDecoder = new QueryStringDecoder(request.getUri());
1644             uriRequest = queryStringDecoder.getPath();
1645             logger.debug("Msg: "+uriRequest);
1646             if (uriRequest.contains("gre/") || uriRequest.contains("img/") ||
1647                     uriRequest.contains("res/")) {
1648                 HttpWriteCacheEnable.writeFile(request, 
1649                         e.getChannel(), Configuration.configuration.httpBasePath+uriRequest,
1650                         R66SESSION);
1651                 return;
1652             }
1653             checkSession(e.getChannel());
1654             if (! authentHttp.isAuthenticated()) {
1655                 logger.debug("Not Authent: "+uriRequest+":{}",authentHttp);
1656                 checkAuthent(e);
1657                 return;
1658             }
1659             String find = uriRequest;
1660             if (uriRequest.charAt(0) == '/') {
1661                 find = uriRequest.substring(1);
1662             }
1663             find = find.substring(0, find.indexOf("."));
1664             REQUEST req = REQUEST.index;
1665             try {
1666                 req = REQUEST.valueOf(find);
1667             } catch (IllegalArgumentException e1) {
1668                 req = REQUEST.index;
1669                 logger.debug("NotFound: "+find+":"+uriRequest);
1670             }
1671             switch (req) {
1672                 case CancelRestart:
1673                     responseContent.append(CancelRestart());
1674                     break;
1675                 case Export:
1676                     responseContent.append(Export());
1677                     break;
1678                 case Hosts:
1679                     responseContent.append(Hosts());
1680                     break;
1681                 case index:
1682                     responseContent.append(index());
1683                     break;
1684                 case Listing:
1685                     responseContent.append(Listing());
1686                     break;
1687                 case Logon:
1688                     responseContent.append(index());
1689                     break;
1690                 case Rules:
1691                     responseContent.append(Rules());
1692                     break;
1693                 case System:
1694                     responseContent.append(System());
1695                     break;
1696                 case Transfers:
1697                     responseContent.append(Transfers());
1698                     break;
1699                 default:
1700                     responseContent.append(index());
1701                     break;
1702             }
1703             writeResponse(e.getChannel());
1704     }
1705     private void checkSession(Channel channel) {
1706         String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
1707         if (cookieString != null) {
1708             CookieDecoder cookieDecoder = new CookieDecoder();
1709             Set<Cookie> cookies = cookieDecoder.decode(cookieString);
1710             if(!cookies.isEmpty()) {
1711                 for (Cookie elt : cookies) {
1712                     if (elt.getName().equalsIgnoreCase(R66SESSION)) {
1713                         admin = elt;
1714                         break;
1715                     }
1716                 }
1717             }
1718         }
1719         if (admin != null) {
1720             R66Session session = sessions.get(admin.getValue());
1721             if (session != null) {
1722                 authentHttp = session;
1723                 authentHttp.setStatus(73);
1724             }
1725             DbSession dbSession = dbSessions.get(admin.getValue());
1726             if (dbSession != null) {
1727                 this.dbSession = dbSession;
1728             }
1729         } else {
1730             logger.debug("NoSession: "+uriRequest+":{}",admin);
1731         }
1732     }
1733     private void handleCookies(HttpResponse response) {
1734         String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
1735         if (cookieString != null) {
1736             CookieDecoder cookieDecoder = new CookieDecoder();
1737             Set<Cookie> cookies = cookieDecoder.decode(cookieString);
1738             if(!cookies.isEmpty()) {
1739                 // Reset the sessions if necessary.
1740                 CookieEncoder cookieEncoder = new CookieEncoder(true);
1741                 boolean findSession = false;
1742                 for (Cookie cookie : cookies) {
1743                     if (cookie.getName().equalsIgnoreCase(R66SESSION)) {
1744                         if (newSession) {
1745                             findSession = false;
1746                         } else {
1747                             findSession = true;
1748                             cookieEncoder.addCookie(cookie);
1749                             response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
1750                             cookieEncoder = new CookieEncoder(true);
1751                         }
1752                     } else {
1753                         cookieEncoder.addCookie(cookie);
1754                         response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
1755                         cookieEncoder = new CookieEncoder(true);
1756                     }
1757                 }
1758                 newSession = false;
1759                 if (! findSession) {
1760                     if (admin != null) {
1761                         cookieEncoder.addCookie(admin);
1762                         response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
1763                         logger.debug("AddSession: "+uriRequest+":{}",admin);
1764                     }
1765                 }
1766             }
1767         } else if (admin != null) {
1768             CookieEncoder cookieEncoder = new CookieEncoder(true);
1769             cookieEncoder.addCookie(admin);
1770             logger.debug("AddSession: "+uriRequest+":{}",admin);
1771             response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
1772         }
1773     }
1774     /**
1775      * Write the response
1776      * @param e
1777      */
1778     private void writeResponse(Channel channel) {
1779         // Convert the response content to a ChannelBuffer.
1780         ChannelBuffer buf = ChannelBuffers.copiedBuffer(responseContent.toString(), GgStringUtils.UTF8);
1781         responseContent.setLength(0);
1782 
1783         // Decide whether to close the connection or not.
1784         boolean keepAlive = HttpHeaders.isKeepAlive(request);
1785         boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request
1786                 .getHeader(HttpHeaders.Names.CONNECTION)) ||
1787                 (!keepAlive) || forceClose;
1788 
1789         // Build the response object.
1790         HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
1791         response.setContent(buf);
1792         response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/html");
1793         if (keepAlive) {
1794             response.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
1795         }
1796         if (!close) {
1797             // There's no need to add 'Content-Length' header
1798             // if this is the last response.
1799             response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
1800         }
1801 
1802         handleCookies(response);
1803 
1804         // Write the response.
1805         ChannelFuture future = channel.write(response);
1806         // Close the connection after the write operation is done if necessary.
1807         if (close) {
1808             future.addListener(ChannelFutureListener.CLOSE);
1809         }
1810         if (shutdown) {
1811             Thread thread = new Thread(new ChannelUtils(), "R66 Shutdown Thread");
1812             thread.setDaemon(true);
1813             thread.start();
1814         }
1815     }
1816     /**
1817      * Send an error and close
1818      * @param ctx
1819      * @param status
1820      */
1821     private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
1822         HttpResponse response = new DefaultHttpResponse(
1823                 HttpVersion.HTTP_1_1, status);
1824         response.setHeader(
1825                 HttpHeaders.Names.CONTENT_TYPE, "text/html");
1826         responseContent.setLength(0);
1827         responseContent.append(error(status.toString()));
1828         response.setContent(ChannelBuffers.copiedBuffer(responseContent.toString(), GgStringUtils.UTF8));
1829         clearSession();
1830         // Close the connection as soon as the error message is sent.
1831         ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
1832     }
1833 
1834     @Override
1835     public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
1836             throws Exception {
1837         OpenR66Exception exception = OpenR66ExceptionTrappedFactory
1838             .getExceptionFromTrappedException(e.getChannel(), e);
1839         if (exception != null) {
1840             if (!(exception instanceof OpenR66ProtocolBusinessNoWriteBackException)) {
1841                 if (e.getCause() instanceof IOException) {
1842                     // Nothing to do
1843                     return;
1844                 }
1845                 logger.warn("Exception in HttpSslHandler {}", exception.getMessage());
1846             }
1847             if (e.getChannel().isConnected()) {
1848                 sendError(ctx, HttpResponseStatus.BAD_REQUEST);
1849             }
1850         } else {
1851             // Nothing to do
1852             return;
1853         }
1854     }
1855 
1856     /* (non-Javadoc)
1857      * @see org.jboss.netty.channel.SimpleChannelUpstreamHandler#channelConnected(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent)
1858      */
1859     @Override
1860     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
1861             throws Exception {
1862         logger.debug("Connected");
1863         // Get the SslHandler in the current pipeline.
1864         // We added it in NetworkSslServerPipelineFactory.
1865         final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);
1866         if (sslHandler != null) {
1867             // Get the SslHandler and begin handshake ASAP.
1868             // Get notified when SSL handshake is done.
1869             ChannelFuture handshakeFuture;
1870             handshakeFuture = sslHandler.handshake();
1871             if (handshakeFuture != null) {
1872                 handshakeFuture.addListener(new ChannelFutureListener() {
1873                     public void operationComplete(ChannelFuture future)
1874                             throws Exception {
1875                         logger.debug("Handshake: "+future.isSuccess(),future.getCause());
1876                         if (future.isSuccess()) {
1877                             setStatusSslConnectedChannel(future.getChannel(), true);
1878                         } else {
1879                             setStatusSslConnectedChannel(future.getChannel(), false);
1880                             future.getChannel().close();
1881                         }
1882                     }
1883                 });
1884             }
1885         } else {
1886             logger.warn("SSL Not found");
1887         }
1888         super.channelConnected(ctx, e);
1889         ChannelGroup group =
1890             Configuration.configuration.getHttpChannelGroup();
1891         if (group != null) {
1892             group.add(e.getChannel());
1893         }
1894     }
1895 }