diff --git a/3rdparty/wepoll/wepoll.pri b/3rdparty/wepoll/wepoll.pri
new file mode 100644
index 0000000000000000000000000000000000000000..c154763ba4a5728086f9206f9e3b6dd33e0c3eff
--- /dev/null
+++ b/3rdparty/wepoll/wepoll.pri
@@ -0,0 +1,5 @@
+SOURCES += $$PWD/wepoll.c
+
+HEADERS += $$PWD/wepoll.h
+
+INCLUDEPATH += $$PWD
diff --git a/dap-sdk/core/libdap.pri b/dap-sdk/core/libdap.pri
index c1ed62e7c2692dca5cf71f9179d27cc799af648e..6a5f474e5a408af21ac8d32ff14ccea6bc8ecac8 100755
--- a/dap-sdk/core/libdap.pri
+++ b/dap-sdk/core/libdap.pri
@@ -24,7 +24,8 @@ darwin {
 
 win32 {
     include(src/win32/win32.pri)
-    LIBS += -lpsapi
+    LIBS += -lntdll -lpsapi -ljson-c -lmagic -lmqrt -lshlwapi -lregex -ltre -lintl -liconv -lbcrypt -lcrypt32 -lsecur32 -luser32 -lws2_32 -lole32
+    include($$PWD/../../3rdparty/wepoll/wepoll.pri)
     DEFINES += DAP_OS_WINDOWS
 }
 
diff --git a/dap-sdk/net/client/dap_client_http.c b/dap-sdk/net/client/dap_client_http.c
index 2849e67a2570ca1a1f29a5f92d351776f9f541a4..66011d201f442906ee85c06b41add2bfc47c0f28 100644
--- a/dap-sdk/net/client/dap_client_http.c
+++ b/dap-sdk/net/client/dap_client_http.c
@@ -381,7 +381,7 @@ void* dap_client_http_request_custom(dap_worker_t * a_worker,const char *a_uplin
     }
     // Get socket flags
 #if defined DAP_OS_WINDOWS
-    u_long l_socket_flags = 0;
+    u_long l_socket_flags = 1;
     if (ioctlsocket((SOCKET)l_socket, (long)FIONBIO, &l_socket_flags))
         log_it(L_ERROR, "Error ioctl %d", WSAGetLastError());
 #else
@@ -404,12 +404,21 @@ void* dap_client_http_request_custom(dap_worker_t * a_worker,const char *a_uplin
 #endif
     // set socket param
     int buffsize = DAP_CLIENT_HTTP_RESPONSE_SIZE_MAX;
-#ifdef _WIN32
+    struct timeval timeout;
+    timeout.tv_sec = 10;
+    timeout.tv_usec = 0;
+#ifdef DAP_OS_WINDOWS
       setsockopt((SOCKET)l_socket, SOL_SOCKET, SO_SNDBUF, (char *)&buffsize, sizeof(int) );
       setsockopt((SOCKET)l_socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int) );
+      if (setsockopt((SOCKET)l_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) < 0)
+          log_it(L_ERROR, "Set send timeout failed, WSA errno %d", WSAGetLastError());
+      if (setsockopt((SOCKET)l_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0)
+          log_it(L_ERROR, "Set recv timeout failed, WSA errno %d", WSAGetLastError());
 #else
     setsockopt(l_socket, SOL_SOCKET, SO_SNDBUF, (void*) &buffsize, sizeof(buffsize));
     setsockopt(l_socket, SOL_SOCKET, SO_RCVBUF, (void*) &buffsize, sizeof(buffsize));
+    setsockopt(l_socket, SOL_SOCKET, SO_SNDTIMEO, (void*) &timeout, sizeof(timeout));
+    setsockopt(l_socket, SOL_SOCKET, SO_RCVTIMEO, (void*) &timeout, sizeof(timeout));
 #endif
     dap_events_socket_t *l_ev_socket = dap_events_socket_wrap_no_add(dap_events_get_default(), l_socket, &l_s_callbacks);
 
@@ -473,13 +482,13 @@ void* dap_client_http_request_custom(dap_worker_t * a_worker,const char *a_uplin
 #ifdef DAP_OS_WINDOWS
     else if(l_err == SOCKET_ERROR) {
         int l_err2 = WSAGetLastError();
-        if (l_err2 == EWOULDBLOCK || l_err2 == EAGAIN) {
+        if (l_err2 == WSAEWOULDBLOCK) {
             log_it(L_DEBUG, "Connecting to %s:%u", a_uplink_addr, a_uplink_port);
             l_http_pvt->worker = a_worker?a_worker: dap_events_worker_get_auto();
             dap_worker_add_events_socket(l_ev_socket,l_http_pvt->worker);
             return l_http_pvt;
         } else {
-            log_it(L_ERROR, "Socket %d connecting error: %d", l_ev_socket->socket, WSAGetLastError());
+            log_it(L_ERROR, "Socket %d connecting error: %d", l_ev_socket->socket, l_err2);
             s_client_http_delete( l_http_pvt);
             l_ev_socket->_inheritor = NULL;
             dap_events_socket_delete_unsafe( l_ev_socket, true);
@@ -556,6 +565,9 @@ static void s_http_connected(dap_events_socket_t * a_esocket)
     if(! dap_strcmp(l_http_pvt->method, "GET") ) {
         // We hide our request and mask them as possible
         l_offset += dap_snprintf(l_request_headers + l_offset, l_offset2 -= l_offset, "User-Agent: Mozilla\r\n");
+        l_offset += l_http_pvt->request_custom_headers
+                ? dap_snprintf(l_request_headers + l_offset, l_offset2 -= l_offset, "%s", l_http_pvt->request_custom_headers)
+                : 0;
         l_offset += l_http_pvt->cookie
                 ? dap_snprintf(l_request_headers + l_offset, l_offset2 -= l_offset, "Cookie: %s\r\n", l_http_pvt->cookie)
                 : 0;
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index b0f1072c9f6b6e259f22a31fc0960d3844e61ad5..056c49119f7ef4b508345de04c60e53a60aff768 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -303,8 +303,11 @@ static bool s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                         a_client_pvt->stage_status = STAGE_STATUS_ERROR;
                         break;
                     }
+                    struct timeval timeout;
+                    timeout.tv_sec = 10;
+                    timeout.tv_usec = 0;
 #ifdef DAP_OS_WINDOWS
-                    u_long l_socket_flags = 0;
+                    u_long l_socket_flags = 1;
                     if (ioctlsocket(a_client_pvt->stream_socket, (long)FIONBIO, &l_socket_flags) == SOCKET_ERROR) {
                         log_it(L_ERROR, "Can't set socket %d to nonblocking mode, error %d", a_client_pvt->stream_socket, WSAGetLastError());
                     }
@@ -316,6 +319,12 @@ static bool s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                     if (setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, &optsize ) < 0) {
                         log_it(L_ERROR, "Cant' set recv buf size on socket %d, error %d", a_client_pvt->stream_socket, WSAGetLastError());
                     }
+                    if (setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
+                        log_it(L_ERROR, "Set send timeout failed, WSA errno %d", WSAGetLastError());
+                    }
+                    if (setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
+                        log_it(L_ERROR, "Set recv timeout failed, WSA errno %d", WSAGetLastError());
+                    }
 #else
                     // Get socket flags
                     int l_socket_flags = fcntl(a_client_pvt->stream_socket, F_GETFL);
@@ -331,6 +340,8 @@ static bool s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                     int buffsize = 65536*4;
                     setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_SNDBUF, ( void *) &buffsize, sizeof(int));
                     setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_RCVBUF, ( void *) &buffsize, sizeof(int));
+                    setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_SNDTIMEO, (void*)&timeout, sizeof(timeout);
+                    setsockopt(a_client_pvt->stream_socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout);
 #endif
 
                     // Wrap socket and setup callbacks
diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c
index 507de9cc2b964d6d70133cea2692b40c9a8faf0c..634e03cae7db1b9d1f37d90f9eaa2558cae552f5 100644
--- a/dap-sdk/net/core/dap_events_socket.c
+++ b/dap-sdk/net/core/dap_events_socket.c
@@ -525,7 +525,7 @@ dap_events_socket_t * s_create_type_queue_ptr(dap_worker_t * a_w, dap_events_soc
     if (setsockopt(l_es->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
         log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket, err: %d", WSAGetLastError());
 
-    unsigned long l_mode = 0;
+    unsigned long l_mode = 1;
     ioctlsocket(l_es->socket, FIONBIO, &l_mode);
 
     int l_addr_len;
@@ -800,7 +800,7 @@ dap_events_socket_t * s_create_type_event(dap_worker_t * a_w, dap_events_socket_
     int buffsize = 1024;
     setsockopt(l_es->socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
 
-    unsigned long l_mode = 0;
+    unsigned long l_mode = 1;
     ioctlsocket(l_es->socket, FIONBIO, &l_mode);
 
     int reuse = 1;
diff --git a/dap-sdk/net/core/dap_server.c b/dap-sdk/net/core/dap_server.c
index f2e9409fa8ff510d3606a36e63d56a9960fa8328..208a50bcc8b69ae99f4bdadb840e52c0b23d50ed 100644
--- a/dap-sdk/net/core/dap_server.c
+++ b/dap-sdk/net/core/dap_server.c
@@ -177,7 +177,7 @@ dap_server_t* dap_server_new(dap_events_t *a_events, const char * a_addr, uint16
         listen(l_server->socket_listener, SOMAXCONN);
     }
 #ifdef DAP_OS_WINDOWS
-     u_long l_mode = 0;
+     u_long l_mode = 1;
      ioctlsocket(l_server->socket_listener, (long)FIONBIO, &l_mode);
 #else
     fcntl( l_server->socket_listener, F_SETFL, O_NONBLOCK);
diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/net/core/dap_timerfd.c
index 584c0e2c8ff49a5e9e8b170f89a576f1eef5b1ee..ae4eb4e2f4738cb89bcbdb334c88873d0c7d2c31 100644
--- a/dap-sdk/net/core/dap_timerfd.c
+++ b/dap-sdk/net/core/dap_timerfd.c
@@ -120,7 +120,7 @@ dap_timerfd_t* dap_timerfd_start_on_worker(dap_worker_t * a_worker, uint64_t a_t
 
     setsockopt(l_tfd, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
 
-    unsigned long l_mode = 0;
+    unsigned long l_mode = 1;
     ioctlsocket(l_tfd, FIONBIO, &l_mode);
 
     int l_addr_len;
diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/net/core/dap_worker.c
index a39a54d1c342a918e58d01ef26db7b41a55739fd..dbe26e98b7cfcf801b841e7b12b6d8fe85806141 100644
--- a/dap-sdk/net/core/dap_worker.c
+++ b/dap-sdk/net/core/dap_worker.c
@@ -261,9 +261,10 @@ void *dap_worker_thread(void *arg)
                     case DESCRIPTOR_TYPE_SOCKET:
                         getsockopt(l_cur->socket, SOL_SOCKET, SO_ERROR, (void *)&l_sock_err, (socklen_t *)&l_sock_err_size);
 #ifdef DAP_OS_WINDOWS
-                        log_it(L_ERROR, "Winsock error: %d", WSAGetLastError());
-#endif
+                        log_it(L_ERROR, "Winsock error: %d", l_sock_err);
+#else
                         log_it(L_ERROR, "Socket error: %s", strerror(l_sock_err));
+#endif
                     default: ;
                 }
                 dap_events_socket_set_readable_unsafe(l_cur, false);
@@ -309,7 +310,11 @@ void *dap_worker_thread(void *arg)
                         l_must_read_smth = true;
                         l_bytes_read = recv(l_cur->fd, (char *) (l_cur->buf_in + l_cur->buf_in_size),
                                             l_cur->buf_in_size_max - l_cur->buf_in_size, 0);
+#ifdef DAP_OS_WINDOWS
+                        l_errno = WSAGetLastError();
+#else
                         l_errno = errno;
+#endif
                     break;
                     case DESCRIPTOR_TYPE_SOCKET_UDP: {
                         l_must_read_smth = true;
@@ -318,7 +323,11 @@ void *dap_worker_thread(void *arg)
                                                 l_cur->buf_in_size_max - l_cur->buf_in_size, 0,
                                                 (struct sockaddr *)&l_cur->remote_addr, &l_size);
 
+#ifdef DAP_OS_WINDOWS
+                        l_errno = WSAGetLastError();
+#else
                         l_errno = errno;
+#endif
                     }
                     break;
                     case DESCRIPTOR_TYPE_SOCKET_LISTENING:
@@ -328,12 +337,19 @@ void *dap_worker_thread(void *arg)
                             socklen_t l_remote_addr_size= sizeof (l_remote_addr);
                             int l_remote_socket= accept(l_cur->socket ,&l_remote_addr,&l_remote_addr_size);
 #ifdef DAP_OS_WINDOWS
-							u_long l_mode = 0;
-                            ioctlsocket((SOCKET)l_remote_socket, (long)FIONBIO, &l_mode);
+                            /*u_long l_mode = 1;
+                            ioctlsocket((SOCKET)l_remote_socket, (long)FIONBIO, &l_mode); */
+                            // no need, since l_cur->socket is already NBIO
+
+                            int l_errno = WSAGetLastError();
+                            if (l_errno == WSAEWOULDBLOCK)
+                                continue;
+                            else {
+                                log_it(L_WARNING,"Can't accept on socket %d, WSA errno: %d",l_cur->socket, l_errno);
+                                break;
+                            }
 #else
                             fcntl( l_remote_socket, F_SETFL, O_NONBLOCK);
-#endif
-
                             int l_errno = errno;
                             if ( l_remote_socket == -1 ){
                                 if( l_errno == EAGAIN || l_errno == EWOULDBLOCK){// Everything is good, we'll receive ACCEPT on next poll
@@ -345,7 +361,7 @@ void *dap_worker_thread(void *arg)
                                     break;
                                 }
                             }
-
+#endif
                             l_cur->callbacks.accept_callback(l_cur,l_remote_socket,&l_remote_addr);
                         }else
                             log_it(L_ERROR,"No accept_callback on listening socket");
@@ -400,8 +416,13 @@ void *dap_worker_thread(void *arg)
                         }
                     }
                     else if(l_bytes_read < 0) {
+#ifdef DAP_OS_WINDOWS
+                        if (l_errno != WSAEWOULDBLOCK) {
+                            log_it(L_ERROR, "Can't recv on socket %d, WSA error: %d", l_cur->socket, l_errno);
+#else
                         if (l_errno != EAGAIN && l_errno != EWOULDBLOCK){ // Socket is blocked
                             log_it(L_ERROR, "Some error occured in recv() function: %s", strerror(errno));
+#endif
                             dap_events_socket_set_readable_unsafe(l_cur, false);
                             l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
                             l_cur->buf_out_size = 0;
@@ -507,7 +528,12 @@ void *dap_worker_thread(void *arg)
                             l_bytes_sent = sendto(l_cur->socket, (const char *)l_cur->buf_out,
                                                   l_cur->buf_out_size, MSG_DONTWAIT | MSG_NOSIGNAL,
                                                   (struct sockaddr *)&l_cur->remote_addr, sizeof(l_cur->remote_addr));
+#ifdef DAP_OS_WINDOWS
+                            dap_events_socket_set_writable_unsafe(l_cur,false);
+                            l_errno = WSAGetLastError();
+#else
                             l_errno = errno;
+#endif
                         break;
                         case DESCRIPTOR_TYPE_QUEUE:
                              if (l_cur->flags & DAP_SOCK_QUEUE_PTR && l_cur->buf_out_size>= sizeof (void*)){
@@ -572,8 +598,13 @@ void *dap_worker_thread(void *arg)
                     }
 
                     if(l_bytes_sent < 0) {
+#ifdef DAP_OS_WINDOWS
+                        if (l_errno != WSAEWOULDBLOCK) {
+                            log_it(L_ERROR, "Can't send to socket %d, WSA error: %d", l_cur->socket, l_errno);
+#else
                         if (l_errno != EAGAIN && l_errno != EWOULDBLOCK ){ // If we have non-blocking socket
                             log_it(L_ERROR, "Some error occured in send(): %s (code %d)", strerror(l_errno), l_errno);
+#endif
                             l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
                             l_cur->buf_out_size = 0;
                         }
diff --git a/dap-sdk/net/server/libdap-net-server.pri b/dap-sdk/net/server/libdap-net-server.pri
index d9646b6662a556f8d83896ffeb3bb0d202e1f63e..7957fdb2529f5f89baaa3ef2471fe91c0100b56c 100755
--- a/dap-sdk/net/server/libdap-net-server.pri
+++ b/dap-sdk/net/server/libdap-net-server.pri
@@ -1,6 +1,8 @@
-# JSON-C
-include (../../../3rdparty/json-c/json-c.pri)
-include (../../../3rdparty/libmagic/file/libmagic.pri)
+
+!win32 {
+    include (../../../3rdparty/json-c/json-c.pri)
+    include (../../../3rdparty/libmagic/file/libmagic.pri)
+}
 
 #enc_server
 HEADERS += $$PWD/enc_server/include/dap_enc_http.h \
diff --git a/modules/app-cli/dap_app_cli_net.c b/modules/app-cli/dap_app_cli_net.c
index 161aa4008ed006d01fdea1f0b43dcfa024488080..5db967d6a096df80a941adba392161e4d8e08930 100644
--- a/modules/app-cli/dap_app_cli_net.c
+++ b/modules/app-cli/dap_app_cli_net.c
@@ -62,7 +62,12 @@ static void dap_app_cli_http_read(dap_app_cli_connect_param_t *socket, dap_app_c
         return;
     }
     if (l_recv_len == -1) {
+#ifdef DAP_OS_WINDOWS
+        int l_errno = WSAGetLastError();
+        if (l_errno == WSAEWOULDBLOCK) {
+#else
         if (errno == EAGAIN || errno == EWOULDBLOCK) {
+#endif
             s_status = DAP_CLI_ERROR_TIMEOUT;
         } else {
             s_status = DAP_CLI_ERROR_SOCKET;