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)
158extern size_t get_callback(
char *ptr,
size_t size,
size_t nmemb,
void *container);
159extern size_t put_callback(
char *ptr,
size_t size,
size_t nmemb,
void *container);
160extern size_t dev_null(
char *_ignore,
size_t size,
size_t nmemb,
void *_ignore_2);
271 int mode = WRITE_AS_BASE_DEFAULT);
284 int mode = WRITE_AS_BASE_DEFAULT);
322 curl = curl_easy_init();
323 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
327 curl_easy_setopt(curl, CURLOPT_URL, url);
328 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
329 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
330 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
get_callback);
331 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void *) &buff);
333 if (p_idx !=
nullptr) {
335 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
336 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
338 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
339 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
341 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
342 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
344 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
345 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
347 c_ret = curl_easy_perform(curl);
349 uint64_t response_code;
351 if (c_ret == CURLE_OK)
352 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
354 curl_easy_cleanup(curl);
359 case CURLE_REMOTE_ACCESS_DENIED:
360 case CURLE_AUTH_ERROR:
361 return SERVICE_ERROR_READ_FORBIDDEN;
362 case CURLE_REMOTE_FILE_NOT_FOUND:
363 return SERVICE_ERROR_BLOCK_NOT_FOUND;
365 return SERVICE_ERROR_IO_ERROR;
368 switch (response_code) {
370 case MHD_HTTP_CREATED:
371 case MHD_HTTP_ACCEPTED:
373 case MHD_HTTP_NOT_FOUND:
375 return SERVICE_ERROR_BLOCK_NOT_FOUND;
376 case MHD_HTTP_BAD_REQUEST:
377 return SERVICE_ERROR_WRONG_ARGUMENTS;
378 case MHD_HTTP_UNAUTHORIZED:
379 case MHD_HTTP_PAYMENT_REQUIRED:
380 case MHD_HTTP_FORBIDDEN:
381 case MHD_HTTP_METHOD_NOT_ALLOWED:
382 case MHD_HTTP_NOT_ACCEPTABLE:
383 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
384 case MHD_HTTP_TOO_MANY_REQUESTS:
385 return SERVICE_ERROR_READ_FORBIDDEN;
386 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
387 return SERVICE_ERROR_MISC_SERVER;
389 return SERVICE_ERROR_IO_ERROR;
391 size_t buf_size = buff.size();
392 if (buf_size > MAX_BLOCK_SIZE)
return SERVICE_ERROR_BLOCK_TOO_BIG;
414 curl = curl_easy_init();
415 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
419 if ((mode & WRITE_AS_ANY_WRITE) == 0)
420 mode = WRITE_AS_STRING | WRITE_AS_FULL_BLOCK;
422 if ((mode & WRITE_AS_STRING) && ( (p_blk->cell_type == CELL_TYPE_STRING && p_blk->size == 1)
423 || (p_blk->cell_type == CELL_TYPE_BYTE && p_blk->rank == 1))) {
424 if (p_blk->cell_type == CELL_TYPE_STRING) {
425 put_buff.
p_base = (uint8_t *) p_blk->get_string(0);
428 put_buff.
p_base = &p_blk->tensor.cell_byte[0];
429 put_buff.
to_send = strnlen((
const char *) put_buff.
p_base, p_blk->size);
431 }
else if ((mode & WRITE_AS_CONTENT) && ((p_blk->cell_type & 0xf0) == 0)) {
432 put_buff.
to_send = p_blk->size*(p_blk->cell_type & 0xff);
433 put_buff.
p_base = &p_blk->tensor.cell_byte[0];
434 }
else if ((mode & WRITE_AS_FULL_BLOCK) && (p_blk->cell_type != CELL_TYPE_INDEX)) {
435 put_buff.
to_send = p_blk->total_bytes;
436 put_buff.
p_base = (uint8_t *) p_blk;
438 return SERVICE_ERROR_WRONG_ARGUMENTS;
440 curl_easy_setopt(curl, CURLOPT_URL, url);
441 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
442 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
443 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
dev_null);
444 curl_easy_setopt(curl, CURLOPT_READFUNCTION,
put_callback);
445 curl_easy_setopt(curl, CURLOPT_READDATA, (
void *) &put_buff);
446 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
447 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) put_buff.
to_send);
449 if (p_idx !=
nullptr) {
451 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
452 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
454 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
455 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
457 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
458 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
460 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
461 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
463 c_ret = curl_easy_perform(curl);
465 uint64_t response_code;
467 if (c_ret == CURLE_OK)
468 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
470 curl_easy_cleanup(curl);
475 case CURLE_REMOTE_ACCESS_DENIED:
476 case CURLE_AUTH_ERROR:
477 return SERVICE_ERROR_WRITE_FORBIDDEN;
478 case CURLE_REMOTE_FILE_NOT_FOUND:
479 return SERVICE_ERROR_BLOCK_NOT_FOUND;
481 return SERVICE_ERROR_IO_ERROR;
484 switch (response_code) {
486 case MHD_HTTP_CREATED:
487 case MHD_HTTP_ACCEPTED:
488 return SERVICE_NO_ERROR;
489 case MHD_HTTP_NOT_FOUND:
491 return SERVICE_ERROR_BLOCK_NOT_FOUND;
492 case MHD_HTTP_BAD_REQUEST:
493 return SERVICE_ERROR_WRONG_ARGUMENTS;
494 case MHD_HTTP_UNAUTHORIZED:
495 case MHD_HTTP_PAYMENT_REQUIRED:
496 case MHD_HTTP_FORBIDDEN:
497 case MHD_HTTP_METHOD_NOT_ALLOWED:
498 case MHD_HTTP_NOT_ACCEPTABLE:
499 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
500 case MHD_HTTP_TOO_MANY_REQUESTS:
501 return SERVICE_ERROR_WRITE_FORBIDDEN;
502 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
503 return SERVICE_ERROR_MISC_SERVER;
505 return SERVICE_ERROR_IO_ERROR;
521 curl = curl_easy_init();
522 if (curl ==
nullptr)
return SERVICE_ERROR_NOT_READY;
524 curl_easy_setopt(curl, CURLOPT_URL, url);
525 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
526 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
527 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST,
"DELETE");
528 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
dev_null);
530 if (p_idx !=
nullptr) {
532 if ((it = p_idx->find(
"CURLOPT_USERNAME")) != p_idx->end())
533 curl_easy_setopt(curl, CURLOPT_USERNAME, it->second.c_str());
535 if ((it = p_idx->find(
"CURLOPT_USERPWD")) != p_idx->end())
536 curl_easy_setopt(curl, CURLOPT_USERPWD, it->second.c_str());
538 if ((it = p_idx->find(
"CURLOPT_COOKIEFILE")) != p_idx->end())
539 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, it->second.c_str());
541 if ((it = p_idx->find(
"CURLOPT_COOKIEJAR")) != p_idx->end())
542 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, it->second.c_str());
544 c_ret = curl_easy_perform(curl);
546 uint64_t response_code;
548 if (c_ret == CURLE_OK)
549 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
551 curl_easy_cleanup(curl);
556 case CURLE_REMOTE_ACCESS_DENIED:
557 case CURLE_AUTH_ERROR:
558 return SERVICE_ERROR_WRITE_FORBIDDEN;
560 case CURLE_REMOTE_FILE_NOT_FOUND:
561 return SERVICE_ERROR_BLOCK_NOT_FOUND;
563 return SERVICE_ERROR_IO_ERROR;
566 switch (response_code) {
568 case MHD_HTTP_CREATED:
569 case MHD_HTTP_ACCEPTED:
570 return SERVICE_NO_ERROR;
571 case MHD_HTTP_NOT_FOUND:
573 return SERVICE_ERROR_BLOCK_NOT_FOUND;
574 case MHD_HTTP_BAD_REQUEST:
575 return SERVICE_ERROR_WRONG_ARGUMENTS;
576 case MHD_HTTP_UNAUTHORIZED:
577 case MHD_HTTP_PAYMENT_REQUIRED:
578 case MHD_HTTP_FORBIDDEN:
579 case MHD_HTTP_METHOD_NOT_ALLOWED:
580 case MHD_HTTP_NOT_ACCEPTABLE:
581 case MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED:
582 case MHD_HTTP_TOO_MANY_REQUESTS:
583 return SERVICE_ERROR_WRITE_FORBIDDEN;
584 case MHD_HTTP_INTERNAL_SERVER_ERROR ... MHD_HTTP_LOOP_DETECTED:
585 return SERVICE_ERROR_MISC_SERVER;
587 return SERVICE_ERROR_IO_ERROR;
593 char HEX[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
612 if (it->second == p_node) {
619 if (ret < 0 || ret >= buff_size)
625 while (buff_size > 0) {
626 u_int8_t cursor = *(p_url++);
645 *(p_dest++) = cursor;
652 *(p_dest++) =
HEX[cursor >> 4];
653 *(p_dest++) =
HEX[cursor & 0x0f];
673 CURL * curl_easy_init ();
674 CURLcode curl_easy_perform(CURL *curl);
675 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, uint64_t *response_code);
677 int curl_easy_return_code = CURL_EASY_NO_BYPASS;
678 int curl_easy_response = CURL_EASY_NO_BYPASS;
Channels: A Container doing block transactions across media (files, folders, shell,...
Definition channel.h:242
PipeMap pipes
A map of pipelines (zeroMQ connections)
Definition channel.h:667
MHD_StatusCode forward_del(Name node, pChar p_url)
Definition channel.cpp:1133
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:298
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:517
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:605
String filesystem_root
The root of the filesystem.
Definition channel.h:301
int can_zmq
If true, the server can use zeroMQ based on configuration key ENABLE_ZEROMQ_CLIENT.
Definition channel.h:662
StatusCode curl_get(pTransaction &p_txn, const char *url, Index *p_idx=nullptr)
The most low level get function.
Definition channel.h:318
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:410
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:665
int can_bash
If true, the server can use bash based on configuration key ENABLE_BASH_EXEC.
Definition channel.h:664
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
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:295
StatusCode shut_down()
Definition channel.cpp:310
char HEX[16]
Hexadecimal digits.
Definition channel.h:593
int zmq_ok
If true, zeroMQ is ready to be used based on config + zeroMQ initialization.
Definition channel.h:663
MHD_StatusCode forward_put(Name node, pChar p_url, pBlock p_block, int mode=WRITE_AS_BASE_DEFAULT)
Definition channel.cpp:1111
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:660
MapII jazz_node_port
The ports of the nodes in the cluster.
Definition channel.h:296
void * zmq_context
The zeroMQ context.
Definition channel.h:670
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:294
int jazz_node_cluster_size
The number of nodes in the cluster.
Definition channel.h:299
ConnMap connect
A map of http connections.
Definition channel.h:668
int curl_ok
If true, libcurl is ready to be used based on config + libcurl initialization.
Definition channel.h:661
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:287
StatusCode unwrap_received(pTransaction &p_txn)
Definition container.h:438
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:126
std::map< String, Index > ConnMap
A structure holding connections.
Definition channel.h:114
std::map< String, pContainer > BaseNames
A map of names for the containers (or structure engines like "map" or "tree" inside Volatile).
Definition container.h:157
std::map< String, Socket > PipeMap
A structure holding pipeline.
Definition channel.h:138
Channels * pChannels
A pointer to a Channels.
Definition channel.h:682
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:125
std::map< int, int > MapII
A map for defining http config ports.
Definition channel.h:142
PutBuffer * pPutBuffer
A pointer to a PutBuffer.
Definition channel.h:134
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:156
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:110
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:189
A structure keep state inside a put callback.
Definition channel.h:130
uint8_t * p_base
The pointer (updated after each call) to the data.
Definition channel.h:132
uint64_t to_send
Number of bytes to be sent.
Definition channel.h:131
A structure to hold a single pipeline.
Definition channel.h:118
char endpoint[120]
The endpoint at which the socket is connected.
Definition channel.h:119
void * requester
The (connected) zmq socket.
Definition channel.h:120
Transaction: A wrapper over a Block that defines the communication of a block with a Container.
Definition container.h:167