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.localhandler.packet;
21
22 import com.fasterxml.jackson.databind.node.ObjectNode;
23 import io.netty.buffer.ByteBuf;
24 import org.waarp.common.json.JsonHandler;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27 import org.waarp.common.utility.WaarpNettyUtil;
28 import org.waarp.common.utility.WaarpStringUtils;
29 import org.waarp.openr66.context.ErrorCode;
30 import org.waarp.openr66.protocol.configuration.Configuration;
31 import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
32 import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
33 import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class RequestPacket extends AbstractLocalPacket {
49
50
51
52 private static final WaarpLogger logger =
53 WaarpLoggerFactory.getLogger(RequestPacket.class);
54 private static final String NOT_ENOUGH_DATA = "Not enough data";
55
56 public enum TRANSFERMODE {
57 UNKNOWNMODE, SENDMODE, RECVMODE, SENDMD5MODE, RECVMD5MODE, SENDTHROUGHMODE,
58 RECVTHROUGHMODE, SENDMD5THROUGHMODE, RECVMD5THROUGHMODE
59 }
60
61 protected enum FIELDS {
62 rule, mode, filename, block, rank, id, code, length, limit
63 }
64
65 protected static final byte REQVALIDATE = 0;
66
67 protected static final byte REQANSWERVALIDATE = 1;
68
69 protected final String rulename;
70
71 protected final int mode;
72
73 protected String filename;
74
75 protected final int blocksize;
76
77 protected int rank;
78
79 protected long specialId;
80
81 protected byte way;
82
83 protected char code;
84
85 protected long originalSize;
86
87 protected long limit;
88
89 protected final String transferInformation;
90
91 protected String separator = PartnerConfiguration.getSEPARATOR_FIELD();
92
93
94
95
96
97
98 public static int getModeMD5(final int mode) {
99 switch (mode) {
100 case 1:
101 case 2:
102 case 5:
103 case 6:
104 return mode + 2;
105 default:
106
107 }
108 return mode;
109 }
110
111
112
113
114
115
116 public static boolean isRecvMode(final int mode) {
117 return mode == TRANSFERMODE.RECVMODE.ordinal() ||
118 mode == TRANSFERMODE.RECVMD5MODE.ordinal() ||
119 mode == TRANSFERMODE.RECVTHROUGHMODE.ordinal() ||
120 mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal();
121 }
122
123
124
125
126
127
128
129 public static boolean isSendThroughMode(final int mode,
130 final boolean isRequested) {
131 return !isRequested && isSendThroughMode(mode) ||
132 isRequested && isRecvThroughMode(mode);
133 }
134
135
136
137
138
139
140 public static boolean isSendThroughMode(final int mode) {
141 return mode == TRANSFERMODE.SENDTHROUGHMODE.ordinal() ||
142 mode == TRANSFERMODE.SENDMD5THROUGHMODE.ordinal();
143 }
144
145
146
147
148
149
150
151 public static boolean isRecvThroughMode(final int mode,
152 final boolean isRequested) {
153 return !isRequested && isRecvThroughMode(mode) ||
154 isRequested && isSendThroughMode(mode);
155 }
156
157
158
159
160
161
162 public static boolean isRecvThroughMode(final int mode) {
163 return mode == TRANSFERMODE.RECVTHROUGHMODE.ordinal() ||
164 mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal();
165 }
166
167 public static boolean isSendMode(final int mode) {
168 return !isRecvMode(mode);
169 }
170
171
172
173
174
175
176 public static boolean isThroughMode(final int mode) {
177 return mode >= TRANSFERMODE.SENDTHROUGHMODE.ordinal() &&
178 mode <= TRANSFERMODE.RECVMD5THROUGHMODE.ordinal();
179 }
180
181
182
183
184
185
186 public static boolean isMD5Mode(final int mode) {
187 return mode == TRANSFERMODE.RECVMD5MODE.ordinal() ||
188 mode == TRANSFERMODE.SENDMD5MODE.ordinal() ||
189 mode == TRANSFERMODE.SENDMD5THROUGHMODE.ordinal() ||
190 mode == TRANSFERMODE.RECVMD5THROUGHMODE.ordinal();
191 }
192
193
194
195
196
197
198
199 public static boolean isCompatibleMode(final int mode1, final int mode2) {
200 return isRecvMode(mode1) && isRecvMode(mode2) ||
201 !isRecvMode(mode1) && !isRecvMode(mode2);
202 }
203
204
205
206
207
208
209
210
211
212
213
214 public static RequestPacket createFromBuffer(final int headerLength,
215 final int middleLength,
216 final int endLength,
217 final ByteBuf buf)
218 throws OpenR66ProtocolPacketException {
219 if (headerLength - 1 <= 0) {
220 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
221 }
222 if (middleLength <= 1) {
223 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
224 }
225 final byte[] bheader = new byte[headerLength - 1];
226 final byte[] bmiddle = new byte[middleLength - 1];
227 final byte[] bend = new byte[endLength];
228 buf.readBytes(bheader);
229 final byte valid = buf.readByte();
230 buf.readBytes(bmiddle);
231 if (endLength > 0) {
232 buf.readBytes(bend);
233 }
234 final String sheader = new String(bheader, WaarpStringUtils.UTF8);
235 final String smiddle = new String(bmiddle, WaarpStringUtils.UTF8);
236 final String send = new String(bend, WaarpStringUtils.UTF8);
237
238
239 if (sheader.startsWith(PartnerConfiguration.BAR_JSON_FIELD)) {
240
241 logger.debug("Request is using JSON");
242 final ObjectNode map = JsonHandler.getFromString(sheader);
243 final ObjectNode map2 = JsonHandler.getFromString(smiddle);
244 return new RequestPacket(map.path(FIELDS.rule.name()).asText(),
245 map.path(FIELDS.mode.name()).asInt(),
246 map2.path(FIELDS.filename.name()).asText(),
247 map2.path(FIELDS.block.name()).asInt(),
248 map2.path(FIELDS.rank.name()).asInt(),
249 map2.path(FIELDS.id.name()).asLong(), valid,
250 send,
251 (char) map2.path(FIELDS.code.name()).asInt(),
252 map2.path(FIELDS.length.name()).asLong(),
253
254 map2.path(FIELDS.limit.name()).asLong(0),
255 PartnerConfiguration.BAR_JSON_FIELD);
256 }
257
258 final String[] aheader =
259 sheader.split(PartnerConfiguration.BLANK_SEPARATOR_FIELD);
260 if (aheader.length != 2) {
261 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
262 }
263
264 String[] amiddle = smiddle.split(PartnerConfiguration.BAR_SEPARATOR_FIELD);
265 String sep = PartnerConfiguration.BAR_SEPARATOR_FIELD;
266 if (amiddle.length < 5) {
267 amiddle = smiddle.split(PartnerConfiguration.BLANK_SEPARATOR_FIELD);
268 sep = PartnerConfiguration.BLANK_SEPARATOR_FIELD;
269 if (amiddle.length < 5) {
270 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
271 }
272 }
273 int blocksize = Integer.parseInt(amiddle[1]);
274 if (blocksize < 100) {
275 blocksize = Configuration.configuration.getBlockSize();
276 }
277 final int rank = Integer.parseInt(amiddle[2]);
278 final long specialId = Long.parseLong(amiddle[3]);
279 final char code = amiddle[4].charAt(0);
280 long originalSize = -1;
281 if (amiddle.length > 5) {
282 originalSize = Long.parseLong(amiddle[5]);
283 }
284 return new RequestPacket(aheader[0], Integer.parseInt(aheader[1]),
285 amiddle[0], blocksize, rank, specialId, valid,
286 send, code, originalSize, sep);
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301 private RequestPacket(final String rulename, final int mode,
302 final String filename, final int blocksize,
303 final int rank, final long specialId, final byte valid,
304 final String transferInformation, final char code,
305 final long originalSize, final String separator) {
306 this.rulename = rulename;
307 this.mode = mode;
308 this.filename = filename;
309 if (blocksize < 100) {
310 this.blocksize = Configuration.configuration.getBlockSize();
311 } else {
312 this.blocksize = blocksize;
313 }
314 this.rank = rank;
315 this.specialId = specialId;
316 way = valid;
317 this.transferInformation = transferInformation;
318 this.code = code;
319 this.originalSize = originalSize;
320 this.separator = separator;
321 }
322
323
324
325
326
327
328
329
330
331
332 public RequestPacket(final String rulename, final int mode,
333 final String filename, final int blocksize,
334 final int rank, final long specialId,
335 final String transferInformation,
336 final long originalSize, final String separator) {
337 this(rulename, mode, filename, blocksize, rank, specialId, REQVALIDATE,
338 transferInformation, ErrorCode.InitOk.code, originalSize, separator);
339 }
340
341
342
343
344 private RequestPacket(final String rulename, final int mode,
345 final String filename, final int blocksize,
346 final int rank, final long specialId, final byte valid,
347 final String transferInformation, final char code,
348 final long originalSize, final long limit,
349 final String separator) {
350 this(rulename, mode, filename, blocksize, rank, specialId, valid,
351 transferInformation, code, originalSize, separator);
352 this.limit = limit;
353 }
354
355 @Override
356 public final boolean hasGlobalBuffer() {
357 return false;
358 }
359
360 @Override
361 public final void createAllBuffers(final LocalChannelReference lcr,
362 final int networkHeader) {
363 throw new IllegalStateException("Should not be called");
364 }
365
366 @Override
367 public final synchronized void createEnd(final LocalChannelReference lcr) {
368 if (transferInformation != null) {
369 end = WaarpNettyUtil.wrappedBuffer(
370 transferInformation.getBytes(WaarpStringUtils.UTF8));
371 }
372 }
373
374 @Override
375 public final synchronized void createHeader(final LocalChannelReference lcr)
376 throws OpenR66ProtocolPacketException {
377 if (rulename == null || mode <= 0) {
378 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
379 }
380 if (lcr.getPartner() != null && lcr.getPartner().useJson()) {
381 logger.debug("Request will use JSON {}", lcr.getPartner());
382 final ObjectNode node = JsonHandler.createObjectNode();
383 JsonHandler.setValue(node, FIELDS.rule, rulename);
384 JsonHandler.setValue(node, FIELDS.mode, mode);
385 header = WaarpNettyUtil.wrappedBuffer(
386 JsonHandler.writeAsString(node).getBytes(WaarpStringUtils.UTF8));
387 } else {
388 header =
389 WaarpNettyUtil.wrappedBuffer(rulename.getBytes(WaarpStringUtils.UTF8),
390 PartnerConfiguration.BLANK_SEPARATOR_FIELD.getBytes(
391 WaarpStringUtils.UTF8),
392 Integer.toString(mode)
393 .getBytes(WaarpStringUtils.UTF8));
394 }
395 }
396
397 @Override
398 public final synchronized void createMiddle(final LocalChannelReference lcr)
399 throws OpenR66ProtocolPacketException {
400 if (filename == null) {
401 throw new OpenR66ProtocolPacketException(NOT_ENOUGH_DATA);
402 }
403 final byte[] away = { way };
404 if (lcr.getPartner() != null && lcr.getPartner().useJson()) {
405 logger.debug("Request {} will use JSON {}", specialId, lcr.getPartner());
406 final ObjectNode node = JsonHandler.createObjectNode();
407 JsonHandler.setValue(node, FIELDS.filename, filename);
408 JsonHandler.setValue(node, FIELDS.block, blocksize);
409 JsonHandler.setValue(node, FIELDS.rank, rank);
410 JsonHandler.setValue(node, FIELDS.id, specialId);
411 JsonHandler.setValue(node, FIELDS.code, code);
412 JsonHandler.setValue(node, FIELDS.length, originalSize);
413
414 JsonHandler.setValue(node, FIELDS.limit, limit);
415 middle = WaarpNettyUtil.wrappedBuffer(away,
416 JsonHandler.writeAsString(node)
417 .getBytes(
418 WaarpStringUtils.UTF8));
419 } else {
420 middle = WaarpNettyUtil.wrappedBuffer(away, filename.getBytes(
421 WaarpStringUtils.UTF8), separator.getBytes(WaarpStringUtils.UTF8),
422 Integer.toString(blocksize)
423 .getBytes(
424 WaarpStringUtils.UTF8),
425 separator.getBytes(
426 WaarpStringUtils.UTF8),
427 Integer.toString(rank).getBytes(
428 WaarpStringUtils.UTF8),
429 separator.getBytes(
430 WaarpStringUtils.UTF8),
431 Long.toString(specialId).getBytes(
432 WaarpStringUtils.UTF8),
433 separator.getBytes(
434 WaarpStringUtils.UTF8),
435 Character.toString(code).getBytes(
436 WaarpStringUtils.UTF8),
437 separator.getBytes(
438 WaarpStringUtils.UTF8),
439 Long.toString(originalSize)
440 .getBytes(
441 WaarpStringUtils.UTF8));
442 }
443 }
444
445 @Override
446 public final byte getType() {
447 return LocalPacketFactory.REQUESTPACKET;
448 }
449
450 @Override
451 public final String toString() {
452 return "RequestPacket: " + specialId + " : " + rulename + " : " + mode +
453 " : " + filename + " : " + transferInformation + " : " + blocksize +
454 " : " + rank + " : " + way + " : " + code + " : " + originalSize +
455 " : " + limit;
456 }
457
458
459
460
461 public final String getRulename() {
462 return rulename;
463 }
464
465
466
467
468 public final String getFilename() {
469 return filename;
470 }
471
472
473
474
475 public final int getMode() {
476 return mode;
477 }
478
479
480
481
482 public final boolean isRetrieve() {
483 return isRecvMode(mode);
484 }
485
486
487
488
489 public final String getTransferInformation() {
490 return transferInformation;
491 }
492
493
494
495
496 public final int getBlocksize() {
497 return blocksize;
498 }
499
500
501
502
503 public final int getRank() {
504 return rank;
505 }
506
507
508
509
510 public final void setRank(final int rank) {
511 this.rank = rank;
512 }
513
514
515
516
517 public final long getOriginalSize() {
518 return originalSize;
519 }
520
521
522
523
524 public final void setOriginalSize(final long originalSize) {
525 this.originalSize = originalSize;
526 }
527
528
529
530
531 public final void setSpecialId(final long specialId) {
532 this.specialId = specialId;
533 }
534
535
536
537
538 public final long getSpecialId() {
539 return specialId;
540 }
541
542
543
544
545 public final boolean isToValidate() {
546 return way == REQVALIDATE;
547 }
548
549
550
551
552 public final synchronized void validate() {
553 way = REQANSWERVALIDATE;
554 middle = null;
555 }
556
557
558
559
560 public void setFilename(final String filename) {
561 this.filename = filename;
562 }
563
564
565
566
567 public final char getCode() {
568 return code;
569 }
570
571
572
573
574 public final void setCode(final char code) {
575 this.code = code;
576 }
577
578 public final long getLimit() {
579 return limit;
580 }
581
582 public final void setLimit(final long limit) {
583 this.limit = limit;
584 }
585 }