static gboolean skip_images = FALSE;
static gboolean skip_attachments = FALSE;
static gboolean protocol_v3 = FALSE;
+static gboolean msgpack_mode = FALSE;
static const char *pubkey = nullptr;
static const char *user_agent = "rspamc";
static const char *files_list = nullptr;
"Skip attachments when learning/unlearning fuzzy", nullptr},
{"protocol-v3", '\0', 0, G_OPTION_ARG_NONE, &protocol_v3,
"Use v3 multipart protocol (structured metadata, multipart response)", nullptr},
+ {"msgpack", '\0', 0, G_OPTION_ARG_NONE, &msgpack_mode,
+ "Use msgpack for v3 metadata and response (requires --protocol-v3)", nullptr},
{"user-agent", 'U', 0, G_OPTION_ARG_STRING, &user_agent,
"Use specific User-Agent instead of \"rspamc\"", nullptr},
{"files-list", '\0', 0, G_OPTION_ARG_FILENAME, &files_list,
rspamd_client_command_v3(conn, "checkv3", metadata, in,
rspamc_client_cb, cbdata, compressed,
+ msgpack_mode,
cbdata->filename.c_str(), &err);
ucl_object_unref(metadata);
}
rspamd_client_callback cb,
gpointer ud,
gboolean compressed,
+ gboolean msgpack,
const char *filename,
GError **err)
{
req->input = input;
}
- /* Serialize metadata to JSON */
- char *metadata_json = NULL;
+ /* Serialize metadata to JSON or msgpack */
+ char *metadata_buf = NULL;
gsize metadata_len = 0;
+ const char *metadata_ctype = "application/json";
if (metadata) {
- metadata_json = (char *) ucl_object_emit(metadata, UCL_EMIT_JSON_COMPACT);
- metadata_len = strlen(metadata_json);
+ if (msgpack) {
+ size_t emit_len;
+ metadata_buf = (char *) ucl_object_emit_len(metadata,
+ UCL_EMIT_MSGPACK, &emit_len);
+ metadata_len = emit_len;
+ metadata_ctype = "application/msgpack";
+ }
+ else {
+ metadata_buf = (char *) ucl_object_emit(metadata, UCL_EMIT_JSON_COMPACT);
+ metadata_len = strlen(metadata_buf);
+ }
}
else {
- metadata_json = g_strdup("{}");
- metadata_len = 2;
+ if (msgpack) {
+ /* Empty msgpack map: 0x80 */
+ metadata_buf = g_malloc(1);
+ metadata_buf[0] = '\x80';
+ metadata_len = 1;
+ metadata_ctype = "application/msgpack";
+ }
+ else {
+ metadata_buf = g_strdup("{}");
+ metadata_len = 2;
+ }
}
/* Build multipart/form-data body with random boundary */
rspamd_printf_gstring(mp_body,
"--%s\r\n"
"Content-Disposition: form-data; name=\"metadata\"\r\n"
- "Content-Type: application/json\r\n"
+ "Content-Type: %s\r\n"
"\r\n",
- boundary);
- g_string_append_len(mp_body, metadata_json, metadata_len);
+ boundary, metadata_ctype);
+ g_string_append_len(mp_body, metadata_buf, metadata_len);
g_string_append(mp_body, "\r\n");
/* Message part */
if (ZSTD_isError(comp_len)) {
g_set_error(err, RCLIENT_ERROR, 500, "compression error");
g_free(comp_buf);
- g_free(metadata_json);
+ g_free(metadata_buf);
g_string_free(mp_body, TRUE);
g_free(req);
if (input) g_string_free(input, TRUE);
/* Closing boundary */
rspamd_printf_gstring(mp_body, "--%s--\r\n", boundary);
- g_free(metadata_json);
+ g_free(metadata_buf);
/* Set body */
body = rspamd_fstring_new_init(mp_body->str, mp_body->len);
"multipart/form-data; boundary=%s", boundary);
/* Add Accept headers */
- rspamd_http_message_add_header(req->msg, "Accept", "application/json");
+ if (msgpack) {
+ rspamd_http_message_add_header(req->msg, "Accept", "application/msgpack");
+ }
+ else {
+ rspamd_http_message_add_header(req->msg, "Accept", "application/json");
+ }
if (compressed) {
rspamd_http_message_add_header(req->msg, "Accept-Encoding", "zstd");
}
/**
* Send a v3 multipart/form-data command.
- * Metadata is sent as a JSON part, message as an octet-stream part.
+ * Metadata is sent as a JSON (or msgpack if msgpack=TRUE) part,
+ * message as an octet-stream part.
* Response is multipart/mixed with "result" (JSON/msgpack) and optional "body" parts.
*/
gboolean rspamd_client_command_v3(
rspamd_client_callback cb,
gpointer ud,
gboolean compressed,
+ gboolean msgpack,
const char *filename,
GError **err);
[Documentation] Send body with wrong boundary, expect HTTP 500 (400 error mapped to 5xx)
Scan File V3 Expect Error ${GTUBE} 500
... content_type_override=multipart/form-data; boundary=wrong-boundary-does-not-match
+
+checkv3 via rspamc with zstd compression
+ [Documentation] Scan via rspamc --protocol-v3 (zstd compression enabled by default)
+ ${result} = Run Rspamc -p -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL} --protocol-v3
+ ... --settings=${SETTINGS_NOSYMBOLS} ${GTUBE}
+ Check Rspamc ${result} GTUBE (
+
+checkv3 via rspamc encrypted
+ [Documentation] Scan via rspamc --protocol-v3 with httpcrypt encryption
+ ${result} = Run Rspamc -p -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL} --protocol-v3
+ ... --key ${RSPAMD_KEY_PUB1} --settings=${SETTINGS_NOSYMBOLS} ${GTUBE}
+ Check Rspamc ${result} GTUBE (
+
+checkv3 via rspamc with msgpack metadata
+ [Documentation] Scan via rspamc --protocol-v3 --msgpack (msgpack metadata and response)
+ ${result} = Run Rspamc -p -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL} --protocol-v3
+ ... --msgpack --settings=${SETTINGS_NOSYMBOLS} ${GTUBE}
+ Check Rspamc ${result} GTUBE (
+
+checkv3 via rspamc encrypted with msgpack
+ [Documentation] Scan via rspamc --protocol-v3 --msgpack --key (encrypted + msgpack)
+ ${result} = Run Rspamc -p -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL} --protocol-v3
+ ... --msgpack --key ${RSPAMD_KEY_PUB1} --settings=${SETTINGS_NOSYMBOLS} ${GTUBE}
+ Check Rspamc ${result} GTUBE (