changeset 1037:e62df9b84df7

NcEventDestination - DNS and Netflow support
author Devel 2
date Thu, 09 Apr 2020 13:49:19 +0200
parents 692f56665b7a
children 9dff4810b5b8
files stress-tester/src/main/java/com/passus/st/ConverterMain.java stress-tester/src/main/java/com/passus/st/ReqRespPair.java stress-tester/src/main/java/com/passus/st/client/http/HttpReqResp.java stress-tester/src/main/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataReader.java stress-tester/src/main/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataWriter.java stress-tester/src/main/java/com/passus/st/reader/nc/HttpWriteMode.java stress-tester/src/main/java/com/passus/st/reader/nc/NcDataBlockWriter.java stress-tester/src/main/java/com/passus/st/reader/nc/NcDataUtils.java stress-tester/src/main/java/com/passus/st/reader/nc/NcDnsPayloadWriter.java stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpDataUtils.java stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpPayloadReader.java stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpPayloadWriter.java stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpWriteMode.java stress-tester/src/main/java/com/passus/st/reader/nc/NcNetflowPayloadWriter.java stress-tester/src/main/java/com/passus/st/source/AbstractNcPayloadWriter.java stress-tester/src/main/java/com/passus/st/source/NcEventDestination.java stress-tester/src/main/java/com/passus/st/source/NcEventSource.java stress-tester/src/main/java/com/passus/st/source/NcPayloadReader.java stress-tester/src/main/java/com/passus/st/source/NcPayloadWriter.java stress-tester/src/test/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataReaderTest.java stress-tester/src/test/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataWriterTest.java stress-tester/src/test/java/com/passus/st/reader/nc/NcHttpPayloadReaderTest.java stress-tester/src/test/java/com/passus/st/reader/nc/NcHttpPayloadWriterTest.java stress-tester/src/test/java/com/passus/st/source/NcEventDestinationTest.java
diffstat 24 files changed, 1049 insertions(+), 941 deletions(-) [+]
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/ConverterMain.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/ConverterMain.java	Thu Apr 09 13:49:19 2020 +0200
@@ -2,7 +2,7 @@
 
 import com.passus.config.ConfigurationContext;
 import com.passus.st.filter.FlowFilter;
-import com.passus.st.reader.nc.HttpWriteMode;
+import com.passus.st.reader.nc.NcHttpWriteMode;
 import com.passus.st.source.NcEventDestination;
 import com.passus.st.source.PcapSessionEventSource;
 import static com.passus.st.utils.CliUtils.option;
@@ -24,7 +24,7 @@
 
     private static final String WRITE_MODES = "skip|headers-only|full-message";
 
