void amqp_destroy_envelope(amqp_envelope_t *envelope) { amqp_destroy_message(&envelope->message); amqp_bytes_free(envelope->routing_key); amqp_bytes_free(envelope->exchange); amqp_bytes_free(envelope->consumer_tag); }
amqp_rpc_reply_t amqp_consume_message(amqp_connection_state_t state, amqp_envelope_t *envelope, struct timeval *timeout, AMQP_UNUSED int flags) { int res; amqp_frame_t frame; amqp_basic_deliver_t *delivery_method; amqp_rpc_reply_t ret; memset(&ret, 0, sizeof(amqp_rpc_reply_t)); memset(envelope, 0, sizeof(amqp_envelope_t)); res = amqp_simple_wait_frame_noblock(state, &frame, timeout); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out1; } if (AMQP_FRAME_METHOD != frame.frame_type || AMQP_BASIC_DELIVER_METHOD != frame.payload.method.id) { amqp_put_back_frame(state, &frame); ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_UNEXPECTED_STATE; goto error_out1; } delivery_method = frame.payload.method.decoded; envelope->channel = frame.channel; envelope->consumer_tag = amqp_bytes_malloc_dup(delivery_method->consumer_tag); envelope->delivery_tag = delivery_method->delivery_tag; envelope->redelivered = delivery_method->redelivered; envelope->exchange = amqp_bytes_malloc_dup(delivery_method->exchange); envelope->routing_key = amqp_bytes_malloc_dup(delivery_method->routing_key); if (amqp_bytes_malloc_dup_failed(envelope->consumer_tag) || amqp_bytes_malloc_dup_failed(envelope->exchange) || amqp_bytes_malloc_dup_failed(envelope->routing_key)) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_NO_MEMORY; goto error_out2; } ret = amqp_read_message(state, envelope->channel, &envelope->message, 0); if (AMQP_RESPONSE_NORMAL != ret.reply_type) { goto error_out2; } ret.reply_type = AMQP_RESPONSE_NORMAL; return ret; error_out2: amqp_bytes_free(envelope->routing_key); amqp_bytes_free(envelope->exchange); amqp_bytes_free(envelope->consumer_tag); error_out1: return ret; }
static gboolean afamqp_worker_publish(AMQPDestDriver *self, LogMessage *msg) { gint pos = 0, ret; amqp_table_t table; amqp_basic_properties_t props; gboolean success = TRUE; SBGString *routing_key = sb_gstring_acquire(); SBGString *body = sb_gstring_acquire(); amqp_bytes_t body_bytes = amqp_cstring_bytes(""); gpointer user_data[] = { &self->entries, &pos, &self->max_entries }; value_pairs_foreach(self->vp, afamqp_vp_foreach, msg, self->seq_num, &self->template_options, user_data); table.num_entries = pos; table.entries = self->entries; props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_HEADERS_FLAG; props.content_type = amqp_cstring_bytes("text/plain"); props.delivery_mode = self->persistent; props.headers = table; log_template_format(self->routing_key_template, msg, NULL, LTZ_LOCAL, self->seq_num, NULL, sb_gstring_string(routing_key)); if (self->body_template) { log_template_format(self->body_template, msg, NULL, LTZ_LOCAL, self->seq_num, NULL, sb_gstring_string(body)); body_bytes = amqp_cstring_bytes(sb_gstring_string(body)->str); } ret = amqp_basic_publish(self->conn, 1, amqp_cstring_bytes(self->exchange), amqp_cstring_bytes(sb_gstring_string(routing_key)->str), 0, 0, &props, body_bytes); sb_gstring_release(routing_key); sb_gstring_release(body); if (ret < 0) { msg_error("Network error while inserting into AMQP server", evt_tag_str("driver", self->super.super.super.id), evt_tag_int("time_reopen", self->super.time_reopen), NULL); success = FALSE; } while (--pos >= 0) { amqp_bytes_free(self->entries[pos].key); amqp_bytes_free(self->entries[pos].value.value.bytes); } return success; }
void BasicMessage::AppId(const std::string& app_id) { if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id); m_impl->m_properties.app_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(app_id.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_APP_ID_FLAG; }
void BasicMessage::AppIdClear() { if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id); m_impl->m_properties._flags &= ~AMQP_BASIC_APP_ID_FLAG; }
void BasicMessage::CorrelationId(const std::string& correlation_id) { if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id); m_impl->m_properties.correlation_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(correlation_id.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_CORRELATION_ID_FLAG; }
void BasicMessage::UserIdClear() { if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id); m_impl->m_properties._flags &= ~AMQP_BASIC_USER_ID_FLAG; }
int main(int argc, char *argv[]) { char const *hostname; int port, status; char const *exchange; char const *routingkey; char const *messagebody; amqp_socket_t *socket = NULL; amqp_connection_state_t conn; amqp_bytes_t reply_to_queue; if (argc < 6) { /* minimum number of mandatory arguments */ fprintf(stderr, "usage:\namqp_rpc_sendstring_client host port exchange routingkey messagebody\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); exchange = argv[3]; routingkey = argv[4]; messagebody = argv[5]; /* establish a channel that is used to connect RabbitMQ server */ conn = amqp_new_connection(); socket = amqp_tcp_socket_new(conn); if (!socket) { printf("creating TCP socket"); } status = amqp_socket_open(socket, hostname, port); if (status) { printf("opening TCP socket"); } printf("established connection!\n"); amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest");// "Logging in"); amqp_channel_open(conn, 1); amqp_get_rpc_reply(conn);//, "Opening channel"); printf("open channel!\n"); /* create private reply_to queue */ { amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table); amqp_get_rpc_reply(conn);//, "Declaring queue"); printf("declare queue!\n"); reply_to_queue = amqp_bytes_malloc_dup(r->queue); if (reply_to_queue.bytes == NULL) { fprintf(stderr, "Out of memory while copying queue name"); return 1; } } /* send the message */ { /* set properties */ amqp_basic_properties_t props; props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_REPLY_TO_FLAG | AMQP_BASIC_CORRELATION_ID_FLAG; props.content_type = amqp_cstring_bytes("text/plain"); props.delivery_mode = 2; /* persistent delivery mode */ props.reply_to = amqp_bytes_malloc_dup(reply_to_queue); if (props.reply_to.bytes == NULL) { fprintf(stderr, "Out of memory while copying queue name"); return 1; } props.correlation_id = amqp_cstring_bytes("1"); /* publish */ amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(routingkey), 0, 0, &props, amqp_cstring_bytes(messagebody)); // "Publishing"); amqp_bytes_free(props.reply_to); } /* wait an answer */ printf("waiting answer!\n"); { amqp_basic_consume(conn, 1, reply_to_queue, amqp_empty_bytes, 0, 1, 0, amqp_empty_table); amqp_get_rpc_reply(conn);//, "Consuming"); amqp_bytes_free(reply_to_queue); { amqp_frame_t frame; int result; amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; while (1) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result: %d\n", result); if (result < 0) { break; } printf("Frame type: %d channel: %d\n", frame.frame_type, frame.channel); if (frame.frame_type != AMQP_FRAME_METHOD) { continue; } printf("Method: %s\n", amqp_method_name(frame.payload.method.id)); if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { continue; } d = (amqp_basic_deliver_t *) frame.payload.method.decoded; printf("Delivery: %u exchange: %.*s routingkey: %.*s\n", (unsigned) d->delivery_tag, (int) d->exchange.len, (char *) d->exchange.bytes, (int) d->routing_key.len, (char *) d->routing_key.bytes); result = amqp_simple_wait_frame(conn, &frame); if (result < 0) { break; } if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { printf("Content-type: %.*s\n", (int) p->content_type.len, (char *) p->content_type.bytes); } printf("----\n"); body_target = frame.payload.properties.body_size; body_received = 0; while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) { break; } if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); abort(); } body_received += frame.payload.body_fragment.len; printf("len -> %d \n",frame.payload.body_fragment.len); assert(body_received <= body_target); amqp_dump(frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); } if (body_received != body_target) { /* Can only happen when amqp_simple_wait_frame returns <= 0 */ /* We break here to close the connection */ break; } /* everything was fine, we can quit now because we received the reply */ break; } } } /* closing */ amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS);//, "Closing channel"); amqp_connection_close(conn, AMQP_REPLY_SUCCESS);//, "Closing connection"); amqp_destroy_connection(conn);//, "Ending connection"); return 0; }
void BasicMessage::ContentEncoding(const std::string& content_encoding) { if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding); m_impl->m_properties.content_encoding = amqp_bytes_malloc_dup(amqp_cstring_bytes(content_encoding.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_CONTENT_ENCODING_FLAG; }
void BasicMessage::MessageId(const std::string& message_id) { if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id); m_impl->m_properties.message_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(message_id.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_MESSAGE_ID_FLAG; }
BasicMessage::~BasicMessage() { amqp_bytes_free(m_impl->m_body); if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type); if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding); if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id); if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to); if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration); if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id); if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type); if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id); if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id); if (ClusterIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id); }
void BasicMessage::Expiration(const std::string& expiration) { if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration); m_impl->m_properties.expiration = amqp_bytes_malloc_dup(amqp_cstring_bytes(expiration.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_EXPIRATION_FLAG; }
void BasicMessage::ExpirationClear() { if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration); m_impl->m_properties._flags &= ~AMQP_BASIC_EXPIRATION_FLAG; }
void BasicMessage::ReplyToClear() { if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to); m_impl->m_properties._flags &= ~AMQP_BASIC_REPLY_TO_FLAG; }
void BasicMessage::ReplyTo(const std::string& reply_to) { if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to); m_impl->m_properties.reply_to = amqp_bytes_malloc_dup(amqp_cstring_bytes(reply_to.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_REPLY_TO_FLAG; }
void BasicMessage::CorrelationIdClear() { if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id); m_impl->m_properties._flags &= ~AMQP_BASIC_CORRELATION_ID_FLAG; }
void BasicMessage::ClusterId(const std::string& cluster_id) { if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id); m_impl->m_properties.cluster_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(cluster_id.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_CLUSTER_ID_FLAG; }
void BasicMessage::MessageIdClear() { if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id); m_impl->m_properties._flags &= ~AMQP_BASIC_MESSAGE_ID_FLAG; }
void BasicMessage::ClusterIdClear() { if (ClusterIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id); m_impl->m_properties._flags &= ~AMQP_BASIC_CLUSTER_ID_FLAG; }
void BasicMessage::Type(const std::string& type) { if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type); m_impl->m_properties.type = amqp_bytes_malloc_dup(amqp_cstring_bytes(type.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_TYPE_FLAG; }
void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void *data) { mod_amqp_command_profile_t *profile = (mod_amqp_command_profile_t *) data; while (profile->running) { amqp_queue_declare_ok_t *recv_queue; amqp_bytes_t queueName = { 0, NULL }; /* Ensure we have an AMQP connection */ if (!profile->conn_active) { switch_status_t status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Amqp no connection- reconnecting...\n"); status = mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr); if ( status != SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n", profile->name, status, profile->reconnect_interval_ms); switch_sleep(profile->reconnect_interval_ms * 1000); continue; } /* Check if exchange already exists */ amqp_exchange_declare(profile->conn_active->state, 1, amqp_cstring_bytes(profile->exchange), amqp_cstring_bytes("topic"), 0, /* passive */ 1, /* durable */ amqp_empty_table); if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Checking for command exchange")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create missing command exchange", profile->name); continue; } /* Ensure we have a queue */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating command queue"); recv_queue = amqp_queue_declare(profile->conn_active->state, // state 1, // channel profile->queue ? amqp_cstring_bytes(profile->queue) : amqp_empty_bytes, // queue name 0, 0, // passive, durable 0, 1, // exclusive, auto-delete amqp_empty_table); // args if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Declaring queue")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n", profile->name, status, profile->reconnect_interval_ms); switch_sleep(profile->reconnect_interval_ms * 1000); continue; } if (queueName.bytes) { amqp_bytes_free(queueName); } queueName = amqp_bytes_malloc_dup(recv_queue->queue); if (!queueName.bytes) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory while copying queue name"); break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Created command queue %.*s", (int)queueName.len, (char *)queueName.bytes); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Binding command queue to exchange %s", profile->exchange); /* Bind the queue to the exchange */ amqp_queue_bind(profile->conn_active->state, // state 1, // channel queueName, // queue amqp_cstring_bytes(profile->exchange), // exchange amqp_cstring_bytes(profile->binding_key), // routing key amqp_empty_table); // args if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Binding queue")) { mod_amqp_connection_close(profile->conn_active); profile->conn_active = NULL; switch_sleep(profile->reconnect_interval_ms * 1000); continue; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Amqp reconnect successful- connected\n"); continue; } // Start a command amqp_basic_consume(profile->conn_active->state, // state 1, // channel queueName, // queue amqp_empty_bytes, // command tag 0, 1, 0, // no_local, no_ack, exclusive amqp_empty_table); // args if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Creating a command")) { mod_amqp_connection_close(profile->conn_active); profile->conn_active = NULL; switch_sleep(profile->reconnect_interval_ms * 1000); continue; } while (profile->running && profile->conn_active) { amqp_rpc_reply_t res; amqp_envelope_t envelope; struct timeval timeout = {0}; char command[1024]; enum ECommandFormat { COMMAND_FORMAT_UNKNOWN, COMMAND_FORMAT_PLAINTEXT } commandFormat = COMMAND_FORMAT_PLAINTEXT; char *fs_resp_exchange = NULL, *fs_resp_key = NULL; amqp_maybe_release_buffers(profile->conn_active->state); timeout.tv_usec = 500 * 1000; res = amqp_consume_message(profile->conn_active->state, &envelope, &timeout, 0); if (res.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION) { if (res.library_error == AMQP_STATUS_UNEXPECTED_STATE) { /* Unexpected frame. Discard it then continue */ amqp_frame_t decoded_frame; amqp_simple_wait_frame(profile->conn_active->state, &decoded_frame); } if (res.library_error == AMQP_STATUS_SOCKET_ERROR) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A socket error occurred. Tearing down and reconnecting\n"); break; } if (res.library_error == AMQP_STATUS_CONNECTION_CLOSED) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP connection was closed. Tearing down and reconnecting\n"); break; } if (res.library_error == AMQP_STATUS_TCP_ERROR) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A TCP error occurred. Tearing down and reconnecting\n"); break; } if (res.library_error == AMQP_STATUS_TIMEOUT) { // nop } /* Try consuming again */ continue; } if (res.reply_type != AMQP_RESPONSE_NORMAL) { break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Delivery:%u, exchange:%.*s routingkey:%.*s\n", (unsigned) envelope.delivery_tag, (int) envelope.exchange.len, (char *) envelope.exchange.bytes, (int) envelope.routing_key.len, (char *) envelope.routing_key.bytes); if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Content-type: %.*s\n", (int) envelope.message.properties.content_type.len, (char *) envelope.message.properties.content_type.bytes); if (strncasecmp("text/plain", envelope.message.properties.content_type.bytes, strlen("text/plain")) == 0) { commandFormat = COMMAND_FORMAT_PLAINTEXT; } else { commandFormat = COMMAND_FORMAT_UNKNOWN; } } if (envelope.message.properties.headers.num_entries) { int x = 0; for ( x = 0; x < envelope.message.properties.headers.num_entries; x++) { char *header_key = (char *)envelope.message.properties.headers.entries[x].key.bytes; char *header_value = (char *)envelope.message.properties.headers.entries[x].value.value.bytes.bytes; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AMQP message custom header key[%s] value[%s]\n", header_key, header_value); if ( !strncmp(header_key, "x-fs-api-resp-exchange", 22)) { fs_resp_exchange = header_value; } else if (!strncmp(header_key, "x-fs-api-resp-key", 17)) { fs_resp_key = header_value; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring unrecognized event header [%s]\n", header_key); } } } if (commandFormat == COMMAND_FORMAT_PLAINTEXT) { switch_stream_handle_t stream = { 0 }; /* Collects the command output */ /* Convert amqp bytes to c-string */ snprintf(command, sizeof(command), "%.*s", (int) envelope.message.body.len, (char *) envelope.message.body.bytes); /* Execute the command */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Executing: %s\n", command); SWITCH_STANDARD_STREAM(stream); if ( fs_resp_exchange && fs_resp_key ) { switch_status_t status = switch_console_execute(command, 0, &stream); mod_amqp_command_response(profile, command, stream, fs_resp_exchange, fs_resp_key, status); } else { if (switch_console_execute(command, 0, &stream) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Remote command failed:\n%s\n", (char *) stream.data); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote command succeeded:\n%s\n", (char *) stream.data); } } switch_safe_free(stream.data); } /* Tidy up */ amqp_destroy_envelope(&envelope); } amqp_bytes_free(queueName); queueName.bytes = NULL; mod_amqp_connection_close(profile->conn_active); profile->conn_active = NULL; if (profile->running) { /* We'll reconnect, but sleep to avoid hammering resources */ switch_sleep(500); } } /* Terminate the thread */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Command listener thread stopped\n"); switch_thread_exit(thread, SWITCH_STATUS_SUCCESS); return NULL; }
amqp_rpc_reply_t amqp_read_message_noblock(amqp_connection_state_t state, amqp_channel_t channel, amqp_message_t *message, AMQP_UNUSED int flags, struct timeval *timeout) { amqp_frame_t frame; amqp_rpc_reply_t ret; size_t body_read; char *body_read_ptr; int res; memset(&ret, 0, sizeof(amqp_rpc_reply_t)); memset(message, 0, sizeof(amqp_message_t)); res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out1; } if (AMQP_FRAME_HEADER != frame.frame_type) { if (AMQP_FRAME_METHOD == frame.frame_type && (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; ret.reply = frame.payload.method; } else { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_UNEXPECTED_STATE; amqp_put_back_frame(state, &frame); } goto error_out1; } init_amqp_pool(&message->pool, 4096); res = amqp_basic_properties_clone(frame.payload.properties.decoded, &message->properties, &message->pool); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out3; } if (0 == frame.payload.properties.body_size) { message->body = amqp_empty_bytes; } else { message->body = amqp_bytes_malloc(frame.payload.properties.body_size); if (NULL == message->body.bytes) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_NO_MEMORY; goto error_out1; } } body_read = 0; body_read_ptr = message->body.bytes; while (body_read < message->body.len) { res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout); if (AMQP_STATUS_OK != res) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = res; goto error_out2; } if (AMQP_FRAME_BODY != frame.frame_type) { if (AMQP_FRAME_METHOD == frame.frame_type && (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; ret.reply = frame.payload.method; } else { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; } goto error_out2; } if (body_read + frame.payload.body_fragment.len > message->body.len) { ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; goto error_out2; } memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); body_read += frame.payload.body_fragment.len; body_read_ptr += frame.payload.body_fragment.len; } ret.reply_type = AMQP_RESPONSE_NORMAL; return ret; error_out2: amqp_bytes_free(message->body); error_out3: empty_amqp_pool(&message->pool); error_out1: return ret; }
void amqp_destroy_message(amqp_message_t *message) { empty_amqp_pool(&message->pool); amqp_bytes_free(message->body); }
void BasicMessage::ContentTypeClear() { if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type); m_impl->m_properties._flags &= ~AMQP_BASIC_CONTENT_TYPE_FLAG; }
void BasicMessage::TypeClear() { if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type); m_impl->m_properties._flags &= ~AMQP_BASIC_TYPE_FLAG; }
void BasicMessage::ContentEncodingClear() { if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding); m_impl->m_properties._flags &= ~AMQP_BASIC_CONTENT_ENCODING_FLAG; }
void BasicMessage::UserId(const std::string& user_id) { if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id); m_impl->m_properties.user_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(user_id.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_USER_ID_FLAG; }
void BasicMessage::ContentType(const std::string& content_type) { if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type); m_impl->m_properties.content_type = amqp_bytes_malloc_dup(amqp_cstring_bytes(content_type.c_str())); m_impl->m_properties._flags |= AMQP_BASIC_CONTENT_TYPE_FLAG; }