1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.protocol.http;
21
22 import io.netty.buffer.ByteBuf;
23 import io.netty.buffer.Unpooled;
24 import io.netty.channel.ChannelFuture;
25 import io.netty.channel.ChannelFutureListener;
26 import io.netty.channel.ChannelHandlerContext;
27 import io.netty.channel.SimpleChannelInboundHandler;
28 import io.netty.channel.group.ChannelGroup;
29 import io.netty.handler.codec.http.DefaultFullHttpResponse;
30 import io.netty.handler.codec.http.FullHttpRequest;
31 import io.netty.handler.codec.http.FullHttpResponse;
32 import io.netty.handler.codec.http.HttpHeaderNames;
33 import io.netty.handler.codec.http.HttpHeaderValues;
34 import io.netty.handler.codec.http.HttpMethod;
35 import io.netty.handler.codec.http.HttpResponseStatus;
36 import io.netty.handler.codec.http.HttpUtil;
37 import io.netty.handler.codec.http.HttpVersion;
38 import io.netty.handler.codec.http.QueryStringDecoder;
39 import io.netty.handler.codec.http.cookie.Cookie;
40 import io.netty.handler.codec.http.cookie.DefaultCookie;
41 import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
42 import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
43 import io.netty.handler.traffic.TrafficCounter;
44 import org.waarp.common.database.DbAdmin;
45 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
46 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
47 import org.waarp.common.exception.FileTransferException;
48 import org.waarp.common.exception.InvalidArgumentException;
49 import org.waarp.common.logging.SysErrLogger;
50 import org.waarp.common.logging.WaarpLogger;
51 import org.waarp.common.logging.WaarpLoggerFactory;
52 import org.waarp.common.utility.ParametersChecker;
53 import org.waarp.common.utility.WaarpStringUtils;
54 import org.waarp.gateway.kernel.http.HttpWriteCacheEnable;
55 import org.waarp.openr66.context.ErrorCode;
56 import org.waarp.openr66.context.R66Session;
57 import org.waarp.openr66.context.task.SpooledInformTask;
58 import org.waarp.openr66.dao.DAOFactory;
59 import org.waarp.openr66.dao.Filter;
60 import org.waarp.openr66.dao.TransferDAO;
61 import org.waarp.openr66.dao.database.DBTransferDAO;
62 import org.waarp.openr66.dao.exception.DAOConnectionException;
63 import org.waarp.openr66.database.data.DbTaskRunner;
64 import org.waarp.openr66.database.data.DbTaskRunner.TASKSTEP;
65 import org.waarp.openr66.pojo.Transfer;
66 import org.waarp.openr66.pojo.UpdatedInfo;
67 import org.waarp.openr66.protocol.configuration.Configuration;
68 import org.waarp.openr66.protocol.configuration.Messages;
69 import org.waarp.openr66.protocol.exception.OpenR66Exception;
70 import org.waarp.openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
71 import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
72 import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
73
74 import java.io.IOException;
75 import java.sql.Timestamp;
76 import java.util.ArrayList;
77 import java.util.Date;
78 import java.util.List;
79 import java.util.Map;
80 import java.util.Map.Entry;
81 import java.util.Set;
82
83
84
85
86 public class HttpFormattedHandler
87 extends SimpleChannelInboundHandler<FullHttpRequest> {
88 private static final String OPEN_R66_WEB_ERROR = "OpenR66 Web Error {}";
89
90
91
92 private static final WaarpLogger logger =
93 WaarpLoggerFactory.getLogger(HttpFormattedHandler.class);
94
95 private static final String MONITORING_HEADER_HTML = "monitoring_header.html";
96 private static final String MONITORING_END_HTML = "monitoring_end.html";
97
98 private enum REQUEST {
99 index("index.html"), active(MONITORING_HEADER_HTML, MONITORING_END_HTML),
100 error(MONITORING_HEADER_HTML, MONITORING_END_HTML),
101 done(MONITORING_HEADER_HTML, MONITORING_END_HTML),
102 all(MONITORING_HEADER_HTML, MONITORING_END_HTML),
103 status(MONITORING_HEADER_HTML, MONITORING_END_HTML), statusxml(""),
104 statusjson("");
105
106 private static final String MONITOR = "monitor/";
107 private final String header;
108 private final String end;
109
110
111
112
113
114
115 REQUEST(final String uniquefile) {
116 header = uniquefile;
117 end = uniquefile;
118 }
119
120
121
122
123
124 REQUEST(final String header, final String end) {
125 this.header = header;
126 this.end = end;
127 }
128
129
130
131
132
133
134 public final String readFileUnique(final HttpFormattedHandler handler) {
135 return handler.readFileHeader(
136 Configuration.configuration.getHttpBasePath() + MONITOR + header);
137 }
138
139 public final String readHeader(final HttpFormattedHandler handler) {
140 return handler.readFileHeader(
141 Configuration.configuration.getHttpBasePath() + MONITOR + header);
142 }
143
144 public final String readEnd() {
145 return WaarpStringUtils.readFile(
146 Configuration.configuration.getHttpBasePath() + MONITOR + end);
147 }
148 }
149
150 protected enum REPLACEMENT {
151 XXXHOSTIDXXX, XXXLOCACTIVEXXX, XXXNETACTIVEXXX, XXXBANDWIDTHXXX, XXXDATEXXX,
152 XXXLANGXXX
153 }
154
155 public static final int LIMITROW = 60;
156 private static final String I18NEXT = "i18next";
157
158 private final R66Session authentHttp = new R66Session(false);
159
160 protected String lang = Messages.getSlocale();
161
162 protected FullHttpRequest request;
163
164 protected final StringBuilder responseContent = new StringBuilder();
165
166 protected HttpResponseStatus status;
167
168 protected String uriRequest;
169
170 private static final String sINFO = "INFO";
171 private static final String sNB = "NB";
172 private static final String sDETAIL = "DETAIL";
173
174 protected boolean isCurrentRequestXml;
175 protected boolean isCurrentRequestJson;
176
177 protected Map<String, List<String>> params;
178
179 private String readFileHeader(final String filename) {
180 final String value;
181 try {
182 value = WaarpStringUtils.readFileException(filename);
183 } catch (final FileTransferException e) {
184 logger.error("Error while trying to read: " + filename, e);
185 return "";
186 }
187 final StringBuilder builder = new StringBuilder(value);
188
189 WaarpStringUtils.replace(builder, REPLACEMENT.XXXDATEXXX.toString(),
190 new Date().toString());
191 WaarpStringUtils.replace(builder, REPLACEMENT.XXXLOCACTIVEXXX.toString(),
192 Integer.toString(
193 Configuration.configuration.getLocalTransaction()
194 .getNumberLocalChannel()));
195 WaarpStringUtils.replace(builder, REPLACEMENT.XXXNETACTIVEXXX.toString(),
196 Integer.toString(DbAdmin.getNbConnection()));
197 WaarpStringUtils.replace(builder, REPLACEMENT.XXXHOSTIDXXX.toString(),
198 Configuration.configuration.getHostId());
199 final TrafficCounter trafficCounter =
200 Configuration.configuration.getGlobalTrafficShapingHandler()
201 .trafficCounter();
202 WaarpStringUtils.replace(builder, REPLACEMENT.XXXBANDWIDTHXXX.toString(),
203 "IN:" +
204 trafficCounter.lastReadThroughput() / 131072 +
205 "Mbits OUT:" +
206 trafficCounter.lastWriteThroughput() / 131072 +
207 "Mbits");
208 WaarpStringUtils.replace(builder, REPLACEMENT.XXXLANGXXX.toString(), lang);
209 return builder.toString();
210 }
211
212 protected final String getTrimValue(final String varname) {
213 String value;
214 try {
215 value = params.get(varname).get(0).trim();
216 } catch (final NullPointerException e) {
217 return null;
218 }
219 if (value.isEmpty()) {
220 value = null;
221 }
222 return value;
223 }
224
225 @Override
226 protected void channelRead0(final ChannelHandlerContext ctx,
227 final FullHttpRequest msg) {
228 isCurrentRequestXml = false;
229 isCurrentRequestJson = false;
230 status = HttpResponseStatus.OK;
231 final FullHttpRequest httpRequest = this.request = msg;
232 QueryStringDecoder queryStringDecoder =
233 new QueryStringDecoder(httpRequest.uri());
234 uriRequest = queryStringDecoder.path();
235 logger.debug("Msg: {}", uriRequest);
236 if (uriRequest.contains("gre/") || uriRequest.contains("img/") ||
237 uriRequest.contains("res/") || uriRequest.contains("favicon.ico")) {
238 HttpWriteCacheEnable.writeFile(httpRequest, ctx,
239 Configuration.configuration.getHttpBasePath() +
240 uriRequest, "XYZR66NOSESSION");
241 return;
242 }
243
244 char cval = 'z';
245 long nb = LIMITROW;
246
247 if ("/active".equalsIgnoreCase(uriRequest)) {
248 cval = '0';
249 } else if ("/error".equalsIgnoreCase(uriRequest)) {
250 cval = '1';
251 } else if ("/done".equalsIgnoreCase(uriRequest)) {
252 cval = '2';
253 } else if ("/all".equalsIgnoreCase(uriRequest)) {
254 cval = '3';
255 } else if ("/status".equalsIgnoreCase(uriRequest)) {
256 cval = '4';
257 } else if ("/statusxml".equalsIgnoreCase(uriRequest)) {
258 cval = '5';
259 nb = 0;
260 isCurrentRequestXml = true;
261 } else if (uriRequest.toLowerCase().startsWith("/spooled")) {
262 cval = '6';
263 } else if ("/statusjson".equalsIgnoreCase(uriRequest)) {
264 cval = '7';
265 nb = 0;
266 isCurrentRequestJson = true;
267 }
268
269 if (httpRequest.method() == HttpMethod.GET) {
270 params = queryStringDecoder.parameters();
271 } else if (httpRequest.method() == HttpMethod.POST) {
272 final ByteBuf content = httpRequest.content();
273 if (content.isReadable()) {
274 final String param = content.toString(WaarpStringUtils.UTF8);
275 queryStringDecoder = new QueryStringDecoder("/?" + param);
276 } else {
277 responseContent.append(REQUEST.index.readFileUnique(this));
278 writeResponse(ctx);
279 return;
280 }
281 params = queryStringDecoder.parameters();
282 boolean invalidEntry = false;
283 for (final Entry<String, List<String>> paramCheck : params.entrySet()) {
284 try {
285 ParametersChecker.checkSanityString(paramCheck.getValue().toArray(
286 ParametersChecker.ZERO_ARRAY_STRING));
287 } catch (final InvalidArgumentException e) {
288 logger.error(
289 "Arguments incompatible with Security: " + paramCheck.getKey() +
290 ": {}", e.getMessage());
291 invalidEntry = true;
292 }
293 }
294 if (invalidEntry) {
295 for (final Entry<String, List<String>> paramCheck : params.entrySet()) {
296 paramCheck.getValue().clear();
297 }
298 params.clear();
299 logger.error("No parameter validated since security issue found");
300 }
301 }
302 boolean getMenu = cval == 'z';
303 boolean extraBoolean = false;
304 if (!params.isEmpty()) {
305
306 if (getMenu) {
307 final String info = getTrimValue(sINFO);
308 if (info != null) {
309 getMenu = false;
310 cval = info.charAt(0);
311 } else {
312 getMenu = true;
313 }
314 }
315
316 final String snb = getTrimValue(sNB);
317 if (snb != null) {
318 try {
319 nb = Long.parseLong(snb);
320 } catch (final Exception ignored) {
321 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
322 }
323 }
324
325 final String sdetail = getTrimValue(sDETAIL);
326 if (sdetail != null) {
327 try {
328 if (Integer.parseInt(sdetail) > 0) {
329 extraBoolean = true;
330 }
331 } catch (final Exception ignored) {
332 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
333 }
334 }
335 final String langarg = getTrimValue("setLng");
336 if (ParametersChecker.isNotEmpty(langarg)) {
337 lang = langarg;
338 }
339 }
340 if (getMenu) {
341 responseContent.append(REQUEST.index.readFileUnique(this));
342 } else {
343
344 switch (cval) {
345 case '0':
346 active(ctx, (int) nb);
347 break;
348 case '1':
349 error(ctx, (int) nb);
350 break;
351 case '2':
352 done(ctx, (int) nb);
353 break;
354 case '3':
355 all(ctx, (int) nb);
356 break;
357 case '4':
358 status(ctx);
359 break;
360 case '5':
361 statusxml(ctx, nb, extraBoolean);
362 break;
363 case '6':
364 String name = null;
365 if (params.containsKey("name")) {
366 name = getTrimValue("name");
367 }
368 int istatus = 0;
369 if (params.containsKey("status")) {
370 final String statusNew = getTrimValue("status");
371 try {
372 istatus = Integer.parseInt(statusNew);
373 } catch (final NumberFormatException e1) {
374 istatus = 0;
375 }
376 }
377 if (uriRequest.toLowerCase().startsWith("/spooleddetail")) {
378 extraBoolean = true;
379 }
380 spooled(extraBoolean, name, istatus);
381 break;
382 case '7':
383 statusjson(ctx, nb, extraBoolean);
384 break;
385 default:
386 responseContent.append(REQUEST.index.readFileUnique(this));
387 }
388 }
389 writeResponse(ctx);
390 }
391
392
393
394
395
396
397
398
399
400
401 private void addRunners(final List<Transfer> transfers, final String type,
402 final int nb) {
403 responseContent.append(
404 "<style>td{font-size: 8pt;}</style><table border=\"2\">")
405 .append("<tr><td>").append(type).append("</td>")
406 .append(DbTaskRunner.headerHtml()).append("</tr>\r\n");
407
408 int i = 0;
409 for (final Transfer transfer : transfers) {
410 final DbTaskRunner taskRunner = new DbTaskRunner(transfer);
411 responseContent.append("<tr><td>")
412 .append(taskRunner.isSender()? "S" : "R").append("</td>");
413 final LocalChannelReference lcr =
414 Configuration.configuration.getLocalTransaction()
415 .getFromRequest(taskRunner.getKey());
416 responseContent.append(taskRunner.toHtml(getAuthentHttp(), lcr != null?
417 Messages.getString("HttpSslHandler.Active") :
418 Messages.getString("HttpSslHandler.NotActive"))).append("</tr>\r\n");
419 if (nb > 0) {
420 i++;
421 if (i >= nb) {
422 break;
423 }
424 }
425 }
426 responseContent.append("</table><br>\r\n");
427 }
428
429
430
431
432
433
434
435 private void active(final ChannelHandlerContext ctx, final int nb) {
436 responseContent.append(REQUEST.active.readHeader(this));
437
438 TransferDAO transferAccess = null;
439 final List<Filter> filters = new ArrayList<Filter>();
440 List<Transfer> transfers;
441 try {
442 transferAccess = DAOFactory.getInstance().getTransferDAO();
443
444
445 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
446 ErrorCode.Running.getCode()));
447 filters.add(DbTaskRunner.getOwnerFilter());
448 transfers =
449 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
450 false, nb);
451 addRunners(transfers, ErrorCode.Running.getMesg(), nb);
452
453 transfers.clear();
454 filters.clear();
455
456 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
457 UpdatedInfo.INTERRUPTED.ordinal()));
458 filters.add(DbTaskRunner.getOwnerFilter());
459 filters.add(new Filter(DBTransferDAO.TRANSFER_START_FIELD, "<",
460 new Timestamp(System.currentTimeMillis())));
461 transfers =
462 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
463 false, nb);
464 addRunners(transfers, UpdatedInfo.INTERRUPTED.name(), nb);
465
466 transfers.clear();
467 filters.clear();
468
469 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
470 UpdatedInfo.TOSUBMIT.ordinal()));
471 filters.add(DbTaskRunner.getOwnerFilter());
472 filters.add(new Filter(DBTransferDAO.TRANSFER_START_FIELD, "<",
473 new Timestamp(System.currentTimeMillis())));
474 transfers =
475 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
476 false, nb);
477 addRunners(transfers, UpdatedInfo.TOSUBMIT.name(), nb);
478
479 transfers.clear();
480 filters.clear();
481
482 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
483 ErrorCode.InitOk.getCode()));
484 filters.add(DbTaskRunner.getOwnerFilter());
485 transfers =
486 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
487 false, nb);
488 addRunners(transfers, ErrorCode.InitOk.getMesg(), nb);
489
490 transfers.clear();
491 filters.clear();
492
493 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
494 ErrorCode.PreProcessingOk.getCode()));
495 filters.add(DbTaskRunner.getOwnerFilter());
496 transfers =
497 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
498 false, nb);
499 addRunners(transfers, ErrorCode.PreProcessingOk.getMesg(), nb);
500
501 transfers.clear();
502 filters.clear();
503
504 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
505 ErrorCode.TransferOk.getCode()));
506 filters.add(DbTaskRunner.getOwnerFilter());
507 transfers =
508 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
509 false, nb);
510 addRunners(transfers, ErrorCode.TransferOk.getMesg(), nb);
511
512 transfers.clear();
513 filters.clear();
514
515 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
516 ErrorCode.PostProcessingOk.getCode()));
517 filters.add(DbTaskRunner.getOwnerFilter());
518 transfers =
519 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
520 false, nb);
521 addRunners(transfers, ErrorCode.PostProcessingOk.getMesg(), nb);
522 } catch (final DAOConnectionException e) {
523 logger.warn(OPEN_R66_WEB_ERROR, e.getMessage());
524 sendError(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE);
525 } finally {
526 DAOFactory.closeDAO(transferAccess);
527 }
528 responseContent.append(REQUEST.active.readEnd());
529 }
530
531
532
533
534
535
536
537 private void error(final ChannelHandlerContext ctx, final int nb) {
538 responseContent.append(REQUEST.error.readHeader(this));
539 TransferDAO transferAccess = null;
540 final List<Filter> filters = new ArrayList<Filter>();
541 List<Transfer> transfers;
542 try {
543 transferAccess = DAOFactory.getInstance().getTransferDAO();
544
545
546 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
547 UpdatedInfo.INERROR.ordinal()));
548 filters.add(DbTaskRunner.getOwnerFilter());
549 filters.add(new Filter(DBTransferDAO.TRANSFER_START_FIELD, "<",
550 new Timestamp(System.currentTimeMillis())));
551 transfers =
552 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
553 false, nb / 2);
554 addRunners(transfers, UpdatedInfo.INERROR.name(), nb / 2);
555
556 transfers.clear();
557 filters.clear();
558
559 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
560 UpdatedInfo.INTERRUPTED.ordinal()));
561 filters.add(DbTaskRunner.getOwnerFilter());
562 filters.add(new Filter(DBTransferDAO.TRANSFER_START_FIELD, "<",
563 new Timestamp(System.currentTimeMillis())));
564 transfers =
565 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
566 false, nb / 2);
567 addRunners(transfers, UpdatedInfo.INTERRUPTED.name(), nb / 2);
568
569 transfers.clear();
570 filters.clear();
571
572 filters.add(new Filter(DBTransferDAO.GLOBAL_STEP_FIELD, "=",
573 Transfer.TASKSTEP.ERRORTASK.ordinal()));
574 filters.add(DbTaskRunner.getOwnerFilter());
575 filters.add(new Filter(DBTransferDAO.TRANSFER_START_FIELD, "<",
576 new Timestamp(System.currentTimeMillis())));
577 transfers =
578 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
579 false, nb / 4);
580 addRunners(transfers, TASKSTEP.ERRORTASK.name(), nb / 4);
581 } catch (final DAOConnectionException e) {
582 logger.warn(OPEN_R66_WEB_ERROR, e.getMessage());
583 sendError(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE);
584 return;
585 } finally {
586 DAOFactory.closeDAO(transferAccess);
587 }
588 responseContent.append(REQUEST.error.readEnd());
589 }
590
591
592
593
594
595
596
597 private void done(final ChannelHandlerContext ctx, final int nb) {
598 responseContent.append(REQUEST.done.readHeader(this));
599
600 TransferDAO transferAccess = null;
601 final List<Transfer> transfers;
602 try {
603 transferAccess = DAOFactory.getInstance().getTransferDAO();
604
605 final List<Filter> filters = new ArrayList<Filter>();
606 filters.add(new Filter(DBTransferDAO.STEP_STATUS_FIELD, "=",
607 ErrorCode.CompleteOk.getCode()));
608 filters.add(DbTaskRunner.getOwnerFilter());
609
610 transfers =
611 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
612 false, nb);
613 addRunners(transfers, "ALL RUNNERS: " + nb, nb);
614 } catch (final DAOConnectionException e) {
615 logger.warn(OPEN_R66_WEB_ERROR, e.getMessage());
616 sendError(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE);
617 return;
618 } finally {
619 DAOFactory.closeDAO(transferAccess);
620 }
621 responseContent.append(REQUEST.done.readEnd());
622 }
623
624
625
626
627
628
629
630 private void all(final ChannelHandlerContext ctx, final int nb) {
631 responseContent.append(REQUEST.all.readHeader(this));
632
633 TransferDAO transferAccess = null;
634 final List<Transfer> transfers;
635 try {
636 transferAccess = DAOFactory.getInstance().getTransferDAO();
637
638 final List<Filter> filters = new ArrayList<Filter>();
639 filters.add(DbTaskRunner.getOwnerFilter());
640
641 transfers =
642 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
643 false, nb);
644 addRunners(transfers, "ALL RUNNERS: " + nb, nb);
645 } catch (final DAOConnectionException e) {
646 logger.warn(OPEN_R66_WEB_ERROR, e.getMessage());
647 sendError(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE);
648 return;
649 } finally {
650 DAOFactory.closeDAO(transferAccess);
651 }
652 responseContent.append(REQUEST.all.readEnd());
653 }
654
655
656
657
658
659
660 private void status(final ChannelHandlerContext ctx) {
661 responseContent.append(REQUEST.status.readHeader(this));
662
663 TransferDAO transferAccess = null;
664 final List<Filter> filters = new ArrayList<Filter>();
665 List<Transfer> transfers;
666 try {
667 transferAccess = DAOFactory.getInstance().getTransferDAO();
668
669
670 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
671 UpdatedInfo.INERROR.ordinal()));
672 filters.add(DbTaskRunner.getOwnerFilter());
673
674 transfers =
675 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
676 false, 1);
677 if (!transfers.isEmpty()) {
678 responseContent.append("<p>Some Transfers are in ERROR</p><br>");
679 status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
680 }
681
682 filters.clear();
683 transfers.clear();
684
685 filters.add(new Filter(DBTransferDAO.UPDATED_INFO_FIELD, "=",
686 UpdatedInfo.INTERRUPTED.ordinal()));
687 filters.add(DbTaskRunner.getOwnerFilter());
688
689 transfers =
690 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
691 false, 1);
692 if (!transfers.isEmpty()) {
693 responseContent.append("<p>Some Transfers are INTERRUPTED</p><br>");
694 status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
695 }
696 filters.clear();
697 transfers.clear();
698
699
700 filters.add(new Filter(DBTransferDAO.GLOBAL_STEP_FIELD, "=",
701 Transfer.TASKSTEP.ERRORTASK.ordinal()));
702 filters.add(DbTaskRunner.getOwnerFilter());
703
704 transfers =
705 transferAccess.find(filters, DBTransferDAO.TRANSFER_START_FIELD,
706 false, 1);
707 if (!transfers.isEmpty()) {
708 responseContent.append("<p>Some Transfers are in ERRORTASK</p><br>");
709 status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
710 }
711 } catch (final DAOConnectionException e) {
712 logger.warn(OPEN_R66_WEB_ERROR, e.getMessage());
713 sendError(ctx, HttpResponseStatus.SERVICE_UNAVAILABLE);
714 return;
715 } finally {
716 DAOFactory.closeDAO(transferAccess);
717 }
718 if (status != HttpResponseStatus.INTERNAL_SERVER_ERROR) {
719 responseContent.append("<p>No problem is found in Transfers</p><br>");
720 }
721 responseContent.append(REQUEST.status.readEnd());
722 }
723
724
725
726
727
728
729
730 protected final void statusxml(final ChannelHandlerContext ctx, final long nb,
731 final boolean detail) {
732 Configuration.configuration.getMonitoring().run(nb, detail);
733 responseContent.append(
734 Configuration.configuration.getMonitoring().exportXml(detail));
735 }
736
737
738
739
740
741
742
743 protected final void statusjson(final ChannelHandlerContext ctx,
744 final long nb, final boolean detail) {
745 Configuration.configuration.getMonitoring().run(nb, detail);
746 responseContent.append(
747 Configuration.configuration.getMonitoring().exportJson(detail));
748 }
749
750 private void spooled(final boolean detail, final String name,
751 final int istatus) {
752 responseContent.append(REQUEST.status.readHeader(this)).append(
753 "<p><table border='0' cellpadding='0' cellspacing='0' >").append(
754 "<tr style='background-image:url(gre/gresm.png);background-repeat:repeat-x;background-position:left top;'><td class='col_MenuHaut'>")
755 .append(
756 "<a data-i18n='menu2.sous-menu4a' href='Spooled.html' style='display:block;width:100%;height:100%;line-height:15px;'>")
757 .append(
758 "SPOOLED DIRECTORY no detail</a></td><td></td><td><img src='gre/gre11.png' height='15' width='1' style='border: none; display: block;' alt='' /></td>")
759 .append(
760 "<td></td><td class='col_MenuHaut'><a data-i18n='menu2.sous-menu4c' href='Spooled.html?status=-1' style='display:block;width:100%;height:100%;line-height:15px;'>")
761 .append(
762 "SPOOLED DIRECTORY no detail KO</a></td><td></td><td><img src='gre/gre11.png' height='15' width='1' style='border: none; display: block;' alt='' /></td>")
763 .append(
764 "<td></td><td class='col_MenuHaut'><a data-i18n='menu2.sous-menu4d' href='Spooled.html?status=1' style='display:block;width:100%;height:100%;line-height:15px;'>")
765 .append(
766 "SPOOLED DIRECTORY no detail OK</a></td></tr><tr style='background-image:url(gre/gre11.png);background-repeat:repeat-x;background-position:left top;'>")
767 .append(
768 "<td><img src='gre/gre11.png' height='1' width='100%' style='border: none; display: block;' alt='' /></td></tr>")
769 .append(
770 "<tr style='background-image:url(gre/gresm.png);background-repeat:repeat-x;background-position:left top;'>")
771 .append(
772 "<td class='col_MenuHaut'><a data-i18n='menu2.sous-menu4b' href='SpooledDetailed.html' style='display:block;width:100%;height:100%;line-height:15px;'>")
773 .append(
774 "SPOOLED DIRECTORY detailed</a></td><td></td><td><img src='gre/gre11.png' height='15' width='1' style='border: none; display: block;' alt='' /></td>")
775 .append(
776 "<td></td><td class='col_MenuHaut'><a data-i18n='menu2.sous-menu4e' href='SpooledDetailed.html?status=-1' style='display:block;width:100%;height:100%;line-height:15px;'>")
777 .append(
778 "SPOOLED DIRECTORY detailed KO</a></td><td></td><td><img src='gre/gre11.png' height='15' width='1' style='border: none; display: block;' alt='' /></td>")
779 .append(
780 "<td></td><td class='col_MenuHaut'><a data-i18n='menu2.sous-menu4f' href='SpooledDetailed.html?status=1' style='display:block;width:100%;height:100%;line-height:15px;'>")
781 .append(
782 "SPOOLED DIRECTORY detailed OK</a></td></tr></table></p>");
783 String uri;
784 if (detail) {
785 uri = "SpooledDetailed.html";
786 } else {
787 uri = "Spooled.html";
788 }
789 if (ParametersChecker.isNotEmpty(name)) {
790
791 uri = request.uri();
792 if (istatus != 0) {
793 uri += "&status=" + istatus;
794 }
795 responseContent.append(
796 SpooledInformTask.buildSpooledUniqueTable(uri, name));
797 } else {
798 if (istatus != 0) {
799 uri += "&status=" + istatus;
800 }
801 responseContent.append(
802 SpooledInformTask.buildSpooledTable(detail, istatus, uri));
803 }
804 responseContent.append(REQUEST.status.readEnd());
805 }
806
807
808
809
810
811
812 protected final void writeResponse(final ChannelHandlerContext ctx) {
813
814 final ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(),
815 WaarpStringUtils.UTF8);
816 responseContent.setLength(0);
817
818 final boolean keepAlive = HttpUtil.isKeepAlive(request);
819 final boolean close = HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(
820 request.headers().get(HttpHeaderNames.CONNECTION)) || !keepAlive;
821
822
823 final FullHttpResponse response =
824 new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, buf);
825 response.headers().add(HttpHeaderNames.CONTENT_LENGTH,
826 response.content().readableBytes());
827 if (isCurrentRequestXml) {
828 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/xml");
829 } else if (isCurrentRequestJson) {
830 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json");
831 } else {
832 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html");
833 }
834 if (keepAlive) {
835 response.headers()
836 .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
837 }
838 if (!close) {
839
840
841 response.headers().set(HttpHeaderNames.CONTENT_LENGTH,
842 String.valueOf(buf.readableBytes()));
843 }
844
845 final String cookieString = request.headers().get(HttpHeaderNames.COOKIE);
846 if (cookieString != null) {
847 final Set<Cookie> cookies = ServerCookieDecoder.LAX.decode(cookieString);
848 boolean i18nextFound = false;
849 if (!cookies.isEmpty()) {
850
851 for (final Cookie cookie : cookies) {
852 if (cookie.name().equalsIgnoreCase(I18NEXT)) {
853 i18nextFound = true;
854 cookie.setValue(lang);
855 response.headers().add(HttpHeaderNames.SET_COOKIE,
856 ServerCookieEncoder.LAX.encode(cookie));
857 } else {
858 response.headers().add(HttpHeaderNames.SET_COOKIE,
859 ServerCookieEncoder.LAX.encode(cookie));
860 }
861 }
862 if (!i18nextFound) {
863 final Cookie cookie = new DefaultCookie(I18NEXT, lang);
864 response.headers().add(HttpHeaderNames.SET_COOKIE,
865 ServerCookieEncoder.LAX.encode(cookie));
866 }
867 }
868 if (!i18nextFound) {
869 final Cookie cookie = new DefaultCookie(I18NEXT, lang);
870 response.headers().add(HttpHeaderNames.SET_COOKIE,
871 ServerCookieEncoder.LAX.encode(cookie));
872 }
873 }
874
875
876 final ChannelFuture future = ctx.writeAndFlush(response);
877
878 if (close) {
879 future.addListener(ChannelFutureListener.CLOSE);
880 }
881 }
882
883
884
885
886
887
888
889 protected final void sendError(final ChannelHandlerContext ctx,
890 final HttpResponseStatus status) {
891 responseContent.setLength(0);
892 responseContent.append(REQUEST.error.readHeader(this))
893 .append("OpenR66 Web Failure: ").append(status)
894 .append(REQUEST.error.readEnd());
895 final ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(),
896 WaarpStringUtils.UTF8);
897 final FullHttpResponse response =
898 new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, buf);
899 response.headers().add(HttpHeaderNames.CONTENT_LENGTH,
900 response.content().readableBytes());
901 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html");
902 responseContent.setLength(0);
903
904 ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
905 }
906
907 @Override
908 public void exceptionCaught(final ChannelHandlerContext ctx,
909 final Throwable cause) {
910 final OpenR66Exception exception =
911 OpenR66ExceptionTrappedFactory.getExceptionFromTrappedException(
912 ctx.channel(), cause);
913 if (exception != null) {
914 if (!(exception instanceof OpenR66ProtocolBusinessNoWriteBackException)) {
915 if (cause instanceof IOException) {
916
917 return;
918 }
919 logger.warn("Exception in HttpHandler {}", exception.getMessage());
920 }
921 if (ctx.channel().isActive()) {
922 sendError(ctx, HttpResponseStatus.BAD_REQUEST);
923 }
924 }
925 }
926
927 @Override
928 public void channelInactive(final ChannelHandlerContext ctx)
929 throws Exception {
930 super.channelInactive(ctx);
931 logger.debug("Closed");
932 }
933
934 @Override
935 public void channelActive(final ChannelHandlerContext ctx) throws Exception {
936 logger.debug("Connected");
937 getAuthentHttp().getAuth().specialNoSessionAuth(false,
938 Configuration.configuration.getHostId());
939 super.channelActive(ctx);
940 final ChannelGroup group =
941 Configuration.configuration.getHttpChannelGroup();
942 if (group != null) {
943 group.add(ctx.channel());
944 }
945 }
946
947
948
949
950 public R66Session getAuthentHttp() {
951 return authentHttp;
952 }
953 }