diff --git a/http_server/dap_http_simple.c b/http_server/dap_http_simple.c
index bcfac6209726a5617ba4d895293bf16b55696f58..37839e8267617eeba0ff1dff63ba9bb7ca4afd51 100755
--- a/http_server/dap_http_simple.c
+++ b/http_server/dap_http_simple.c
@@ -1,575 +1,571 @@
-/*
- * 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 <sys/queue.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 <wepoll.h>
-#endif
-
-#include <pthread.h>
-#include <json-c/json.h>
-
-#include "utlist.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 = dap_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);
-//        }
-//    }
+/*
+* Authors:
+* Dmitrii Gerasimov <naeper@demlabs.net>
+* DeM Labs Inc.   https://demlabs.net
+* Cellframe https://cellframe.net
+* Copyright  (c) 2017-2019
+* All rights reserved.
+
+This file is part of DAP the open source project.
+
+DAP is free software: you can redistribute it and/or modify
+it under the terms of the GNU 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 General Public License for more details.
+
+See more details here <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 <sys/queue.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 <wepoll.h>
+#endif
+
+#include <pthread.h>
+#include <json-c/json.h>
+
+#include "utlist.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"
+
+static void s_headers_read( dap_http_client_t *cl_ht, void *arg );
+static void s_data_write( dap_http_client_t *a_http_client, void *a_arg );
+static void s_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 a_http HTTP server instance
+ * @param a_url_path URL path
+ * @param a_reply_size_max Maximum reply size
+ * @param a_callback Callback for data processing
+ */
+void dap_http_simple_proc_add( dap_http_t *a_http, const char *a_url_path, size_t a_reply_size_max, dap_http_simple_callback_t a_callback )
+{
+    dap_http_simple_url_proc_t *l_url_proc = DAP_NEW_Z( dap_http_simple_url_proc_t );
+
+    l_url_proc->proc_callback = a_callback;
+    l_url_proc->reply_size_max = a_reply_size_max;
+
+    dap_http_add_proc( a_http, a_url_path,
+                     l_url_proc, // Internal structure
+                     NULL, // Contrustor
+                     NULL, //  Destructor
+                     s_headers_read, NULL, // Headers read, write
+                     s_data_read, s_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;
+}
+
+
+static void s_headers_read( dap_http_client_t *a_http_client, void *a_arg )
+{
+    (void) a_arg;
+
+    a_http_client->_inheritor = DAP_NEW_Z( dap_http_simple_t );
+
+    //  log_it(L_DEBUG,"dap_http_simple_headers_read");
+    //  Sleep(300);
+
+    DAP_HTTP_SIMPLE(a_http_client)->http = a_http_client;
+    DAP_HTTP_SIMPLE(a_http_client)->reply_size_max = DAP_HTTP_SIMPLE_URL_PROC( a_http_client->proc )->reply_size_max;
+    DAP_HTTP_SIMPLE(a_http_client)->reply_byte = DAP_NEW_Z_SIZE(uint8_t, DAP_HTTP_SIMPLE(a_http_client)->reply_size_max );
+
+    if( a_http_client->in_content_length ) {
+        if( a_http_client->in_content_length < DAP_HTTP_SIMPLE_REQUEST_MAX )
+            DAP_HTTP_SIMPLE(a_http_client)->request = calloc( 1, a_http_client->in_content_length + 1 );
+        else
+            log_it( L_ERROR, "Too big content-length %u in request", a_http_client->in_content_length );
+    } else {
+        log_it( L_DEBUG, "No data section, execution proc callback" );
+        queue_http_request_put( DAP_HTTP_SIMPLE(a_http_client) );
+    }
+}
+
+void s_data_read( dap_http_client_t *a_http_client, void * a_arg )
+{
+    int *ret = (int *)a_arg;
+
+    //  log_it(L_DEBUG,"dap_http_simple_data_read");
+    //  Sleep(300);
+
+    dap_http_simple_t *l_http_simple = DAP_HTTP_SIMPLE(a_http_client);
+
+    size_t bytes_to_read = (a_http_client->client->buf_in_size + l_http_simple->request_size) < a_http_client->in_content_length ?
+                            a_http_client->client->buf_in_size : ( a_http_client->in_content_length - l_http_simple->request_size );
+
+    if( bytes_to_read ) {
+        memcpy( l_http_simple->request_byte + l_http_simple->request_size, a_http_client->client->buf_in, bytes_to_read );
+        l_http_simple->request_size += bytes_to_read;
+    }
+
+    if( l_http_simple->request_size >= a_http_client->in_content_length ) {
+
+        // bool isOK=true;
+        log_it( L_DEBUG,"Data collected" );
+        queue_http_request_put( l_http_simple );
+    }
+
+    *ret = (int) a_http_client->client->buf_in_size;
+}
+
+
+/**
+ * @brief dap_http_simple_data_write
+ * @param a_http_client
+ * @param a_arg
+ */
+static void s_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_byte + 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 *a_http_simple, void *a_data, size_t a_data_size )
+{
+    size_t l_data_copy_size = (a_data_size > (a_http_simple->reply_size_max - a_http_simple->reply_size) ) ? (a_http_simple->reply_size_max - a_http_simple->reply_size) : a_data_size;
+
+    memcpy( a_http_simple->reply_byte + a_http_simple->reply_size, a_data, l_data_copy_size );
+    a_http_simple->reply_size += l_data_copy_size;
+
+    return l_data_copy_size;
+}
+
+/**
+ * @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 = dap_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 a71fb8cc85308ded74d542bbc208453cecdbad63..12e3d3461e3c71eed797b6f7f2d62580670806c5 100755
--- a/http_server/dap_http_simple.h
+++ b/http_server/dap_http_simple.h
@@ -1,80 +1,84 @@
-/*
- 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
+/*
+* Authors:
+* Dmitrii Gerasimov <naeper@demlabs.net>
+* DeM Labs Inc.   https://demlabs.net
+* Cellframe https://cellframe.net
+* Copyright  (c) 2017-2019
+* All rights reserved.
+
+This file is part of DAP the open source project.
+
+DAP is free software: you can redistribute it and/or modify
+it under the terms of the GNU 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 General Public License for more details.
+
+See more details here <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.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;
+    uint8_t * request_byte;
+  };
+
+  union {
+    void *reply;
+    uint8_t *reply_byte;
+    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, ... );
+