static void process_reply( pn_messenger_t *messenger, pn_message_t *message) { int rc; pn_data_t *body = pn_message_body(message); pn_bytes_t m_type; pn_bytes_t m_command; pn_bytes_t m_value; pn_bytes_t m_status; bool duplicate = false; rc = pn_data_scan( body, "{.S.S.S.S}", &m_type, &m_command, &m_value, &m_status ); check( rc == 0, "Failed to decode response message" ); check(strncmp("response", m_type.start, m_type.size) == 0, "Unknown message type received"); if (strncmp("DUPLICATE", m_status.start, m_status.size) == 0) { LOG( "Server detected duplicate request!\n" ); duplicate = true; } else if (strncmp("OK", m_status.start, m_status.size)) { fprintf( stderr, "Request failed - error: %.*s\n", (int)m_status.size, m_status.start ); return; } fprintf( stdout, "Fortune%s: \"%.*s\"%s\n", strncmp("set", m_command.start, m_command.size) == 0 ? " set to" : "", (int)m_value.size, m_value.start, duplicate ? " (duplicate detected by server)" : "" ); }
int pn_message_save_text(pn_message_t *msg, char *data, size_t *size) { if (!msg) return PN_ARG_ERR; if (!msg->body) { *size = 0; return 0; } uint64_t desc; pn_bytes_t str; bool scanned; int err = pn_data_scan(msg->body, "DL?S", &desc, &scanned, &str); if (err) return err; if (desc == AMQP_VALUE && scanned) { if (str.size >= *size) { return PN_OVERFLOW; } else { memcpy(data, str.start, str.size); data[str.size] = '\0'; *size = str.size; return 0; } } else { return PN_STATE_ERR; } }
int pn_message_save_data(pn_message_t *msg, char *data, size_t *size) { if (!msg) return PN_ARG_ERR; if (!msg->body || pn_data_size(msg->body) == 0) { *size = 0; return 0; } uint64_t desc; pn_bytes_t bytes; bool scanned; int err = pn_data_scan(msg->body, "DL?z", &desc, &scanned, &bytes); if (err) return err; if (desc == DATA && scanned) { if (bytes.size > *size) { return PN_OVERFLOW; } else { memcpy(data, bytes.start, bytes.size); *size = bytes.size; return 0; } } else { return PN_STATE_ERR; } }
// Received server side int pn_do_response(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload) { pn_bytes_t recv; int err = pn_data_scan(args, "D.[z]", &recv); if (err) return err; pni_process_response(transport, &recv); return 0; }
// Received Server side int pn_do_init(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload) { pni_sasl_t *sasl = transport->sasl; pn_bytes_t mech; pn_bytes_t recv; int err = pn_data_scan(args, "D.[sz]", &mech, &recv); if (err) return err; sasl->selected_mechanism = pn_strndup(mech.start, mech.size); pni_process_init(transport, sasl->selected_mechanism, &recv); return 0; }
int buffer(int argc, char **argv) { pn_buffer_t *buf = pn_buffer(16); pn_buffer_append(buf, "abcd", 4); pn_buffer_print(buf); printf("\n"); pn_buffer_prepend(buf, "012", 3); pn_buffer_print(buf); printf("\n"); pn_buffer_prepend(buf, "z", 1); pn_buffer_print(buf); printf("\n"); pn_buffer_append(buf, "efg", 3); pn_buffer_print(buf); printf("\n"); pn_buffer_append(buf, "hijklm", 6); pn_buffer_print(buf); printf("\n"); pn_buffer_defrag(buf); pn_buffer_print(buf); printf("\n"); pn_buffer_trim(buf, 1, 1); pn_buffer_print(buf); printf("\n"); pn_buffer_trim(buf, 4, 0); pn_buffer_print(buf); printf("\n"); pn_buffer_clear(buf); pn_buffer_print(buf); printf("\n"); pn_buffer_free(buf); pn_data_t *data = pn_data(16); int err = pn_data_fill(data, "Ds[iSi]", "desc", 1, "two", 3); if (err) { printf("%s\n", pn_code(err)); } pn_data_print(data); printf("\n"); pn_bytes_t str; err = pn_data_scan(data, "D.[.S.]", &str); if (err) { printf("%s\n", pn_code(err)); } else { printf("%.*s\n", (int) str.size, str.start); } pn_data_clear(data); pn_data_fill(data, "DL[SIonn?DL[S]?DL[S]nnI]", ATTACH, "asdf", 1, true, true, SOURCE, "queue", true, TARGET, "queue", 0); pn_data_print(data); printf("\n"); pn_data_free(data); return 0; }
// Received client side int pn_do_outcome(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload) { uint8_t outcome; int err = pn_data_scan(args, "D.[B]", &outcome); if (err) return err; pni_sasl_t *sasl = transport->sasl; sasl->outcome = (pn_sasl_outcome_t) outcome; bool authenticated = sasl->outcome==PN_SASL_OK; transport->authenticated = authenticated; pni_sasl_set_desired_state(transport, authenticated ? SASL_RECVED_OUTCOME_SUCCEED : SASL_RECVED_OUTCOME_FAIL); return 0; }
int pn_dispatch_frame(pn_dispatcher_t *disp, pn_frame_t frame) { if (frame.size == 0) { // ignore null frames if (disp->trace & PN_TRACE_FRM) pn_transport_logf(disp->transport, "%u <- (EMPTY FRAME)\n", frame.channel); return 0; } ssize_t dsize = pn_data_decode(disp->args, frame.payload, frame.size); if (dsize < 0) { pn_string_format(disp->scratch, "Error decoding frame: %s %s\n", pn_code(dsize), pn_error_text(pn_data_error(disp->args))); pn_quote(disp->scratch, frame.payload, frame.size); pn_transport_log(disp->transport, pn_string_get(disp->scratch)); return dsize; } disp->channel = frame.channel; // XXX: assuming numeric uint64_t lcode; bool scanned; int e = pn_data_scan(disp->args, "D?L.", &scanned, &lcode); if (e) { pn_transport_log(disp->transport, "Scan error"); return e; } if (!scanned) { pn_transport_log(disp->transport, "Error dispatching frame"); return PN_ERR; } uint8_t code = lcode; disp->code = code; disp->size = frame.size - dsize; if (disp->size) disp->payload = frame.payload + dsize; pn_do_trace(disp, disp->channel, IN, disp->args, disp->payload, disp->size); pn_action_t *action = disp->actions[code]; int err = action(disp); disp->channel = 0; disp->code = 0; pn_data_clear(disp->args); disp->size = 0; disp->payload = NULL; return err; }
// Received client side int pn_do_mechanisms(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload) { pni_sasl_t *sasl = transport->sasl; // If we already pretended we got the ANONYMOUS mech then ignore if (sasl->last_state==SASL_PRETEND_OUTCOME) return 0; // This scanning relies on pn_data_scan leaving the pn_data_t cursors // where they are after finishing the scan int err = pn_data_scan(args, "D.[@["); if (err) return err; pn_string_t *mechs = pn_string(""); // Now keep checking for end of array and pull a symbol while(pn_data_next(args)) { pn_bytes_t s = pn_data_get_symbol(args); if (pni_included_mech(transport->sasl->included_mechanisms, s)) { pn_string_addf(mechs, "%*s ", (int)s.size, s.start); } } if (pn_string_size(mechs)) { pn_string_buffer(mechs)[pn_string_size(mechs)-1] = 0; } if (pni_init_client(transport) && pni_process_mechanisms(transport, pn_string_get(mechs))) { pni_sasl_set_desired_state(transport, SASL_POSTED_INIT); } else { sasl->outcome = PN_SASL_PERM; pni_sasl_set_desired_state(transport, SASL_RECVED_OUTCOME_FAIL); } pn_free(mechs); return 0; }
int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size) { if (!msg || !bytes || !size) return PN_ARG_ERR; if (!msg->data) { msg->data = pn_data(64); } if (!msg->body) { msg->body = pn_data(64); } pn_data_clear(msg->body); while (size) { size_t copy = size; pn_data_clear(msg->data); int err = pn_data_decode(msg->data, (char *) bytes, ©); if (err) return err; size -= copy; bytes += copy; bool scanned; uint64_t desc; err = pn_data_scan(msg->data, "D?L.", &scanned, &desc); if (err) return err; if (!scanned){ desc = 0; } switch (desc) { case HEADER: pn_data_scan(msg->data, "D.[oBIoI]", &msg->durable, &msg->priority, &msg->ttl, &msg->first_acquirer, &msg->delivery_count); break; case PROPERTIES: { pn_bytes_t user_id, address, subject, reply_to, ctype, cencoding, group_id, reply_to_group_id; err = pn_data_scan(msg->data, "D.[.zSSS.ssLLSiS]", &user_id, &address, &subject, &reply_to, &ctype, &cencoding, &msg->expiry_time, &msg->creation_time, &group_id, &msg->group_sequence, &reply_to_group_id); if (err) return err; err = pn_buffer_set_bytes(&msg->user_id, user_id); if (err) return err; err = pn_buffer_set_strn(&msg->address, address.start, address.size); if (err) return err; err = pn_buffer_set_strn(&msg->subject, subject.start, subject.size); if (err) return err; err = pn_buffer_set_strn(&msg->reply_to, reply_to.start, reply_to.size); if (err) return err; err = pn_buffer_set_strn(&msg->content_type, ctype.start, ctype.size); if (err) return err; err = pn_buffer_set_strn(&msg->content_encoding, cencoding.start, cencoding.size); if (err) return err; err = pn_buffer_set_strn(&msg->group_id, group_id.start, group_id.size); if (err) return err; err = pn_buffer_set_strn(&msg->reply_to_group_id, reply_to_group_id.start, reply_to_group_id.size); if (err) return err; } break; case DELIVERY_ANNOTATIONS: case MESSAGE_ANNOTATIONS: break; default: { pn_data_t *data = msg->body; msg->body = msg->data; msg->data = data; err = pn_data_intern(msg->body); if (err) return err; } break; } } return pn_data_clear(msg->data); }