int pn_transform_apply(pn_transform_t *transform, const char *src, pn_string_t *dst) { for (size_t i = 0; i < pn_list_size(transform->rules); i++) { pn_rule_t *rule = (pn_rule_t *) pn_list_get(transform->rules, i); if (pni_match(&transform->matcher, pn_string_get(rule->pattern), src)) { transform->matched = true; if (!pn_string_get(rule->substitution)) { return pn_string_set(dst, NULL); } while (true) { size_t capacity = pn_string_capacity(dst); size_t n = pni_substitute(&transform->matcher, pn_string_get(rule->substitution), pn_string_buffer(dst), capacity); int err = pn_string_resize(dst, n); if (err) return err; if (n <= capacity) { return 0; } } } } transform->matched = false; return pn_string_set(dst, src); }
int pn_quote(pn_string_t *dst, const char *src, size_t size) { while (true) { size_t str_size = pn_string_size(dst); char *str = pn_string_buffer(dst) + str_size; size_t capacity = pn_string_capacity(dst) - str_size; ssize_t ssize = pn_quote_data(str, capacity, src, size); if (ssize == PN_OVERFLOW) { int err = pn_string_grow(dst, (str_size + capacity) ? 2*(str_size + capacity) : 16); if (err) return err; } else if (ssize >= 0) { return pn_string_resize(dst, str_size + ssize); } else { return ssize; } } }
// 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; }
void pni_handle_bound(pn_reactor_t *reactor, pn_event_t *event) { assert(reactor); assert(event); pn_connection_t *conn = pn_event_connection(event); pn_transport_t *transport = pn_event_transport(event); pn_record_t *record = pn_connection_attachments(conn); pn_url_t *url = (pn_url_t *)pn_record_get(record, PNI_CONN_PEER_ADDRESS); const char *host = NULL; const char *port = "5672"; pn_string_t *str = NULL; // link the new transport to its reactor: pni_record_init_reactor(pn_transport_attachments(transport), reactor); if (pn_connection_acceptor(conn) != NULL) { // this connection was created by the acceptor. There is already a // socket assigned to this connection. Nothing needs to be done. return; } if (url) { host = pn_url_get_host(url); const char *uport = pn_url_get_port(url); if (uport) { port = uport; } else { const char *scheme = pn_url_get_scheme(url); if (scheme && strcmp(scheme, "amqps") == 0) { port = "5671"; } } if (!pn_connection_get_user(conn)) { // user did not manually set auth info const char *user = pn_url_get_username(url); if (user) pn_connection_set_user(conn, user); const char *passwd = pn_url_get_password(url); if (passwd) pn_connection_set_password(conn, passwd); } } else { // for backward compatibility, see if the connection's hostname can be // used for the remote address. See JIRA PROTON-1133 const char *hostname = pn_connection_get_hostname(conn); if (hostname) { str = pn_string(hostname); char *h = pn_string_buffer(str); // see if a port has been included in the hostname. This is not // allowed by the spec, but the old reactor interface allowed it. char *colon = strrchr(h, ':'); if (colon) { *colon = '\0'; port = colon + 1; } host = h; } } if (!host) { // error: no address configured pn_condition_t *cond = pn_transport_condition(transport); pn_condition_set_name(cond, "proton:io"); pn_condition_set_description(cond, "Connection failed: no address configured"); pn_transport_close_tail(transport); pn_transport_close_head(transport); } else { pn_socket_t sock = pn_connect(pni_reactor_io(reactor), host, port); // invalid sockets are ignored by poll, so we need to do this manually if (sock == PN_INVALID_SOCKET) { pn_condition_t *cond = pn_transport_condition(transport); pn_condition_set_name(cond, "proton:io"); pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor))); pn_transport_close_tail(transport); pn_transport_close_head(transport); } else { pn_reactor_selectable_transport(reactor, sock, transport); } } pn_free(str); }