From 4c7a9b425de74df920babbf47898c7ab69fb15b4 Mon Sep 17 00:00:00 2001
From: anta999 <antarctic@linuxpc>
Date: Fri, 14 Jun 2019 15:58:09 +0400
Subject: [PATCH] change0

---
 http_server/dap_http.c        |  356 +++++-----
 http_server/dap_http.h        |  156 ++---
 http_server/dap_http_folder.c |  628 ++++++++---------
 http_server/dap_http_folder.h |   62 +-
 http_server/dap_http_simple.c | 1184 ++++++++++++++++-----------------
 http_server/dap_http_simple.h |  160 ++---
 6 files changed, 1257 insertions(+), 1289 deletions(-)

diff --git a/http_server/dap_http.c b/http_server/dap_http.c
index eb66d5e..57b4a3e 100755
--- a/http_server/dap_http.c
+++ b/http_server/dap_http.c
@@ -1,178 +1,178 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-
-#ifndef _WIN32
-#include <netinet/in.h>
-
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <netdb.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <time.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include "dap_common.h"
-
-#include "dap_server.h"
-#include "dap_client_remote.h"
-
-#include "dap_http.h"
-#include "dap_http_header.h"
-#include "dap_http_client.h"
-
-#define LOG_TAG "dap_http"
-
-
-/**
- * @brief dap_http_init // Init HTTP module
- * @return Zero if ok others if not
- */
-int dap_http_init( )
-{
-  if ( dap_http_header_init() != 0 ) { // Init submodule for headers manipulations
-    log_it(L_CRITICAL,"Can't init HTTP headers processing submodule");
-    return -1;
-  }
-
-  if ( dap_http_client_init() !=0 ) { // Init submodule for HTTP client event processing
-    log_it(L_CRITICAL,"Can't init HTTP client submodule");
-    return -2;
-  }
-
-  log_it( L_NOTICE, "Initialized HTTP server module" );
-  return 0;
-}
-
-/**
- * @brief dap_http_deinit Deinit HTTP module
- */
-void dap_http_deinit()
-{
-  dap_http_header_deinit( );
-  dap_http_client_deinit( );
-}
-
-
-/**
- * @brief dap_server_http_init Init HTTP server
- * @param sh Server instance
- * @return 0 if ok lesser number if error
- */
-int dap_http_new( dap_server_t *sh, const char * server_name )
-{
-  sh->_inheritor = calloc( 1, sizeof(dap_http_t) );
-
-  dap_http_t *shttp = DAP_HTTP( sh );
-
-  shttp->server = sh;
-  strncpy( shttp->server_name, server_name, sizeof(shttp->server_name)-1 );
-
-  sh->client_new_callback    = dap_http_client_new;
-  sh->client_delete_callback = dap_http_client_delete;
-  sh->client_read_callback   = dap_http_client_read;
-  sh->client_write_callback  = dap_http_client_write;
-  sh->client_error_callback  = dap_http_client_error;
-
-  return 0;
-}
-
-/**
- * @brief dap_http_delete Clear dap_http structure in the internal data field of dap_server_t instance
- * @param sh Server's instance
- * @param arg Non-used argument
- */
-void dap_http_delete( dap_server_t *sh, void * arg )
-{
-  (void) arg;
-  (void) sh;
-  dap_http_t *shttp = DAP_HTTP( sh );
-  dap_http_url_proc_t *up, *tmp;
-
-  HASH_ITER( hh, shttp->url_proc ,up, tmp ) {
-    HASH_DEL(shttp->url_proc, up);
-    if( up->_inheritor )
-      free( up->_inheritor );
-    free( up );
-  }
-}
-
-
-/**
- * @brief dap_http_add_proc  Add custom procesor for the HTTP server
- * @param sh                Server's instance
- * @param url_path          Part of URL to be processed
- * @param read_callback     Callback for read in DATA state
- * @param write_callback    Callback for write in DATA state
- * @param error_callback    Callback for error processing
- */
-void dap_http_add_proc(dap_http_t *sh, const char *url_path, void *internal
-                      ,dap_http_client_callback_t new_callback
-                      ,dap_http_client_callback_t delete_callback
-                      ,dap_http_client_callback_t headers_read_callback
-                      ,dap_http_client_callback_t headers_write_callback
-                      ,dap_http_client_callback_t data_read_callback
-                      ,dap_http_client_callback_t data_write_callback
-                      ,dap_http_client_callback_t error_callback
-
-                      )
-{
-  dap_http_url_proc_t *up = (dap_http_url_proc_t *) calloc( 1, sizeof(dap_http_url_proc_t) );
-
-  strncpy( up->url, url_path, sizeof(up->url) );
-
-  up->new_callback    = new_callback;
-  up->delete_callback = delete_callback;
-
-  up->data_read_callback = data_read_callback;
-  up->data_write_callback = data_write_callback;
-  up->headers_read_callback = headers_read_callback;
-  up->headers_write_callback = headers_write_callback;
-  up->error_callback = error_callback;
-
-  up->_inheritor = internal;
-
-  HASH_ADD_STR( sh->url_proc, url, up );
-
-  log_it( L_DEBUG, "Added URL processor for '%s' path", up->url );
-}
-
-
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <netdb.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <time.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include "dap_common.h"
+
+#include "dap_server.h"
+#include "dap_client_remote.h"
+
+#include "dap_http.h"
+#include "dap_http_header.h"
+#include "dap_http_client.h"
+
+#define LOG_TAG "dap_http"
+
+
+/**
+ * @brief dap_http_init // Init HTTP module
+ * @return Zero if ok others if not
+ */
+int dap_http_init( )
+{
+  if ( dap_http_header_init() != 0 ) { // Init submodule for headers manipulations
+    log_it(L_CRITICAL,"Can't init HTTP headers processing submodule");
+    return -1;
+  }
+
+  if ( dap_http_client_init() !=0 ) { // Init submodule for HTTP client event processing
+    log_it(L_CRITICAL,"Can't init HTTP client submodule");
+    return -2;
+  }
+
+  log_it( L_NOTICE, "Initialized HTTP server module" );
+  return 0;
+}
+
+/**
+ * @brief dap_http_deinit Deinit HTTP module
+ */
+void dap_http_deinit()
+{
+  dap_http_header_deinit( );
+  dap_http_client_deinit( );
+}
+
+
+/**
+ * @brief dap_server_http_init Init HTTP server
+ * @param sh Server instance
+ * @return 0 if ok lesser number if error
+ */
+int dap_http_new( dap_server_t *sh, const char * server_name )
+{
+  sh->_inheritor = calloc( 1, sizeof(dap_http_t) );
+
+  dap_http_t *shttp = DAP_HTTP( sh );
+
+  shttp->server = sh;
+  strncpy( shttp->server_name, server_name, sizeof(shttp->server_name)-1 );
+
+  sh->client_new_callback    = dap_http_client_new;
+  sh->client_delete_callback = dap_http_client_delete;
+  sh->client_read_callback   = dap_http_client_read;
+  sh->client_write_callback  = dap_http_client_write;
+  sh->client_error_callback  = dap_http_client_error;
+
+  return 0;
+}
+
+/**
+ * @brief dap_http_delete Clear dap_http structure in the internal data field of dap_server_t instance
+ * @param sh Server's instance
+ * @param arg Non-used argument
+ */
+void dap_http_delete( dap_server_t *sh, void * arg )
+{
+  (void) arg;
+  (void) sh;
+  dap_http_t *shttp = DAP_HTTP( sh );
+  dap_http_url_proc_t *up, *tmp;
+
+  HASH_ITER( hh, shttp->url_proc ,up, tmp ) {
+    HASH_DEL(shttp->url_proc, up);
+    if( up->_inheritor )
+      free( up->_inheritor );
+    free( up );
+  }
+}
+
+
+/**
+ * @brief dap_http_add_proc  Add custom procesor for the HTTP server
+ * @param sh                Server's instance
+ * @param url_path          Part of URL to be processed
+ * @param read_callback     Callback for read in DATA state
+ * @param write_callback    Callback for write in DATA state
+ * @param error_callback    Callback for error processing
+ */
+void dap_http_add_proc(dap_http_t *sh, const char *url_path, void *internal
+                      ,dap_http_client_callback_t new_callback
+                      ,dap_http_client_callback_t delete_callback
+                      ,dap_http_client_callback_t headers_read_callback
+                      ,dap_http_client_callback_t headers_write_callback
+                      ,dap_http_client_callback_t data_read_callback
+                      ,dap_http_client_callback_t data_write_callback
+                      ,dap_http_client_callback_t error_callback
+
+                      )
+{
+  dap_http_url_proc_t *up = (dap_http_url_proc_t *) calloc( 1, sizeof(dap_http_url_proc_t) );
+
+  strncpy( up->url, url_path, sizeof(up->url) );
+
+  up->new_callback    = new_callback;
+  up->delete_callback = delete_callback;
+
+  up->data_read_callback = data_read_callback;
+  up->data_write_callback = data_write_callback;
+  up->headers_read_callback = headers_read_callback;
+  up->headers_write_callback = headers_write_callback;
+  up->error_callback = error_callback;
+
+  up->_inheritor = internal;
+
+  HASH_ADD_STR( sh->url_proc, url, up );
+
+  log_it( L_DEBUG, "Added URL processor for '%s' path", up->url );
+}
+
+
diff --git a/http_server/dap_http.h b/http_server/dap_http.h
index 13d3a70..9ed36a1 100755
--- a/http_server/dap_http.h
+++ b/http_server/dap_http.h
@@ -1,78 +1,78 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SERVER_HTTP_H_
-#define _SERVER_HTTP_H_
-#include "dap_server.h"
-#include "dap_client_remote.h"
-#include "http_client/dap_http_header.h"
-#include "http_client/dap_http_client.h"
-#include "uthash.h"
-
-struct dap_http;
-struct dap_http_url_processor;
-//Structure for internal data of dap_server_t structure for holding special HTTP data
-
-// Structure for holding URL processors
-typedef struct dap_http_url_proc{
-    char url[512]; // First part of URL that will be processed
-    struct dap_http * http; // Pointer to HTTP server instance
-
-    dap_http_client_callback_t new_callback; // Init internal structure
-    dap_http_client_callback_t delete_callback; // Delete internal structure
-
-    dap_http_client_callback_t headers_read_callback;
-    dap_http_client_callback_t headers_write_callback;
-
-    dap_http_client_callback_t data_read_callback;
-    dap_http_client_callback_t data_write_callback;
-    dap_http_client_callback_t error_callback;
-
-    dap_http_client_callback_t access_callback;
-
-    void *_inheritor; // Internal data specific to the current URL processor
-    UT_hash_handle hh; // makes this structure hashable with UTHASH library
-} dap_http_url_proc_t;
-
-// Internal server structure for HTTP server
-typedef struct dap_http {
-    dap_server_t *server;
-    char server_name[256];
-    dap_http_url_proc_t * url_proc;
-} dap_http_t;
-
-#define DAP_HTTP(a) ((dap_http_t *) (a)->_inheritor)
-
-extern int dap_http_init( ); // Init module
-extern void dap_http_deinit( ); // Deinit module
-
-extern int dap_http_new( dap_server_t *sh, const char *server_name ); // Create dap_http structure in the internal data field of dap_server_t instance
-extern void dap_http_delete( dap_server_t *sh, void *arg ); // Clear dap_http structure in the internal data field of dap_server_t instance
-
-extern void dap_http_add_proc(dap_http_t *sh, const char *url_path, void *internal
-                             ,dap_http_client_callback_t new_callback
-                             ,dap_http_client_callback_t delete_callback
-                             ,dap_http_client_callback_t headers_read_callback
-                             ,dap_http_client_callback_t headers_write_callback
-                             ,dap_http_client_callback_t data_read_callback
-                             ,dap_http_client_callback_t data_write_callback
-                             ,dap_http_client_callback_t error_callback ); // Add custom procesor for the HTTP server
-
-#endif
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SERVER_HTTP_H_
+#define _SERVER_HTTP_H_
+#include "dap_server.h"
+#include "dap_client_remote.h"
+#include "http_client/dap_http_header.h"
+#include "http_client/dap_http_client.h"
+#include "uthash.h"
+
+struct dap_http;
+struct dap_http_url_processor;
+//Structure for internal data of dap_server_t structure for holding special HTTP data
+
+// Structure for holding URL processors
+typedef struct dap_http_url_proc{
+    char url[512]; // First part of URL that will be processed
+    struct dap_http * http; // Pointer to HTTP server instance
+
+    dap_http_client_callback_t new_callback; // Init internal structure
+    dap_http_client_callback_t delete_callback; // Delete internal structure
+
+    dap_http_client_callback_t headers_read_callback;
+    dap_http_client_callback_t headers_write_callback;
+
+    dap_http_client_callback_t data_read_callback;
+    dap_http_client_callback_t data_write_callback;
+    dap_http_client_callback_t error_callback;
+
+    dap_http_client_callback_t access_callback;
+
+    void *_inheritor; // Internal data specific to the current URL processor
+    UT_hash_handle hh; // makes this structure hashable with UTHASH library
+} dap_http_url_proc_t;
+
+// Internal server structure for HTTP server
+typedef struct dap_http {
+    dap_server_t *server;
+    char server_name[256];
+    dap_http_url_proc_t * url_proc;
+} dap_http_t;
+
+#define DAP_HTTP(a) ((dap_http_t *) (a)->_inheritor)
+
+extern int dap_http_init( ); // Init module
+extern void dap_http_deinit( ); // Deinit module
+
+extern int dap_http_new( dap_server_t *sh, const char *server_name ); // Create dap_http structure in the internal data field of dap_server_t instance
+extern void dap_http_delete( dap_server_t *sh, void *arg ); // Clear dap_http structure in the internal data field of dap_server_t instance
+
+extern void dap_http_add_proc(dap_http_t *sh, const char *url_path, void *internal
+                             ,dap_http_client_callback_t new_callback
+                             ,dap_http_client_callback_t delete_callback
+                             ,dap_http_client_callback_t headers_read_callback
+                             ,dap_http_client_callback_t headers_write_callback
+                             ,dap_http_client_callback_t data_read_callback
+                             ,dap_http_client_callback_t data_write_callback
+                             ,dap_http_client_callback_t error_callback ); // Add custom procesor for the HTTP server
+
+#endif
diff --git a/http_server/dap_http_folder.c b/http_server/dap_http_folder.c
index 8639a25..090ece3 100755
--- a/http_server/dap_http_folder.c
+++ b/http_server/dap_http_folder.c
@@ -1,314 +1,314 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#ifndef _WIN32
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include <magic.h>
-
-#include "dap_common.h"
-#include "dap_client_remote.h"
-#include "dap_http.h"
-#include "dap_http_client.h"
-#include "dap_http_folder.h"
-#include "http_status_code.h"
-
-typedef struct dap_http_url_proc_folder {
-    char local_path[4096];
-    magic_t mime_detector;
-} dap_http_url_proc_folder_t;
-
-#define URL_PROC_FOLDER(a) ((dap_http_url_proc_folder_t*) (a)->_inhertior )
-
-typedef struct dap_http_file{
-    FILE * fd;
-    size_t position;
-    char local_path[4096];
-    dap_http_client_t *client;
-} dap_http_file_t;
-
-#define DAP_HTTP_FILE(a) ((dap_http_file_t*) (a)->_inheritor )
-
-void dap_http_folder_headers_read( dap_http_client_t *cl_ht, void *arg );
-void dap_http_folder_headers_write( dap_http_client_t *cl_ht, void *arg );
-void dap_http_folder_data_read( dap_http_client_t *cl_ht, void *arg );
-void dap_http_folder_data_write( dap_http_client_t *cl_ht, void *arg );
-
-#define LOG_TAG "dap_http_folder"
-
-int dap_http_folder_init( )
-{
-    return 0;
-}
-
-void dap_http_folder_deinit( )
-{
-
-}
-
-
-/**
- * @brief dap_http_folder_add Add folder for reading to the HTTP server
- * @param sh Server instance
- * @param url_path Beginning part of the URL
- * @param local_path Local path that will be read for
- */
-int dap_http_folder_add( dap_http_t *sh, const char *url_path, const char *local_path )
-{
-  if ( !local_path ) {
-    log_it( L_ERROR, "Directory Path parameter is empty!" );
-    return -11;
-  }
-
-  log_it( L_DEBUG, "Checking url path %s", local_path );
-
-#ifndef _WIN32
-  DIR *dirptr = opendir( local_path );
-  if ( dirptr == NULL ) {
-    log_it( L_ERROR, "Directory Not Found!" );
-    return -11;
-  }
-  else {
-    closedir( dirptr );
-  }
-#else // WIN32
-
-  DWORD attr = GetFileAttributesA( local_path );
-  if ( attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY) ) {
-    log_it( L_ERROR, "Directory Not Found!" );
-    return -11;
-  }
-
-#endif
-
-  log_it( L_NOTICE, "File service for %s => %s ", url_path, local_path );
-
-  dap_http_url_proc_folder_t *up_folder = (dap_http_url_proc_folder_t *)calloc( 1, sizeof(dap_http_url_proc_folder_t) );
-  strncpy( up_folder->local_path, local_path, sizeof(up_folder->local_path) );
-
-  up_folder->mime_detector = magic_open( MAGIC_SYMLINK | MAGIC_MIME | MAGIC_PRESERVE_ATIME );
-
-  if ( up_folder->mime_detector == NULL) {
-    log_it( L_CRITICAL,"Can't init MIME detection library" );
-    free( up_folder );
-    return -1;
-  }
-
-#ifndef _WIN32
-  if( 0 != magic_load( up_folder->mime_detector, NULL) ) {
-#else
-  if( 0 != magic_load( up_folder->mime_detector, "data.mag" )  ) {
-#endif
-
-    log_it( L_CRITICAL, "Can't load MIME magic detection database" );
-    magic_close( up_folder->mime_detector );
-    free( up_folder );
-    return -2;
-  }
-
-  dap_http_add_proc(  sh, 
-                      url_path, 
-                      up_folder, 
-                      NULL,
-                      NULL,
-                      dap_http_folder_headers_read,
-                      dap_http_folder_headers_write,
-                      dap_http_folder_data_read,
-                      dap_http_folder_data_write,
-                      NULL );
-    return 0;
-}
-
-/**
- * @brief dap_http_folder_headers_read Signal thats HTTP client is now going to output the data
- * @param cl_ht HTTP client instance
- * @param arg Not used
- */
-void dap_http_folder_headers_read(dap_http_client_t * cl_ht, void * arg)
-{
-    (void) arg;
-    cl_ht->state_write=DAP_HTTP_CLIENT_STATE_START;
-    cl_ht->state_read=cl_ht->keep_alive?DAP_HTTP_CLIENT_STATE_START:DAP_HTTP_CLIENT_STATE_NONE;
-    dap_client_remote_ready_to_write(cl_ht->client,true);
-    dap_client_remote_ready_to_read(cl_ht->client, cl_ht->keep_alive);
-}
-
-#ifdef _WIN32
-time_t FileTimeToUnixTime( FILETIME ft )
-{
-  ULARGE_INTEGER ull;
- 
-  ull.LowPart = ft.dwLowDateTime;
-  ull.HighPart = ft.dwHighDateTime;
- 
-  return ull.QuadPart / 10000000ULL - 11644473600ULL;
-}
-#endif
-
-/**
- * @brief dap_http_folder_headers Prepare response HTTP headers for file folder request
- * @param cl_ht HTTP client instane
- * @param arg Not used
- */
-void dap_http_folder_headers_write( dap_http_client_t *cl_ht, void * arg)
-{
-  (void) arg;
-  // Get specific data for folder URL processor
-  dap_http_url_proc_folder_t * up_folder=(dap_http_url_proc_folder_t*) cl_ht->proc->_inheritor;
-
-  // Init specific file response data for HTTP client instance
-  cl_ht->_inheritor=DAP_NEW_Z(dap_http_file_t);
-
-  dap_http_file_t* cl_ht_file=DAP_HTTP_FILE(cl_ht);
-  cl_ht_file->client=cl_ht;
-
-  // Produce local path for file to open
-  snprintf(cl_ht_file->local_path,sizeof(cl_ht_file->local_path),"%s/%s", up_folder->local_path, cl_ht->url_path );
-  log_it(L_DEBUG, "Check %s file", cl_ht_file->local_path);
-
-#ifndef _WIN32
-
-  struct stat file_stat;
-
-  if ( stat(cl_ht_file->local_path, &file_stat) != 0 ) 
-    goto err;
-
-  cl_ht->out_last_modified  = file_stat.st_mtime;
-  cl_ht->out_content_length = file_stat.st_size;
-
-#else
-
-  FILETIME CreationTime;
-  FILETIME LastAccessTime;
-  FILETIME LastWriteTime;
-
-  HANDLE fileh = CreateFileA( cl_ht_file->local_path, 
-                              GENERIC_READ, 
-                              FILE_SHARE_READ, 
-                              NULL, 
-                              OPEN_EXISTING, 
-                              FILE_ATTRIBUTE_ARCHIVE, 
-                              NULL 
-                 );
-
-  if ( fileh == INVALID_HANDLE_VALUE ) 
-    goto err;
-
-  GetFileTime( fileh,
-               &CreationTime,
-               &LastAccessTime,
-               &LastWriteTime );
-
-  cl_ht->out_last_modified  = FileTimeToUnixTime( LastWriteTime );
-  cl_ht->out_content_length = GetFileSize( fileh, NULL );
-
-  CloseHandle( fileh );
-
-#endif
-
-  cl_ht_file->fd = fopen( cl_ht_file->local_path, "rb" );
-
-  if ( cl_ht_file->fd == NULL ) {
-    log_it(L_ERROR, "Can't open %s: %s",cl_ht_file->local_path,strerror(errno));
-    cl_ht->reply_status_code = Http_Status_NotFound;
-    strncpy( cl_ht->reply_reason_phrase, "Not Found", sizeof(cl_ht->reply_reason_phrase) );
-  }
-  else {
-    cl_ht->reply_status_code = Http_Status_OK;
-    strncpy( cl_ht->reply_reason_phrase,"OK",sizeof(cl_ht->reply_reason_phrase) );
-
-    const char *mime_type = magic_file( up_folder->mime_detector, cl_ht_file->local_path );
-    if( mime_type ) {
-      strncpy(cl_ht->out_content_type,mime_type,sizeof(cl_ht->out_content_type));
-      log_it( L_DEBUG, "MIME type detected: '%s'", mime_type );
-    }
-    else {
-      cl_ht->reply_status_code=Http_Status_NotFound;
-      cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
-      log_it(L_WARNING,"Can't detect MIME type of %s file: %s",cl_ht_file->local_path,magic_error(up_folder->mime_detector));
-    }
-  }
-
-  return;
-
-err:
-
-  log_it( L_WARNING, "Can't get file info: %s", strerror(errno) );
-  cl_ht->reply_status_code = 404;
-  strncpy( cl_ht->reply_reason_phrase, "Not Found", sizeof(cl_ht->reply_reason_phrase) );
-
-  return;
-}
-
-/**
- * @brief dap_http_folder_read HTTP client callback for reading function for the folder processing
- * @param cl_ht HTTP client instance
- * @param arg Pointer to int with return bytes number
- */
-void dap_http_folder_data_read(dap_http_client_t * cl_ht, void * arg)
-{
-    int * bytes_return = (int*) arg; // Return number of read bytes
-    //Do nothing
-    *bytes_return=cl_ht->client->buf_in_size;
-}
-
-/**
- * @brief dap_http_folder_write HTTP client callback for writting function for the folder processing
- * @param cl_ht HTTP client instance
- * @param arg
- */
-void dap_http_folder_data_write(dap_http_client_t * cl_ht, void * arg)
-{
-    (void) arg;
-    dap_http_file_t * cl_ht_file= DAP_HTTP_FILE(cl_ht);
-    cl_ht->client->buf_out_size=fread(cl_ht->client->buf_out,1,sizeof(cl_ht->client->buf_out),cl_ht_file->fd);
-    cl_ht_file->position+=cl_ht->client->buf_out_size;
-
-    if(feof(cl_ht_file->fd)!=0){
-        log_it(L_INFO, "All the file %s is sent out",cl_ht_file->local_path);
-        //strncat(cl_ht->client->buf_out+cl_ht->client->buf_out_size,"\r\n",sizeof(cl_ht->client->buf_out));
-        fclose(cl_ht_file->fd);
-        dap_client_remote_ready_to_write(cl_ht->client,false);
-
-        if ( !cl_ht->keep_alive )
-            cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
-
-        cl_ht->state_write=DAP_HTTP_CLIENT_STATE_NONE;
-    }
-}
-
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#ifndef _WIN32
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include <magic.h>
+
+#include "dap_common.h"
+#include "dap_client_remote.h"
+#include "dap_http.h"
+#include "dap_http_client.h"
+#include "dap_http_folder.h"
+#include "http_status_code.h"
+
+typedef struct dap_http_url_proc_folder {
+    char local_path[4096];
+    magic_t mime_detector;
+} dap_http_url_proc_folder_t;
+
+#define URL_PROC_FOLDER(a) ((dap_http_url_proc_folder_t*) (a)->_inhertior )
+
+typedef struct dap_http_file{
+    FILE * fd;
+    size_t position;
+    char local_path[4096];
+    dap_http_client_t *client;
+} dap_http_file_t;
+
+#define DAP_HTTP_FILE(a) ((dap_http_file_t*) (a)->_inheritor )
+
+void dap_http_folder_headers_read( dap_http_client_t *cl_ht, void *arg );
+void dap_http_folder_headers_write( dap_http_client_t *cl_ht, void *arg );
+void dap_http_folder_data_read( dap_http_client_t *cl_ht, void *arg );
+void dap_http_folder_data_write( dap_http_client_t *cl_ht, void *arg );
+
+#define LOG_TAG "dap_http_folder"
+
+int dap_http_folder_init( )
+{
+    return 0;
+}
+
+void dap_http_folder_deinit( )
+{
+
+}
+
+
+/**
+ * @brief dap_http_folder_add Add folder for reading to the HTTP server
+ * @param sh Server instance
+ * @param url_path Beginning part of the URL
+ * @param local_path Local path that will be read for
+ */
+int dap_http_folder_add( dap_http_t *sh, const char *url_path, const char *local_path )
+{
+  if ( !local_path ) {
+    log_it( L_ERROR, "Directory Path parameter is empty!" );
+    return -11;
+  }
+
+  log_it( L_DEBUG, "Checking url path %s", local_path );
+
+#ifndef _WIN32
+  DIR *dirptr = opendir( local_path );
+  if ( dirptr == NULL ) {
+    log_it( L_ERROR, "Directory Not Found!" );
+    return -11;
+  }
+  else {
+    closedir( dirptr );
+  }
+#else // WIN32
+
+  DWORD attr = GetFileAttributesA( local_path );
+  if ( attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY) ) {
+    log_it( L_ERROR, "Directory Not Found!" );
+    return -11;
+  }
+
+#endif
+
+  log_it( L_NOTICE, "File service for %s => %s ", url_path, local_path );
+
+  dap_http_url_proc_folder_t *up_folder = (dap_http_url_proc_folder_t *)calloc( 1, sizeof(dap_http_url_proc_folder_t) );
+  strncpy( up_folder->local_path, local_path, sizeof(up_folder->local_path) );
+
+  up_folder->mime_detector = magic_open( MAGIC_SYMLINK | MAGIC_MIME | MAGIC_PRESERVE_ATIME );
+
+  if ( up_folder->mime_detector == NULL) {
+    log_it( L_CRITICAL,"Can't init MIME detection library" );
+    free( up_folder );
+    return -1;
+  }
+
+#ifndef _WIN32
+  if( 0 != magic_load( up_folder->mime_detector, NULL) ) {
+#else
+  if( 0 != magic_load( up_folder->mime_detector, "data.mag" )  ) {
+#endif
+
+    log_it( L_CRITICAL, "Can't load MIME magic detection database" );
+    magic_close( up_folder->mime_detector );
+    free( up_folder );
+    return -2;
+  }
+
+  dap_http_add_proc(  sh, 
+                      url_path, 
+                      up_folder, 
+                      NULL,
+                      NULL,
+                      dap_http_folder_headers_read,
+                      dap_http_folder_headers_write,
+                      dap_http_folder_data_read,
+                      dap_http_folder_data_write,
+                      NULL );
+    return 0;
+}
+
+/**
+ * @brief dap_http_folder_headers_read Signal thats HTTP client is now going to output the data
+ * @param cl_ht HTTP client instance
+ * @param arg Not used
+ */
+void dap_http_folder_headers_read(dap_http_client_t * cl_ht, void * arg)
+{
+    (void) arg;
+    cl_ht->state_write=DAP_HTTP_CLIENT_STATE_START;
+    cl_ht->state_read=cl_ht->keep_alive?DAP_HTTP_CLIENT_STATE_START:DAP_HTTP_CLIENT_STATE_NONE;
+    dap_client_remote_ready_to_write(cl_ht->client,true);
+    dap_client_remote_ready_to_read(cl_ht->client, cl_ht->keep_alive);
+}
+
+#ifdef _WIN32
+time_t FileTimeToUnixTime( FILETIME ft )
+{
+  ULARGE_INTEGER ull;
+ 
+  ull.LowPart = ft.dwLowDateTime;
+  ull.HighPart = ft.dwHighDateTime;
+ 
+  return ull.QuadPart / 10000000ULL - 11644473600ULL;
+}
+#endif
+
+/**
+ * @brief dap_http_folder_headers Prepare response HTTP headers for file folder request
+ * @param cl_ht HTTP client instane
+ * @param arg Not used
+ */
+void dap_http_folder_headers_write( dap_http_client_t *cl_ht, void * arg)
+{
+  (void) arg;
+  // Get specific data for folder URL processor
+  dap_http_url_proc_folder_t * up_folder=(dap_http_url_proc_folder_t*) cl_ht->proc->_inheritor;
+
+  // Init specific file response data for HTTP client instance
+  cl_ht->_inheritor=DAP_NEW_Z(dap_http_file_t);
+
+  dap_http_file_t* cl_ht_file=DAP_HTTP_FILE(cl_ht);
+  cl_ht_file->client=cl_ht;
+
+  // Produce local path for file to open
+  snprintf(cl_ht_file->local_path,sizeof(cl_ht_file->local_path),"%s/%s", up_folder->local_path, cl_ht->url_path );
+  log_it(L_DEBUG, "Check %s file", cl_ht_file->local_path);
+
+#ifndef _WIN32
+
+  struct stat file_stat;
+
+  if ( stat(cl_ht_file->local_path, &file_stat) != 0 ) 
+    goto err;
+
+  cl_ht->out_last_modified  = file_stat.st_mtime;
+  cl_ht->out_content_length = file_stat.st_size;
+
+#else
+
+  FILETIME CreationTime;
+  FILETIME LastAccessTime;
+  FILETIME LastWriteTime;
+
+  HANDLE fileh = CreateFileA( cl_ht_file->local_path, 
+                              GENERIC_READ, 
+                              FILE_SHARE_READ, 
+                              NULL, 
+                              OPEN_EXISTING, 
+                              FILE_ATTRIBUTE_ARCHIVE, 
+                              NULL 
+                 );
+
+  if ( fileh == INVALID_HANDLE_VALUE ) 
+    goto err;
+
+  GetFileTime( fileh,
+               &CreationTime,
+               &LastAccessTime,
+               &LastWriteTime );
+
+  cl_ht->out_last_modified  = FileTimeToUnixTime( LastWriteTime );
+  cl_ht->out_content_length = GetFileSize( fileh, NULL );
+
+  CloseHandle( fileh );
+
+#endif
+
+  cl_ht_file->fd = fopen( cl_ht_file->local_path, "rb" );
+
+  if ( cl_ht_file->fd == NULL ) {
+    log_it(L_ERROR, "Can't open %s: %s",cl_ht_file->local_path,strerror(errno));
+    cl_ht->reply_status_code = Http_Status_NotFound;
+    strncpy( cl_ht->reply_reason_phrase, "Not Found", sizeof(cl_ht->reply_reason_phrase) );
+  }
+  else {
+    cl_ht->reply_status_code = Http_Status_OK;
+    strncpy( cl_ht->reply_reason_phrase,"OK",sizeof(cl_ht->reply_reason_phrase) );
+
+    const char *mime_type = magic_file( up_folder->mime_detector, cl_ht_file->local_path );
+    if( mime_type ) {
+      strncpy(cl_ht->out_content_type,mime_type,sizeof(cl_ht->out_content_type));
+      log_it( L_DEBUG, "MIME type detected: '%s'", mime_type );
+    }
+    else {
+      cl_ht->reply_status_code=Http_Status_NotFound;
+      cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
+      log_it(L_WARNING,"Can't detect MIME type of %s file: %s",cl_ht_file->local_path,magic_error(up_folder->mime_detector));
+    }
+  }
+
+  return;
+
+err:
+
+  log_it( L_WARNING, "Can't get file info: %s", strerror(errno) );
+  cl_ht->reply_status_code = 404;
+  strncpy( cl_ht->reply_reason_phrase, "Not Found", sizeof(cl_ht->reply_reason_phrase) );
+
+  return;
+}
+
+/**
+ * @brief dap_http_folder_read HTTP client callback for reading function for the folder processing
+ * @param cl_ht HTTP client instance
+ * @param arg Pointer to int with return bytes number
+ */
+void dap_http_folder_data_read(dap_http_client_t * cl_ht, void * arg)
+{
+    int * bytes_return = (int*) arg; // Return number of read bytes
+    //Do nothing
+    *bytes_return=cl_ht->client->buf_in_size;
+}
+
+/**
+ * @brief dap_http_folder_write HTTP client callback for writting function for the folder processing
+ * @param cl_ht HTTP client instance
+ * @param arg
+ */
+void dap_http_folder_data_write(dap_http_client_t * cl_ht, void * arg)
+{
+    (void) arg;
+    dap_http_file_t * cl_ht_file= DAP_HTTP_FILE(cl_ht);
+    cl_ht->client->buf_out_size=fread(cl_ht->client->buf_out,1,sizeof(cl_ht->client->buf_out),cl_ht_file->fd);
+    cl_ht_file->position+=cl_ht->client->buf_out_size;
+
+    if(feof(cl_ht_file->fd)!=0){
+        log_it(L_INFO, "All the file %s is sent out",cl_ht_file->local_path);
+        //strncat(cl_ht->client->buf_out+cl_ht->client->buf_out_size,"\r\n",sizeof(cl_ht->client->buf_out));
+        fclose(cl_ht_file->fd);
+        dap_client_remote_ready_to_write(cl_ht->client,false);
+
+        if ( !cl_ht->keep_alive )
+            cl_ht->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
+
+        cl_ht->state_write=DAP_HTTP_CLIENT_STATE_NONE;
+    }
+}
+
diff --git a/http_server/dap_http_folder.h b/http_server/dap_http_folder.h
index 3dec049..05d0eed 100755
--- a/http_server/dap_http_folder.h
+++ b/http_server/dap_http_folder.h
@@ -1,31 +1,31 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _DAP_HTTP_FOLDER_H_
-#define _DAP_HTTP_FOLDER_H_
-
-struct dap_http;
-
-extern int dap_http_folder_init();
-extern void dap_http_folder_deinit();
-
-extern int dap_http_folder_add(struct dap_http *sh, const char * url_path, const char * local_path); // Add folder for reading to the HTTP server
-
-#endif
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _DAP_HTTP_FOLDER_H_
+#define _DAP_HTTP_FOLDER_H_
+
+struct dap_http;
+
+extern int dap_http_folder_init();
+extern void dap_http_folder_deinit();
+
+extern int dap_http_folder_add(struct dap_http *sh, const char * url_path, const char * local_path); // Add folder for reading to the HTTP server
+
+#endif
diff --git a/http_server/dap_http_simple.c b/http_server/dap_http_simple.c
index 0a3413c..0c9c159 100755
--- a/http_server/dap_http_simple.c
+++ b/http_server/dap_http_simple.c
@@ -1,608 +1,576 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <kahovski@gmail.com>
- * Anatolii Kurotych <akurotych@gmail.com>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-   DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-   it under the terms of the GNU Lesser General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   DAP is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public License
-   along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-
-#ifndef _WIN32
-//#include <ev.h> 
-#include <sys/queue.h>
-#include <utlist.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include <json-c/json.h>
-
-#include "dap_common.h"
-#include "dap_config.h"
-#include "dap_http.h"
-#include "dap_http_client.h"
-#include "dap_http_simple.h"
-#include "dap_enc_key.h"
-#include "dap_http_user_agent.h"
-
-#include "../enc_server/dap_enc_ks.h"
-#include "../enc_server/dap_enc_http.h"
-
-#include "http_status_code.h"
-
-#define LOG_TAG "dap_http_simple"
-
-void dap_http_simple_headers_read( dap_http_client_t *cl_ht, void *arg );
-void dap_http_simple_data_write( dap_http_client_t *a_http_client, void *a_arg );
-void dap_http_simple_data_read( dap_http_client_t * cl_ht, void *arg );
-void *dap_http_simple_proc( dap_http_simple_t * cl_sh );
-
-static void *loop_http_simple_proc( void *arg );
-
-static void async_control_proc( void );
-static void queue_http_request_put( dap_http_simple_t *cl_sh );
-
-
-typedef struct dap_http_simple_url_proc {
-
-  dap_http_simple_callback_t proc_callback;
-  size_t reply_size_max;
-
-} dap_http_simple_url_proc_t;
-
-//typedef struct tailq_entry {
-
-//  dap_http_simple_t *cl_sh;
-//  TAILQ_ENTRY(tailq_entry) entries;
-
-//} tailq_entry_t;
-
-//TAILQ_HEAD(, tailq_entry) tailq_head;
-
-///DAP_HTTP_SIMPLE_REQUEST_MAX
-
-typedef struct user_agents_item {
-  dap_http_user_agent_ptr_t user_agent;
-  /* This is instead of "struct foo *next" */
-  struct user_agents_item *next;
-} user_agents_item_t;
-
-static user_agents_item_t *user_agents_list = NULL;
-static bool is_unknown_user_agents_pass = false;
-
-#define DAP_HTTP_SIMPLE_URL_PROC(a) ((dap_http_simple_url_proc_t*) (a)->_inheritor)
-
-///static struct ev_loop* http_simple_loop;
-///static ev_async async_watcher_http_simple;
-
-static pthread_mutex_t mutex_on_queue_http_response = PTHREAD_MUTEX_INITIALIZER;
-static pthread_t http_simple_loop_thread;
-static bool bSimpleLoopThreadQuitSignal = false;
-
-static dap_http_simple_t **s_requests = NULL;
-static uint32_t s_requests_count = 0;
-
-// uint64_t s_TTL_session_key=3600;
-
-static void _free_user_agents_list( void );
-
-int dap_http_simple_module_init( )
-{
-  s_requests = DAP_NEW_Z_SIZE( dap_http_simple_t *, sizeof(dap_http_simple_t *) * DAP_HTTP_SIMPLE_REQUEST_MAX );
-  if ( !s_requests ) {
-
-    log_it( L_ERROR, "Out of memory" );
-    return -1;
-  }
-
-  s_requests_count = 0;
-
-//  http_simple_loop = ev_loop_new(0);
-
-//  TAILQ_INIT( &tailq_head );
-
-//  ev_async_init( &async_watcher_http_simple, async_control_proc );
-//  ev_async_start( http_simple_loop, &async_watcher_http_simple );
-
-  bSimpleLoopThreadQuitSignal = false;
-  pthread_create( &http_simple_loop_thread, NULL, loop_http_simple_proc, NULL );
-
-  return 0;
-}
-
-void dap_http_simple_module_deinit( void )
-{
-//  ev_async_stop( http_simple_loop, &async_watcher_http_simple );
-
-  bSimpleLoopThreadQuitSignal = true;
-
-  pthread_mutex_destroy( &mutex_on_queue_http_response );
-  pthread_join( http_simple_loop_thread, NULL );
-
-//  ev_loop_destroy( http_simple_loop );
-  _free_user_agents_list( );
-
-  if ( s_requests ) {
-    free( s_requests );
-    s_requests = NULL;
-  } 
-}
-
-//static void async_control_proc( EV_P_ ev_async *w, int revents )
-
-static void async_control_proc( void )
-{
-  pthread_mutex_lock( &mutex_on_queue_http_response );
-
-  for ( uint32_t i = 0; i < s_requests_count; ++ i ) {
-
-    dap_http_simple_proc( s_requests[i] );
-    free( s_requests[i] );
-  }
-
-  s_requests_count = 0;
-
-//  tailq_entry_t *item;
-
-//  while ( item = TAILQ_FIRST(&tailq_head) ) {
-//    dap_http_simple_proc( item->cl_sh );
-//    TAILQ_REMOVE( &tailq_head, item, entries );
-//    free(item);
-//  }
-
-  pthread_mutex_unlock( &mutex_on_queue_http_response );
-}
-
-#define SIMPLE_LOOP_SLEEP   250 // ms
-static struct timespec simple_loop_sleep = { 0, SIMPLE_LOOP_SLEEP * 1000 * 1000 };
-
-static void *loop_http_simple_proc( void *arg )
-{
-  log_it( L_NOTICE, "Start loop http simple thread" );
-
-  return NULL;
-  do {
-
-    #ifndef _WIN32
-      nanosleep( &simple_loop_sleep, NULL );
-    #else
-      Sleep( SIMPLE_LOOP_SLEEP );
-    #endif
-
-///    async_control_proc( );
-
-  } while( !bSimpleLoopThreadQuitSignal );
-
-//  for ( i = 0; i < ui32TotalRequests; ++ i ) {
-
-//    dap_http_simple_proc( pRequestsBuffer[i] );
-//    free( pRequestsBuffer[i] );
-//  }
-
-
-//  ev_loop( http_simple_loop, 0 );
-  return NULL;
-}
-
-/**
- * @brief dap_http_simple_proc_add Add simple HTTP processor
- * @param sh HTTP server instance
- * @param url_path URL path
- * @param cb Callback for data processing
- */
-void dap_http_simple_proc_add( dap_http_t *sh, const char *url_path, size_t reply_size_max, dap_http_simple_callback_t cb )
-{
-  dap_http_simple_url_proc_t *shs_up = DAP_NEW_Z( dap_http_simple_url_proc_t );
-
-  shs_up->proc_callback = cb;
-  shs_up->reply_size_max = reply_size_max;
-
-  dap_http_add_proc( sh, url_path,
-                     shs_up, // Internal structure
-                     NULL, // Contrustor
-                     NULL, //  Destructor
-                     dap_http_simple_headers_read, NULL, // Headers read, write
-                     dap_http_simple_data_read, dap_http_simple_data_write, // Data read, write
-                     NULL); // errror
-}
-
-static void _free_user_agents_list()
-{
-  user_agents_item_t *elt, *tmp;
-  LL_FOREACH_SAFE( user_agents_list, elt, tmp ) {
-    LL_DELETE( user_agents_list, elt );
-    dap_http_user_agent_delete( elt->user_agent );
-    free( elt );
-  }
-}
-
-static bool _is_user_agent_supported( const char *user_agent )
-{
-  bool result = is_unknown_user_agents_pass;
-
-  dap_http_user_agent_ptr_t find_agent = dap_http_user_agent_new_from_str( user_agent );
-
-  if ( find_agent == NULL ) {
-    return result;
-  }
-
-  const char* find_agent_name = dap_http_user_agent_get_name( find_agent );
-
-  user_agents_item_t *elt;
-  LL_FOREACH( user_agents_list, elt ) {
-
-    const char* user_agent_name = dap_http_user_agent_get_name( elt->user_agent );
-
-    if ( strcmp(find_agent_name, user_agent_name) == 0) {
-      if(dap_http_user_agent_versions_compare(find_agent, elt->user_agent) >= 0) {
-        result = true;
-        goto END;
-      } 
-      else {
-        result = false;
-        goto END;
-      }
-    }
-  }
-
-END:
-  dap_http_user_agent_delete( find_agent );
-  return result;
-}
-
-bool dap_http_simple_set_supported_user_agents( const char *user_agents, ... )
-{
-  va_list argptr;
-  va_start( argptr, user_agents );
-
-  const char* str = user_agents;
-
-//  log_it(L_DEBUG,"dap_http_simple_set_supported_user_agents");
-//  Sleep(300);
-
-  while ( str != NULL )
-  {
-    dap_http_user_agent_ptr_t user_agent = dap_http_user_agent_new_from_str( str );
-
-    if ( user_agent == NULL ) {
-      log_it(L_ERROR, "Can't parse user agent string");
-       _free_user_agents_list();
-       return NULL;
-    }
-
-    user_agents_item_t *item = calloc( 1, sizeof (user_agents_item_t) );
-
-    item->user_agent = user_agent;
-    LL_APPEND( user_agents_list, item );
-
-    str = va_arg( argptr, const char * );
-  }
-
-  va_end( argptr );
-
-  return true;
-}
-
-// if this function was called. We checking version only supported user-agents
-// other will pass automatically ( and request with without user-agents field too )
-void dap_http_simple_set_pass_unknown_user_agents(bool pass)
-{
-    is_unknown_user_agents_pass = pass;
-}
-
-inline static bool _is_supported_user_agents_list_setted()
-{
-  user_agents_item_t * tmp;
-  int cnt = 0;
-  LL_COUNT(user_agents_list, tmp, cnt);
-
-  return cnt;
-}
-
-inline static void _set_only_write_http_client_state(dap_http_client_t* http_client)
-{
-//  log_it(L_DEBUG,"_set_only_write_http_client_state");
-//  Sleep(300);
-
-  dap_client_remote_ready_to_read(http_client->client,false);
-  http_client->state_write=DAP_HTTP_CLIENT_STATE_NONE;
-
-  dap_client_remote_ready_to_write(http_client->client,true);
-  http_client->state_write=DAP_HTTP_CLIENT_STATE_START;
-}
-
-static void _copy_reply_and_mime_to_response( dap_http_simple_t *cl_sh )
-{
-//  log_it(L_DEBUG,"_copy_reply_and_mime_to_response");
-//  Sleep(300);
-
-  if( !cl_sh->reply_size ) {
-
-    log_it( L_WARNING, " cl_sh->reply_size equal 0" );
-    return;
-  }
-
-  cl_sh->http->out_content_length = cl_sh->reply_size;
-  strcpy( cl_sh->http->out_content_type, cl_sh->reply_mime );
-  return;
-}
-
-inline static void _write_response_bad_request( dap_http_simple_t * cl_sh,
-                                               const char* error_msg )
-{
-//  log_it(L_DEBUG,"_write_response_bad_request");
-//  Sleep(300);
-
-  struct json_object *jobj = json_object_new_object( );
-  json_object_object_add( jobj, "error", json_object_new_string(error_msg) );
-
-  log_it( L_DEBUG, "error message %s",  json_object_to_json_string(jobj) );
-  cl_sh->http->reply_status_code = Http_Status_BadRequest;
-
-  const char* json_str = json_object_to_json_string( jobj );
-  dap_http_simple_reply(cl_sh, (void*) json_str,
-                          (size_t) strlen(json_str) );
-
-  strcpy( cl_sh->reply_mime, "application/json" );
-
-  _copy_reply_and_mime_to_response( cl_sh );
-
-  json_object_put( jobj ); // free obj
-  _set_only_write_http_client_state( cl_sh->http );
-}
-
-/**
- * @brief dap_http_simple_proc Execute procession callback and switch to write state
- * @param cl_sh HTTP simple client instance
- */
-void* dap_http_simple_proc( dap_http_simple_t *cl_sh )
-{
-//  log_it(L_DEBUG, "dap http simple proc");
-//  Sleep(300);
-
-    http_status_code_t return_code = (http_status_code_t)0;
-
-    if(_is_supported_user_agents_list_setted() == true) {
-        dap_http_header_t *header = dap_http_header_find(cl_sh->http->in_headers, "User-Agent");
-        if(header == NULL && is_unknown_user_agents_pass == false) {
-            const char* error_msg = "Not found User-Agent HTTP header";
-            _write_response_bad_request(cl_sh, error_msg);
-            return NULL;
-        }
-
-        if(_is_user_agent_supported(header->value) == false) {
-            log_it(L_DEBUG, "Not supported user agent in request: %s", header->value);
-            const char* error_msg = "User-Agent version not supported. Update your software";
-            _write_response_bad_request(cl_sh, error_msg);
-            return NULL;
-        }
-    }
-
-    DAP_HTTP_SIMPLE_URL_PROC(cl_sh->http->proc)->proc_callback(cl_sh,&return_code);
-
-    if(return_code) {
-        log_it(L_DEBUG, "Request was processed well");
-        cl_sh->http->reply_status_code = (uint16_t)return_code;
-        _copy_reply_and_mime_to_response(cl_sh);
-    } else {
-        log_it(L_ERROR, "Request was processed with ERROR");
-        cl_sh->http->reply_status_code = Http_Status_InternalServerError;
-    }
-
-    _set_only_write_http_client_state(cl_sh->http);
-    return NULL;
-}
-
-/**
- * @brief dap_http_simple_headers_read Prepare reply on request
- * @param cl_ht
- * @param arg
- */
-void dap_http_simple_headers_read( dap_http_client_t *cl_ht, void *arg )
-{
-  cl_ht->_inheritor = DAP_NEW_Z( dap_http_simple_t );
-
-//  log_it(L_DEBUG,"dap_http_simple_headers_read");
-//  Sleep(300);
-
-  DAP_HTTP_SIMPLE(cl_ht)->http = cl_ht;
-  DAP_HTTP_SIMPLE(cl_ht)->reply_size_max = DAP_HTTP_SIMPLE_URL_PROC( cl_ht->proc )->reply_size_max;
-  DAP_HTTP_SIMPLE(cl_ht)->reply = calloc( 1, DAP_HTTP_SIMPLE(cl_ht)->reply_size_max );
-
-  if( cl_ht->in_content_length ) {
-    if( cl_ht->in_content_length < DAP_HTTP_SIMPLE_REQUEST_MAX )
-      DAP_HTTP_SIMPLE(cl_ht)->request = calloc( 1, cl_ht->in_content_length + 1 );
-    else
-      log_it( L_ERROR, "Too big content-length %u in request", cl_ht->in_content_length );
-  }
-  else {
-    log_it( L_DEBUG, "No data section, execution proc callback" );
-    queue_http_request_put( DAP_HTTP_SIMPLE(cl_ht) );
-  }
-}
-
-void dap_http_simple_data_read( dap_http_client_t *cl_ht, void * arg )
-{
-  int *ret = (int *)arg;
-
-//  log_it(L_DEBUG,"dap_http_simple_data_read");
-//  Sleep(300);
-
-  dap_http_simple_t *shs = DAP_HTTP_SIMPLE(cl_ht);
-
-  size_t bytes_to_read = (cl_ht->client->buf_in_size + shs->request_size) < cl_ht->in_content_length ?
-                            cl_ht->client->buf_in_size : ( cl_ht->in_content_length - shs->request_size );
-  if( bytes_to_read ) {
-    memcpy( shs->request + shs->request_size, cl_ht->client->buf_in, bytes_to_read );
-    shs->request_size += bytes_to_read;
-  }
-
-  if( shs->request_size >= cl_ht->in_content_length ) {
-
-    // bool isOK=true;
-    log_it( L_DEBUG,"Data collected" );
-    queue_http_request_put( shs );
-  }
-
-  *ret = cl_ht->client->buf_in_size;
-}
-
-
-/**
- * @brief dap_http_simple_data_write
- * @param a_http_client
- * @param a_arg
- */
-void dap_http_simple_data_write( dap_http_client_t *a_http_client, void *a_arg )
-{
-  (void) a_arg;
-  dap_http_simple_t *cl_st = DAP_HTTP_SIMPLE( a_http_client );
-
-//  log_it(L_DEBUG,"dap_http_simple_data_write");
-//  Sleep(300);
-
-  if ( !cl_st->reply ) {
-
-    a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
-    log_it( L_WARNING, "No reply to write, close connection" );
-
-    return;
-  }
-
-  cl_st->reply_sent += dap_client_remote_write( a_http_client->client,
-                                              cl_st->reply + cl_st->reply_sent,
-                                              a_http_client->out_content_length - cl_st->reply_sent );
-
-  if ( cl_st->reply_sent >= a_http_client->out_content_length ) {
-    log_it(L_INFO, "All the reply (%u) is sent out", a_http_client->out_content_length );
-    //cl_ht->client->signal_close=cl_ht->keep_alive;
-    a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
-    //dap_client_ready_to_write(cl_ht->client,false);
-  }
-
-  free( cl_st->reply );
-}
-
-/**
- * @brief dap_http_simple_reply Add data to the reply buffer
- * @param shs HTTP simple client instance
- * @param data
- * @param data_size
- */
-size_t dap_http_simple_reply( dap_http_simple_t *shs, void *data, size_t data_size )
-{
-  size_t wb = (data_size > (shs->reply_size_max - shs->reply_size) ) ? (shs->reply_size_max - shs->reply_size) : data_size;
-
-  memcpy( shs->reply + shs->reply_size, data, wb );
-  shs->reply_size += wb;
-
-  return wb;
-}
-
-/**
- * @brief dap_http_simple_reply_f
- * @param shs
- * @param data
- */
-size_t dap_http_simple_reply_f( dap_http_simple_t * shs, const char * data, ... )
-{
-  char buf[4096];
-  va_list va;
-  int vret;
-
-  va_start(va,data);
-  vret = vsnprintf( buf, sizeof(buf) - 1, data, va );
-  va_end(va);
-
-  if ( vret > 0 )
-    return dap_http_simple_reply( shs, buf, vret );
-  else
-    return 0;
-}
-
-inline void queue_http_request_put( dap_http_simple_t *cl_sh )
-{
-  dap_http_simple_proc( cl_sh );
-
-  return;
-
-  pthread_mutex_lock( &mutex_on_queue_http_response );
-
-//  tailq_entry_t *item = malloc (sizeof(tailq_entry_t));
-//  item->cl_sh = cl_sh;
-//  TAILQ_INSERT_TAIL(&tailq_head, item, entries);
-
-  if ( s_requests_count >= DAP_HTTP_SIMPLE_REQUEST_MAX ) {
-
-    log_it( L_NOTICE, "Requests Buffer is FULL( %u ) ignore request" );
-    pthread_mutex_unlock( &mutex_on_queue_http_response );
-    return;
-  }
-
-  log_it( L_WARNING, "queue_http_request_put >>> %u", s_requests_count );
-
-  s_requests[ s_requests_count ++ ] = cl_sh;
-
-  pthread_mutex_unlock( &mutex_on_queue_http_response );
-
-//  ev_async_send( http_simple_loop, &async_watcher_http_simple );
-}
-
-/* Key Expired deprecated code */
-
-//    bool key_is_expiried = false;
-
-//    dap_enc_key_t * key = dap_enc_ks_find_http(cl_sh->http);
-//    if(key){
-//        if( key->last_used_timestamp && ( (time(NULL) - key->last_used_timestamp  )
-//                                          > s_TTL_session_key ) ) {
-
-//            enc_http_delegate_t * dg = enc_http_request_decode(cl_sh);
-
-//            if( dg == NULL ) {
-//                log_it(L_ERROR, "dg is NULL");
-//                return NULL;
-//            }
-
-//            log_it(L_WARNING, "Key has been expiried");
-//            strcpy(cl_sh->reply_mime,"text/plain");
-//            enc_http_reply_f(dg,"Key has been expiried");
-//            enc_http_reply_encode(cl_sh,dg);
-//            enc_http_delegate_delete(dg);
-//            key_is_expiried = true;
-//        } else{
-//            key->last_used_timestamp = time(NULL);
-//        }
-//    }
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * Anatolii Kurotych <akurotych@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+   DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   DAP is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+#include <time.h>
+
+#ifndef _WIN32
+//#include <ev.h> 
+#include <sys/queue.h>
+#include <utlist.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include <json-c/json.h>
+
+#include "dap_common.h"
+#include "dap_config.h"
+#include "dap_http.h"
+#include "dap_http_client.h"
+#include "dap_http_simple.h"
+#include "dap_enc_key.h"
+#include "dap_http_user_agent.h"
+
+#include "../enc_server/dap_enc_ks.h"
+#include "../enc_server/dap_enc_http.h"
+
+#include "http_status_code.h"
+
+#define LOG_TAG "dap_http_simple"
+
+void dap_http_simple_headers_read( dap_http_client_t *cl_ht, void *arg );
+void dap_http_simple_data_write( dap_http_client_t *a_http_client, void *a_arg );
+void dap_http_simple_data_read( dap_http_client_t * cl_ht, void *arg );
+void *dap_http_simple_proc( dap_http_simple_t * cl_sh );
+
+static void *loop_http_simple_proc( void *arg );
+
+static void async_control_proc( void );
+static void queue_http_request_put( dap_http_simple_t *cl_sh );
+
+
+typedef struct dap_http_simple_url_proc {
+
+  dap_http_simple_callback_t proc_callback;
+  size_t reply_size_max;
+
+} dap_http_simple_url_proc_t;
+
+//typedef struct tailq_entry {
+
+//  dap_http_simple_t *cl_sh;
+//  TAILQ_ENTRY(tailq_entry) entries;
+
+//} tailq_entry_t;
+
+//TAILQ_HEAD(, tailq_entry) tailq_head;
+
+///DAP_HTTP_SIMPLE_REQUEST_MAX
+
+typedef struct user_agents_item {
+  dap_http_user_agent_ptr_t user_agent;
+  /* This is instead of "struct foo *next" */
+  struct user_agents_item *next;
+} user_agents_item_t;
+
+static user_agents_item_t *user_agents_list = NULL;
+static bool is_unknown_user_agents_pass = false;
+
+#define DAP_HTTP_SIMPLE_URL_PROC(a) ((dap_http_simple_url_proc_t*) (a)->_inheritor)
+
+///static struct ev_loop* http_simple_loop;
+///static ev_async async_watcher_http_simple;
+
+static pthread_mutex_t mutex_on_queue_http_response = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t http_simple_loop_thread;
+static bool bSimpleLoopThreadQuitSignal = false;
+
+static dap_http_simple_t **s_requests = NULL;
+static dap_http_simple_t **s_requestsproc = NULL;
+
+static uint32_t s_requests_count = 0;
+static uint32_t s_requestsproc_count = 0;
+
+static void _free_user_agents_list( void );
+
+int dap_http_simple_module_init( )
+{
+  s_requests = (dap_http_simple_t *)malloc( sizeof(dap_http_simple_t *) * DAP_HTTP_SIMPLE_REQUEST_MAX * 2 );
+  if ( !s_requests ) {
+
+    log_it( L_ERROR, "Out of memory" );
+    return -1;
+  }
+
+  s_requestsproc = s_requests + DAP_HTTP_SIMPLE_REQUEST_MAX;
+  s_requests_count = 0;
+
+  bSimpleLoopThreadQuitSignal = false;
+  pthread_create( &http_simple_loop_thread, NULL, loop_http_simple_proc, NULL );
+
+  return 0;
+}
+
+void dap_http_simple_module_deinit( void )
+{
+  bSimpleLoopThreadQuitSignal = true;
+
+  pthread_mutex_destroy( &mutex_on_queue_http_response );
+  pthread_join( http_simple_loop_thread, NULL );
+
+  _free_user_agents_list( );
+
+  if ( s_requests ) {
+    free( s_requests );
+    s_requests = NULL;
+  } 
+}
+
+//#define SIMPLE_LOOP_SLEEP   25 // ms
+#define SIMPLE_LOOP_SLEEP   50 // ms
+
+static struct timespec simple_loop_sleep = { 0, SIMPLE_LOOP_SLEEP * 1000 * 1000 };
+
+static void *loop_http_simple_proc( void *arg )
+{
+  log_it( L_NOTICE, "Start loop http simple thread" );
+
+  do {
+
+    pthread_mutex_lock( &mutex_on_queue_http_response );
+    if ( s_requests_count ) {
+
+      s_requestsproc_count = s_requests_count;
+      s_requests_count = 0;
+      memcpy( s_requestsproc, s_requests, sizeof(void *) * s_requestsproc_count );
+      pthread_mutex_unlock( &mutex_on_queue_http_response );
+
+      for ( uint32_t i = 0; i < s_requestsproc_count; ++ i ) {
+        dap_http_simple_proc( s_requestsproc[i] );
+//        s_requestsproc[i]->http->client->no_close = false;
+//        free( s_requestsproc[i] ); // ???
+      }
+    }
+    else {
+      pthread_mutex_unlock( &mutex_on_queue_http_response );
+      #ifndef _WIN32
+        nanosleep( &simple_loop_sleep, NULL );
+      #else
+        Sleep( SIMPLE_LOOP_SLEEP );
+      #endif
+    }
+
+  } while( !bSimpleLoopThreadQuitSignal );
+
+  return NULL;
+}
+
+/**
+ * @brief dap_http_simple_proc_add Add simple HTTP processor
+ * @param sh HTTP server instance
+ * @param url_path URL path
+ * @param cb Callback for data processing
+ */
+void dap_http_simple_proc_add( dap_http_t *sh, const char *url_path, size_t reply_size_max, dap_http_simple_callback_t cb )
+{
+  dap_http_simple_url_proc_t *shs_up = DAP_NEW_Z( dap_http_simple_url_proc_t );
+
+  shs_up->proc_callback = cb;
+  shs_up->reply_size_max = reply_size_max;
+
+  dap_http_add_proc( sh, url_path,
+                     shs_up, // Internal structure
+                     NULL, // Contrustor
+                     NULL, //  Destructor
+                     dap_http_simple_headers_read, NULL, // Headers read, write
+                     dap_http_simple_data_read, dap_http_simple_data_write, // Data read, write
+                     NULL); // errror
+}
+
+static void _free_user_agents_list()
+{
+  user_agents_item_t *elt, *tmp;
+  LL_FOREACH_SAFE( user_agents_list, elt, tmp ) {
+    LL_DELETE( user_agents_list, elt );
+    dap_http_user_agent_delete( elt->user_agent );
+    free( elt );
+  }
+}
+
+static bool _is_user_agent_supported( const char *user_agent )
+{
+  bool result = is_unknown_user_agents_pass;
+
+  dap_http_user_agent_ptr_t find_agent = dap_http_user_agent_new_from_str( user_agent );
+
+  if ( find_agent == NULL ) {
+    return result;
+  }
+
+  const char* find_agent_name = dap_http_user_agent_get_name( find_agent );
+
+  user_agents_item_t *elt;
+  LL_FOREACH( user_agents_list, elt ) {
+
+    const char* user_agent_name = dap_http_user_agent_get_name( elt->user_agent );
+
+    if ( strcmp(find_agent_name, user_agent_name) == 0) {
+      if(dap_http_user_agent_versions_compare(find_agent, elt->user_agent) >= 0) {
+        result = true;
+        goto END;
+      } 
+      else {
+        result = false;
+        goto END;
+      }
+    }
+  }
+
+END:
+  dap_http_user_agent_delete( find_agent );
+  return result;
+}
+
+bool dap_http_simple_set_supported_user_agents( const char *user_agents, ... )
+{
+  va_list argptr;
+  va_start( argptr, user_agents );
+
+  const char* str = user_agents;
+
+//  log_it(L_DEBUG,"dap_http_simple_set_supported_user_agents");
+//  Sleep(300);
+
+  while ( str != NULL )
+  {
+    dap_http_user_agent_ptr_t user_agent = dap_http_user_agent_new_from_str( str );
+
+    if ( user_agent == NULL ) {
+      log_it(L_ERROR, "Can't parse user agent string");
+       _free_user_agents_list();
+       return NULL;
+    }
+
+    user_agents_item_t *item = calloc( 1, sizeof (user_agents_item_t) );
+
+    item->user_agent = user_agent;
+    LL_APPEND( user_agents_list, item );
+
+    str = va_arg( argptr, const char * );
+  }
+
+  va_end( argptr );
+
+  return true;
+}
+
+// if this function was called. We checking version only supported user-agents
+// other will pass automatically ( and request with without user-agents field too )
+void dap_http_simple_set_pass_unknown_user_agents(bool pass)
+{
+    is_unknown_user_agents_pass = pass;
+}
+
+inline static bool _is_supported_user_agents_list_setted()
+{
+  user_agents_item_t * tmp;
+  int cnt = 0;
+  LL_COUNT(user_agents_list, tmp, cnt);
+
+  return cnt;
+}
+
+inline static void _set_only_write_http_client_state(dap_http_client_t* http_client)
+{
+//  log_it(L_DEBUG,"_set_only_write_http_client_state");
+//  Sleep(300);
+
+  dap_client_remote_ready_to_read(http_client->client,false);
+  http_client->state_write=DAP_HTTP_CLIENT_STATE_NONE;
+
+  dap_client_remote_ready_to_write(http_client->client,true);
+  http_client->state_write=DAP_HTTP_CLIENT_STATE_START;
+}
+
+static void _copy_reply_and_mime_to_response( dap_http_simple_t *cl_sh )
+{
+//  log_it(L_DEBUG,"_copy_reply_and_mime_to_response");
+//  Sleep(300);
+
+  if( !cl_sh->reply_size ) {
+
+    log_it( L_WARNING, " cl_sh->reply_size equal 0" );
+    return;
+  }
+
+  cl_sh->http->out_content_length = cl_sh->reply_size;
+  strcpy( cl_sh->http->out_content_type, cl_sh->reply_mime );
+  return;
+}
+
+inline static void _write_response_bad_request( dap_http_simple_t * cl_sh,
+                                               const char* error_msg )
+{
+//  log_it(L_DEBUG,"_write_response_bad_request");
+//  Sleep(300);
+
+  struct json_object *jobj = json_object_new_object( );
+  json_object_object_add( jobj, "error", json_object_new_string(error_msg) );
+
+  log_it( L_DEBUG, "error message %s",  json_object_to_json_string(jobj) );
+  cl_sh->http->reply_status_code = Http_Status_BadRequest;
+
+  const char* json_str = json_object_to_json_string( jobj );
+  dap_http_simple_reply(cl_sh, (void*) json_str,
+                          (size_t) strlen(json_str) );
+
+  strcpy( cl_sh->reply_mime, "application/json" );
+
+  _copy_reply_and_mime_to_response( cl_sh );
+
+  json_object_put( jobj ); // free obj
+  _set_only_write_http_client_state( cl_sh->http );
+}
+
+/**
+ * @brief dap_http_simple_proc Execute procession callback and switch to write state
+ * @param cl_sh HTTP simple client instance
+ */
+void* dap_http_simple_proc( dap_http_simple_t *cl_sh )
+{
+//  log_it(L_DEBUG, "dap http simple proc");
+//  Sleep(300);
+
+    http_status_code_t return_code = (http_status_code_t)0;
+
+    if(_is_supported_user_agents_list_setted() == true) {
+        dap_http_header_t *header = dap_http_header_find(cl_sh->http->in_headers, "User-Agent");
+        if(header == NULL && is_unknown_user_agents_pass == false) {
+            const char* error_msg = "Not found User-Agent HTTP header";
+            _write_response_bad_request(cl_sh, error_msg);
+            return NULL;
+        }
+
+        if(_is_user_agent_supported(header->value) == false) {
+            log_it(L_DEBUG, "Not supported user agent in request: %s", header->value);
+            const char* error_msg = "User-Agent version not supported. Update your software";
+            _write_response_bad_request(cl_sh, error_msg);
+            return NULL;
+        }
+    }
+
+    DAP_HTTP_SIMPLE_URL_PROC(cl_sh->http->proc)->proc_callback(cl_sh,&return_code);
+
+    if(return_code) {
+        log_it(L_DEBUG, "Request was processed well");
+        cl_sh->http->reply_status_code = (uint16_t)return_code;
+        _copy_reply_and_mime_to_response(cl_sh);
+    } else {
+        log_it(L_ERROR, "Request was processed with ERROR");
+        cl_sh->http->reply_status_code = Http_Status_InternalServerError;
+    }
+
+    _set_only_write_http_client_state(cl_sh->http);
+    return NULL;
+}
+
+/**
+ * @brief dap_http_simple_headers_read Prepare reply on request
+ * @param cl_ht
+ * @param arg
+ */
+void dap_http_simple_headers_read( dap_http_client_t *cl_ht, void *arg )
+{
+  cl_ht->_inheritor = DAP_NEW_Z( dap_http_simple_t );
+
+//  log_it(L_DEBUG,"dap_http_simple_headers_read");
+//  Sleep(300);
+
+  DAP_HTTP_SIMPLE(cl_ht)->http = cl_ht;
+  DAP_HTTP_SIMPLE(cl_ht)->reply_size_max = DAP_HTTP_SIMPLE_URL_PROC( cl_ht->proc )->reply_size_max;
+  DAP_HTTP_SIMPLE(cl_ht)->reply = calloc( 1, DAP_HTTP_SIMPLE(cl_ht)->reply_size_max );
+
+  if( cl_ht->in_content_length ) {
+    if( cl_ht->in_content_length < DAP_HTTP_SIMPLE_REQUEST_MAX )
+      DAP_HTTP_SIMPLE(cl_ht)->request = calloc( 1, cl_ht->in_content_length + 1 );
+    else
+      log_it( L_ERROR, "Too big content-length %u in request", cl_ht->in_content_length );
+  }
+  else {
+    log_it( L_DEBUG, "No data section, execution proc callback" );
+    queue_http_request_put( DAP_HTTP_SIMPLE(cl_ht) );
+  }
+}
+
+void dap_http_simple_data_read( dap_http_client_t *cl_ht, void * arg )
+{
+  int *ret = (int *)arg;
+
+//  log_it(L_DEBUG,"dap_http_simple_data_read");
+//  Sleep(300);
+
+  dap_http_simple_t *shs = DAP_HTTP_SIMPLE(cl_ht);
+
+  size_t bytes_to_read = (cl_ht->client->buf_in_size + shs->request_size) < cl_ht->in_content_length ?
+                            cl_ht->client->buf_in_size : ( cl_ht->in_content_length - shs->request_size );
+  if( bytes_to_read ) {
+    memcpy( shs->request + shs->request_size, cl_ht->client->buf_in, bytes_to_read );
+    shs->request_size += bytes_to_read;
+  }
+
+  if( shs->request_size >= cl_ht->in_content_length ) {
+
+    // bool isOK=true;
+    log_it( L_DEBUG,"Data collected" );
+    queue_http_request_put( shs );
+  }
+
+  *ret = cl_ht->client->buf_in_size;
+}
+
+
+/**
+ * @brief dap_http_simple_data_write
+ * @param a_http_client
+ * @param a_arg
+ */
+void dap_http_simple_data_write( dap_http_client_t *a_http_client, void *a_arg )
+{
+  (void) a_arg;
+  dap_http_simple_t *cl_st = DAP_HTTP_SIMPLE( a_http_client );
+
+//  log_it(L_DEBUG,"dap_http_simple_data_write");
+//  Sleep(300);
+
+  if ( !cl_st->reply ) {
+
+    a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
+    log_it( L_WARNING, "No reply to write, close connection" );
+
+    return;
+  }
+
+  cl_st->reply_sent += dap_client_remote_write( a_http_client->client,
+                                              cl_st->reply + cl_st->reply_sent,
+                                              a_http_client->out_content_length - cl_st->reply_sent );
+
+  if ( cl_st->reply_sent >= a_http_client->out_content_length ) {
+    log_it(L_INFO, "All the reply (%u) is sent out", a_http_client->out_content_length );
+    //cl_ht->client->signal_close=cl_ht->keep_alive;
+    a_http_client->client->flags |= DAP_SOCK_SIGNAL_CLOSE;
+    //dap_client_ready_to_write(cl_ht->client,false);
+  }
+
+  free( cl_st->reply );
+}
+
+/**
+ * @brief dap_http_simple_reply Add data to the reply buffer
+ * @param shs HTTP simple client instance
+ * @param data
+ * @param data_size
+ */
+size_t dap_http_simple_reply( dap_http_simple_t *shs, void *data, size_t data_size )
+{
+  size_t wb = (data_size > (shs->reply_size_max - shs->reply_size) ) ? (shs->reply_size_max - shs->reply_size) : data_size;
+
+  memcpy( shs->reply + shs->reply_size, data, wb );
+  shs->reply_size += wb;
+
+  return wb;
+}
+
+/**
+ * @brief dap_http_simple_reply_f
+ * @param shs
+ * @param data
+ */
+size_t dap_http_simple_reply_f( dap_http_simple_t * shs, const char * data, ... )
+{
+  char buf[4096];
+  va_list va;
+  int vret;
+
+  va_start(va,data);
+  vret = vsnprintf( buf, sizeof(buf) - 1, data, va );
+  va_end(va);
+
+  if ( vret > 0 )
+    return dap_http_simple_reply( shs, buf, vret );
+  else
+    return 0;
+}
+
+inline void queue_http_request_put( dap_http_simple_t *cl_sh )
+{
+//  dap_http_simple_proc( cl_sh );
+
+  pthread_mutex_lock( &mutex_on_queue_http_response );
+
+  if ( s_requests_count >= DAP_HTTP_SIMPLE_REQUEST_MAX ) {
+
+    log_it( L_NOTICE, "Requests Buffer is FULL( %u ) ignore request" );
+    pthread_mutex_unlock( &mutex_on_queue_http_response );
+    return;
+  }
+
+  log_it( L_WARNING, "queue_http_request_put >>> %u", s_requests_count );
+
+  s_requests[ s_requests_count ++ ] = cl_sh;
+//  cl_sh->http->client->no_close = true;
+
+  pthread_mutex_unlock( &mutex_on_queue_http_response );
+}
+
+/* Key Expired deprecated code */
+
+//    bool key_is_expiried = false;
+
+//    dap_enc_key_t * key = dap_enc_ks_find_http(cl_sh->http);
+//    if(key){
+//        if( key->last_used_timestamp && ( (time(NULL) - key->last_used_timestamp  )
+//                                          > s_TTL_session_key ) ) {
+
+//            enc_http_delegate_t * dg = enc_http_request_decode(cl_sh);
+
+//            if( dg == NULL ) {
+//                log_it(L_ERROR, "dg is NULL");
+//                return NULL;
+//            }
+
+//            log_it(L_WARNING, "Key has been expiried");
+//            strcpy(cl_sh->reply_mime,"text/plain");
+//            enc_http_reply_f(dg,"Key has been expiried");
+//            enc_http_reply_encode(cl_sh,dg);
+//            enc_http_delegate_delete(dg);
+//            key_is_expiried = true;
+//        } else{
+//            key->last_used_timestamp = time(NULL);
+//        }
+//    }
diff --git a/http_server/dap_http_simple.h b/http_server/dap_http_simple.h
index b7f2ac6..a71fb8c 100755
--- a/http_server/dap_http_simple.h
+++ b/http_server/dap_http_simple.h
@@ -1,80 +1,80 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _DAP_HTTP_SIMPLE_H_
-#define _DAP_HTTP_SIMPLE_H_
-
-#include <stddef.h>
-#include "dap_http.h"
-
-//#define DAP_HTTP_SIMPLE_REQUEST_MAX 100000
-
-#define DAP_HTTP_SIMPLE_REQUEST_MAX 65536
-
-struct dap_http_simple;
-typedef void ( *dap_http_simple_callback_t )( struct dap_http_simple *, void * );
-
-typedef struct dap_http_simple {
-
-  dap_http_client_t *http;
-
-  union {
-    void *request;
-    char *request_str;
-  };
-
-  union {
-    void *reply;
-    char *reply_str;
-  };
-
-  size_t request_size;
-  size_t reply_size;
-  size_t reply_size_max;
-  size_t reply_sent;
-
-  char reply_mime[256];
-
-   // dap_http_simple_callback_t reply_proc_post_callback;
-} dap_http_simple_t;
-
-#define DAP_HTTP_SIMPLE(a) ((dap_http_simple_t*) (a)->_inheritor )
-
-void dap_http_simple_proc_add( dap_http_t *sh, const char *url_path, size_t reply_size_max, dap_http_simple_callback_t cb ); // Add simple processor
-int  dap_http_simple_module_init( void );
-void dap_http_simple_module_deinit(void);
-
-// input string must match NameClient/MiminalVersion
-// For example DapClient/2.2
-// If this function was not called. All user agents will supported by default
-// ATTENTION: Last parameter must be NULL
-// example call: dap_http_simple_set_supported_user_agents("DapVpnClient/2.2", "Mozila/5.0", NULL);
-// returns false if operation not successful
-bool dap_http_simple_set_supported_user_agents( const char *str_agents, ... );
-
-// if this function was called. We checking version only supported user-agents
-// other will pass automatically ( and request with without user-agents field too )
-// Affects the behavior of the internal function _is_user_agent_supported
-void dap_http_simple_set_pass_unknown_user_agents( bool pass );
-
-size_t dap_http_simple_reply( dap_http_simple_t *shs, void *data, size_t data_size );
-size_t dap_http_simple_reply_f( dap_http_simple_t *shs, const char *data, ... );
-
-#endif
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _DAP_HTTP_SIMPLE_H_
+#define _DAP_HTTP_SIMPLE_H_
+
+#include <stddef.h>
+#include "dap_http.h"
+
+//#define DAP_HTTP_SIMPLE_REQUEST_MAX 100000
+
+#define DAP_HTTP_SIMPLE_REQUEST_MAX 65536
+
+struct dap_http_simple;
+typedef void ( *dap_http_simple_callback_t )( struct dap_http_simple *, void * );
+
+typedef struct dap_http_simple {
+
+  dap_http_client_t *http;
+
+  union {
+    void *request;
+    char *request_str;
+  };
+
+  union {
+    void *reply;
+    char *reply_str;
+  };
+
+  size_t request_size;
+  size_t reply_size;
+  size_t reply_size_max;
+  size_t reply_sent;
+
+  char reply_mime[256];
+
+   // dap_http_simple_callback_t reply_proc_post_callback;
+} dap_http_simple_t;
+
+#define DAP_HTTP_SIMPLE(a) ((dap_http_simple_t*) (a)->_inheritor )
+
+void dap_http_simple_proc_add( dap_http_t *sh, const char *url_path, size_t reply_size_max, dap_http_simple_callback_t cb ); // Add simple processor
+int  dap_http_simple_module_init( void );
+void dap_http_simple_module_deinit(void);
+
+// input string must match NameClient/MiminalVersion
+// For example DapClient/2.2
+// If this function was not called. All user agents will supported by default
+// ATTENTION: Last parameter must be NULL
+// example call: dap_http_simple_set_supported_user_agents("DapVpnClient/2.2", "Mozila/5.0", NULL);
+// returns false if operation not successful
+bool dap_http_simple_set_supported_user_agents( const char *str_agents, ... );
+
+// if this function was called. We checking version only supported user-agents
+// other will pass automatically ( and request with without user-agents field too )
+// Affects the behavior of the internal function _is_user_agent_supported
+void dap_http_simple_set_pass_unknown_user_agents( bool pass );
+
+size_t dap_http_simple_reply( dap_http_simple_t *shs, void *data, size_t data_size );
+size_t dap_http_simple_reply_f( dap_http_simple_t *shs, const char *data, ... );
+
+#endif
-- 
GitLab