int main(int argc, char const *const *argv) { char const *hostname; int port, status; char const *queuename; amqp_socket_t *socket; amqp_connection_state_t conn; if (argc < 4) { fprintf(stderr, "Usage: amqps_listenq host port queuename " "[cacert.pem [key.pem cert.pem]]\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); queuename = argv[3]; conn = amqp_new_connection(); socket = amqp_ssl_socket_new(); if (!socket) { die("creating SSL/TLS socket"); } if (argc > 4) { status = amqp_ssl_socket_set_cacert(socket, argv[4]); if (status) { die("setting CA certificate"); } } if (argc > 6) { status = amqp_ssl_socket_set_key(socket, argv[6], argv[5]); if (status) { die("setting client cert"); } } status = amqp_socket_open(socket, hostname, port); if (status) { die("opening SSL/TLS connection"); } amqp_set_socket(conn, socket); die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in"); amqp_channel_open(conn, 1); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, 0, 0, 0, amqp_empty_table); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { 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; 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; } amqp_basic_ack(conn, 1, d->delivery_tag, 0); } } die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }
static int inner_send_frame(amqp_connection_state_t state, amqp_frame_t const *frame, amqp_bytes_t *encoded, int *payload_len) { int separate_body; E_8(state->outbound_buffer, 0, frame->frame_type); E_16(state->outbound_buffer, 1, frame->channel); switch (frame->frame_type) { case AMQP_FRAME_METHOD: E_32(state->outbound_buffer, HEADER_SIZE, frame->payload.method.id); encoded->len = state->outbound_buffer.len - (HEADER_SIZE + 4 + FOOTER_SIZE); encoded->bytes = D_BYTES(state->outbound_buffer, HEADER_SIZE + 4, encoded->len); *payload_len = AMQP_CHECK_RESULT(amqp_encode_method(frame->payload.method.id, frame->payload.method.decoded, *encoded)) + 4; separate_body = 0; break; case AMQP_FRAME_HEADER: E_16(state->outbound_buffer, HEADER_SIZE, frame->payload.properties.class_id); E_16(state->outbound_buffer, HEADER_SIZE+2, 0); /* "weight" */ E_64(state->outbound_buffer, HEADER_SIZE+4, frame->payload.properties.body_size); encoded->len = state->outbound_buffer.len - (HEADER_SIZE + 12 + FOOTER_SIZE); encoded->bytes = D_BYTES(state->outbound_buffer, HEADER_SIZE + 12, encoded->len); *payload_len = AMQP_CHECK_RESULT(amqp_encode_properties(frame->payload.properties.class_id, frame->payload.properties.decoded, *encoded)) + 12; separate_body = 0; break; case AMQP_FRAME_BODY: *encoded = frame->payload.body_fragment; *payload_len = encoded->len; separate_body = 1; break; case AMQP_FRAME_HEARTBEAT: *encoded = AMQP_EMPTY_BYTES; *payload_len = 0; separate_body = 0; break; default: return -EINVAL; } E_32(state->outbound_buffer, 3, *payload_len); if (!separate_body) { E_8(state->outbound_buffer, *payload_len + HEADER_SIZE, AMQP_FRAME_END); } #if 0 if (separate_body) { printf("sending body frame (header):\n"); amqp_dump(state->outbound_buffer.bytes, HEADER_SIZE); printf("sending body frame (payload):\n"); amqp_dump(encoded->bytes, *payload_len); } else { printf("sending:\n"); amqp_dump(state->outbound_buffer.bytes, *payload_len + HEADER_SIZE + FOOTER_SIZE); } #endif return separate_body; }
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; }
int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data, amqp_frame_t *decoded_frame) { int total_bytes_consumed = 0; int bytes_consumed; /* Returning frame_type of zero indicates either insufficient input, or a complete, ignored frame was read. */ decoded_frame->frame_type = 0; read_more: if (received_data.len == 0) { return total_bytes_consumed; } if (state->state == CONNECTION_STATE_IDLE) { state->inbound_buffer.bytes = amqp_pool_alloc(&state->frame_pool, state->inbound_buffer.len); if (state->inbound_buffer.bytes == NULL) { /* state->inbound_buffer.len is always nonzero, because it corresponds to frame_max, which is not permitted to be less than AMQP_FRAME_MIN_SIZE (currently 4096 bytes). */ return -ENOMEM; } state->state = CONNECTION_STATE_WAITING_FOR_HEADER; } bytes_consumed = state->target_size - state->inbound_offset; if (received_data.len < bytes_consumed) { bytes_consumed = received_data.len; } E_BYTES(state->inbound_buffer, state->inbound_offset, bytes_consumed, received_data.bytes); state->inbound_offset += bytes_consumed; total_bytes_consumed += bytes_consumed; assert(state->inbound_offset <= state->target_size); if (state->inbound_offset < state->target_size) { return total_bytes_consumed; } switch (state->state) { case CONNECTION_STATE_WAITING_FOR_HEADER: if (D_8(state->inbound_buffer, 0) == AMQP_PSEUDOFRAME_PROTOCOL_HEADER && D_16(state->inbound_buffer, 1) == AMQP_PSEUDOFRAME_PROTOCOL_CHANNEL) { state->target_size = 8; state->state = CONNECTION_STATE_WAITING_FOR_PROTOCOL_HEADER; } else { state->target_size = D_32(state->inbound_buffer, 3) + HEADER_SIZE + FOOTER_SIZE; state->state = CONNECTION_STATE_WAITING_FOR_BODY; } /* Wind buffer forward, and try to read some body out of it. */ received_data.len -= bytes_consumed; received_data.bytes = ((char *) received_data.bytes) + bytes_consumed; goto read_more; case CONNECTION_STATE_WAITING_FOR_BODY: { int frame_type = D_8(state->inbound_buffer, 0); #if 0 printf("recving:\n"); amqp_dump(state->inbound_buffer.bytes, state->target_size); #endif /* Check frame end marker (footer) */ if (D_8(state->inbound_buffer, state->target_size - 1) != AMQP_FRAME_END) { return -EINVAL; } decoded_frame->channel = D_16(state->inbound_buffer, 1); switch (frame_type) { case AMQP_FRAME_METHOD: { amqp_bytes_t encoded; /* Four bytes of method ID before the method args. */ encoded.len = state->target_size - (HEADER_SIZE + 4 + FOOTER_SIZE); encoded.bytes = D_BYTES(state->inbound_buffer, HEADER_SIZE + 4, encoded.len); decoded_frame->frame_type = AMQP_FRAME_METHOD; decoded_frame->payload.method.id = D_32(state->inbound_buffer, HEADER_SIZE); AMQP_CHECK_RESULT(amqp_decode_method(decoded_frame->payload.method.id, &state->decoding_pool, encoded, &decoded_frame->payload.method.decoded)); break; } case AMQP_FRAME_HEADER: { amqp_bytes_t encoded; /* 12 bytes for properties header. */ encoded.len = state->target_size - (HEADER_SIZE + 12 + FOOTER_SIZE); encoded.bytes = D_BYTES(state->inbound_buffer, HEADER_SIZE + 12, encoded.len); decoded_frame->frame_type = AMQP_FRAME_HEADER; decoded_frame->payload.properties.class_id = D_16(state->inbound_buffer, HEADER_SIZE); decoded_frame->payload.properties.body_size = D_64(state->inbound_buffer, HEADER_SIZE+4); decoded_frame->payload.properties.raw = encoded; AMQP_CHECK_RESULT(amqp_decode_properties(decoded_frame->payload.properties.class_id, &state->decoding_pool, encoded, &decoded_frame->payload.properties.decoded)); break; } case AMQP_FRAME_BODY: { size_t fragment_len = state->target_size - (HEADER_SIZE + FOOTER_SIZE); decoded_frame->frame_type = AMQP_FRAME_BODY; decoded_frame->payload.body_fragment.len = fragment_len; decoded_frame->payload.body_fragment.bytes = D_BYTES(state->inbound_buffer, HEADER_SIZE, fragment_len); break; } case AMQP_FRAME_HEARTBEAT: decoded_frame->frame_type = AMQP_FRAME_HEARTBEAT; break; default: /* Ignore the frame by not changing frame_type away from 0. */ break; } return_to_idle(state); return total_bytes_consumed; } case CONNECTION_STATE_WAITING_FOR_PROTOCOL_HEADER: decoded_frame->frame_type = AMQP_PSEUDOFRAME_PROTOCOL_HEADER; decoded_frame->channel = AMQP_PSEUDOFRAME_PROTOCOL_CHANNEL; amqp_assert(D_8(state->inbound_buffer, 3) == (uint8_t) 'P', "Invalid protocol header received"); decoded_frame->payload.protocol_header.transport_high = D_8(state->inbound_buffer, 4); decoded_frame->payload.protocol_header.transport_low = D_8(state->inbound_buffer, 5); decoded_frame->payload.protocol_header.protocol_version_major = D_8(state->inbound_buffer, 6); decoded_frame->payload.protocol_header.protocol_version_minor = D_8(state->inbound_buffer, 7); return_to_idle(state); return total_bytes_consumed; default: amqp_assert(0, "Internal error: invalid amqp_connection_state_t->state %d", state->state); } }
int main(int argc, char const * const *argv) { char const *hostname; int port; char const *exchange; char const *bindingkey; int sockfd; amqp_connection_state_t conn; amqp_bytes_t queuename; if (argc < 5) { fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); exchange = argv[3]; bindingkey = argv[4]; conn = amqp_new_connection(); die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket"); amqp_set_sockfd(conn, sockfd); die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in"); amqp_channel_open(conn, 1); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); { amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, AMQP_EMPTY_BYTES, 0, 0, 0, 1, AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); queuename = amqp_bytes_malloc_dup(r->queue); if (queuename.bytes == NULL) { die_on_error(-ENOMEM, "Copying queue name"); } } amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey), AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue"); amqp_basic_consume(conn, 1, queuename, AMQP_EMPTY_BYTES, 0, 1, 0); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { 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; 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; } } } die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); amqp_destroy_connection(conn); die_on_error(close(sockfd), "Closing socket"); return 0; }