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