1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package goldengate.ftp.exec.adminssl;
22
23 import goldengate.common.command.ReplyCode;
24 import goldengate.common.command.exception.CommandAbstractException;
25 import goldengate.common.database.DbAdmin;
26 import goldengate.common.database.DbPreparedStatement;
27 import goldengate.common.database.DbSession;
28 import goldengate.common.database.exception.GoldenGateDatabaseException;
29 import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
30 import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
31 import goldengate.common.future.GgFuture;
32 import goldengate.common.logging.GgInternalLogger;
33 import goldengate.common.logging.GgInternalLoggerFactory;
34 import goldengate.common.utility.GgStringUtils;
35 import goldengate.ftp.core.file.FtpDir;
36 import goldengate.ftp.core.session.FtpSession;
37 import goldengate.ftp.core.utils.FtpChannelUtils;
38 import goldengate.ftp.exec.config.FileBasedConfiguration;
39 import goldengate.ftp.exec.control.FtpConstraintLimitHandler;
40 import goldengate.ftp.exec.database.DbConstant;
41 import goldengate.ftp.exec.database.data.DbTransferLog;
42 import goldengate.ftp.exec.exec.AbstractExecutor;
43 import goldengate.ftp.exec.exec.AbstractExecutor.CommandExecutor;
44 import goldengate.ftp.exec.file.FileBasedAuth;
45 import goldengate.ftp.exec.utils.Version;
46
47 import java.io.IOException;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Random;
51 import java.util.Set;
52 import java.util.concurrent.ConcurrentHashMap;
53
54 import openr66.protocol.http.HttpWriteCacheEnable;
55
56 import org.jboss.netty.buffer.ChannelBuffer;
57 import org.jboss.netty.buffer.ChannelBuffers;
58 import org.jboss.netty.channel.Channel;
59 import org.jboss.netty.channel.ChannelFuture;
60 import org.jboss.netty.channel.ChannelFutureListener;
61 import org.jboss.netty.channel.ChannelHandlerContext;
62 import org.jboss.netty.channel.ChannelStateEvent;
63 import org.jboss.netty.channel.ExceptionEvent;
64 import org.jboss.netty.channel.MessageEvent;
65 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
66 import org.jboss.netty.channel.group.ChannelGroup;
67 import org.jboss.netty.handler.codec.http.Cookie;
68 import org.jboss.netty.handler.codec.http.CookieDecoder;
69 import org.jboss.netty.handler.codec.http.CookieEncoder;
70 import org.jboss.netty.handler.codec.http.DefaultCookie;
71 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
72 import org.jboss.netty.handler.codec.http.HttpHeaders;
73 import org.jboss.netty.handler.codec.http.HttpMethod;
74 import org.jboss.netty.handler.codec.http.HttpRequest;
75 import org.jboss.netty.handler.codec.http.HttpResponse;
76 import org.jboss.netty.handler.codec.http.HttpResponseStatus;
77 import org.jboss.netty.handler.codec.http.HttpVersion;
78 import org.jboss.netty.handler.codec.http.QueryStringDecoder;
79 import org.jboss.netty.handler.ssl.SslHandler;
80 import org.jboss.netty.handler.traffic.TrafficCounter;
81
82
83
84
85
86 public class HttpSslHandler extends SimpleChannelUpstreamHandler {
87
88
89
90 private static final GgInternalLogger logger = GgInternalLoggerFactory
91 .getLogger(HttpSslHandler.class);
92
93
94
95 private static final ConcurrentHashMap<Integer, GgFuture> waitForSsl
96 = new ConcurrentHashMap<Integer, GgFuture>();
97
98
99
100 private static final ConcurrentHashMap<String, FileBasedAuth> sessions
101 = new ConcurrentHashMap<String, FileBasedAuth>();
102 private static final ConcurrentHashMap<String, DbSession> dbSessions
103 = new ConcurrentHashMap<String, DbSession>();
104 private volatile FtpSession ftpSession =
105 new FtpSession(FileBasedConfiguration.fileBasedConfiguration,
106 null);
107 private volatile FileBasedAuth authentHttp =
108 new FileBasedAuth(ftpSession);
109
110 private volatile HttpRequest request;
111 private volatile boolean newSession = false;
112 private volatile Cookie admin = null;
113 private final StringBuilder responseContent = new StringBuilder();
114 private volatile String uriRequest;
115 private volatile Map<String, List<String>> params;
116 private volatile QueryStringDecoder queryStringDecoder;
117 private volatile boolean forceClose = false;
118 private volatile boolean shutdown = false;
119
120 private static final String FTPSESSION = "FTPSESSION";
121 private static enum REQUEST {
122 Logon("Logon.html"),
123 index("index.html"),
124 error("error.html"),
125 Transfer("Transfer_head.html","Transfer_body.html","Transfer_end.html"),
126 Rule("Rule.html"),
127 User("User_head.html","User_body.html","User_end.html"),
128 System("System.html");
129
130 private String header;
131 private String body;
132 private String end;
133
134
135
136
137 private REQUEST(String uniquefile) {
138 this.header = uniquefile;
139 this.body = null;
140 this.end = null;
141 }
142
143
144
145
146
147 private REQUEST(String header, String body, String end) {
148 this.header = header;
149 this.body = body;
150 this.end = end;
151 }
152
153
154
155
156
157 public String readFileUnique() {
158 return GgStringUtils.readFile(FileBasedConfiguration.fileBasedConfiguration.httpBasePath+this.header);
159 }
160
161 public String readHeader() {
162 return GgStringUtils.readFile(FileBasedConfiguration.fileBasedConfiguration.httpBasePath+this.header);
163 }
164 public String readBody() {
165 return GgStringUtils.readFile(FileBasedConfiguration.fileBasedConfiguration.httpBasePath+this.body);
166 }
167 public String readEnd() {
168 return GgStringUtils.readFile(FileBasedConfiguration.fileBasedConfiguration.httpBasePath+this.end);
169 }
170 }
171 public static final int LIMITROW = 48;
172
173
174
175
176
177 private volatile DbSession dbSession = null;
178
179
180
181 private volatile boolean isPrivateDbSession = false;
182
183
184
185
186 private static final ChannelFutureListener remover = new ChannelFutureListener() {
187 public void operationComplete(ChannelFuture future) {
188 logger.debug("SSL remover");
189 waitForSsl.remove(future.getChannel().getId());
190 }
191 };
192
193 private String getTrimValue(String varname) {
194 String value = params.get(varname).get(0).trim();
195 if (value.length() == 0) {
196 value = null;
197 }
198 return value;
199 }
200
201
202
203
204 private static void addSslConnectedChannel(Channel channel) {
205 GgFuture futureSSL = new GgFuture(true);
206 waitForSsl.put(channel.getId(),futureSSL);
207 channel.getCloseFuture().addListener(remover);
208 }
209
210
211
212
213
214 private static void setStatusSslConnectedChannel(Channel channel, boolean status) {
215 GgFuture futureSSL = waitForSsl.get(channel.getId());
216 if (futureSSL != null) {
217 if (status) {
218 futureSSL.setSuccess();
219 } else {
220 futureSSL.cancel();
221 }
222 }
223 }
224
225
226
227
228 @Override
229 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
230 throws Exception {
231 Channel channel = e.getChannel();
232 logger.debug("Add channel to ssl");
233 addSslConnectedChannel(channel);
234 FileBasedConfiguration.fileBasedConfiguration.getHttpChannelGroup().add(channel);
235 super.channelOpen(ctx, e);
236 }
237
238
239
240 private String index() {
241 String index = REQUEST.index.readFileUnique();
242 StringBuilder builder = new StringBuilder(index);
243 GgStringUtils.replace(builder, "XXXLOCALXXX",
244 Integer.toString(
245 FileBasedConfiguration.fileBasedConfiguration.
246 getFtpInternalConfiguration().getNumberSessions())
247 +" "+Thread.activeCount());
248 TrafficCounter trafficCounter =
249 FileBasedConfiguration.fileBasedConfiguration.getFtpInternalConfiguration()
250 .getGlobalTrafficShapingHandler().getTrafficCounter();
251 GgStringUtils.replace(builder, "XXXBANDWIDTHXXX",
252 "IN:"+(trafficCounter.getLastReadThroughput()/131072)+
253 "Mbits <br> OUT:"+
254 (trafficCounter.getLastWriteThroughput()/131072)+"Mbits");
255 GgStringUtils.replaceAll(builder, "XXXHOSTIDXXX",
256 FileBasedConfiguration.fileBasedConfiguration.HOST_ID);
257 GgStringUtils.replaceAll(builder, "XXXADMINXXX",
258 "Administrator Connected");
259 GgStringUtils.replace(builder, "XXXVERSIONXXX",
260 Version.ID);
261 return builder.toString();
262 }
263 private String error(String mesg) {
264 String index = REQUEST.error.readFileUnique();
265 return index.replaceAll("XXXERRORMESGXXX",
266 mesg);
267 }
268 private String Logon() {
269 return REQUEST.Logon.readFileUnique();
270 }
271
272 private String System() {
273 getParams();
274 FtpConstraintLimitHandler handler =
275 FileBasedConfiguration.fileBasedConfiguration.constraintLimitHandler;
276 if (params == null) {
277 String system = REQUEST.System.readFileUnique();
278 StringBuilder builder = new StringBuilder(system);
279 GgStringUtils.replace(builder, "XXXXCHANNELLIMITRXXX",
280 Long.toString(FileBasedConfiguration.fileBasedConfiguration.getServerGlobalReadLimit()));
281 GgStringUtils.replace(builder, "XXXXCPULXXX",
282 Double.toString(handler.getCpuLimit()));
283 GgStringUtils.replace(builder, "XXXXCONLXXX",
284 Integer.toString(handler.getChannelLimit()));
285 GgStringUtils.replace(builder, "XXXRESULTXXX", "");
286 return builder.toString();
287 }
288 String extraInformation = null;
289 if (params.containsKey("ACTION")) {
290 List<String> action = params.get("ACTION");
291 for (String act : action) {
292 if (act.equalsIgnoreCase("Disconnect")) {
293 String logon = Logon();
294 newSession = true;
295 clearSession();
296 forceClose = true;
297 return logon;
298 } else if (act.equalsIgnoreCase("Shutdown")) {
299 String error = error("Shutdown in progress");
300 newSession = true;
301 clearSession();
302 forceClose = true;
303 shutdown = true;
304 return error;
305 } else if (act.equalsIgnoreCase("Validate")) {
306 String bglobalr = getTrimValue("BGLOBR");
307 long lglobal = FileBasedConfiguration.fileBasedConfiguration.getServerGlobalReadLimit();
308 if (bglobalr != null) {
309 lglobal = Long.parseLong(bglobalr);
310 }
311 FileBasedConfiguration.fileBasedConfiguration.changeNetworkLimit(lglobal, lglobal);
312 bglobalr = getTrimValue("CPUL");
313 double dcpu = handler.getCpuLimit();
314 if (bglobalr != null) {
315 dcpu = Double.parseDouble(bglobalr);
316 }
317 handler.setCpuLimit(dcpu);
318 bglobalr = getTrimValue("CONL");
319 int iconn = handler.getChannelLimit();
320 if (bglobalr != null) {
321 iconn = Integer.parseInt(bglobalr);
322 }
323 handler.setChannelLimit(iconn);
324 extraInformation = "Configuration Saved";
325 }
326 }
327 }
328 String system = REQUEST.System.readFileUnique();
329 StringBuilder builder = new StringBuilder(system);
330 GgStringUtils.replace(builder, "XXXXCHANNELLIMITRXXX",
331 Long.toString(FileBasedConfiguration.fileBasedConfiguration.getServerGlobalReadLimit()));
332 GgStringUtils.replace(builder, "XXXXCPULXXX",
333 Double.toString(handler.getCpuLimit()));
334 GgStringUtils.replace(builder, "XXXXCONLXXX",
335 Integer.toString(handler.getChannelLimit()));
336 if (extraInformation != null) {
337 GgStringUtils.replace(builder, "XXXRESULTXXX", extraInformation);
338 } else {
339 GgStringUtils.replace(builder, "XXXRESULTXXX", "");
340 }
341 return builder.toString();
342 }
343
344 private String Rule() {
345 getParams();
346 if (params == null) {
347 String system = REQUEST.Rule.readFileUnique();
348 StringBuilder builder = new StringBuilder(system);
349 CommandExecutor exec = AbstractExecutor.getCommandExecutor();
350 GgStringUtils.replace(builder, "XXXSTCXXX",
351 exec.getStorType()+" "+exec.pstorCMD);
352 GgStringUtils.replace(builder, "XXXSTDXXX",
353 Long.toString(exec.pstorDelay));
354 GgStringUtils.replace(builder, "XXXRTCXXX",
355 exec.getRetrType()+" "+exec.pretrCMD);
356 GgStringUtils.replace(builder, "XXXRTDXXX",
357 Long.toString(exec.pretrDelay));
358 GgStringUtils.replace(builder, "XXXRESULTXXX", "");
359 return builder.toString();
360 }
361 String extraInformation = null;
362 if (params.containsKey("ACTION")) {
363 List<String> action = params.get("ACTION");
364 for (String act : action) {
365 if (act.equalsIgnoreCase("Update")) {
366 CommandExecutor exec = AbstractExecutor.getCommandExecutor();
367 String bglobalr = getTrimValue("std");
368 long lglobal = exec.pstorDelay;
369 if (bglobalr != null) {
370 lglobal = Long.parseLong(bglobalr);
371 }
372 exec.pstorDelay = lglobal;
373 bglobalr = getTrimValue("rtd");
374 lglobal = exec.pretrDelay;
375 if (bglobalr != null) {
376 lglobal = Long.parseLong(bglobalr);
377 }
378 exec.pretrDelay = lglobal;
379 bglobalr = getTrimValue("stc");
380 String store = exec.getStorType()+" "+exec.pstorCMD;
381 if (bglobalr != null) {
382 store = bglobalr;
383 }
384 bglobalr = getTrimValue("rtc");
385 String retr = exec.getRetrType()+" "+exec.pretrCMD;
386 if (bglobalr != null) {
387 retr = bglobalr;
388 }
389 AbstractExecutor.initializeExecutor(retr, exec.pretrDelay,
390 store, exec.pstorDelay);
391 extraInformation = "Configuration Saved";
392 }
393 }
394 }
395 String system = REQUEST.Rule.readFileUnique();
396 StringBuilder builder = new StringBuilder(system);
397 CommandExecutor exec = AbstractExecutor.getCommandExecutor();
398 GgStringUtils.replace(builder, "XXXSTCXXX",
399 exec.getStorType()+" "+exec.pstorCMD);
400 GgStringUtils.replace(builder, "XXXSTDXXX",
401 Long.toString(exec.pstorDelay));
402 GgStringUtils.replace(builder, "XXXRTCXXX",
403 exec.getRetrType()+" "+exec.pretrCMD);
404 GgStringUtils.replace(builder, "XXXRTDXXX",
405 Long.toString(exec.pretrDelay));
406 if (extraInformation != null) {
407 GgStringUtils.replace(builder, "XXXRESULTXXX", extraInformation);
408 } else {
409 GgStringUtils.replace(builder, "XXXRESULTXXX", "");
410 }
411 return builder.toString();
412 }
413
414 private String Transfer() {
415 getParams();
416 String head = REQUEST.Transfer.readHeader();
417 String end = REQUEST.Transfer.readEnd();
418 String body = REQUEST.Transfer.readBody();
419 if (params == null || (!DbConstant.admin.isConnected)) {
420 end = end.replace("XXXRESULTXXX", "");
421 body = FileBasedConfiguration.fileBasedConfiguration.getHtmlTransfer(body, LIMITROW);
422 return head+body+end;
423 }
424 String message = "";
425 List<String> parms = params.get("ACTION");
426 if (parms != null) {
427 String parm = parms.get(0);
428 boolean purgeAll = false;
429 boolean purgeCorrect = false;
430 boolean delete = false;
431 if ("PurgeCorrectTransferLogs".equalsIgnoreCase(parm)) {
432 purgeCorrect = true;
433 } else if ("PurgeAllTransferLogs".equalsIgnoreCase(parm)) {
434 purgeAll = true;
435 } else if ("Delete".equalsIgnoreCase(parm)) {
436 delete = true;
437 }
438 if (purgeCorrect) {
439 DbPreparedStatement preparedStatement = null;
440 try {
441 preparedStatement =
442 DbTransferLog.getStatusPrepareStament(dbSession,
443 ReplyCode.REPLY_250_REQUESTED_FILE_ACTION_OKAY, 0);
444 } catch (GoldenGateDatabaseNoConnectionException e) {
445 message = "Error during purge";
446 } catch (GoldenGateDatabaseSqlException e) {
447 message = "Error during purge";
448 }
449 if (preparedStatement != null) {
450 try {
451 FileBasedConfiguration config = FileBasedConfiguration.fileBasedConfiguration;
452 String filename =
453 config.getBaseDirectory()+
454 FtpDir.SEPARATOR+config.ADMINNAME+FtpDir.SEPARATOR+
455 config.HOST_ID+"_logs_"+System.currentTimeMillis()+".xml";
456 message = DbTransferLog.saveDbTransferLogFile(preparedStatement, filename);
457 } finally {
458 preparedStatement.realClose();
459 }
460 }
461 } else if (purgeAll) {
462 DbPreparedStatement preparedStatement = null;
463 try {
464 preparedStatement =
465 DbTransferLog.getStatusPrepareStament(dbSession,
466 null, 0);
467 } catch (GoldenGateDatabaseNoConnectionException e) {
468 message = "Error during purgeAll";
469 } catch (GoldenGateDatabaseSqlException e) {
470 message = "Error during purgeAll";
471 }
472 if (preparedStatement != null) {
473 try {
474 FileBasedConfiguration config = FileBasedConfiguration.fileBasedConfiguration;
475 String filename =
476 config.getBaseDirectory()+
477 FtpDir.SEPARATOR+config.ADMINNAME+FtpDir.SEPARATOR+
478 config.HOST_ID+"_logs_"+System.currentTimeMillis()+".xml";
479 message = DbTransferLog.saveDbTransferLogFile(preparedStatement, filename);
480 } finally {
481 preparedStatement.realClose();
482 }
483 }
484 } else if (delete) {
485 String user = getTrimValue("user");
486 String acct = getTrimValue("account");
487 String specid = getTrimValue("specialid");
488 long specialId = Long.parseLong(specid);
489 try {
490 DbTransferLog log = new DbTransferLog(dbSession, user, acct, specialId);
491 FileBasedConfiguration config = FileBasedConfiguration.fileBasedConfiguration;
492 String filename =
493 config.getBaseDirectory()+
494 FtpDir.SEPARATOR+config.ADMINNAME+FtpDir.SEPARATOR+
495 config.HOST_ID+"_log_"+System.currentTimeMillis()+".xml";
496 message = log.saveDbTransferLog(filename);
497 } catch (GoldenGateDatabaseException e) {
498 message = "Error during delete 1 Log";
499 }
500 } else {
501 message = "No Action";
502 }
503 end = end.replace("XXXRESULTXXX", message);
504 }
505 end = end.replace("XXXRESULTXXX", "");
506 body = FileBasedConfiguration.fileBasedConfiguration.getHtmlTransfer(body, LIMITROW);
507 return head+body+end;
508 }
509 private String User() {
510 getParams();
511 String head = REQUEST.User.readHeader();
512 String end = REQUEST.User.readEnd();
513 String body = REQUEST.User.readBody();
514 FileBasedConfiguration config = FileBasedConfiguration.fileBasedConfiguration;
515 String filedefault = config.getBaseDirectory()+
516 FtpDir.SEPARATOR+config.ADMINNAME+
517 FtpDir.SEPARATOR+"authentication.xml";
518 if (params == null) {
519 end = end.replace("XXXRESULTXXX", "");
520 end = end.replace("XXXFILEXXX", filedefault);
521 body = FileBasedConfiguration.fileBasedConfiguration.getHtmlAuth(body);
522 return head+body+end;
523 }
524 List<String> parms = params.get("ACTION");
525 if (parms != null) {
526 String parm = parms.get(0);
527 if ("ImportExport".equalsIgnoreCase(parm)) {
528 String file = getTrimValue("file");
529 String exportImport = getTrimValue("export");
530 String message = "";
531 boolean purge = false;
532 purge = params.containsKey("purge");
533 boolean replace = false;
534 replace = params.containsKey("replace");
535 if (file == null) {
536 file = filedefault;
537 }
538 end = end.replace("XXXFILEXXX", file);
539 if (exportImport.equalsIgnoreCase("import")) {
540 if (! config.initializeAuthent(file, purge)) {
541 message += "Cannot initialize Authentication from "+file;
542 } else {
543 message += "Initialization of Authentication OK from "+file;
544 if (replace) {
545 if (! config.saveAuthenticationFile(
546 config.authenticationFile)) {
547 message += " but cannot replace server authenticationFile";
548 } else {
549 message += " and replacement done";
550 }
551 }
552 }
553 } else {
554
555 if (! config.saveAuthenticationFile(file)) {
556 message += "Authentications CANNOT be saved into "+file;
557 } else {
558 message += "Authentications saved into "+file;
559 }
560 }
561 end = end.replace("XXXRESULTXXX", message);
562 } else {
563 end = end.replace("XXXFILEXXX", filedefault);
564 }
565 }
566 end = end.replace("XXXRESULTXXX", "");
567 body = FileBasedConfiguration.fileBasedConfiguration.getHtmlAuth(body);
568 return head+body+end;
569 }
570 private void getParams() {
571 if (request.getMethod() == HttpMethod.GET) {
572 params = null;
573 } else if (request.getMethod() == HttpMethod.POST) {
574 ChannelBuffer content = request.getContent();
575 if (content.readable()) {
576 String param = content.toString(GgStringUtils.UTF8);
577 QueryStringDecoder queryStringDecoder2 = new QueryStringDecoder("/?"+param);
578 params = queryStringDecoder2.getParameters();
579 } else {
580 params = null;
581 }
582 }
583 }
584 private void clearSession() {
585 if (admin != null) {
586 FileBasedAuth auth = sessions.remove(admin.getValue());
587 DbSession ldbsession = dbSessions.remove(admin.getValue());
588 admin = null;
589 if (auth != null) {
590 auth.clear();
591 }
592 if (ldbsession != null) {
593 ldbsession.disconnect();
594 DbAdmin.nbHttpSession--;
595 }
596 }
597 }
598 private void checkAuthent(MessageEvent e) {
599 newSession = true;
600 if (request.getMethod() == HttpMethod.GET) {
601 String logon = Logon();
602 responseContent.append(logon);
603 clearSession();
604 writeResponse(e.getChannel());
605 return;
606 } else if (request.getMethod() == HttpMethod.POST) {
607 getParams();
608 if (params == null) {
609 String logon = Logon();
610 responseContent.append(logon);
611 clearSession();
612 writeResponse(e.getChannel());
613 return;
614 }
615 }
616 boolean getMenu = false;
617 if (params.containsKey("Logon")) {
618 String name = null, password = null;
619 List<String> values = null;
620 if (!params.isEmpty()) {
621
622 if (params.containsKey("name")) {
623 values = params.get("name");
624 if (values != null) {
625 name = values.get(0);
626 if (name == null || name.length() == 0) {
627 getMenu = true;
628 }
629 }
630 } else {
631 getMenu = true;
632 }
633
634 if ((!getMenu) && params.containsKey("passwd")) {
635 values = params.get("passwd");
636 if (values != null) {
637 password = values.get(0);
638 if (password == null || password.length() == 0) {
639 getMenu = true;
640 } else {
641 getMenu = false;
642 }
643 } else {
644 getMenu = true;
645 }
646 } else {
647 getMenu = true;
648 }
649 } else {
650 getMenu = true;
651 }
652 if (! getMenu) {
653 logger.debug("Name="+name+" vs "+name.equals(FileBasedConfiguration.fileBasedConfiguration.ADMINNAME)+
654 " Passwd="+password+" vs "+
655 FileBasedConfiguration.fileBasedConfiguration.checkPassword(password));
656 if (name.equals(FileBasedConfiguration.fileBasedConfiguration.ADMINNAME) &&
657 FileBasedConfiguration.fileBasedConfiguration.checkPassword(password)) {
658 authentHttp.specialNoSessionAuth(FileBasedConfiguration.fileBasedConfiguration.HOST_ID);
659 } else {
660 getMenu = true;
661 }
662 if (! authentHttp.isIdentified()) {
663 logger.debug("Still not authenticated: {}",authentHttp);
664 getMenu = true;
665 }
666
667 if (this.dbSession == null) {
668 try {
669 if (DbConstant.admin.isConnected) {
670 this.dbSession = new DbSession(DbConstant.admin, false);
671 DbAdmin.nbHttpSession++;
672 this.isPrivateDbSession = true;
673 }
674 } catch (GoldenGateDatabaseNoConnectionException e1) {
675
676 logger.warn("Use default database connection");
677 this.dbSession = DbConstant.admin.session;
678 }
679 }
680 }
681 } else {
682 getMenu = true;
683 }
684 if (getMenu) {
685 String logon = Logon();
686 responseContent.append(logon);
687 clearSession();
688 writeResponse(e.getChannel());
689 } else {
690 String index = index();
691 responseContent.append(index);
692 clearSession();
693 admin = new DefaultCookie(FTPSESSION,
694 FileBasedConfiguration.fileBasedConfiguration.HOST_ID+
695 Long.toHexString(new Random().nextLong()));
696 sessions.put(admin.getValue(), this.authentHttp);
697 if (this.isPrivateDbSession) {
698 dbSessions.put(admin.getValue(), dbSession);
699 }
700 logger.debug("CreateSession: "+uriRequest+":{}",admin);
701 writeResponse(e.getChannel());
702 }
703 }
704
705 @Override
706 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
707 HttpRequest request = this.request = (HttpRequest) e.getMessage();
708 queryStringDecoder = new QueryStringDecoder(request.getUri());
709 uriRequest = queryStringDecoder.getPath();
710 if (uriRequest.contains("gre/") || uriRequest.contains("img/") ||
711 uriRequest.contains("res/")) {
712 HttpWriteCacheEnable.writeFile(request,
713 e.getChannel(),
714 FileBasedConfiguration.fileBasedConfiguration.httpBasePath+uriRequest,
715 FTPSESSION);
716 return;
717 }
718 checkSession(e.getChannel());
719 if (! authentHttp.isIdentified()) {
720 logger.debug("Not Authent: "+uriRequest+":{}",authentHttp);
721 checkAuthent(e);
722 return;
723 }
724 String find = uriRequest;
725 if (uriRequest.charAt(0) == '/') {
726 find = uriRequest.substring(1);
727 }
728 find = find.substring(0, find.indexOf("."));
729 REQUEST req = REQUEST.index;
730 try {
731 req = REQUEST.valueOf(find);
732 } catch (IllegalArgumentException e1) {
733 req = REQUEST.index;
734 logger.debug("NotFound: "+find+":"+uriRequest);
735 }
736 switch (req) {
737 case index:
738 responseContent.append(index());
739 break;
740 case Logon:
741 responseContent.append(index());
742 break;
743 case System:
744 responseContent.append(System());
745 break;
746 case Rule:
747 responseContent.append(Rule());
748 break;
749 case User:
750 responseContent.append(User());
751 break;
752 case Transfer:
753 responseContent.append(Transfer());
754 break;
755 default:
756 responseContent.append(index());
757 break;
758 }
759 writeResponse(e.getChannel());
760 }
761 private void checkSession(Channel channel) {
762 String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
763 if (cookieString != null) {
764 CookieDecoder cookieDecoder = new CookieDecoder();
765 Set<Cookie> cookies = cookieDecoder.decode(cookieString);
766 if(!cookies.isEmpty()) {
767 for (Cookie elt : cookies) {
768 if (elt.getName().equalsIgnoreCase(FTPSESSION)) {
769 admin = elt;
770 break;
771 }
772 }
773 }
774 }
775 if (admin != null) {
776 FileBasedAuth auth = sessions.get(admin.getValue());
777 if (auth != null) {
778 authentHttp = auth;
779 }
780 DbSession dbSession = dbSessions.get(admin.getValue());
781 if (dbSession != null) {
782 this.dbSession = dbSession;
783 }
784 } else {
785 logger.debug("NoSession: "+uriRequest+":{}",admin);
786 }
787 }
788 private void handleCookies(HttpResponse response) {
789 String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
790 if (cookieString != null) {
791 CookieDecoder cookieDecoder = new CookieDecoder();
792 Set<Cookie> cookies = cookieDecoder.decode(cookieString);
793 if(!cookies.isEmpty()) {
794
795 CookieEncoder cookieEncoder = new CookieEncoder(true);
796 boolean findSession = false;
797 for (Cookie cookie : cookies) {
798 if (cookie.getName().equalsIgnoreCase(FTPSESSION)) {
799 if (newSession) {
800 findSession = false;
801 } else {
802 findSession = true;
803 cookieEncoder.addCookie(cookie);
804 response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
805 cookieEncoder = new CookieEncoder(true);
806 }
807 } else {
808 cookieEncoder.addCookie(cookie);
809 response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
810 cookieEncoder = new CookieEncoder(true);
811 }
812 }
813 newSession = false;
814 if (! findSession) {
815 if (admin != null) {
816 cookieEncoder.addCookie(admin);
817 response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
818 cookieEncoder = new CookieEncoder(true);
819 logger.debug("AddSession: "+uriRequest+":{}",admin);
820 }
821 }
822 }
823 } else if (admin != null) {
824 CookieEncoder cookieEncoder = new CookieEncoder(true);
825 cookieEncoder.addCookie(admin);
826 logger.debug("AddSession: "+uriRequest+":{}",admin);
827 response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
828 }
829 }
830
831
832
833
834 private void writeResponse(Channel channel) {
835
836 ChannelBuffer buf = ChannelBuffers.copiedBuffer(responseContent.toString(), GgStringUtils.UTF8);
837 responseContent.setLength(0);
838
839
840 boolean keepAlive = HttpHeaders.isKeepAlive(request);
841 boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request
842 .getHeader(HttpHeaders.Names.CONNECTION)) ||
843 (!keepAlive) || forceClose;
844
845
846 HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
847 response.setContent(buf);
848 response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/html");
849 if (keepAlive) {
850 response.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
851 }
852 if (!close) {
853
854
855 response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
856 }
857
858 handleCookies(response);
859
860
861 ChannelFuture future = channel.write(response);
862
863 if (close) {
864 future.addListener(ChannelFutureListener.CLOSE);
865 }
866 if (shutdown) {
867
868
869
870
871
872
873
874
875
876
877 FtpChannelUtils.teminateServer(FileBasedConfiguration.fileBasedConfiguration);
878 if (! close){
879 future.addListener(ChannelFutureListener.CLOSE);
880 }
881 }
882 }
883
884
885
886
887
888 private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
889 HttpResponse response = new DefaultHttpResponse(
890 HttpVersion.HTTP_1_1, status);
891 response.setHeader(
892 HttpHeaders.Names.CONTENT_TYPE, "text/html");
893 responseContent.setLength(0);
894 responseContent.append(error(status.toString()));
895 response.setContent(ChannelBuffers.copiedBuffer(responseContent.toString(), GgStringUtils.UTF8));
896 clearSession();
897
898 ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
899 }
900
901 @Override
902 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
903 throws Exception {
904 Throwable e1 = e.getCause();
905 if (!(e1 instanceof CommandAbstractException)) {
906 if (e1 instanceof IOException) {
907
908 return;
909 }
910 logger.warn("Exception in HttpSslHandler", e1);
911 }
912 if (e.getChannel().isConnected()) {
913 sendError(ctx, HttpResponseStatus.BAD_REQUEST);
914 }
915 }
916
917
918
919
920 @Override
921 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
922 throws Exception {
923
924
925 final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);
926 if (sslHandler != null) {
927
928
929 ChannelFuture handshakeFuture;
930 handshakeFuture = sslHandler.handshake();
931 if (handshakeFuture != null) {
932 handshakeFuture.addListener(new ChannelFutureListener() {
933 public void operationComplete(ChannelFuture future)
934 throws Exception {
935 logger.debug("Handshake: "+future.isSuccess(),future.getCause());
936 if (future.isSuccess()) {
937 setStatusSslConnectedChannel(future.getChannel(), true);
938 } else {
939 setStatusSslConnectedChannel(future.getChannel(), false);
940 future.getChannel().close();
941 }
942 }
943 });
944 }
945 } else {
946 logger.warn("SSL Not found");
947 }
948 super.channelConnected(ctx, e);
949 ChannelGroup group =
950 FileBasedConfiguration.fileBasedConfiguration.getHttpChannelGroup();
951 if (group != null) {
952 group.add(e.getChannel());
953 }
954 }
955 }