View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, 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 Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.protocol.localhandler;
21  
22  import org.waarp.common.logging.WaarpLogger;
23  import org.waarp.common.logging.WaarpLoggerFactory;
24  import org.waarp.common.utility.WaarpShutdownHook;
25  import org.waarp.openr66.context.ErrorCode;
26  import org.waarp.openr66.context.R66Result;
27  import org.waarp.openr66.context.R66Session;
28  import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
29  import org.waarp.openr66.context.task.exception.OpenR66RunnerException;
30  import org.waarp.openr66.database.data.DbTaskRunner;
31  import org.waarp.openr66.protocol.configuration.Configuration;
32  import org.waarp.openr66.protocol.configuration.Messages;
33  import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
34  import org.waarp.openr66.protocol.exception.OpenR66Exception;
35  import org.waarp.openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
36  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessCancelException;
37  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
38  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessQueryAlreadyFinishedException;
39  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessQueryStillRunningException;
40  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessRemoteFileNotFoundException;
41  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessStopException;
42  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNetworkException;
43  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
44  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoCorrectAuthenticationException;
45  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoDataException;
46  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
47  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
48  import org.waarp.openr66.protocol.exception.OpenR66ProtocolRemoteShutdownException;
49  import org.waarp.openr66.protocol.exception.OpenR66ProtocolShutdownException;
50  import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
51  import org.waarp.openr66.protocol.localhandler.packet.AbstractLocalPacket;
52  import org.waarp.openr66.protocol.localhandler.packet.AuthentPacket;
53  import org.waarp.openr66.protocol.localhandler.packet.BlockRequestPacket;
54  import org.waarp.openr66.protocol.localhandler.packet.BusinessRequestPacket;
55  import org.waarp.openr66.protocol.localhandler.packet.ConnectionErrorPacket;
56  import org.waarp.openr66.protocol.localhandler.packet.DataPacket;
57  import org.waarp.openr66.protocol.localhandler.packet.EndRequestPacket;
58  import org.waarp.openr66.protocol.localhandler.packet.EndTransferPacket;
59  import org.waarp.openr66.protocol.localhandler.packet.ErrorPacket;
60  import org.waarp.openr66.protocol.localhandler.packet.InformationPacket;
61  import org.waarp.openr66.protocol.localhandler.packet.JsonCommandPacket;
62  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketCodec;
63  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
64  import org.waarp.openr66.protocol.localhandler.packet.RequestPacket;
65  import org.waarp.openr66.protocol.localhandler.packet.ShutdownPacket;
66  import org.waarp.openr66.protocol.localhandler.packet.TestPacket;
67  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
68  import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
69  import org.waarp.openr66.protocol.localhandler.packet.json.RequestJsonPacket;
70  import org.waarp.openr66.protocol.networkhandler.packet.NetworkPacket;
71  import org.waarp.openr66.protocol.utils.ChannelCloseTimer;
72  import org.waarp.openr66.protocol.utils.ChannelUtils;
73  import org.waarp.openr66.protocol.utils.R66Future;
74  
75  import static org.waarp.openr66.context.R66FiniteDualStates.*;
76  
77  /**
78   * The local server handler handles real end file operations.
79   */
80  public final class LocalServerHandler {
81    /**
82     * Internal Logger
83     */
84    private static final WaarpLogger logger =
85        WaarpLoggerFactory.getLogger(LocalServerHandler.class);
86  
87    private LocalServerHandler() {
88    }
89  
90    public static void channelInactive(final TransferActions serverHandler) {
91      serverHandler.channelClosed();
92    }
93  
94    public static void channelActive(final TransferActions serverHandler) {
95      serverHandler.newSession();
96    }
97  
98    /**
99     * Replacement for local channels
100    *
101    * @param localChannelReference
102    * @param networkPacket
103    */
104   public static void channelRead0(
105       final LocalChannelReference localChannelReference,
106       final NetworkPacket networkPacket) {
107     try {
108       final AbstractLocalPacket packet =
109           LocalPacketCodec.decodeNetworkPacket(networkPacket.getBuffer());
110       channelRead1(localChannelReference, packet);
111     } catch (final OpenR66ProtocolShutdownException e) {
112       logger.error(e.getMessage());
113       exceptionCaught(localChannelReference.getServerHandler(), e);
114     } catch (final Exception e) {
115       exceptionCaught(localChannelReference.getServerHandler(), e);
116     } finally {
117       networkPacket.clear();
118     }
119   }
120 
121   public static void channelRead0(
122       final LocalChannelReference localChannelReference,
123       final AbstractLocalPacket msg) {
124     try {
125       channelRead1(localChannelReference, msg);
126     } catch (final Exception e) {
127       exceptionCaught(localChannelReference.getServerHandler(), e);
128     }
129   }
130 
131   public static void channelRead1(
132       final LocalChannelReference localChannelReference,
133       final AbstractLocalPacket packet) throws Exception {
134     // action as requested and answer if necessary
135     final TransferActions serverHandler =
136         localChannelReference.getServerHandler();
137     if (packet.getType() == LocalPacketFactory.STARTUPPACKET) {
138       logger.warn("Error in the protocol: {}", packet.toString());
139     } else {
140       if (serverHandler.getLocalChannelReference() == null) {
141         logger.error(
142             "No LocalChannelReference at " + packet.getClass().getName());
143         serverHandler.getSession().newState(ERROR);
144         final ErrorPacket errorPacket = new ErrorPacket(
145             "No LocalChannelReference at " + packet.getClass().getName(),
146             ErrorCode.ConnectionImpossible.getCode(),
147             ErrorPacket.FORWARDCLOSECODE);
148         ChannelUtils.writeAbstractLocalPacket(localChannelReference,
149                                               errorPacket, false);
150         if (Configuration.configuration.getR66Mib() != null) {
151           Configuration.configuration.getR66Mib()
152                                      .notifyWarning("No LocalChannelReference",
153                                                     packet.getClass()
154                                                           .getSimpleName());
155         }
156         packet.clear();
157         return;
158       }
159       switch (packet.getType()) {
160         case LocalPacketFactory.AUTHENTPACKET: {
161           serverHandler.authent((AuthentPacket) packet,
162                                 localChannelReference.getNetworkChannelObject()
163                                                      .isSSL());
164           break;
165         }
166         // Already done case LocalPacketFactory.STARTUPPACKET:
167         case LocalPacketFactory.DATAPACKET: {
168           if (((DataPacket) packet).getPacketRank() % 100 == 1 ||
169               serverHandler.getSession().getState() != DATAR) {
170             serverHandler.getSession().newState(DATAR);
171             logger.debug("DATA RANK: {} : {}",
172                          ((DataPacket) packet).getPacketRank(),
173                          serverHandler.getSession().getRunner().getRank());
174           }
175           ((DataPacket) packet).createByteBufFromRecv(
176               serverHandler.getSession());
177           logger.debug("DATA RANK: {} : {} for {} bytes",
178                        ((DataPacket) packet).getPacketRank(),
179                        serverHandler.getSession().getRunner().getRank(),
180                        ((DataPacket) packet).getLengthPacket());
181           if (localChannelReference.getSession().isCompressionEnabled()) {
182             R66Session.getCodec().uncompress(((DataPacket) packet),
183                                              serverHandler.getSession());
184           }
185           serverHandler.data((DataPacket) packet);
186           break;
187         }
188         case LocalPacketFactory.VALIDPACKET: {
189           // SHUTDOWNPACKET does not need authentication
190           if (((ValidPacket) packet).getTypeValid() !=
191               LocalPacketFactory.SHUTDOWNPACKET &&
192               !serverHandler.getSession().isAuthenticated()) {
193             logger.warn("Valid packet received while not authenticated: {} {}",
194                         packet, serverHandler.getSession());
195             serverHandler.getSession().newState(ERROR);
196             packet.clear();
197             throw new OpenR66ProtocolNotAuthenticatedException(
198                 "Not authenticated while Valid received");
199           }
200           if (((ValidPacket) packet).getTypeValid() ==
201               LocalPacketFactory.REQUESTPACKET) {
202             final String[] fields = ((ValidPacket) packet).getSmiddle().split(
203                 PartnerConfiguration.BAR_SEPARATOR_FIELD);
204             String newfilename = fields[0];
205             // potential file size changed
206             long newSize = -1;
207             String newFileInfo = null;
208             if (fields.length > 1) {
209               try {
210                 newSize = Long.parseLong(fields[1]);
211                 // potential fileInfo changed
212                 if (fields.length > 2) {
213                   newFileInfo = fields[2];
214                 }
215               } catch (final NumberFormatException e2) {
216                 newfilename +=
217                     PartnerConfiguration.BAR_SEPARATOR_FIELD + fields[1];
218                 newSize = -1;
219               }
220             }
221             if (newFileInfo != null && !newFileInfo.equals(
222                 serverHandler.getSession().getRunner().getFileInformation())) {
223               serverHandler.requestChangeFileInfo(newFileInfo);
224             }
225             serverHandler.requestChangeNameSize(newfilename, newSize);
226             serverHandler.saveAfterChangingFileInfo();
227             packet.clear();
228           } else {
229             serverHandler.valid((ValidPacket) packet);
230           }
231           break;
232         }
233         case LocalPacketFactory.ERRORPACKET: {
234           serverHandler.getSession().newState(ERROR);
235           serverHandler.errorMesg((ErrorPacket) packet);
236           break;
237         }
238         case LocalPacketFactory.CONNECTERRORPACKET: {
239           serverHandler.connectionError((ConnectionErrorPacket) packet);
240           break;
241         }
242         case LocalPacketFactory.REQUESTPACKET: {
243           serverHandler.request((RequestPacket) packet);
244           break;
245         }
246         case LocalPacketFactory.SHUTDOWNPACKET: {
247           serverHandler.getSession().newState(SHUTDOWN);
248           serverHandler.shutdown((ShutdownPacket) packet);
249           break;
250         }
251         case LocalPacketFactory.STOPPACKET:
252         case LocalPacketFactory.CANCELPACKET:
253         case LocalPacketFactory.CONFIMPORTPACKET:
254         case LocalPacketFactory.CONFEXPORTPACKET:
255         case LocalPacketFactory.BANDWIDTHPACKET: {
256           logger.error("Unimplemented Mesg: " + packet.getClass().getName());
257           serverHandler.getSession().newState(ERROR);
258           serverHandler.getLocalChannelReference().invalidateRequest(
259               new R66Result(
260                   new OpenR66ProtocolSystemException("Not implemented"),
261                   serverHandler.getSession(), true, ErrorCode.Unimplemented,
262                   null));
263           final ErrorPacket errorPacket = new ErrorPacket(
264               "Unimplemented Mesg: " + packet.getClass().getName(),
265               ErrorCode.Unimplemented.getCode(), ErrorPacket.FORWARDCLOSECODE);
266           ChannelUtils.writeAbstractLocalPacket(
267               serverHandler.getLocalChannelReference(), errorPacket, false);
268           packet.clear();
269           break;
270         }
271         case LocalPacketFactory.TESTPACKET: {
272           serverHandler.getSession().newState(TEST);
273           serverHandler.test((TestPacket) packet);
274           break;
275         }
276         case LocalPacketFactory.ENDTRANSFERPACKET: {
277           serverHandler.endTransfer((EndTransferPacket) packet);
278           break;
279         }
280         case LocalPacketFactory.INFORMATIONPACKET: {
281           serverHandler.getSession().newState(INFORMATION);
282           serverHandler.information((InformationPacket) packet);
283           break;
284         }
285         case LocalPacketFactory.ENDREQUESTPACKET: {
286           serverHandler.endRequest((EndRequestPacket) packet);
287           break;
288         }
289         case LocalPacketFactory.BUSINESSREQUESTPACKET: {
290           serverHandler.businessRequest((BusinessRequestPacket) packet);
291           break;
292         }
293         case LocalPacketFactory.BLOCKREQUESTPACKET: {
294           serverHandler.blockRequest((BlockRequestPacket) packet);
295           break;
296         }
297         case LocalPacketFactory.JSONREQUESTPACKET: {
298           if (!serverHandler.getSession().isAuthenticated()) {
299             logger.warn(
300                 "JsonCommand packet received while not authenticated: {} {}",
301                 packet, serverHandler.getSession());
302             serverHandler.getSession().newState(ERROR);
303             throw new OpenR66ProtocolNotAuthenticatedException(
304                 "Not authenticated while Valid received");
305           }
306           JsonPacket json = ((JsonCommandPacket) packet).getJsonRequest();
307           if (json == null) {
308             final ErrorCode code = ErrorCode.CommandNotFound;
309             final R66Result resulttest =
310                 new R66Result(serverHandler.getSession(), true, code,
311                               serverHandler.getSession().getRunner());
312             json = new JsonPacket();
313             json.setComment("Invalid command");
314             json.setRequestUserPacket(
315                 ((JsonCommandPacket) packet).getTypeValid());
316             final JsonCommandPacket valid =
317                 new JsonCommandPacket(json, resulttest.getCode().getCode(),
318                                       LocalPacketFactory.REQUESTUSERPACKET);
319             resulttest.setOther(packet);
320             serverHandler.getLocalChannelReference()
321                          .validateRequest(resulttest);
322             try {
323               ChannelUtils.writeAbstractLocalPacket(
324                   serverHandler.getLocalChannelReference(), valid, false);
325             } catch (final OpenR66ProtocolPacketException ignored) {
326               // ignore
327             }
328             serverHandler.getSession().setStatus(99);
329             localChannelReference.close();
330             return;
331           }
332           json.setRequestUserPacket(
333               ((JsonCommandPacket) packet).getTypeValid());
334           if (((JsonCommandPacket) packet).getTypeValid() ==
335               LocalPacketFactory.REQUESTPACKET) {
336             final RequestJsonPacket node = (RequestJsonPacket) json;
337             final String newfilename = node.getFilename();
338             if (newfilename == null) {
339               // error so ignore
340               return;
341             }
342             final long newSize = node.getFilesize();
343             final String newFileInfo = node.getFileInfo();
344             logger.debug("NewSize {} NewName {}", newSize, newfilename);
345             // potential fileInfo changed
346             if (newFileInfo != null && !newFileInfo.equals(
347                 serverHandler.getSession().getRunner().getFileInformation())) {
348               logger.debug("NewSize {} NewName {} newFileInfo {}", newSize,
349                            newfilename, newFileInfo);
350               serverHandler.requestChangeFileInfo(newFileInfo);
351             }
352             // potential file size changed
353             serverHandler.requestChangeNameSize(newfilename, newSize);
354             serverHandler.saveAfterChangingFileInfo();
355           } else {
356             serverHandler.jsonCommand((JsonCommandPacket) packet, json);
357           }
358           break;
359         }
360         default: {
361           logger.error("Unknown Mesg: " + packet.getClass().getName());
362           serverHandler.getSession().newState(ERROR);
363           serverHandler.getLocalChannelReference().invalidateRequest(
364               new R66Result(
365                   new OpenR66ProtocolSystemException("Unknown Message"),
366                   serverHandler.getSession(), true, ErrorCode.Unimplemented,
367                   null));
368           final ErrorPacket errorPacket =
369               new ErrorPacket("Unkown Mesg: " + packet.getClass().getName(),
370                               ErrorCode.Unimplemented.getCode(),
371                               ErrorPacket.FORWARDCLOSECODE);
372           ChannelUtils.writeAbstractLocalPacket(
373               serverHandler.getLocalChannelReference(), errorPacket, false);
374           packet.clear();
375         }
376       }
377     }
378   }
379 
380   public static void exceptionCaught(final TransferActions serverHandler,
381                                      final Throwable cause) {
382     // inform clients
383     final R66Future futureRequest =
384         serverHandler.getLocalChannelReference() != null?
385             serverHandler.getLocalChannelReference().getFutureRequest() : null;
386     logger.debug("Exception and isFinished: {}",
387                  (futureRequest != null && futureRequest.isDone()), cause);
388     if (futureRequest != null && futureRequest.isDone()) {
389       ChannelCloseTimer.closeFutureTransaction(serverHandler);
390       return;
391     }
392     final OpenR66Exception exception =
393         OpenR66ExceptionTrappedFactory.getExceptionFromTrappedException(
394             serverHandler.getLocalChannelReference() != null?
395                 serverHandler.getLocalChannelReference().getNetworkChannel() :
396                 null, cause);
397     ErrorCode code;
398     if (exception != null) {
399       serverHandler.getSession().newState(ERROR);
400       boolean isAnswered = false;
401       if (exception instanceof OpenR66ProtocolShutdownException) {
402         shutdownFromException(serverHandler, exception);
403         return;
404       } else {
405         if (futureRequest != null) {
406           if (futureRequest.isDone()) {
407             final R66Result result = futureRequest.getResult();
408             if (result != null) {
409               isAnswered = result.isAnswered();
410             }
411           }
412         }
413         final DbTaskRunner runner = serverHandler.getSession().getRunner();
414         if (exception instanceof OpenR66ProtocolNoConnectionException) {
415           code = ErrorCode.ConnectionImpossible;
416           if (runner != null) {
417             runner.stopOrCancelRunner(code);
418           }
419         } else if (exception instanceof OpenR66ProtocolBusinessCancelException) {
420           code = ErrorCode.CanceledTransfer;
421           if (runner != null) {
422             runner.stopOrCancelRunner(code);
423           }
424         } else if (exception instanceof OpenR66ProtocolBusinessStopException) {
425           code = ErrorCode.StoppedTransfer;
426           if (runner != null) {
427             runner.stopOrCancelRunner(code);
428           }
429         } else if (exception instanceof OpenR66ProtocolBusinessQueryAlreadyFinishedException) {
430           code = ErrorCode.QueryAlreadyFinished;
431           try {
432             serverHandler.tryFinalizeRequest(
433                 new R66Result(serverHandler.getSession(), true, code, runner));
434             ChannelCloseTimer.closeFutureTransaction(serverHandler);
435             return;
436           } catch (final OpenR66RunnerErrorException ignored) {
437             // nothing
438           } catch (final OpenR66ProtocolSystemException ignored) {
439             // nothing
440           }
441         } else if (exception instanceof OpenR66ProtocolBusinessQueryStillRunningException) {
442           code = ErrorCode.QueryStillRunning;
443           // nothing is to be done
444           logger.error("Will close channel since ", exception);
445           serverHandler.getLocalChannelReference().close();
446           serverHandler.getSession().setStatus(56);
447           return;
448         } else if (exception instanceof OpenR66ProtocolBusinessRemoteFileNotFoundException) {
449           code = ErrorCode.FileNotFound;
450         } else if (exception instanceof OpenR66RunnerException) {
451           code = ErrorCode.ExternalOp;
452         } else if (exception instanceof OpenR66RunnerErrorException) {
453           code = ErrorCode.ExternalOp;
454         } else if (exception instanceof OpenR66ProtocolNotAuthenticatedException) {
455           code = ErrorCode.BadAuthent;
456           isAnswered = true;
457         } else if (exception instanceof OpenR66ProtocolNoCorrectAuthenticationException) {
458           code = ErrorCode.BadAuthent;
459         } else if (exception instanceof OpenR66ProtocolNetworkException) {
460           code = ErrorCode.Disconnection;
461           if (runner != null) {
462             final R66Result finalValue = new R66Result(
463                 new OpenR66ProtocolSystemException(
464                     Messages.getString("LocalServerHandler.2")),
465                 //$NON-NLS-1$
466                 serverHandler.getSession(), true, code, runner);
467             try {
468               serverHandler.tryFinalizeRequest(finalValue);
469             } catch (final OpenR66Exception ignored) {
470               // nothing
471             }
472           }
473         } else if (exception instanceof OpenR66ProtocolRemoteShutdownException) {
474           code = ErrorCode.RemoteShutdown;
475           if (runner != null) {
476             runner.stopOrCancelRunner(code);
477           }
478         } else if (exception instanceof OpenR66ProtocolNoDataException) {
479           code = ErrorCode.FileNotFound;
480         } else {
481           if (runner != null) {
482             switch (runner.getErrorInfo()) {
483               case InitOk:
484               case PostProcessingOk:
485               case PreProcessingOk:
486               case Running:
487               case TransferOk:
488                 code = ErrorCode.Internal;
489                 break;
490               default:
491                 code = runner.getErrorInfo();
492             }
493           } else {
494             code = ErrorCode.Internal;
495           }
496         }
497         if (!isAnswered &&
498             !(exception instanceof OpenR66ProtocolBusinessNoWriteBackException) &&
499             !(exception instanceof OpenR66ProtocolNoConnectionException)) {
500           if (code == null || code == ErrorCode.Internal) {
501             code = ErrorCode.RemoteError;
502           }
503           final ErrorPacket errorPacket =
504               new ErrorPacket(exception.getMessage(), code.getCode(),
505                               ErrorPacket.FORWARDCLOSECODE);
506           try {
507             if (serverHandler.getLocalChannelReference() != null) {
508               ChannelUtils.writeAbstractLocalPacket(
509                   serverHandler.getLocalChannelReference(), errorPacket, false);
510             }
511           } catch (final OpenR66ProtocolPacketException e1) {
512             // should not be
513           }
514         }
515         if (Configuration.configuration.getR66Mib() != null) {
516           Configuration.configuration.getR66Mib().notifyError(
517               "Transfer in error since " + exception.getMessage(),
518               code != null? code.getMesg() : "Unknown Error");
519         }
520         final R66Result finalValue =
521             new R66Result(exception, serverHandler.getSession(), true, code,
522                           runner);
523         try {
524           serverHandler.getSession().setFinalizeTransfer(false, finalValue);
525           if (serverHandler.getLocalChannelReference() != null) {
526             serverHandler.getLocalChannelReference()
527                          .invalidateRequest(finalValue);
528           }
529         } catch (final OpenR66RunnerErrorException e1) {
530           if (serverHandler.getLocalChannelReference() != null) {
531             serverHandler.getLocalChannelReference()
532                          .invalidateRequest(finalValue);
533           }
534         } catch (final OpenR66ProtocolSystemException e1) {
535           if (serverHandler.getLocalChannelReference() != null) {
536             serverHandler.getLocalChannelReference()
537                          .invalidateRequest(finalValue);
538           }
539         }
540       }
541       if (exception instanceof OpenR66ProtocolBusinessNoWriteBackException) {
542         logger.error("Will close channel {}", exception.getMessage());
543         ChannelCloseTimer.closeFutureTransaction(serverHandler);
544         serverHandler.getSession().setStatus(56);
545         return;
546       } else if (exception instanceof OpenR66ProtocolNoConnectionException) {
547         logger.error("Will close channel {}", exception.getMessage());
548         ChannelCloseTimer.closeFutureTransaction(serverHandler);
549         serverHandler.getSession().setStatus(57);
550         return;
551       }
552       serverHandler.getSession().setStatus(58);
553       ChannelCloseTimer.closeFutureTransaction(serverHandler);
554     } else {
555       // Nothing to do
556       serverHandler.getSession().setStatus(59);
557     }
558   }
559 
560   private static void shutdownFromException(final TransferActions serverHandler,
561                                             final OpenR66Exception exception) {
562     WaarpShutdownHook.shutdownWillStart();
563     logger.warn(Messages.getString("LocalServerHandler.0") +
564                 //$NON-NLS-1$
565                 serverHandler.getSession().getAuth().getUser());
566     if (serverHandler.getLocalChannelReference() != null) {
567       final R66Result finalValue =
568           new R66Result(exception, serverHandler.getSession(), true,
569                         ErrorCode.Shutdown,
570                         serverHandler.getSession().getRunner());
571       try {
572         serverHandler.tryFinalizeRequest(finalValue);
573       } catch (final OpenR66RunnerErrorException ignored) {
574         // ignore
575       } catch (final OpenR66ProtocolSystemException ignored) {
576         // ignore
577       }
578       if (!serverHandler.getLocalChannelReference().getFutureRequest()
579                         .isDone()) {
580         try {
581           serverHandler.getSession().setFinalizeTransfer(false, finalValue);
582         } catch (final OpenR66RunnerErrorException e1) {
583           serverHandler.getLocalChannelReference()
584                        .invalidateRequest(finalValue);
585         } catch (final OpenR66ProtocolSystemException e1) {
586           serverHandler.getLocalChannelReference()
587                        .invalidateRequest(finalValue);
588         }
589       }
590     }
591     // dont'close, thread will do
592     ChannelUtils.startShutdown();
593     // set global shutdown info and before close, send a valid
594     // shutdown to all
595     serverHandler.getSession().setStatus(54);
596   }
597 }