Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* Authors:
* Dmitriy A. Gearasimov <kahovski@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* 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 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.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dap_client.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include "dap_chain_node_cli.h" // for UNIX_SOCKET_FILE
#include "main_node_cli_net.h"
/**
* Add to one array another one
*
* memory - destination array of data
* add_mem - source array of data
* memory_len - memory array size
* add_size - add_mem array size
*/
static int add_mem_data(uint8_t **memory, size_t *memory_len, char *add_mem, size_t add_size)
{
*memory = (char*) realloc(*memory, *memory_len + add_size + 1);
//out of memory!
if(*memory == NULL) {
//printf("not enough memory (realloc returned NULL)\n");
return 0;
}
if(add_mem) {
memcpy((*memory + *memory_len), add_mem, add_size);
// increase the received bytes number
*memory_len += add_size;
// zero out the last byte
*(*memory + *memory_len) = 0;
}
return add_size;
}
//callback functions to receive header
static size_t WriteHttpMemoryHeadCallback(void *contents, size_t size, size_t nmemb, cmd_state *cmd)
{
if(!cmd)
return 0;
printf("[header] %s len=%d\n", contents, size * nmemb);
// добавить к заголовку принятые данные
//return add_mem_data(&page->raw_header, &page->header_len,(char*)contents, size * nmemb);
return size;
}
// callback function to receive data
static size_t WriteHttpMemoryCallback(void *contents, size_t size, size_t nmemb, cmd_state *cmd)
{
if(!cmd)
return 0;
printf("[data] %s len=%d\n", contents, size * nmemb);
// add received data to body
return add_mem_data(&cmd->ret_str, &cmd->ret_str_len, (char*) contents, size * nmemb);
}
/**
* Connect to node unix socket server
*
* return struct connect_param if connect established, else NULL
*/
connect_param* node_cli_connect(void)
{
curl_global_init(CURL_GLOBAL_DEFAULT);
connect_param *param = DAP_NEW_Z(connect_param);
CURL *curl_handle = curl_easy_init();
int ret = curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, UNIX_SOCKET_FILE); // unix socket mode
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 20L); // complete within 20 seconds
ret = curl_easy_setopt(curl_handle, CURLOPT_CONNECT_ONLY, 1L); // connection only
ret = curl_easy_setopt(curl_handle, CURLOPT_URL, "http:/localhost/connect");
// execute request
ret = curl_easy_perform(curl_handle);
if(!ret)
{
param->curl = curl_handle;
curl_easy_setopt(curl_handle, CURLOPT_CONNECT_ONLY, 0L); // disable mode - connection only
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
}
else
{
curl_easy_cleanup(curl_handle);
DAP_DELETE(param);
param = NULL;
}
return param;
}
/**
* Send request to kelvin-node
*
* return 0 if OK, else error code
*/
int node_cli_post_command(connect_param *conn, cmd_state *cmd)
{
if(!conn || !conn->curl || !cmd || !cmd->cmd_name)
{
assert(0);
return -1;
}
CURLcode ret;
CURL *curl = conn->curl;
ret = curl_easy_setopt(curl, CURLOPT_HEADER, 0L); // don't get header in the body
//ret = curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate"); // allow receive of compressed data
//callback functions to receive data
ret = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteHttpMemoryCallback); // callback for the data read
//callback functions to receive header
ret = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WriteHttpMemoryHeadCallback); // callback for the header read
// passing a parameter to the callback function
ret = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void * )cmd);
ret = curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void * )cmd);
ret = curl_easy_setopt(curl, CURLOPT_USERAGENT, "kelvin-console 1.0");
// ret = curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);// GET запрос
// ret = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);// удалённый сервер не будет проверять наш сертификат. В противном случае необходимо этот самый сертификат послать.
//ret = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
char *post_data = NULL;
ret = curl_easy_setopt(curl, CURLOPT_POST, 1); // POST request - optional if CURLOPT_POSTFIELDS will be
size_t post_data_len = 0;
add_mem_data((uint8_t**) &post_data, &post_data_len, cmd->cmd_name, strlen(cmd->cmd_name));
if(cmd->cmd_param) {
for(int i = 0; i < cmd->cmd_param_count; i++) {
if(cmd->cmd_param[i]) {
add_mem_data((uint8_t**) &post_data, &post_data_len, "\r\n", 2);
add_mem_data((uint8_t**) &post_data, &post_data_len, cmd->cmd_param[i], strlen(cmd->cmd_param[i]));
}
}
add_mem_data((uint8_t**) &post_data, &post_data_len, "\r\n\r\n", 4);
if(post_data)
ret = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); // data for POST request
if(post_data_len >= 0)
ret = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long )post_data_len); // if need a lot to send: CURLOPT_POSTFIELDSIZE_LARGE
// sending request and receiving the http page (filling cmd)
ret = curl_easy_perform(curl); // curl_easy_send
free(post_data);
return ret;
}
return -1;
}
int node_cli_desconnect(connect_param *param)
{
if(param) {
if(param->curl)
curl_easy_cleanup(param->curl);
DAP_DELETE(param);
}
curl_global_cleanup();
}