-    private static HttpWriteMode resolveWriteMode(String raw, HttpWriteMode defaultValue) {
+    private static NcHttpWriteMode resolveWriteMode(String raw, NcHttpWriteMode defaultValue) {
         if (raw == null) {
             return defaultValue;
         }
@@ -32,11 +32,11 @@
         raw = raw.toLowerCase();
         switch (raw) {
             case "skip":
-                return HttpWriteMode.SKIP;
+                return NcHttpWriteMode.SKIP;
             case "headers-only":
-                return HttpWriteMode.HEADERS_ONLY;
+                return NcHttpWriteMode.HEADERS_ONLY;
             case "full-message":
-                return HttpWriteMode.FULL_MESSAGE;
+                return NcHttpWriteMode.FULL_MESSAGE;
             default:
                 throw new IllegalArgumentException("Invalid write mode '" + raw + "'.");
         }
@@ -126,8 +126,10 @@
 
             NcEventDestination dst = new NcEventDestination(output);
             dst.setAllowOverwrite(overwrite);
-            dst.setHttpRequestWriteMode(resolveWriteMode(cl.getOptionValue("hreqpwm"), HttpWriteMode.FULL_MESSAGE));
-            dst.setHttpResponseWriteMode(resolveWriteMode(cl.getOptionValue("hrespwm"), HttpWriteMode.HEADERS_ONLY));
+/*
+            dst.setHttpRequestWriteMode(resolveWriteMode(cl.getOptionValue("hreqpwm"), NcHttpWriteMode.FULL_MESSAGE));
+            dst.setHttpResponseWriteMode(resolveWriteMode(cl.getOptionValue("hrespwm"), NcHttpWriteMode.HEADERS_ONLY));
+*/
 
             ConverterHttpClient client = new ConverterHttpClient(dst);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/ReqRespPair.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,21 @@
+package com.passus.st;
+
+public class ReqRespPair<R, S> {
+
+    final R request;
+    final S response;
+
+    public ReqRespPair(R request, S response) {
+        this.request = request;
+        this.response = response;
+    }
+
+    public R getRequest() {
+        return request;
+    }
+
+    public S getResponse() {
+        return response;
+    }
+
+}
--- a/stress-tester/src/main/java/com/passus/st/client/http/HttpReqResp.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/client/http/HttpReqResp.java	Thu Apr 09 13:49:19 2020 +0200
@@ -2,27 +2,14 @@
 
 import com.passus.net.http.HttpRequest;
 import com.passus.net.http.HttpResponse;
+import com.passus.st.ReqRespPair;
 
 /**
- *
  * @author Mirosław Hawrot
  */
-public class HttpReqResp {
-    
-    final HttpRequest request;
-    final HttpResponse response;
+public class HttpReqResp extends ReqRespPair<HttpRequest, HttpResponse> {
 
     public HttpReqResp(HttpRequest request, HttpResponse response) {
-        this.request = request;
-        this.response = response;
+        super(request, response);
     }
-
-    public HttpRequest getRequest() {
-        return request;
-    }
-
-    public HttpResponse getResponse() {
-        return response;
-    }
-    
 }
--- a/stress-tester/src/main/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataReader.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-package com.passus.st.reader.nc;
-
-import com.passus.commons.Assert;
-import com.passus.data.*;
-import com.passus.net.http.*;
-import com.passus.st.client.SessionPayloadEvent;
-import com.passus.st.client.http.HttpReqResp;
-
-import java.io.IOException;
-
-import static com.passus.st.reader.nc.NcHttpDataUtils.*;
-
-/**
- * @author Mirosław Hawrot
- */
-public class HttpSessionPayloadEventDataReader {
-
-    private final NcDataHelper ncDataHelper = NcDataHelper.getInstance();
-
-    private ByteBuffAllocator allocator = new DefaultByteBuffAllocator();
-
-    public ByteBuffAllocator getAllocator() {
-        return allocator;
-    }
-
-    public void setAllocator(ByteBuffAllocator allocator) {
-        Assert.notNull(allocator, "allocator");
-        this.allocator = allocator;
-    }
-
-    private void skipRequest(ByteBuff buffer) throws IOException {
-        ncDataHelper.skipByteStringNullTerminated(buffer);
-        ncDataHelper.skipByteStringNullTerminated(buffer);
-        buffer.read();
-        skipHeaders(buffer);
-    }
-
-    private void skipResponse(ByteBuff buffer) throws IOException {
-        buffer.skipBytes(2);
-        ncDataHelper.skipByteStringNullTerminated(buffer);
-        buffer.read();
-        skipHeaders(buffer);
-    }
-
-    public int decodeVersion(ByteBuff buffer) throws IOException {
-        byte b = buffer.read();
-        if (b == NcHttpDataUtils.VERSION_1_0) {
-            return HttpConsts.VERSION_1_0;
-        } else if (b == NcHttpDataUtils.VERSION_1_1) {
-            return HttpConsts.VERSION_1_1;
-        }
-
-        throw new IOException("Not supported HTTP version '" + b + "'.");
-    }
-
-    private void skipHeaders(ByteBuff buffer) throws IOException {
-        long headerSize = ncDataHelper.readLongVLC(buffer);
-        if (headerSize <= Integer.MAX_VALUE) {
-            buffer.skipBytes((int) headerSize);
-        } else {
-            throw new IOException("Too big header size > Integer.MAX_VALUE");
-        }
-    }
-
-    private HttpMethod decodeMethod(ByteBuff buff) throws IOException {
-        byte code = buff.read();
-        switch (code) {
-            case 0:
-                ByteString methodStr = ncDataHelper.readByteStringNullTerminated(buff);
-                return new HttpMethod(methodStr);
-            case 1:
-                return HttpMethod.GET;
-            case 2:
-                return HttpMethod.POST;
-            case 3:
-                return HttpMethod.PUT;
-            case 4:
-                return HttpMethod.DELETE;
-            case 5:
-                return HttpMethod.CONNECT;
-            case 6:
-                return HttpMethod.HEAD;
-            case 7:
-                return HttpMethod.OPTIONS;
-            case 8:
-                return HttpMethod.TRACE;
-            case 9:
-                return HttpMethod.PATCH;
-            default:
-                throw new IOException("Unknwon request method code '" + code + "'.");
-
-        }
-    }
-
-    public HttpHeaders decodeHeaders(ByteBuff buffer) throws IOException {
-        long headerSize = ncDataHelper.readLongVLC(buffer);
-        HttpHeaders headers;
-        if (HttpHeadersDecoder.isDefaultEnableCachedHeaders()) {
-            headers = new HttpHeadersImpl();
-        } else {
-            headers = new HttpCachedHeadersImpl();
-        }
-
-        if (headerSize > 0) {
-            int startIndex = buffer.startIndex();
-            for (; ; ) {
-                byte headerCode = buffer.read();
-                ByteString headerName;
-                if (headerCode == CUSTOM_HEADER_CODE) {
-                    headerName = ncDataHelper.readByteStringNullTerminated(buffer);
-                } else {
-                    headerName = NcHttpDataUtils.codeToHeader(headerCode);
-                    if (headerName == null) {
-                        throw new IOException("Unknown header code '" + headerCode + "'.");
-                    }
-                }
-
-                ByteString headerValue = ncDataHelper.readByteStringNullTerminated(buffer);
-                headers.add(headerName, headerValue);
-
-                int readed = buffer.startIndex() - startIndex;
-                if (readed == headerSize) {
-                    break;
-                } else if (readed > headerSize) {
-                    throw new IOException("Readed bytes > header size.");
-                }
-            }
-        }
-
-        return headers;
-    }
-
-    private DataSource decodeContent(ByteBuff buffer) throws IOException {
-        long contentSize = ncDataHelper.readLongVLC(buffer);
-        if (contentSize == 0) {
-            return null;
-        } else if (contentSize <= Integer.MAX_VALUE) {
-            int contentSizeInt = (int) contentSize;
-            ByteBuff data = allocator.allocate();
-            buffer.read(data, contentSizeInt);
-            return new ByteBuffDataSource(data);
-        } else {
-            throw new IOException("Too big content size > Integer.MAX_VALUE");
-        }
-    }
-
-    public HttpRequest decodeRequest(ByteBuff buffer) throws IOException {
-        HttpMethod method = decodeMethod(buffer);
-        ByteString uri = ncDataHelper.readByteStringNullTerminated(buffer);
-        HttpRequest req = new HttpRequest(uri, method);
-        req.setVersion(decodeVersion(buffer));
-        req.setHeaders(decodeHeaders(buffer));
-        return req;
-    }
-
-    public HttpRequest decodeFullRequest(ByteBuff buffer) throws IOException {
-        HttpRequest req = decodeRequest(buffer);
-        req.setContent(decodeContent(buffer));
-        return req;
-    }
-
-    public HttpResponse decodeResponse(ByteBuff buffer) throws IOException {
-        int statusCode = ncDataHelper.readInt2(buffer);
-        ByteString reasonPhrase = ncDataHelper.readByteStringNullTerminated(buffer);
-        HttpStatus status = new HttpStatus(statusCode, reasonPhrase);
-        HttpResponse resp = new HttpResponse(status);
-        resp.setVersion(decodeVersion(buffer));
-        resp.setHeaders(decodeHeaders(buffer));
-        return resp;
-    }
-
-    public HttpResponse decodeFullResponse(ByteBuff buffer) throws IOException {
-        HttpResponse resp = decodeResponse(buffer);
-        resp.setContent(decodeContent(buffer));
-        return resp;
-    }
-
-    public HttpMessage decodeMessage(ByteBuff buffer) throws IOException {
-        byte flags = buffer.read();
-
-        HttpMessage msg;
-        if ((flags & FLAG_REQUEST) != 0) {
-            msg = decodeRequest(buffer);
-        } else {
-            msg = decodeResponse(buffer);
-        }
-
-        return msg;
-    }
-
-    public HttpReqResp decodeMessages(ByteBuff buffer) throws IOException {
-        return decodeMessages(buffer, false, false);
-    }
-
-    public HttpReqResp decodeMessages(ByteBuff buffer, boolean skipRequest, boolean skipResponse) throws IOException {
-        byte flags = buffer.read();
-        HttpRequest req = null;
-        if ((flags & FLAG_REQUEST) != 0) {
-            if (skipRequest) {
-                skipRequest(buffer);
-            } else {
-                req = decodeFullRequest(buffer);
-            }
-        }
-
-        HttpResponse resp = null;
-        if ((flags & FLAG_RESPONSE) != 0) {
-            if (skipResponse) {
-                skipResponse(buffer);
-            } else {
-                resp = decodeFullResponse(buffer);
-            }
-        }
-
-        buffer.release();
-        return new HttpReqResp(req, resp);
-    }
-
-    public SessionPayloadEvent read(NcDataBlockReader reader) throws IOException {
-        return null;
-    }
-
-}
--- a/stress-tester/src/main/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataWriter.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-package com.passus.st.reader.nc;
-
-import com.passus.commons.Assert;
-import com.passus.data.ByteBuff;
-import com.passus.data.DataSource;
-import com.passus.data.HeapByteBuff;
-import com.passus.net.http.*;
-import com.passus.st.client.SessionPayloadEvent;
-import com.passus.st.emitter.SessionInfo;
-
-import java.io.IOException;
-
-import static com.passus.st.Protocols.HTTP;
-import static com.passus.st.reader.nc.NcHttpDataUtils.FLAG_REQUEST;
-import static com.passus.st.reader.nc.NcHttpDataUtils.FLAG_RESPONSE;
-
-/**
- * @author Mirosław Hawrot
- */
-public class HttpSessionPayloadEventDataWriter {
-
-    private final NcDataHelper ncDataHelper = NcDataHelper.getInstance();
-
-    private HttpWriteMode reqWriteMode = HttpWriteMode.FULL_MESSAGE;
-
-    private HttpWriteMode respWriteMode = HttpWriteMode.FULL_MESSAGE;
-
-    public void setRequestWriteMode(HttpWriteMode mode) {
-        Assert.notNull(mode, "mode");
-        this.reqWriteMode = mode;
-    }
-
-    public void setResponseWriteMode(HttpWriteMode mode) {
-        Assert.notNull(mode, "mode");
-        this.respWriteMode = mode;
-    }
-
-    public int encodeHeaders(HttpHeaders headers, ByteBuff buff) {
-        ByteBuff headersBuff = new HeapByteBuff();
-        for (HttpHeaderEntry entry : headers.getEntries()) {
-            int code = NcHttpDataUtils.headerToCode(entry.getName());
-            if (code == -1) {
-                headersBuff.append(NcHttpDataUtils.CUSTOM_HEADER_CODE);
-                ncDataHelper.writeByteStringNullTerminated(headersBuff, entry.getName());
-            } else {
-                headersBuff.append((byte) code);
-            }
-
-            ncDataHelper.writeByteStringNullTerminated(headersBuff, entry.getValue());
-        }
-
-        int len = headersBuff.readableBytes();
-        len += ncDataHelper.writeLongVLC(buff, headersBuff.readableBytes());
-        buff.append(headersBuff);
-        return len;
-    }
-
-    private int encodeMethod(HttpMethod method, ByteBuff buff) throws IOException {
-        byte code;
-        int size = 1;
-        if (HttpMethod.GET.equals(method)) {
-            code = 1;
-        } else if (HttpMethod.POST.equals(method)) {
-            code = 2;
-        } else if (HttpMethod.PUT.equals(method)) {
-            code = 3;
-        } else if (HttpMethod.DELETE.equals(method)) {
-            code = 4;
-        } else if (HttpMethod.CONNECT.equals(method)) {
-            code = 5;
-        } else if (HttpMethod.HEAD.equals(method)) {
-            code = 6;
-        } else if (HttpMethod.OPTIONS.equals(method)) {
-            code = 7;
-        } else if (HttpMethod.TRACE.equals(method)) {
-            code = 8;
-        } else if (HttpMethod.PATCH.equals(method)) {
-            code = 9;
-        } else {
-            code = 0;
-        }
-
-        buff.append(code);
-        if (code == 0) {
-            size += ncDataHelper.writeByteStringNullTerminated(buff, method.toByteString());
-        }
-
-        return size;
-    }
-
-    private long encodeVersion(HttpMessage msg, ByteBuff buff) throws IOException {
-        if (HttpConsts.VERSION_1_0 == msg.getVersion()) {
-            buff.append(NcHttpDataUtils.VERSION_1_0);
-        } else if (HttpConsts.VERSION_1_1 == msg.getVersion()) {
-            buff.append(NcHttpDataUtils.VERSION_1_1);
-        } else {
-            throw new IOException("Not supported HTTP version '" + msg.getVersion() + "'.");
-        }
-
-        return 1;
-    }
-
-    private long encodeRequest(HttpRequest req, ByteBuff buff) throws IOException {
-        long size = 0;
-        size += encodeMethod(req.getMethod(), buff);
-        size += ncDataHelper.writeByteStringNullTerminated(buff, req.getUri());
-        size += encodeVersion(req, buff);
-        size += encodeHeaders(req.getHeaders(), buff);
-        return size;
-    }
-
-    private long encodeResponse(HttpResponse resp, ByteBuff buff) throws IOException {
-        long size = 0;
-        ncDataHelper.writeInt2(buff, resp.getStatus().getCode());
-        size += 2;
-        size += ncDataHelper.writeByteStringNullTerminated(buff, resp.getStatus().getReasonPhrase());
-        size += encodeVersion(resp, buff);
-        size += encodeHeaders(resp.getHeaders(), buff);
-        return size;
-    }
-
-    public long encodeMessage(HttpMessage msg, ByteBuff buff) throws IOException {
-        return encodeMessage(msg, buff, true);
-    }
-
-    public long encodeMessage(HttpMessage msg, ByteBuff buff, boolean appendFlags) throws IOException {
-        long size = 0;
-        if (msg.isRequest()) {
-            HttpRequest req = (HttpRequest) msg;
-
-            if (appendFlags) {
-                buff.append(FLAG_REQUEST);
-                size++;
-            }
-
-            size += encodeRequest(req, buff);
-        } else {
-            HttpResponse resp = (HttpResponse) msg;
-
-            if (appendFlags) {
-                buff.append(FLAG_RESPONSE);
-                size++;
-            }
-
-            size += encodeResponse(resp, buff);
-        }
-
-        return size;
-    }
-
-
-    public void encodeFullMessages(long timestamp, SessionInfo session, HttpRequest req, HttpResponse resp, NcDataBlockWriter writer) throws IOException {
-        ByteBuff reqBuffer = new HeapByteBuff();
-        ByteBuff respBuffer = new HeapByteBuff();
-        byte flags = 0;
-        DataSource reqContent = null;
-        if (reqWriteMode.code() > HttpWriteMode.SKIP.code()
-                && req != null) {
-            flags |= FLAG_REQUEST;
-            encodeRequest(req, reqBuffer);
-
-            if (reqWriteMode == HttpWriteMode.FULL_MESSAGE) {
-                reqContent = req.getContent();
-                if (reqContent != null) {
-                    reqContent.available();
-                    ncDataHelper.writeLongVLC(reqBuffer, reqContent.available());
-                } else {
-                    ncDataHelper.writeLongVLC(reqBuffer, 0);
-                }
-            } else {
-                ncDataHelper.writeLongVLC(reqBuffer, 0);
-            }
-        }
-
-        DataSource respContent = null;
-        if (respWriteMode.code() > HttpWriteMode.SKIP.code()
-                && resp != null) {
-            flags |= FLAG_RESPONSE;
-
-            encodeResponse(resp, respBuffer);
-
-            if (respWriteMode == HttpWriteMode.FULL_MESSAGE) {
-                respContent = resp.getContent();
-                if (respContent != null) {
-                    respContent.available();
-                    ncDataHelper.writeLongVLC(respBuffer, respContent.available());
-                } else {
-                    ncDataHelper.writeLongVLC(respBuffer, 0);
-                }
-            } else {
-                ncDataHelper.writeLongVLC(respBuffer, 0);
-            }
-        }
-
-        writer.writeSessionPayloadHeader(timestamp, session, (byte) 1);
-        writer.writeSessionPayloadData(new byte[]{flags});
-        writer.writeSessionPayloadData(reqBuffer);
-        if (reqContent != null) {
-            writer.writeSessionPayloadData(reqContent);
-        }
-
-        writer.writeSessionPayloadData(respBuffer);
-        if (respContent != null) {
-            writer.writeSessionPayloadData(respContent);
-        }
-        writer.closeSessionPayloadBlock();
-    }
-
-    public void write(SessionPayloadEvent event, NcDataBlockWriter writer) throws IOException {
-        if (event.getProtocolId() != HTTP) {
-            throw new IllegalArgumentException("event.getProtocolId() != HTTP");
-        }
-
-        long time = event.getTimestamp();
-        SessionInfo session = event.getSessionInfo();
-        encodeFullMessages(time, session, (HttpRequest) event.getRequest(), (HttpResponse) event.getResponse(), writer);
-    }
-
-}
--- a/stress-tester/src/main/java/com/passus/st/reader/nc/HttpWriteMode.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-package com.passus.st.reader.nc;
-
-/**
- *
- * @author mikolaj.podbielski
- */
-public enum HttpWriteMode {
-
-    SKIP(0),
-    HEADERS_ONLY(1),
-    FULL_MESSAGE(2);
-    /*FULL_MESSAGE_IF_TAGGED(3); - implementacja w przyszlosci*/
-
-    private final int code;
-
-    private HttpWriteMode(int code) {
-        this.code = code;
-    }
-
-    public int code() {
-        return code;
-    }
-
-    public static HttpWriteMode defaultMode() {
-        return FULL_MESSAGE;
-    }
-}
--- a/stress-tester/src/main/java/com/passus/st/reader/nc/NcDataBlockWriter.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcDataBlockWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -387,7 +387,7 @@
         currentBlockStage = BLOCK_STAGE_CONTENT_WRITE;
     }
 
-    private ByteBuffer wrapData(Object data) throws IOException {
+    public static ByteBuffer wrapData(Object data) throws IOException {
         ByteBuffer dataBuffer;
         if (data == null) {
             return ByteBuffer.allocate(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcDataUtils.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,138 @@
+package com.passus.st.reader.nc;
+
+import com.passus.data.ByteString;
+import com.passus.net.http.HttpHeaders;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class NcDataUtils {
+
+    public static final byte FLAG_REQUEST = (byte) 0b10000000;
+
+    public static final byte FLAG_RESPONSE = (byte) 0b01000000;
+
+    public static final byte FLAG_ENCODED = (byte) 0b00100000;
+
+    public static final byte FLAG_COMPRESSED = (byte) 0b00010000;
+
+    public static final byte VERSION_1_0 = 1;
+
+    public static final byte VERSION_1_1 = 2;
+
+    public static final int CUSTOM_HEADER_CODE = 0;
+
+    private static final Map<Byte, ByteString> CODE_TO_HEADER;
+
+    private static final Map<ByteString, Byte> HEADER_TO_CODE;
+
+    static {
+        Map<Byte, ByteString> codeToHeader = new HashMap<>();
+        codeToHeader.put((byte) 1, HttpHeaders.ACCEPT);
+        codeToHeader.put((byte) 2, HttpHeaders.ACCEPT_CHARSET);
+        codeToHeader.put((byte) 3, HttpHeaders.ACCEPT_ENCODING);
+        codeToHeader.put((byte) 4, HttpHeaders.ACCEPT_LANGUAGE);
+        codeToHeader.put((byte) 5, HttpHeaders.ACCEPT_RANGES);
+        codeToHeader.put((byte) 6, HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS);
+        codeToHeader.put((byte) 7, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS);
+        codeToHeader.put((byte) 8, HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS);
+        codeToHeader.put((byte) 9, HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
+        codeToHeader.put((byte) 10, HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS);
+        codeToHeader.put((byte) 11, HttpHeaders.ACCESS_CONTROL_MAX_AGE);
+        codeToHeader.put((byte) 12, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
+        codeToHeader.put((byte) 13, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
+        codeToHeader.put((byte) 14, HttpHeaders.AGE);
+        codeToHeader.put((byte) 15, HttpHeaders.ALLOW);
+        codeToHeader.put((byte) 16, HttpHeaders.AUTHORIZATION);
+        codeToHeader.put((byte) 17, HttpHeaders.CACHE_CONTROL);
+        codeToHeader.put((byte) 18, HttpHeaders.CONNECTION);
+        codeToHeader.put((byte) 19, HttpHeaders.CONTENT_DISPOSITION);
+        codeToHeader.put((byte) 20, HttpHeaders.CONTENT_ENCODING);
+        codeToHeader.put((byte) 21, HttpHeaders.CONTENT_LANGUAGE);
+        codeToHeader.put((byte) 22, HttpHeaders.CONTENT_LENGTH);
+        codeToHeader.put((byte) 23, HttpHeaders.CONTENT_LOCATION);
+        codeToHeader.put((byte) 24, HttpHeaders.CONTENT_RANGE);
+        codeToHeader.put((byte) 25, HttpHeaders.CONTENT_SECURITY_POLICY);
+        codeToHeader.put((byte) 26, HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
+        codeToHeader.put((byte) 27, HttpHeaders.CONTENT_TYPE);
+        codeToHeader.put((byte) 28, HttpHeaders.COOKIE);
+        codeToHeader.put((byte) 29, HttpHeaders.COOKIE2);
+        codeToHeader.put((byte) 30, HttpHeaders.DNT);
+        codeToHeader.put((byte) 31, HttpHeaders.DATE);
+        codeToHeader.put((byte) 32, HttpHeaders.ETAG);
+        codeToHeader.put((byte) 33, HttpHeaders.EXPECT);
+        codeToHeader.put((byte) 34, HttpHeaders.EXPIRES);
+        codeToHeader.put((byte) 35, HttpHeaders.FORWARDED);
+        codeToHeader.put((byte) 36, HttpHeaders.FROM);
+        codeToHeader.put((byte) 37, HttpHeaders.HOST);
+        codeToHeader.put((byte) 38, HttpHeaders.IF_MATCH);
+        codeToHeader.put((byte) 39, HttpHeaders.IF_MODIFIED_SINCE);
+        codeToHeader.put((byte) 40, HttpHeaders.IF_NONE_MATCH);
+        codeToHeader.put((byte) 41, HttpHeaders.IF_RANGE);
+        codeToHeader.put((byte) 42, HttpHeaders.IF_UNMODIFIED_SINCE);
+        codeToHeader.put((byte) 43, HttpHeaders.KEEP_ALIVE);
+        codeToHeader.put((byte) 44, HttpHeaders.LARGE_ALLOCATION);
+        codeToHeader.put((byte) 45, HttpHeaders.LAST_MODIFIED);
+        codeToHeader.put((byte) 46, HttpHeaders.LOCATION);
+        codeToHeader.put((byte) 47, HttpHeaders.ORIGIN);
+        codeToHeader.put((byte) 48, HttpHeaders.P3P);
+        codeToHeader.put((byte) 49, HttpHeaders.PRAGMA);
+        codeToHeader.put((byte) 50, HttpHeaders.PROXY_AUTHENTICATE);
+        codeToHeader.put((byte) 51, HttpHeaders.PROXY_AUTHORIZATION);
+        codeToHeader.put((byte) 52, HttpHeaders.PROXY_CONNECTION);
+        codeToHeader.put((byte) 53, HttpHeaders.PUBLIC_KEY_PINS);
+        codeToHeader.put((byte) 54, HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
+        codeToHeader.put((byte) 55, HttpHeaders.RANGE);
+        codeToHeader.put((byte) 56, HttpHeaders.REFERER);
+        codeToHeader.put((byte) 57, HttpHeaders.REFERRER_POLICY);
+        codeToHeader.put((byte) 58, HttpHeaders.RETRY_AFTER);
+        codeToHeader.put((byte) 59, HttpHeaders.SERVER);
+        codeToHeader.put((byte) 60, HttpHeaders.SET_COOKIE);
+        codeToHeader.put((byte) 61, HttpHeaders.SET_COOKIE2);
+        codeToHeader.put((byte) 62, HttpHeaders.SOURCEMAP);
+        codeToHeader.put((byte) 63, HttpHeaders.STRICT_TRANSPORT_SECURITY);
+        codeToHeader.put((byte) 64, HttpHeaders.TE);
+        codeToHeader.put((byte) 65, HttpHeaders.TIMING_ALLOW_ORIGIN);
+        codeToHeader.put((byte) 66, HttpHeaders.TK);
+        codeToHeader.put((byte) 67, HttpHeaders.TRAILER);
+        codeToHeader.put((byte) 68, HttpHeaders.TRANSFER_ENCODING);
+        codeToHeader.put((byte) 69, HttpHeaders.UPGRADE_INSECURE_REQUESTS);
+        codeToHeader.put((byte) 70, HttpHeaders.USER_AGENT);
+        codeToHeader.put((byte) 71, HttpHeaders.VARY);
+        codeToHeader.put((byte) 72, HttpHeaders.VIA);
+        codeToHeader.put((byte) 73, HttpHeaders.WWW_AUTHENTICATE);
+        codeToHeader.put((byte) 74, HttpHeaders.WARNING);
+        codeToHeader.put((byte) 75, HttpHeaders.X_CONTENT_TYPE_OPTIONS);
+        codeToHeader.put((byte) 76, HttpHeaders.X_DNS_PREFETCH_CONTROL);
+        codeToHeader.put((byte) 77, HttpHeaders.X_FORWARDED_FOR);
+        codeToHeader.put((byte) 78, HttpHeaders.X_FORWARDED_HOST);
+        codeToHeader.put((byte) 79, HttpHeaders.X_FORWARDED_PROTO);
+        codeToHeader.put((byte) 80, HttpHeaders.X_FRAME_OPTIONS);
+        codeToHeader.put((byte) 81, HttpHeaders.X_REQUESTED_WITH);
+        codeToHeader.put((byte) 82, HttpHeaders.X_XSS_PROTECTION);
+
+        Map<ByteString, Byte> headerToCode = new HashMap<>(codeToHeader.size());
+        codeToHeader.forEach((code, header) -> headerToCode.put(header, code));
+
+        CODE_TO_HEADER = Collections.unmodifiableMap(codeToHeader);
+        HEADER_TO_CODE = Collections.unmodifiableMap(headerToCode);
+    }
+
+    public static byte headerToCode(CharSequence name) {
+        ByteString bs = ByteString.create(name);
+        Byte code = HEADER_TO_CODE.get(bs);
+        if (code == null) {
+            return -1;
+        }
+
+        return code;
+    }
+
+    public static ByteString codeToHeader(byte code) {
+        return CODE_TO_HEADER.get(code);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcDnsPayloadWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,12 @@
+package com.passus.st.reader.nc;
+
+import com.passus.net.dns.Dns;
+import com.passus.net.dns.DnsEncoder;
+import com.passus.st.source.AbstractNcPayloadWriter;
+
+public class NcDnsPayloadWriter extends AbstractNcPayloadWriter<Dns, Dns> {
+
+    public NcDnsPayloadWriter() {
+        super(new DnsEncoder(), new DnsEncoder());
+    }
+}
--- a/stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpDataUtils.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-package com.passus.st.reader.nc;
-
-import com.passus.data.ByteString;
-import com.passus.net.http.HttpHeaders;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- * @author Mirosław Hawrot
- */
-public class NcHttpDataUtils {
-
-    public static final byte FLAG_REQUEST = (byte) 0b10000000;
-
-    public static final byte FLAG_RESPONSE = (byte) 0b01000000;
-
-    public static final byte FLAG_ENCODED = (byte) 0b00100000;
-
-    public static final byte FLAG_COMPRESSED = (byte) 0b00010000;
-
-    public static final byte VERSION_1_0 = 1;
-
-    public static final byte VERSION_1_1 = 2;
-
-    public static final int CUSTOM_HEADER_CODE = 0;
-
-    private static final Map<Byte, ByteString> CODE_TO_HEADER;
-
-    private static final Map<ByteString, Byte> HEADER_TO_CODE;
-
-    static {
-        Map<Byte, ByteString> codeToHeader = new HashMap<>();
-        codeToHeader.put((byte) 1, HttpHeaders.ACCEPT);
-        codeToHeader.put((byte) 2, HttpHeaders.ACCEPT_CHARSET);
-        codeToHeader.put((byte) 3, HttpHeaders.ACCEPT_ENCODING);
-        codeToHeader.put((byte) 4, HttpHeaders.ACCEPT_LANGUAGE);
-        codeToHeader.put((byte) 5, HttpHeaders.ACCEPT_RANGES);
-        codeToHeader.put((byte) 6, HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS);
-        codeToHeader.put((byte) 7, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS);
-        codeToHeader.put((byte) 8, HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS);
-        codeToHeader.put((byte) 9, HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
-        codeToHeader.put((byte) 10, HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS);
-        codeToHeader.put((byte) 11, HttpHeaders.ACCESS_CONTROL_MAX_AGE);
-        codeToHeader.put((byte) 12, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
-        codeToHeader.put((byte) 13, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
-        codeToHeader.put((byte) 14, HttpHeaders.AGE);
-        codeToHeader.put((byte) 15, HttpHeaders.ALLOW);
-        codeToHeader.put((byte) 16, HttpHeaders.AUTHORIZATION);
-        codeToHeader.put((byte) 17, HttpHeaders.CACHE_CONTROL);
-        codeToHeader.put((byte) 18, HttpHeaders.CONNECTION);
-        codeToHeader.put((byte) 19, HttpHeaders.CONTENT_DISPOSITION);
-        codeToHeader.put((byte) 20, HttpHeaders.CONTENT_ENCODING);
-        codeToHeader.put((byte) 21, HttpHeaders.CONTENT_LANGUAGE);
-        codeToHeader.put((byte) 22, HttpHeaders.CONTENT_LENGTH);
-        codeToHeader.put((byte) 23, HttpHeaders.CONTENT_LOCATION);
-        codeToHeader.put((byte) 24, HttpHeaders.CONTENT_RANGE);
-        codeToHeader.put((byte) 25, HttpHeaders.CONTENT_SECURITY_POLICY);
-        codeToHeader.put((byte) 26, HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
-        codeToHeader.put((byte) 27, HttpHeaders.CONTENT_TYPE);
-        codeToHeader.put((byte) 28, HttpHeaders.COOKIE);
-        codeToHeader.put((byte) 29, HttpHeaders.COOKIE2);
-        codeToHeader.put((byte) 30, HttpHeaders.DNT);
-        codeToHeader.put((byte) 31, HttpHeaders.DATE);
-        codeToHeader.put((byte) 32, HttpHeaders.ETAG);
-        codeToHeader.put((byte) 33, HttpHeaders.EXPECT);
-        codeToHeader.put((byte) 34, HttpHeaders.EXPIRES);
-        codeToHeader.put((byte) 35, HttpHeaders.FORWARDED);
-        codeToHeader.put((byte) 36, HttpHeaders.FROM);
-        codeToHeader.put((byte) 37, HttpHeaders.HOST);
-        codeToHeader.put((byte) 38, HttpHeaders.IF_MATCH);
-        codeToHeader.put((byte) 39, HttpHeaders.IF_MODIFIED_SINCE);
-        codeToHeader.put((byte) 40, HttpHeaders.IF_NONE_MATCH);
-        codeToHeader.put((byte) 41, HttpHeaders.IF_RANGE);
-        codeToHeader.put((byte) 42, HttpHeaders.IF_UNMODIFIED_SINCE);
-        codeToHeader.put((byte) 43, HttpHeaders.KEEP_ALIVE);
-        codeToHeader.put((byte) 44, HttpHeaders.LARGE_ALLOCATION);
-        codeToHeader.put((byte) 45, HttpHeaders.LAST_MODIFIED);
-        codeToHeader.put((byte) 46, HttpHeaders.LOCATION);
-        codeToHeader.put((byte) 47, HttpHeaders.ORIGIN);
-        codeToHeader.put((byte) 48, HttpHeaders.P3P);
-        codeToHeader.put((byte) 49, HttpHeaders.PRAGMA);
-        codeToHeader.put((byte) 50, HttpHeaders.PROXY_AUTHENTICATE);
-        codeToHeader.put((byte) 51, HttpHeaders.PROXY_AUTHORIZATION);
-        codeToHeader.put((byte) 52, HttpHeaders.PROXY_CONNECTION);
-        codeToHeader.put((byte) 53, HttpHeaders.PUBLIC_KEY_PINS);
-        codeToHeader.put((byte) 54, HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
-        codeToHeader.put((byte) 55, HttpHeaders.RANGE);
-        codeToHeader.put((byte) 56, HttpHeaders.REFERER);
-        codeToHeader.put((byte) 57, HttpHeaders.REFERRER_POLICY);
-        codeToHeader.put((byte) 58, HttpHeaders.RETRY_AFTER);
-        codeToHeader.put((byte) 59, HttpHeaders.SERVER);
-        codeToHeader.put((byte) 60, HttpHeaders.SET_COOKIE);
-        codeToHeader.put((byte) 61, HttpHeaders.SET_COOKIE2);
-        codeToHeader.put((byte) 62, HttpHeaders.SOURCEMAP);
-        codeToHeader.put((byte) 63, HttpHeaders.STRICT_TRANSPORT_SECURITY);
-        codeToHeader.put((byte) 64, HttpHeaders.TE);
-        codeToHeader.put((byte) 65, HttpHeaders.TIMING_ALLOW_ORIGIN);
-        codeToHeader.put((byte) 66, HttpHeaders.TK);
-        codeToHeader.put((byte) 67, HttpHeaders.TRAILER);
-        codeToHeader.put((byte) 68, HttpHeaders.TRANSFER_ENCODING);
-        codeToHeader.put((byte) 69, HttpHeaders.UPGRADE_INSECURE_REQUESTS);
-        codeToHeader.put((byte) 70, HttpHeaders.USER_AGENT);
-        codeToHeader.put((byte) 71, HttpHeaders.VARY);
-        codeToHeader.put((byte) 72, HttpHeaders.VIA);
-        codeToHeader.put((byte) 73, HttpHeaders.WWW_AUTHENTICATE);
-        codeToHeader.put((byte) 74, HttpHeaders.WARNING);
-        codeToHeader.put((byte) 75, HttpHeaders.X_CONTENT_TYPE_OPTIONS);
-        codeToHeader.put((byte) 76, HttpHeaders.X_DNS_PREFETCH_CONTROL);
-        codeToHeader.put((byte) 77, HttpHeaders.X_FORWARDED_FOR);
-        codeToHeader.put((byte) 78, HttpHeaders.X_FORWARDED_HOST);
-        codeToHeader.put((byte) 79, HttpHeaders.X_FORWARDED_PROTO);
-        codeToHeader.put((byte) 80, HttpHeaders.X_FRAME_OPTIONS);
-        codeToHeader.put((byte) 81, HttpHeaders.X_REQUESTED_WITH);
-        codeToHeader.put((byte) 82, HttpHeaders.X_XSS_PROTECTION);
-
-        Map<ByteString, Byte> headerToCode = new HashMap<>(codeToHeader.size());
-        codeToHeader.forEach((code, header) -> headerToCode.put(header, code));
-
-        CODE_TO_HEADER = Collections.unmodifiableMap(codeToHeader);
-        HEADER_TO_CODE = Collections.unmodifiableMap(headerToCode);
-    }
-
-    public static byte headerToCode(CharSequence name) {
-        ByteString bs = ByteString.create(name);
-        Byte code = HEADER_TO_CODE.get(bs);
-        if (code == null) {
-            return -1;
-        }
-
-        return code;
-    }
-
-    public static ByteString codeToHeader(byte code) {
-        return CODE_TO_HEADER.get(code);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpPayloadReader.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,225 @@
+package com.passus.st.reader.nc;
+
+import com.passus.commons.Assert;
+import com.passus.data.*;
+import com.passus.net.http.*;
+import com.passus.st.client.SessionPayloadEvent;
+import com.passus.st.client.http.HttpReqResp;
+import com.passus.st.source.NcPayloadReader;
+
+import java.io.IOException;
+
+import static com.passus.st.reader.nc.NcDataUtils.*;
+
+/**
+ * @author Mirosław Hawrot
+ */
+public class NcHttpPayloadReader implements NcPayloadReader {
+
+    private final NcDataHelper ncDataHelper = NcDataHelper.getInstance();
+
+    private ByteBuffAllocator allocator = new DefaultByteBuffAllocator();
+
+    public ByteBuffAllocator getAllocator() {
+        return allocator;
+    }
+
+    public void setAllocator(ByteBuffAllocator allocator) {
+        Assert.notNull(allocator, "allocator");
+        this.allocator = allocator;
+    }
+
+    private void skipRequest(ByteBuff buffer) throws IOException {
+        ncDataHelper.skipByteStringNullTerminated(buffer);
+        ncDataHelper.skipByteStringNullTerminated(buffer);
+        buffer.read();
+        skipHeaders(buffer);
+    }
+
+    private void skipResponse(ByteBuff buffer) throws IOException {
+        buffer.skipBytes(2);
+        ncDataHelper.skipByteStringNullTerminated(buffer);
+        buffer.read();
+        skipHeaders(buffer);
+    }
+
+    public int decodeVersion(ByteBuff buffer) throws IOException {
+        byte b = buffer.read();
+        if (b == NcDataUtils.VERSION_1_0) {
+            return HttpConsts.VERSION_1_0;
+        } else if (b == NcDataUtils.VERSION_1_1) {
+            return HttpConsts.VERSION_1_1;
+        }
+
+        throw new IOException("Not supported HTTP version '" + b + "'.");
+    }
+
+    private void skipHeaders(ByteBuff buffer) throws IOException {
+        long headerSize = ncDataHelper.readLongVLC(buffer);
+        if (headerSize <= Integer.MAX_VALUE) {
+            buffer.skipBytes((int) headerSize);
+        } else {
+            throw new IOException("Too big header size > Integer.MAX_VALUE");
+        }
+    }
+
+    private HttpMethod decodeMethod(ByteBuff buff) throws IOException {
+        byte code = buff.read();
+        switch (code) {
+            case 0:
+                ByteString methodStr = ncDataHelper.readByteStringNullTerminated(buff);
+                return new HttpMethod(methodStr);
+            case 1:
+                return HttpMethod.GET;
+            case 2:
+                return HttpMethod.POST;
+            case 3:
+                return HttpMethod.PUT;
+            case 4:
+                return HttpMethod.DELETE;
+            case 5:
+                return HttpMethod.CONNECT;
+            case 6:
+                return HttpMethod.HEAD;
+            case 7:
+                return HttpMethod.OPTIONS;
+            case 8:
+                return HttpMethod.TRACE;
+            case 9:
+                return HttpMethod.PATCH;
+            default:
+                throw new IOException("Unknwon request method code '" + code + "'.");
+
+        }
+    }
+
+    public HttpHeaders decodeHeaders(ByteBuff buffer) throws IOException {
+        long headerSize = ncDataHelper.readLongVLC(buffer);
+        HttpHeaders headers;
+        if (HttpHeadersDecoder.isDefaultEnableCachedHeaders()) {
+            headers = new HttpHeadersImpl();
+        } else {
+            headers = new HttpCachedHeadersImpl();
+        }
+
+        if (headerSize > 0) {
+            int startIndex = buffer.startIndex();
+            for (; ; ) {
+                byte headerCode = buffer.read();
+                ByteString headerName;
+                if (headerCode == CUSTOM_HEADER_CODE) {
+                    headerName = ncDataHelper.readByteStringNullTerminated(buffer);
+                } else {
+                    headerName = NcDataUtils.codeToHeader(headerCode);
+                    if (headerName == null) {
+                        throw new IOException("Unknown header code '" + headerCode + "'.");
+                    }
+                }
+
+                ByteString headerValue = ncDataHelper.readByteStringNullTerminated(buffer);
+                headers.add(headerName, headerValue);
+
+                int readed = buffer.startIndex() - startIndex;
+                if (readed == headerSize) {
+                    break;
+                } else if (readed > headerSize) {
+                    throw new IOException("Readed bytes > header size.");
+                }
+            }
+        }
+
+        return headers;
+    }
+
+    private DataSource decodeContent(ByteBuff buffer) throws IOException {
+        long contentSize = ncDataHelper.readLongVLC(buffer);
+        if (contentSize == 0) {
+            return null;
+        } else if (contentSize <= Integer.MAX_VALUE) {
+            int contentSizeInt = (int) contentSize;
+            ByteBuff data = allocator.allocate();
+            buffer.read(data, contentSizeInt);
+            return new ByteBuffDataSource(data);
+        } else {
+            throw new IOException("Too big content size > Integer.MAX_VALUE");
+        }
+    }
+
+    public HttpRequest decodeRequest(ByteBuff buffer) throws IOException {
+        HttpMethod method = decodeMethod(buffer);
+        ByteString uri = ncDataHelper.readByteStringNullTerminated(buffer);
+        HttpRequest req = new HttpRequest(uri, method);
+        req.setVersion(decodeVersion(buffer));
+        req.setHeaders(decodeHeaders(buffer));
+        return req;
+    }
+
+    public HttpRequest decodeFullRequest(ByteBuff buffer) throws IOException {
+        HttpRequest req = decodeRequest(buffer);
+        req.setContent(decodeContent(buffer));
+        return req;
+    }
+
+    public HttpResponse decodeResponse(ByteBuff buffer) throws IOException {
+        int statusCode = ncDataHelper.readInt2(buffer);
+        ByteString reasonPhrase = ncDataHelper.readByteStringNullTerminated(buffer);
+        HttpStatus status = new HttpStatus(statusCode, reasonPhrase);
+        HttpResponse resp = new HttpResponse(status);
+        resp.setVersion(decodeVersion(buffer));
+        resp.setHeaders(decodeHeaders(buffer));
+        return resp;
+    }
+
+    public HttpResponse decodeFullResponse(ByteBuff buffer) throws IOException {
+        HttpResponse resp = decodeResponse(buffer);
+        resp.setContent(decodeContent(buffer));
+        return resp;
+    }
+
+    public HttpMessage decodeMessage(ByteBuff buffer) throws IOException {
+        byte flags = buffer.read();
+
+        HttpMessage msg;
+        if ((flags & FLAG_REQUEST) != 0) {
+            msg = decodeRequest(buffer);
+        } else {
+            msg = decodeResponse(buffer);
+        }
+
+        return msg;
+    }
+
+    public HttpReqResp decodeMessages(ByteBuff buffer) throws IOException {
+        return decodeMessages(buffer, false, false);
+    }
+
+    public HttpReqResp decodeMessages(ByteBuff buffer, boolean skipRequest, boolean skipResponse) throws IOException {
+        byte flags = buffer.read();
+        HttpRequest req = null;
+        if ((flags & FLAG_REQUEST) != 0) {
+            if (skipRequest) {
+                skipRequest(buffer);
+            } else {
+                req = decodeFullRequest(buffer);
+            }
+        }
+
+        HttpResponse resp = null;
+        if ((flags & FLAG_RESPONSE) != 0) {
+            if (skipResponse) {
+                skipResponse(buffer);
+            } else {
+                resp = decodeFullResponse(buffer);
+            }
+        }
+
+        buffer.release();
+        return new HttpReqResp(req, resp);
+    }
+
+    @Override
+    public SessionPayloadEvent read(NcDataBlockReader reader) throws IOException {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpPayloadWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,175 @@
+package com.passus.st.reader.nc;
+
+import com.passus.data.ByteBuff;
+import com.passus.data.DataSource;
+import com.passus.data.HeapByteBuff;
+import com.passus.net.http.*;
+import com.passus.st.source.NcPayloadWriter;
+
+import java.io.IOException;
+
+import static com.passus.st.reader.nc.NcDataBlockWriter.wrapData;
+import static com.passus.st.reader.nc.NcDataUtils.FLAG_REQUEST;
+import static com.passus.st.reader.nc.NcDataUtils.FLAG_RESPONSE;
+
+/**
+ * @author Mirosław Hawrot
+ */
+public class NcHttpPayloadWriter extends NcPayloadWriter<HttpRequest, HttpResponse> {
+
+    private final NcDataHelper ncDataHelper = NcDataHelper.getInstance();
+
+    private boolean writeRequestContent = true;
+
+    private boolean writeResponseContent = true;
+
+    public boolean isWriteRequestContent() {
+        return writeRequestContent;
+    }
+
+    public void setWriteRequestContent(boolean writeRequestContent) {
+        this.writeRequestContent = writeRequestContent;
+    }
+
+    public boolean isWriteResponseContent() {
+        return writeResponseContent;
+    }
+
+    public void setWriteResponseContent(boolean writeResponseContent) {
+        this.writeResponseContent = writeResponseContent;
+    }
+
+    public int encodeHeaders(HttpHeaders headers, ByteBuff buff) {
+        ByteBuff headersBuff = new HeapByteBuff();
+        for (HttpHeaderEntry entry : headers.getEntries()) {
+            int code = NcDataUtils.headerToCode(entry.getName());
+            if (code == -1) {
+                headersBuff.append(NcDataUtils.CUSTOM_HEADER_CODE);
+                ncDataHelper.writeByteStringNullTerminated(headersBuff, entry.getName());
+            } else {
+                headersBuff.append((byte) code);
+            }
+
+            ncDataHelper.writeByteStringNullTerminated(headersBuff, entry.getValue());
+        }
+
+        int len = headersBuff.readableBytes();
+        len += ncDataHelper.writeLongVLC(buff, headersBuff.readableBytes());
+        buff.append(headersBuff);
+        return len;
+    }
+
+    private int encodeMethod(HttpMethod method, ByteBuff buff) throws IOException {
+        byte code;
+        int size = 1;
+        if (HttpMethod.GET.equals(method)) {
+            code = 1;
+        } else if (HttpMethod.POST.equals(method)) {
+            code = 2;
+        } else if (HttpMethod.PUT.equals(method)) {
+            code = 3;
+        } else if (HttpMethod.DELETE.equals(method)) {
+            code = 4;
+        } else if (HttpMethod.CONNECT.equals(method)) {
+            code = 5;
+        } else if (HttpMethod.HEAD.equals(method)) {
+            code = 6;
+        } else if (HttpMethod.OPTIONS.equals(method)) {
+            code = 7;
+        } else if (HttpMethod.TRACE.equals(method)) {
+            code = 8;
+        } else if (HttpMethod.PATCH.equals(method)) {
+            code = 9;
+        } else {
+            code = 0;
+        }
+
+        buff.append(code);
+        if (code == 0) {
+            size += ncDataHelper.writeByteStringNullTerminated(buff, method.toByteString());
+        }
+
+        return size;
+    }
+
+    private long encodeVersion(HttpMessage msg, ByteBuff buff) throws IOException {
+        if (HttpConsts.VERSION_1_0 == msg.getVersion()) {
+            buff.append(NcDataUtils.VERSION_1_0);
+        } else if (HttpConsts.VERSION_1_1 == msg.getVersion()) {
+            buff.append(NcDataUtils.VERSION_1_1);
+        } else {
+            throw new IOException("Not supported HTTP version '" + msg.getVersion() + "'.");
+        }
+
+        return 1;
+    }
+
+    private long writeContent(HttpMessage msg, boolean writeContent, ByteBuff buff) throws IOException {
+        if (writeContent) {
+            DataSource content = msg.getContent();
+            if (content != null) {
+                ncDataHelper.writeLongVLC(buff, content.available());
+                buff.append(wrapData(content));
+                return content.available();
+            } else {
+                ncDataHelper.writeLongVLC(buff, 0);
+            }
+        } else {
+            ncDataHelper.writeLongVLC(buff, 0);
+        }
+
+        return 0;
+    }
+
+    @Override
+    protected long writeRequest(HttpRequest req, ByteBuff buff) throws IOException {
+        long size = 0;
+        size += encodeMethod(req.getMethod(), buff);
+        size += ncDataHelper.writeByteStringNullTerminated(buff, req.getUri());
+        size += encodeVersion(req, buff);
+        size += encodeHeaders(req.getHeaders(), buff);
+        size += writeContent(req, writeRequestContent, buff);
+        return size;
+    }
+
+    @Override
+    protected long writeResponse(HttpResponse resp, ByteBuff buff) throws IOException {
+        long size = 0;
+        ncDataHelper.writeInt2(buff, resp.getStatus().getCode());
+        size += 2;
+        size += ncDataHelper.writeByteStringNullTerminated(buff, resp.getStatus().getReasonPhrase());
+        size += encodeVersion(resp, buff);
+        size += encodeHeaders(resp.getHeaders(), buff);
+        size += writeContent(resp, writeResponseContent, buff);
+        return size;
+    }
+
+    public long encodeMessage(HttpMessage msg, ByteBuff buff) throws IOException {
+        return encodeMessage(msg, buff, true);
+    }
+
+    public long encodeMessage(HttpMessage msg, ByteBuff buff, boolean appendFlags) throws IOException {
+        long size = 0;
+        if (msg.isRequest()) {
+            HttpRequest req = (HttpRequest) msg;
+            if (appendFlags) {
+                buff.append(FLAG_REQUEST);
+                size++;
+            }
+
+            size += writeRequest(req, buff);
+        } else {
+            HttpResponse resp = (HttpResponse) msg;
+            if (appendFlags) {
+                buff.append(FLAG_RESPONSE);
+                size++;
+            }
+
+            size += writeResponse(resp, buff);
+        }
+
+        return size;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcHttpWriteMode.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,26 @@
+package com.passus.st.reader.nc;
+
+/**
+ * @author mikolaj.podbielski
+ */
+public enum NcHttpWriteMode {
+
+    SKIP(0),
+    HEADERS_ONLY(1),
+    FULL_MESSAGE(2);
+    /*FULL_MESSAGE_IF_TAGGED(3); - implementacja w przyszlosci*/
+
+    private final int code;
+
+    private NcHttpWriteMode(int code) {
+        this.code = code;
+    }
+
+    public int code() {
+        return code;
+    }
+
+    public static NcHttpWriteMode defaultMode() {
+        return FULL_MESSAGE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/NcNetflowPayloadWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,30 @@
+package com.passus.st.reader.nc;
+
+import com.passus.data.ByteBuff;
+import com.passus.net.netflow.*;
+import com.passus.st.source.NcPayloadWriter;
+
+import java.io.IOException;
+
+public class NcNetflowPayloadWriter extends NcPayloadWriter<Netflow, Netflow> {
+
+    private final Netflow5Encoder netflow5Encoder = new Netflow5Encoder();
+
+    private final Netflow9Encoder netflow9Encoder = new Netflow9Encoder();
+
+    @Override
+    protected long writeRequest(Netflow req, ByteBuff buff) throws IOException {
+        long startLen = buff.length();
+        if (req.getVersion() == NetflowUtils.VERSION_5) {
+            netflow5Encoder.encode((Netflow5) req, buff);
+        } else if (req.getVersion() == NetflowUtils.VERSION_9) {
+            netflow9Encoder.encode((Netflow9) req, buff);
+        }
+        return buff.length() - startLen;
+    }
+
+    @Override
+    protected long writeResponse(Netflow resp, ByteBuff buff) throws IOException {
+        return 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/source/AbstractNcPayloadWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,36 @@
+package com.passus.st.source;
+
+import com.passus.commons.Assert;
+import com.passus.data.ByteBuff;
+import com.passus.data.DataEncoder;
+
+import java.io.IOException;
+
+public abstract class AbstractNcPayloadWriter<R, S> extends NcPayloadWriter<R, S> {
+
+    private final DataEncoder<R> requestEncoder;
+
+    private final DataEncoder<S> responseEncoder;
+
+    public AbstractNcPayloadWriter(DataEncoder<R> requestEncoder, DataEncoder<S> responseEncoder) {
+        Assert.notNull(requestEncoder, "requestEncoder");
+        Assert.notNull(responseEncoder, "responseEncoder");
+        this.requestEncoder = requestEncoder;
+        this.responseEncoder = responseEncoder;
+    }
+
+    @Override
+    protected long writeRequest(R req, ByteBuff buff) throws IOException {
+        long startLen = buff.length();
+        requestEncoder.encode(req, buff);
+        return buff.length() - startLen;
+    }
+
+    @Override
+    protected long writeResponse(S resp, ByteBuff buff) throws IOException {
+        long startLen = buff.length();
+        responseEncoder.encode(resp, buff);
+        return buff.length() - startLen;
+    }
+
+}
--- a/stress-tester/src/main/java/com/passus/st/source/NcEventDestination.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/source/NcEventDestination.java	Thu Apr 09 13:49:19 2020 +0200
@@ -3,23 +3,22 @@
 import com.passus.commons.service.ServiceException;
 import com.passus.config.Configuration;
 import com.passus.config.ConfigurationContext;
-import com.passus.data.ByteBuff;
-import com.passus.data.HeapByteBuff;
-import com.passus.net.http.HttpRequest;
 import com.passus.net.http.HttpRequestEncoder;
-import com.passus.net.http.HttpResponse;
 import com.passus.net.http.HttpResponseEncoder;
 import com.passus.st.client.DataEvents.DataEnd;
 import com.passus.st.client.Event;
 import com.passus.st.client.SessionPayloadEvent;
 import com.passus.st.client.SessionStatusEvent;
-import com.passus.st.reader.nc.HttpSessionPayloadEventDataWriter;
-import com.passus.st.reader.nc.HttpWriteMode;
 import com.passus.st.reader.nc.NcDataBlockWriter;
+import com.passus.st.reader.nc.NcDnsPayloadWriter;
+import com.passus.st.reader.nc.NcHttpPayloadWriter;
+import com.passus.st.reader.nc.NcNetflowPayloadWriter;
 
 import java.io.File;
 import java.io.IOException;
 
+import static com.passus.st.Protocols.*;
+
 /**
  * @author Mirosław Hawrot
  */
@@ -35,14 +34,14 @@
 
     private final HttpResponseEncoder responseEncoder = HttpResponseEncoder.getInstance();
 
-    private final HttpSessionPayloadEventDataWriter httpPayloadWriter = new HttpSessionPayloadEventDataWriter();
+    private final NcHttpPayloadWriter httpWriter = new NcHttpPayloadWriter();
 
-    private boolean encodeData = true;
+    private final NcDnsPayloadWriter dnsWriter = new NcDnsPayloadWriter();
+
+    private final NcNetflowPayloadWriter netflowWriter = new NcNetflowPayloadWriter();
 
     private boolean allowOverwrite;
 
-    private HttpWriteMode mode = HttpWriteMode.defaultMode();
-
     public NcEventDestination() {
     }
 
@@ -67,14 +66,6 @@
         return started;
     }
 
-    public boolean isEncodeData() {
-        return encodeData;
-    }
-
-    public void setEncodeData(boolean encodeData) {
-        this.encodeData = encodeData;
-    }
-
     public boolean isAllowOverwrite() {
         return allowOverwrite;
     }
@@ -83,16 +74,6 @@
         this.allowOverwrite = allowOverwrite;
     }
 
-    public void setHttpRequestWriteMode(HttpWriteMode mode) {
-        this.mode = mode;
-        httpPayloadWriter.setRequestWriteMode(mode);
-    }
-
-    public void setHttpResponseWriteMode(HttpWriteMode mode) {
-        this.mode = mode;
-        httpPayloadWriter.setResponseWriteMode(mode);
-    }
-
     @Override
     public void start() {
         if (started) {
@@ -103,7 +84,6 @@
             writer = new NcDataBlockWriter(ncFile);
             writer.setAllowOverwrite(allowOverwrite);
             writer.open();
-
             started = true;
         } catch (Exception e) {
             stop0();
@@ -141,25 +121,18 @@
 
     }
 
-    private void writeNotEncoded(SessionPayloadEvent event) throws IOException {
-        if (event.getRequest() != null) {
-            ByteBuff buff = new HeapByteBuff();
-            requestEncoder.encode((HttpRequest) event.getRequest(), buff);
-            writer.writeSessionPayload(event.getTimestamp(), event.getSessionInfo(), (byte) 1, buff);
+    private void write(SessionPayloadEvent event) throws IOException {
+        switch (event.getProtocolId()) {
+            case HTTP:
+                httpWriter.write(event, writer);
+                break;
+            case DNS:
+                dnsWriter.write(event, writer);
+                break;
+            case NETFLOW:
+                netflowWriter.write(event, writer);
+                break;
         }
-
-        boolean encodeResponse
-                = (mode == HttpWriteMode.FULL_MESSAGE
-                || mode == HttpWriteMode.HEADERS_ONLY);
-        if (event.getResponse() != null && encodeResponse) {
-            ByteBuff buff = new HeapByteBuff();
-            responseEncoder.encode((HttpResponse) event.getResponse(), buff);
-            writer.writeSessionPayload(event.getTimestamp(), event.getSessionInfo(), (byte) 1, buff);
-        }
-    }
-
-    private void writeEncoded(SessionPayloadEvent event) throws IOException {
-        httpPayloadWriter.write(event, writer);
     }
 
     @Override
@@ -174,13 +147,7 @@
                     break;
                 case SessionPayloadEvent.TYPE:
                     SessionPayloadEvent payloadEvent = (SessionPayloadEvent) event;
-
-                    if (encodeData) {
-                        writeEncoded(payloadEvent);
-                    } else {
-                        writeNotEncoded(payloadEvent);
-                    }
-
+                    write(payloadEvent);
                     break;
                 case DataEnd.TYPE:
                     stop();
--- a/stress-tester/src/main/java/com/passus/st/source/NcEventSource.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/source/NcEventSource.java	Thu Apr 09 13:49:19 2020 +0200
@@ -14,17 +14,17 @@
 import com.passus.data.ByteBuffAllocator;
 import com.passus.data.ByteBuffDataSource;
 import com.passus.data.DefaultByteBuffAllocator;
+import com.passus.st.ReqRespPair;
 import com.passus.st.client.DataEvents;
 import com.passus.st.client.DataEvents.DataEnd;
 import com.passus.st.client.DataEvents.DataLoopEnd;
 import com.passus.st.client.EventHandler;
 import com.passus.st.client.SessionPayloadEvent;
 import com.passus.st.client.SessionStatusEvent;
-import com.passus.st.client.http.HttpReqResp;
 import com.passus.st.emitter.SessionInfo;
 import com.passus.st.plugin.PluginConstants;
-import com.passus.st.reader.nc.HttpSessionPayloadEventDataReader;
 import com.passus.st.reader.nc.NcDataBlockReader;
+import com.passus.st.reader.nc.NcHttpPayloadReader;
 import com.passus.st.reader.nc.NcSessionPayloadBlock;
 import com.passus.st.reader.nc.NcSessionStatusBlock;
 import org.apache.logging.log4j.LogManager;
@@ -55,7 +55,7 @@
 
     private EventHandler handler;
 
-    private HttpSessionPayloadEventDataReader httpReader = new HttpSessionPayloadEventDataReader();
+    private NcHttpPayloadReader httpReader = new NcHttpPayloadReader();
 
     private String name = UniqueIdGenerator.generate();
 
@@ -239,8 +239,14 @@
                 NcSessionPayloadBlock payloadBlock = (NcSessionPayloadBlock) reader.read();
                 SessionInfo sessionInfo = payloadBlock.sessionInfo();
                 sessionInfo.setSourceName(getName());
+
                 ByteBuff payload = readPayload(payloadBlock.data());
-                HttpReqResp messages = httpReader.decodeMessages(payload);
+                ReqRespPair messages = null;
+                if (payloadBlock.proto() == HTTP) {
+                    messages = httpReader.decodeMessages(payload);
+                }
+
+
                 handler.handle(new SessionPayloadEvent(sessionInfo, messages.getRequest(), messages.getResponse(), HTTP, getName()));
                 break;
             default:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/source/NcPayloadReader.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,12 @@
+package com.passus.st.source;
+
+import com.passus.st.client.SessionPayloadEvent;
+import com.passus.st.reader.nc.NcDataBlockReader;
+
+import java.io.IOException;
+
+public interface NcPayloadReader {
+
+    SessionPayloadEvent read(NcDataBlockReader reader) throws IOException;
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/source/NcPayloadWriter.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,78 @@
+package com.passus.st.source;
+
+import com.passus.data.ByteBuff;
+import com.passus.data.HeapByteBuff;
+import com.passus.st.client.SessionPayloadEvent;
+import com.passus.st.emitter.SessionInfo;
+import com.passus.st.reader.nc.NcDataBlockWriter;
+import com.passus.st.reader.nc.NcDataHelper;
+
+import java.io.IOException;
+
+import static com.passus.st.reader.nc.NcDataUtils.FLAG_REQUEST;
+import static com.passus.st.reader.nc.NcDataUtils.FLAG_RESPONSE;
+
+public abstract class NcPayloadWriter<R, S> {
+
+    public static final int FLAG_WRITE_REQUEST = 1 << 1;
+    public static final int FLAG_WRITE_RESPONSE = 1 << 2;
+
+    protected final NcDataHelper ncDataHelper = NcDataHelper.getInstance();
+
+    private int flags = FLAG_WRITE_REQUEST | FLAG_WRITE_RESPONSE;
+
+    private final ByteBuff reqBuffer = new HeapByteBuff();
+
+    private final ByteBuff respBuffer = new HeapByteBuff();
+
+    public int getFlags() {
+        return flags;
+    }
+
+    public void setFlags(int flags) {
+        this.flags = flags;
+    }
+
+    public boolean isWriteRequestFlag() {
+        return (flags & FLAG_WRITE_REQUEST) > 0;
+    }
+
+    public boolean isWriteResponseFlag() {
+        return (flags & FLAG_WRITE_RESPONSE) > 0;
+    }
+
+    protected abstract long writeRequest(R req, ByteBuff buff) throws IOException;
+
+    protected abstract long writeResponse(S resp, ByteBuff buff) throws IOException;
+
+    protected void encodeMessages(long timestamp, SessionInfo session, R req, S resp, NcDataBlockWriter writer) throws IOException {
+        try {
+            byte flags = 0;
+            if (isWriteRequestFlag() && req != null) {
+                flags |= FLAG_REQUEST;
+                writeRequest(req, reqBuffer);
+            }
+
+            if (isWriteResponseFlag() && resp != null) {
+                flags |= FLAG_RESPONSE;
+                writeResponse(resp, respBuffer);
+            }
+
+            writer.writeSessionPayloadHeader(timestamp, session, (byte) session.getProtocolId());
+            writer.writeSessionPayloadData(new byte[]{flags});
+            writer.writeSessionPayloadData(reqBuffer);
+            writer.writeSessionPayloadData(respBuffer);
+            writer.closeSessionPayloadBlock();
+        } finally {
+            reqBuffer.clear();
+            respBuffer.clear();
+        }
+    }
+
+    public void write(SessionPayloadEvent event, NcDataBlockWriter writer) throws IOException {
+        long time = event.getTimestamp();
+        SessionInfo session = event.getSessionInfo();
+        encodeMessages(time, session, (R) event.getRequest(), (S) event.getResponse(), writer);
+    }
+
+}
--- a/stress-tester/src/test/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataReaderTest.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-package com.passus.st.reader.nc;
-
-import com.passus.data.ByteBuff;
-import com.passus.data.HeapByteBuff;
-import com.passus.net.http.HttpMessage;
-import com.passus.net.http.HttpRequest;
-import com.passus.net.http.HttpRequestBuilder;
-import com.passus.net.http.HttpResponse;
-import com.passus.net.http.HttpResponseBuilder;
-import org.testng.annotations.Test;
-import static com.passus.st.utils.HttpMessageAssert.*;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
-
-/**
- *
- * @author Mirosław Hawrot
- */
-public class HttpSessionPayloadEventDataReaderTest {
-
-    private final HttpSessionPayloadEventDataWriter writer = new HttpSessionPayloadEventDataWriter();
-
-    private ByteBuff buffer = new HeapByteBuff();
-
-    private final HttpRequest req;
-
-    private final HttpResponse resp;
-
-    public HttpSessionPayloadEventDataReaderTest() {
-        req = HttpRequestBuilder.get("http://test.com/test")
-                .header("X-Header", "X-Header-Value")
-                .build();
-
-        resp = HttpResponseBuilder.ok()
-                .header("X-Header", "X-Header-Value")
-                .build();
-    }
-
-    @AfterMethod
-    public void afterMethod() {
-        buffer.clear();
-    }
-
-    @AfterClass
-    public void afterClass() {
-        buffer = null;
-    }
-
-    @Test
-    public void testDecode_Request() throws Exception {
-        writer.encodeMessage(req, buffer);
-
-        HttpSessionPayloadEventDataReader reader = new HttpSessionPayloadEventDataReader();
-        HttpMessage msgDecoded = reader.decodeMessage(buffer);
-        assertMessages(req, msgDecoded);
-    }
-
-    @Test
-    public void testDecode_Response() throws Exception {
-        writer.encodeMessage(resp, buffer);
-
-        HttpSessionPayloadEventDataReader reader = new HttpSessionPayloadEventDataReader();
-        HttpMessage msgDecoded = reader.decodeMessage(buffer);
-        assertMessages(resp, msgDecoded);
-    }
-
-    @Test
-    public void testDecode_Messages() throws Exception {
-        //writer.encodeFullMessages(req, resp, buffer);
-    }
-}
--- a/stress-tester/src/test/java/com/passus/st/reader/nc/HttpSessionPayloadEventDataWriterTest.java	Tue Apr 07 15:04:06 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-package com.passus.st.reader.nc;
-
-import com.passus.data.HeapByteBuff;
-import com.passus.net.http.*;
-import com.passus.st.client.SessionPayloadEvent;
-import com.passus.st.client.http.HttpReqResp;
-import com.passus.st.emitter.SessionInfo;
-import org.testng.annotations.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.UUID;
-
-import static com.passus.data.DataSourceUtils.toByteBuff;
-import static com.passus.st.Protocols.HTTP;
-import static com.passus.st.utils.HttpMessageAssert.assertMessages;
-import static com.passus.st.utils.HttpMessageAssert.assertMessagesContent;
-import static org.testng.AssertJUnit.*;
-
-/**
- * @author Mirosław Hawrot
- */
-public class HttpSessionPayloadEventDataWriterTest {
-
-    private final SessionInfo session;
-
-    public HttpSessionPayloadEventDataWriterTest() throws Exception {
-        session = new SessionInfo("1.1.1.1:5000", "2.2.2.2:80");
-    }
-
-    private File createTmpFile() throws IOException {
-        File tmpDir = new File(System.getProperty("java.io.tmpdir"), "st");
-        if (!tmpDir.exists()) {
-            tmpDir.mkdir();
-        }
-
-        return new File(tmpDir, "st_" + UUID.randomUUID().toString() + ".tmp");
-    }
-
-    @Test
-    public void testEncodeHeaders() throws Exception {
-        HttpHeaders headers = new HttpHeadersImpl();
-        headers.add(HttpHeaders.HOST, "test");
-        headers.add("X-HEADER", "X-HEADER-VALUE");
-        HeapByteBuff buffer = new HeapByteBuff();
-
-        HttpSessionPayloadEventDataWriter payloadWriter = new HttpSessionPayloadEventDataWriter();
-        payloadWriter.encodeHeaders(headers, buffer);
-        assertEquals(33, buffer.readableBytes());
-    }
-
-    private void writeMessages(File file, HttpRequest req, HttpResponse resp) throws Exception {
-        HttpSessionPayloadEventDataWriter payloadWriter = new HttpSessionPayloadEventDataWriter();
-        try (NcDataBlockWriter writer = new NcDataBlockWriter(file)) {
-            writer.open();
-            payloadWriter.write(new SessionPayloadEvent(session, req, resp, HTTP, ""), writer);
-        }
-    }
-
-    private NcSessionPayloadBlock readPayloadBlock(File file) throws IOException {
-        try (NcDataBlockReader reader = new NcDataBlockReader(file)) {
-            reader.open();
-
-            NcDataBlock block;
-            while ((block = reader.read()) != null) {
-                if (block.type() == NcSessionPayloadBlock.TYPE) {
-                    return (NcSessionPayloadBlock) block;
-                }
-            }
-        }
-
-        throw new IOException("Unble to find payload block.");
-    }
-
-    @Test
-    public void testWrite_HttpRequest() throws Exception {
-        File file = createTmpFile();
-        try {
-            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
-                    .header("X-Header", "X-Header-Value")
-                    .content("content")
-                    .build();
-
-            writeMessages(file, req, null);
-
-            NcSessionPayloadBlock payload = readPayloadBlock(file);
-            HttpSessionPayloadEventDataReader payloadReader = new HttpSessionPayloadEventDataReader();
-            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
-            assertFalse(reqResp == null);
-            assertTrue(reqResp.getResponse() == null);
-            assertMessages(req, reqResp.getRequest());
-            assertMessagesContent(req, reqResp.getRequest());
-        } finally {
-            file.delete();
-        }
-    }
-
-    @Test
-    public void testWrite_HttpRequest_NoContent() throws Exception {
-        File file = createTmpFile();
-        try {
-            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
-                    .header("X-Header", "X-Header-Value")
-                    .build();
-
-            writeMessages(file, req, null);
-
-            NcSessionPayloadBlock payload = readPayloadBlock(file);
-            HttpSessionPayloadEventDataReader payloadReader = new HttpSessionPayloadEventDataReader();
-            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
-            assertFalse(reqResp == null);
-            assertTrue(reqResp.getResponse() == null);
-            assertMessages(req, reqResp.getRequest());
-            assertMessagesContent(req, reqResp.getRequest());
-        } finally {
-            file.delete();
-        }
-    }
-
-    @Test
-    public void testWrite_HttpRequest_NoHeaders() throws Exception {
-        File file = createTmpFile();
-        try {
-            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
-                    .version(HttpConsts.VERSION_1_0)
-                    .build();
-
-            writeMessages(file, req, null);
-
-            NcSessionPayloadBlock payload = readPayloadBlock(file);
-            HttpSessionPayloadEventDataReader payloadReader = new HttpSessionPayloadEventDataReader();
-            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
-            assertFalse(reqResp == null);
-            assertTrue(reqResp.getResponse() == null);
-            assertMessages(req, reqResp.getRequest());
-        } finally {
-            file.delete();
-        }
-    }
-
-    @Test
-    public void testWrite_HttpResponse() throws Exception {
-        File file = createTmpFile();
-        try {
-            HttpResponse resp = HttpResponseBuilder.ok()
-                    .header("X-Header", "X-Header-Value")
-                    .content("test")
-                    .build();
-
-            writeMessages(file, null, resp);
-
-            NcSessionPayloadBlock payload = readPayloadBlock(file);
-            HttpSessionPayloadEventDataReader payloadReader = new HttpSessionPayloadEventDataReader();
-            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
-            assertFalse(reqResp == null);
-            assertTrue(reqResp.getRequest() == null);
-            assertMessages(resp, reqResp.getResponse());
-            assertMessagesContent(resp, reqResp.getResponse());
-        } finally {
-            file.delete();
-        }
-    }
-
-    @Test
-    public void testWrite_NoMessage() throws Exception {
-        File file = createTmpFile();
-        try {
-            writeMessages(file, null, null);
-
-            NcSessionPayloadBlock payload = readPayloadBlock(file);
-            HttpSessionPayloadEventDataReader payloadReader = new HttpSessionPayloadEventDataReader();
-            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
-            assertFalse(reqResp == null);
-            assertTrue(reqResp.getRequest() == null);
-            assertTrue(reqResp.getResponse() == null);
-        } finally {
-            file.delete();
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/reader/nc/NcHttpPayloadReaderTest.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,71 @@
+package com.passus.st.reader.nc;
+
+import com.passus.data.ByteBuff;
+import com.passus.data.HeapByteBuff;
+import com.passus.net.http.HttpMessage;
+import com.passus.net.http.HttpRequest;
+import com.passus.net.http.HttpRequestBuilder;
+import com.passus.net.http.HttpResponse;
+import com.passus.net.http.HttpResponseBuilder;
+import org.testng.annotations.Test;
+import static com.passus.st.utils.HttpMessageAssert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class NcHttpPayloadReaderTest {
+
+    private final NcHttpPayloadWriter writer = new NcHttpPayloadWriter();
+
+    private ByteBuff buffer = new HeapByteBuff();
+
+    private final HttpRequest req;
+
+    private final HttpResponse resp;
+
+    public NcHttpPayloadReaderTest() {
+        req = HttpRequestBuilder.get("http://test.com/test")
+                .header("X-Header", "X-Header-Value")
+                .build();
+
+        resp = HttpResponseBuilder.ok()
+                .header("X-Header", "X-Header-Value")
+                .build();
+    }
+
+    @AfterMethod
+    public void afterMethod() {
+        buffer.clear();
+    }
+
+    @AfterClass
+    public void afterClass() {
+        buffer = null;
+    }
+
+    @Test
+    public void testDecode_Request() throws Exception {
+        writer.encodeMessage(req, buffer);
+
+        NcHttpPayloadReader reader = new NcHttpPayloadReader();
+        HttpMessage msgDecoded = reader.decodeMessage(buffer);
+        assertMessages(req, msgDecoded);
+    }
+
+    @Test
+    public void testDecode_Response() throws Exception {
+        writer.encodeMessage(resp, buffer);
+
+        NcHttpPayloadReader reader = new NcHttpPayloadReader();
+        HttpMessage msgDecoded = reader.decodeMessage(buffer);
+        assertMessages(resp, msgDecoded);
+    }
+
+    @Test
+    public void testDecode_Messages() throws Exception {
+        //writer.encodeFullMessages(req, resp, buffer);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/reader/nc/NcHttpPayloadWriterTest.java	Thu Apr 09 13:49:19 2020 +0200
@@ -0,0 +1,180 @@
+package com.passus.st.reader.nc;
+
+import com.passus.data.HeapByteBuff;
+import com.passus.net.http.*;
+import com.passus.st.client.SessionPayloadEvent;
+import com.passus.st.client.http.HttpReqResp;
+import com.passus.st.emitter.SessionInfo;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
+
+import static com.passus.data.DataSourceUtils.toByteBuff;
+import static com.passus.st.Protocols.HTTP;
+import static com.passus.st.utils.HttpMessageAssert.assertMessages;
+import static com.passus.st.utils.HttpMessageAssert.assertMessagesContent;
+import static org.testng.AssertJUnit.*;
+
+/**
+ * @author Mirosław Hawrot
+ */
+public class NcHttpPayloadWriterTest {
+
+    private final SessionInfo session;
+
+    public NcHttpPayloadWriterTest() throws Exception {
+        session = new SessionInfo("1.1.1.1:5000", "2.2.2.2:80");
+    }
+
+    private File createTmpFile() throws IOException {
+        File tmpDir = new File(System.getProperty("java.io.tmpdir"), "st");
+        if (!tmpDir.exists()) {
+            tmpDir.mkdir();
+        }
+
+        return new File(tmpDir, "st_" + UUID.randomUUID().toString() + ".tmp");
+    }
+
+    @Test
+    public void testEncodeHeaders() throws Exception {
+        HttpHeaders headers = new HttpHeadersImpl();
+        headers.add(HttpHeaders.HOST, "test");
+        headers.add("X-HEADER", "X-HEADER-VALUE");
+        HeapByteBuff buffer = new HeapByteBuff();
+
+        NcHttpPayloadWriter payloadWriter = new NcHttpPayloadWriter();
+        payloadWriter.encodeHeaders(headers, buffer);
+        assertEquals(33, buffer.readableBytes());
+    }
+
+    private void writeMessages(File file, HttpRequest req, HttpResponse resp) throws Exception {
+        NcHttpPayloadWriter payloadWriter = new NcHttpPayloadWriter();
+        try (NcDataBlockWriter writer = new NcDataBlockWriter(file)) {
+            writer.open();
+            payloadWriter.write(new SessionPayloadEvent(session, req, resp, HTTP, ""), writer);
+        }
+    }
+
+    private NcSessionPayloadBlock readPayloadBlock(File file) throws IOException {
+        try (NcDataBlockReader reader = new NcDataBlockReader(file)) {
+            reader.open();
+
+            NcDataBlock block;
+            while ((block = reader.read()) != null) {
+                if (block.type() == NcSessionPayloadBlock.TYPE) {
+                    return (NcSessionPayloadBlock) block;
+                }
+            }
+        }
+
+        throw new IOException("Unable to find payload block.");
+    }
+
+    @Test
+    public void testWrite_HttpRequest() throws Exception {
+        File file = createTmpFile();
+        try {
+            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
+                    .header("X-Header", "X-Header-Value")
+                    .content("content")
+                    .build();
+
+            writeMessages(file, req, null);
+
+            NcSessionPayloadBlock payload = readPayloadBlock(file);
+            NcHttpPayloadReader payloadReader = new NcHttpPayloadReader();
+            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
+            assertFalse(reqResp == null);
+            assertTrue(reqResp.getResponse() == null);
+            assertMessages(req, reqResp.getRequest());
+            assertMessagesContent(req, reqResp.getRequest());
+        } finally {
+            file.delete();
+        }
+    }
+
+    @Test
+    public void testWrite_HttpRequest_NoContent() throws Exception {
+        File file = createTmpFile();
+        try {
+            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
+                    .header("X-Header", "X-Header-Value")
+                    .build();
+
+            writeMessages(file, req, null);
+
+            NcSessionPayloadBlock payload = readPayloadBlock(file);
+            NcHttpPayloadReader payloadReader = new NcHttpPayloadReader();
+            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
+            assertFalse(reqResp == null);
+            assertTrue(reqResp.getResponse() == null);
+            assertMessages(req, reqResp.getRequest());
+            assertMessagesContent(req, reqResp.getRequest());
+        } finally {
+            file.delete();
+        }
+    }
+
+    @Test
+    public void testWrite_HttpRequest_NoHeaders() throws Exception {
+        File file = createTmpFile();
+        try {
+            HttpRequest req = HttpRequestBuilder.get("http://test.com/test")
+                    .version(HttpConsts.VERSION_1_0)
+                    .build();
+
+            writeMessages(file, req, null);
+
+            NcSessionPayloadBlock payload = readPayloadBlock(file);
+            NcHttpPayloadReader payloadReader = new NcHttpPayloadReader();
+            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
+            assertFalse(reqResp == null);
+            assertTrue(reqResp.getResponse() == null);
+            assertMessages(req, reqResp.getRequest());
+        } finally {
+            file.delete();
+        }
+    }
+
+    @Test
+    public void testWrite_HttpResponse() throws Exception {
+        File file = createTmpFile();
+        try {
+            HttpResponse resp = HttpResponseBuilder.ok()
+                    .header("X-Header", "X-Header-Value")
+                    .content("test")
+                    .build();
+
+            writeMessages(file, null, resp);
+
+            NcSessionPayloadBlock payload = readPayloadBlock(file);
+            NcHttpPayloadReader payloadReader = new NcHttpPayloadReader();
+            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
+            assertFalse(reqResp == null);
+            assertTrue(reqResp.getRequest() == null);
+            assertMessages(resp, reqResp.getResponse());
+            assertMessagesContent(resp, reqResp.getResponse());
+        } finally {
+            file.delete();
+        }
+    }
+
+    @Test
+    public void testWrite_NoMessage() throws Exception {
+        File file = createTmpFile();
+        try {
+            writeMessages(file, null, null);
+
+            NcSessionPayloadBlock payload = readPayloadBlock(file);
+            NcHttpPayloadReader payloadReader = new NcHttpPayloadReader();
+            HttpReqResp reqResp = payloadReader.decodeMessages(toByteBuff(payload.data()));
+            assertFalse(reqResp == null);
+            assertTrue(reqResp.getRequest() == null);
+            assertTrue(reqResp.getResponse() == null);
+        } finally {
+            file.delete();
+        }
+    }
+}
--- a/stress-tester/src/test/java/com/passus/st/source/NcEventDestinationTest.java	Tue Apr 07 15:04:06 2020 +0200
+++ b/stress-tester/src/test/java/com/passus/st/source/NcEventDestinationTest.java	Thu Apr 09 13:49:19 2020 +0200
@@ -27,7 +27,7 @@
 public class NcEventDestinationTest {
 
     @Test
-    public void testHandle() throws Exception {
+    public void testWriteHttp() throws Exception {
         Map<String, Object> props = new HashMap<>();
         props.put("allowPartialSession", true);
         props.put("ports", 4214);