37#include <microhttpd.h>
40#include "src/jazz_elements/container.h"
43#ifndef INCLUDED_JAZZ_CATCH2
44#define INCLUDED_JAZZ_CATCH2
46#include "src/catch2/catch.hpp"
52#ifndef INCLUDED_JAZZ_ELEMENTS_CHANNEL
53#define INCLUDED_JAZZ_ELEMENTS_CHANNEL
58#define BASE_BASH_10BIT 0x022
59#define BASE_FILE_10BIT 0x126
60#define BASE_HTTP_10BIT 0x288
61#define BASE_0_MQ_10BIT 0x1b0
64#define MAX_FILE_OR_URL_SIZE 1712
68#define APPLY_NOTHING 0
71#define APPLY_FUNCTION 3
72#define APPLY_FUNCT_CONST 4
74#define APPLY_FILT_CONST 6
77#define APPLY_ASSIGN_NOTHING 9
78#define APPLY_ASSIGN_NAME 10
79#define APPLY_ASSIGN_URL 11
80#define APPLY_ASSIGN_FUNCTION 12
81#define APPLY_ASSIGN_FUNCT_CONST 13
82#define APPLY_ASSIGN_FILTER 14
83#define APPLY_ASSIGN_FILT_CONST 15
84#define APPLY_ASSIGN_RAW 16
85#define APPLY_ASSIGN_TEXT 17
86#define APPLY_ASSIGN_CONST 18
87#define APPLY_NEW_ENTITY 19
88#define APPLY_GET_ATTRIBUTE 20
89#define APPLY_SET_ATTRIBUTE 21
90#define APPLY_JAZZ_INFO 22
95#define CURL_EASY_NO_BYPASS -1
98#define TRIGGER_FAIL_CURL_EASY_INIT (1u << 15)
99#define TRIGGER_FAIL_CURL_EASY_PERFORM (1u << 16)
100#define TRIGGER_FAIL_CURL_EASY_GETINFO (1u << 17)
102#define TRIGGER_FAIL_GETIFADDRS (1u << 18)
103#define TRIGGER_FAIL_GETNAMEINFO (1u << 19)
104#define TRIGGER_FAIL_MYINDEX_FIND (1u << 20)
105#define TRIGGER_FAIL_FILE_IO (1u << 21)
106#define TRIGGER_FAIL_ZMQ (1u << 22)
107#define TRIGGER_FAIL_BASH (1u << 23)
109#define TRIGGER_FAKE_FORWARD_SUCCESS (1u << 24)
160extern size_t get_callback(
char *ptr,
size_t size,
size_t nmemb,
void *container);
161extern size_t put_callback(
char *ptr,
size_t size,
size_t nmemb,
void *container);
162extern size_t dev_null(
char *_ignore,
size_t size,
size_t nmemb,
void *_ignore_2);
273 int mode = WRITE_AS_BASE_DEFAULT);
286 int mode = WRITE_AS_BASE_DEFAULT);
324 curl = curl_easy_init();
325 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
329 curl_easy_setopt(curl, CURLOPT_URL, url);
330 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
331 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
332 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
get_callback);
333 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void *) &buff);
335 if (p_idx !=
nullptr) {
337 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
338 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
340 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
341 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
343 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
344 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
346 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
347 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
349 c_ret = curl_easy_perform(curl);
351 uint64_t response_code;
353 if (c_ret == CURLE_OK)
354 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
356 curl_easy_cleanup(curl);
361 case CURLE_REMOTE_ACCESS_DENIED:
362 case CURLE_AUTH_ERROR:
363 return SERVICE_ERROR_READ_FORBIDDEN;
364 case CURLE_REMOTE_FILE_NOT_FOUND:
365 return SERVICE_ERROR_BLOCK_NOT_FOUND;
367 return SERVICE_ERROR_IO_ERROR;
370 switch (response_code) {
372 case MHD_HTTP_CREATED:
373 case MHD_HTTP_ACCEPTED:
375 case MHD_HTTP_NOT_FOUND:
377 return SERVICE_ERROR_BLOCK_NOT_FOUND;
378 case MHD_HTTP_BAD_REQUEST:
379 return SERVICE_ERROR_WRONG_ARGUMENTS;
380 case MHD_HTTP_UNAUTHORIZED:
381 case MHD_HTTP_PAYMENT_REQUIRED:
382 case MHD_HTTP_FORBIDDEN:
383 case MHD_HTTP_METHOD_NOT_ALLOWED:
384 case MHD_HTTP_NOT_ACCEPTABLE:
385 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
386 case MHD_HTTP_TOO_MANY_REQUESTS:
387 return SERVICE_ERROR_READ_FORBIDDEN;
388 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
389 return SERVICE_ERROR_MISC_SERVER;
391 return SERVICE_ERROR_IO_ERROR;
393 size_t buf_size = buff.size();
394 if (buf_size > MAX_BLOCK_SIZE)
return SERVICE_ERROR_BLOCK_TOO_BIG;
416 curl = curl_easy_init();
417 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
421 if ((mode & WRITE_AS_ANY_WRITE) == 0)
422 mode = WRITE_AS_STRING | WRITE_AS_FULL_BLOCK;
424 if ((mode & WRITE_AS_STRING) && ( (p_blk->cell_type == CELL_TYPE_STRING && p_blk->size == 1)
425 || (p_blk->cell_type == CELL_TYPE_BYTE && p_blk->rank == 1))) {
426 if (p_blk->cell_type == CELL_TYPE_STRING) {
427 put_buff.
p_base = (uint8_t *) p_blk->get_string(0);
430 put_buff.
p_base = &p_blk->tensor.cell_byte[0];
431 put_buff.
to_send = strnlen((
const char *) put_buff.
p_base, p_blk->size);
433 }
else if ((mode & WRITE_AS_CONTENT) && ((p_blk->cell_type & 0xf0) == 0)) {
434 put_buff.
to_send = p_blk->size*(p_blk->cell_type & 0xff);
435 put_buff.
p_base = &p_blk->tensor.cell_byte[0];
436 }
else if ((mode & WRITE_AS_FULL_BLOCK) && (p_blk->cell_type != CELL_TYPE_INDEX)) {
437 put_buff.
to_send = p_blk->total_bytes;
438 put_buff.
p_base = (uint8_t *) p_blk;
440 return SERVICE_ERROR_WRONG_ARGUMENTS;
442 curl_easy_setopt(curl, CURLOPT_URL, url);
443 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
444 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
445 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
dev_null);
446 curl_easy_setopt(curl, CURLOPT_READFUNCTION,
put_callback);
447 curl_easy_setopt(curl, CURLOPT_READDATA, (
void *) &put_buff);
448 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
449 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) put_buff.
to_send);
451 if (p_idx !=
nullptr) {
453 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
454 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
456 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
457 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
459 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
460 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
462 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
463 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
465 c_ret = curl_easy_perform(curl);
467 uint64_t response_code;
469 if (c_ret == CURLE_OK)
470 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
472 curl_easy_cleanup(curl);
477 case CURLE_REMOTE_ACCESS_DENIED:
478 case CURLE_AUTH_ERROR:
479 return SERVICE_ERROR_WRITE_FORBIDDEN;
480 case CURLE_REMOTE_FILE_NOT_FOUND:
481 return SERVICE_ERROR_BLOCK_NOT_FOUND;
483 return SERVICE_ERROR_IO_ERROR;
486 switch (response_code) {
488 case MHD_HTTP_CREATED:
489 case MHD_HTTP_ACCEPTED:
490 return SERVICE_NO_ERROR;
491 case MHD_HTTP_NOT_FOUND:
493 return SERVICE_ERROR_BLOCK_NOT_FOUND;
494 case MHD_HTTP_BAD_REQUEST:
495 return SERVICE_ERROR_WRONG_ARGUMENTS;
496 case MHD_HTTP_UNAUTHORIZED:
497 case MHD_HTTP_PAYMENT_REQUIRED:
498 case MHD_HTTP_FORBIDDEN:
499 case MHD_HTTP_METHOD_NOT_ALLOWED:
500 case MHD_HTTP_NOT_ACCEPTABLE:
501 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
502 case MHD_HTTP_TOO_MANY_REQUESTS:
503 return SERVICE_ERROR_WRITE_FORBIDDEN;
504 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
505 return SERVICE_ERROR_MISC_SERVER;
507 return SERVICE_ERROR_IO_ERROR;
523 curl = curl_easy_init();
524 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
526 curl_easy_setopt(curl, CURLOPT_URL, url);
527 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
528 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
529 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST,
"DELETE");
530 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
dev_null);
532 if (p_idx !=
nullptr) {
534 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
535 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
537 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
538 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
540 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
541 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
543 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
544 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
546 c_ret = curl_easy_perform(curl);
548 uint64_t response_code;
550 if (c_ret == CURLE_OK)
551 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
553 curl_easy_cleanup(curl);
558 case CURLE_REMOTE_ACCESS_DENIED:
559 case CURLE_AUTH_ERROR:
560 return SERVICE_ERROR_WRITE_FORBIDDEN;
562 case CURLE_REMOTE_FILE_NOT_FOUND:
563 return SERVICE_ERROR_BLOCK_NOT_FOUND;
565 return SERVICE_ERROR_IO_ERROR;
568 switch (response_code) {
570 case MHD_HTTP_CREATED:
571 case MHD_HTTP_ACCEPTED:
572 return SERVICE_NO_ERROR;
573 case MHD_HTTP_NOT_FOUND:
575 return SERVICE_ERROR_BLOCK_NOT_FOUND;
576 case MHD_HTTP_BAD_REQUEST:
577 return SERVICE_ERROR_WRONG_ARGUMENTS;
578 case MHD_HTTP_UNAUTHORIZED:
579 case MHD_HTTP_PAYMENT_REQUIRED:
580 case MHD_HTTP_FORBIDDEN:
581 case MHD_HTTP_METHOD_NOT_ALLOWED:
582 case MHD_HTTP_NOT_ACCEPTABLE:
583 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
584 case MHD_HTTP_TOO_MANY_REQUESTS:
585 return SERVICE_ERROR_WRITE_FORBIDDEN;
586 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
587 return SERVICE_ERROR_MISC_SERVER;
589 return SERVICE_ERROR_IO_ERROR;
595 char HEX[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
614 if (it->second == p_node) {
621 if (ret < 0 || ret >= buff_size)
627 while (buff_size > 0) {
628 u_int8_t cursor = *(p_url++);
647 *(p_dest++) = cursor;
654 *(p_dest++) =
HEX[cursor >> 4];
655 *(p_dest++) =
HEX[cursor & 0x0f];
675 CURL * curl_easy_init ();
676 CURLcode curl_easy_perform(CURL *curl);
677 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, uint64_t *response_code);
679 int curl_easy_return_code = CURL_EASY_NO_BYPASS;
680 int curl_easy_response = CURL_EASY_NO_BYPASS;
Channels: A Container doing block transactions across media (files, folders, shell,...
Definition channel.h:244
PipeMap pipes
A map of pipelines (zeroMQ connections)
Definition channel.h:669
MHD_StatusCode forward_del(Name node, pChar p_url)
Definition channel.cpp:1138
virtual StatusCode header(StaticBlockHeader &hea, pChar p_what)
Definition channel.cpp:547
int jazz_node_my_index
The index of the node in the cluster.
Definition channel.h:300
virtual StatusCode put(pChar p_where, pBlock p_block, int mode=WRITE_AS_BASE_DEFAULT)
Definition channel.cpp:581
StatusCode curl_remove(const char *url, Index *p_idx=nullptr)
The most low level remove function.
Definition channel.h:519
bool compose_url(pChar p_dest, pChar p_node, pChar p_url, int buff_size)
Compose a url from a node, a base and an entity.
Definition channel.h:607
String filesystem_root
The root of the filesystem.
Definition channel.h:303
int can_zmq
If true, the server can use zeroMQ based on configuration key ENABLE_ZEROMQ_CLIENT.
Definition channel.h:664
StatusCode curl_get(pTransaction &p_txn, const char *url, Index *p_idx=nullptr)
The most low level get function.
Definition channel.h:320
StatusCode curl_put(const char *url, pBlock p_blk, int mode=WRITE_AS_STRING|WRITE_AS_FULL_BLOCK, Index *p_idx=nullptr)
The most low level put function.
Definition channel.h:412
virtual StatusCode modify(Locator &function, pTuple p_args)
Definition channel.cpp:946
int file_lev
The level of file operations allowed based on configuration key ENABLE_FILE_LEVEL.
Definition channel.h:667
int can_bash
If true, the server can use bash based on configuration key ENABLE_BASH_EXEC.
Definition channel.h:666
virtual StatusCode remove(pChar p_where)
Definition channel.cpp:798
virtual StatusCode copy(pChar p_where, pChar p_what)
Definition channel.cpp:902
virtual StatusCode get(pTransaction &p_txn, pChar p_what)
Definition channel.cpp:352
virtual void base_names(BaseNames &base_names)
Definition channel.cpp:1073
virtual StatusCode locate(Locator &location, pChar p_what)
Definition channel.cpp:532
MapIS jazz_node_ip
The ip addresses of the nodes in the cluster.
Definition channel.h:297
StatusCode shut_down()
Definition channel.cpp:310
char HEX[16]
Hexadecimal digits.
Definition channel.h:595
int zmq_ok
If true, zeroMQ is ready to be used based on config + zeroMQ initialization.
Definition channel.h:665
MHD_StatusCode forward_put(Name node, pChar p_url, pBlock p_block, int mode=WRITE_AS_BASE_DEFAULT)
Definition channel.cpp:1116
StatusCode start()
Definition channel.cpp:150
int can_curl
If true, the server can use libcurl based on configuration key ENABLE_HTTP_CLIENT.
Definition channel.h:662
MapII jazz_node_port
The ports of the nodes in the cluster.
Definition channel.h:298
void * zmq_context
The zeroMQ context.
Definition channel.h:672
MHD_StatusCode forward_get(pTransaction &p_txn, Name node, pChar p_url)
Definition channel.cpp:1090
virtual pChar const id()
Definition channel.cpp:140
MapIS jazz_node_name
The names of the nodes (other Jazz servers) in the cluster.
Definition channel.h:296
int jazz_node_cluster_size
The number of nodes in the cluster.
Definition channel.h:301
ConnMap connect
A map of http connections.
Definition channel.h:670
int curl_ok
If true, libcurl is ready to be used based on config + libcurl initialization.
Definition channel.h:663
virtual StatusCode new_entity(pChar p_where)
Definition channel.cpp:764
A configuration file as a key/value store.
Definition utils.h:218
Container: A Service to manage Jazz blocks. All Jazz blocks are managed by this or a descendant of th...
Definition container.h:296
StatusCode unwrap_received(pTransaction &p_txn)
Definition container.h:447
A simple logger.
Definition utils.h:248
Tuple: A Jazz Block with multiple Tensors.
Definition tuple.h:94
The namespace for Jazz Utils, Blocks, Kinds, Tuples, Containers, etc.
Definition block.cpp:39
std::string String
A standard string used in many other places in Jazz.
Definition types.h:239
GetBuffer * pGetBuffer
A pointer to a GetBuffer.
Definition channel.h:128
std::map< String, Index > ConnMap
A structure holding connections.
Definition channel.h:116
std::map< String, pContainer > BaseNames
A map of names for the containers (or structure engines like "map" or "tree" inside Volatile).
Definition container.h:166
std::map< String, Socket > PipeMap
A structure holding pipeline.
Definition channel.h:140
Channels * pChannels
A pointer to a Channels.
Definition channel.h:684
char * pChar
A pointer to a char buffer.
Definition types.h:189
class Block * pBlock
A (forward defined) pointer to a Block.
Definition block.h:66
char Name[NAME_SIZE]
A short identifier used in Blocks, Containers and API.
Definition types.h:187
std::vector< uint8_t > GetBuffer
A structure to share with the libcurl get callback.
Definition channel.h:127
std::map< int, int > MapII
A map for defining http config ports.
Definition channel.h:144
PutBuffer * pPutBuffer
A pointer to a PutBuffer.
Definition channel.h:136
int StatusCode
Type returned by the Service API.
Definition utils.h:142
size_t get_callback(char *ptr, size_t size, size_t nmemb, void *container)
A callback for libCURL GET.
Definition channel.cpp:61
unsigned int MHD_StatusCode
A proper type for specifying http status codes.
Definition channel.h:158
size_t put_callback(char *ptr, size_t size, size_t nmemb, void *container)
A callback for libCURL PUT.
Definition channel.cpp:107
size_t dev_null(char *_ignore, size_t size, size_t nmemb, void *_ignore_2)
A callback for libCURL GET to ignore all the blocks sent by the server in PUT and DELETE calls.
Definition channel.cpp:89
std::map< int, String > MapIS
A map for defining http config names.
Definition channel.h:112
std::map< String, String > Index
An Index kept in RAM by Volatile implemented as an stdlib map (string, string)
Definition types.h:243
Locator: A minimal structure to define the location of resources inside a Container.
Definition container.h:198
A structure keep state inside a put callback.
Definition channel.h:132
uint8_t * p_base
The pointer (updated after each call) to the data.
Definition channel.h:134
uint64_t to_send
Number of bytes to be sent.
Definition channel.h:133
A structure to hold a single pipeline.
Definition channel.h:120
char endpoint[120]
The endpoint at which the socket is connected.
Definition channel.h:121
void * requester
The (connected) zmq socket.
Definition channel.h:122
Transaction: A wrapper over a Block that defines the communication of a block with a Container.
Definition container.h:176