示例#1
0
void sender_context_init(sender_context_t *sc, Options_t *opts, Statistics_t *stats)
{
  sc->opts = opts;
  sc->stats = stats;
  sc->sent = 0;
  sc->received = 0;
  sc->id.type = PN_ULONG;
  sc->reply_message = 0;
  // 4096 extra bytes should easily cover the message metadata
  sc->encoded_data_size = sc->opts->msg_size + 4096;
  sc->encoded_data = (char *)calloc(1, sc->encoded_data_size);
  check(sc->encoded_data, "failed to allocate encoding buffer");
  sc->container_id = pn_string("reactor-send"); // prefer uuid-like name

  sc->reply_message = (sc->opts->get_replies) ? pn_message() : 0;
  sc->message = pn_message();
  check(sc->message, "failed to allocate a message");
  pn_string_t *rpto = pn_string("amqp://");
  pn_string_addf(rpto, "%s", pn_string_get(sc->container_id));
  pn_message_set_reply_to(sc->message, pn_string_get(rpto));
  pn_free(rpto);
  pn_data_t *body = pn_message_body(sc->message);
  // borrow the encoding buffer this one time
  char *data = sc->encoded_data;
  pn_data_put_binary(body, pn_bytes(sc->opts->msg_size, data));

  check(sc->opts->targets.count > 0, "no specified address");
  sc->send_url = pn_url_parse(sc->opts->targets.addresses[0]);
  const char *host = pn_url_get_host(sc->send_url);
  const char *port = pn_url_get_port(sc->send_url);
  sc->hostname = pn_string(host);
  if (port && strlen(port))
    pn_string_addf(sc->hostname, ":%s", port);
}
示例#2
0
int pni_subscription_set_address(pn_subscription_t *sub, const char *address)
{
  assert(sub);

  if (!address) return 0;

  bool absolute = strncmp(address, "amqp:", 5) == 0;

  if (absolute) {
    return pn_string_set(sub->address, address);
  } else {
    pn_string_set(sub->address, "");
    bool scheme = pn_string_get(sub->scheme);
    if (scheme) {
      int e = pn_string_addf(sub->address, "%s:", pn_string_get(sub->scheme));
      if (e) return e;
    }
    if (pn_string_get(sub->host)) {
      int e = pn_string_addf(sub->address, scheme ? "//%s" : "%s", pn_string_get(sub->host));
      if (e) return e;
    }
    if (pn_string_get(sub->port)) {
      int e = pn_string_addf(sub->address, ":%s", pn_string_get(sub->port));
      if (e) return e;
    }
    return pn_string_addf(sub->address, "/%s", address);
  }
}
示例#3
0
static int pn_url_inspect(void *obj, pn_string_t *dst)
{
    pn_url_t *url = (pn_url_t *) obj;
    int err = 0;
    err = pn_string_addf(dst, "Url("); if (err) return err;
    err = pn_inspect(pn_url_string(url), dst); if (err) return err;
    return pn_string_addf(dst, ")");
}
示例#4
0
/** URL-encode src and append to dst. */
static void pni_urlencode(pn_string_t *dst, const char* src) {
    static const char *bad = "@:/";

    if (!src) return;
    const char *i = src;
    const char *j = strpbrk(i, bad);
    while (j) {
        pn_string_addf(dst, "%.*s", (int)(j-i), i);
        pn_string_addf(dst, "%%%02X", (int)*j);
        i = j + 1;
        j = strpbrk(i, bad);
    }
    pn_string_addf(dst, "%s", i);
}
示例#5
0
文件: list.c 项目: MZDN/qpid-proton
static int pn_list_inspect(void *obj, pn_string_t *dst)
{
  assert(obj);
  pn_list_t *list = (pn_list_t *) obj;
  int err = pn_string_addf(dst, "[");
  if (err) return err;
  size_t n = pn_list_size(list);
  for (size_t i = 0; i < n; i++) {
    if (i > 0) {
      err = pn_string_addf(dst, ", ");
      if (err) return err;
    }
    err = pn_class_inspect(list->clazz, pn_list_get(list, i), dst);
    if (err) return err;
  }
  return pn_string_addf(dst, "]");
}
示例#6
0
static int pn_collector_inspect(pn_collector_t *collector, pn_string_t *dst)
{
  assert(collector);
  int err = pn_string_addf(dst, "EVENTS[");
  if (err) return err;
  pn_event_t *event = collector->head;
  bool first = true;
  while (event) {
    if (first) {
      first = false;
    } else {
      err = pn_string_addf(dst, ", ");
      if (err) return err;
    }
    err = pn_inspect(event, dst);
    if (err) return err;
    event = event->next;
  }
  return pn_string_addf(dst, "]");
}
示例#7
0
文件: object.c 项目: MZDN/qpid-proton
static void test_string_addf(void)
{
  pn_string_t *str = pn_string("hello ");
  assert(str);
  int err = pn_string_addf(str, "%s", "this is a string that should be long "
                           "enough to force growth but just in case we'll "
                           "tack this other really long string on for the "
                           "heck of it");
  assert(err == 0);
  pn_free(str);
}
示例#8
0
static int pn_event_inspect(pn_event_t *event, pn_string_t *dst)
{
  assert(event);
  assert(dst);
  const char *name = pn_event_type_name(event->type);
  int err;
  if (name) {
    err = pn_string_addf(dst, "(%s", pn_event_type_name(event->type));
  } else {
    err = pn_string_addf(dst, "(<%u>", (unsigned int) event->type);
  }
  if (err) return err;
  if (event->context) {
    err = pn_string_addf(dst, ", ");
    if (err) return err;
    err = pn_class_inspect(event->clazz, event->context, dst);
    if (err) return err;
  }

  return pn_string_addf(dst, ")");
}
示例#9
0
int pn_post_frame(pn_dispatcher_t *disp, uint16_t ch, const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  pn_data_clear(disp->output_args);
  int err = pn_data_vfill(disp->output_args, fmt, ap);
  va_end(ap);
  if (err) {
    pn_transport_logf(disp->transport,
                      "error posting frame: %s, %s: %s", fmt, pn_code(err),
                      pn_error_text(pn_data_error(disp->output_args)));
    return PN_ERR;
  }

  pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, disp->output_size);

 encode_performatives:
  pn_buffer_clear( disp->frame );
  pn_bytes_t buf = pn_buffer_bytes( disp->frame );
  buf.size = pn_buffer_available( disp->frame );

  ssize_t wr = pn_data_encode( disp->output_args, buf.start, buf.size );
  if (wr < 0) {
    if (wr == PN_OVERFLOW) {
      pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 );
      goto encode_performatives;
    }
    pn_transport_logf(disp->transport,
                      "error posting frame: %s", pn_code(wr));
    return PN_ERR;
  }

  pn_frame_t frame = {disp->frame_type};
  frame.channel = ch;
  frame.payload = buf.start;
  frame.size = wr;
  size_t n;
  while (!(n = pn_write_frame(disp->output + disp->available,
                              disp->capacity - disp->available, frame))) {
    disp->capacity *= 2;
    disp->output = (char *) realloc(disp->output, disp->capacity);
  }
  disp->output_frames_ct += 1;
  if (disp->trace & PN_TRACE_RAW) {
    pn_string_set(disp->scratch, "RAW: \"");
    pn_quote(disp->scratch, disp->output + disp->available, n);
    pn_string_addf(disp->scratch, "\"");
    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
  }
  disp->available += n;

  return 0;
}
示例#10
0
static void pn_do_trace(pn_dispatcher_t *disp, uint16_t ch, pn_dir_t dir,
                        pn_data_t *args, const char *payload, size_t size)
{
  if (disp->trace & PN_TRACE_FRM) {
    pn_string_format(disp->scratch, "%u %s ", ch, dir == OUT ? "->" : "<-");
    pn_inspect(args, disp->scratch);

    if (size) {
      char buf[1024];
      int e = pn_quote_data(buf, 1024, payload, size);
      pn_string_addf(disp->scratch, " (%" PN_ZU ") \"%s\"%s", size, buf,
                     e == PN_OVERFLOW ? "... (truncated)" : "");
    }

    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
  }
}
示例#11
0
/** Return the string form of a URL. */
PN_EXTERN const char *pn_url_str(pn_url_t *url) {
    if (pn_string_get(url->str) == NULL) {
        pn_string_set(url->str, "");
        if (url->scheme) pn_string_addf(url->str, "%s://", url->scheme);
        if (url->username) pni_urlencode(url->str, url->username);
        if (url->password) {
            pn_string_addf(url->str, ":");
            pni_urlencode(url->str, url->password);
        }
        if (url->username || url->password) pn_string_addf(url->str, "@");
        if (url->host) {
            if (strchr(url->host, ':')) pn_string_addf(url->str, "[%s]", url->host);
            else pn_string_addf(url->str, "%s", url->host);
        }
        if (url->port) pn_string_addf(url->str, ":%s", url->port);
        if (url->path) pn_string_addf(url->str, "/%s", url->path);
    }
    return pn_string_get(url->str);
}
示例#12
0
// 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;
}
示例#13
0
int pn_post_transfer_frame(pn_dispatcher_t *disp, uint16_t ch,
                           uint32_t handle,
                           pn_sequence_t id,
                           const pn_bytes_t *tag,
                           uint32_t message_format,
                           bool settled,
                           bool more,
                           pn_sequence_t frame_limit)
{
  bool more_flag = more;
  int framecount = 0;

  // create preformatives, assuming 'more' flag need not change

 compute_performatives:
  pn_data_clear(disp->output_args);
  int err = pn_data_fill(disp->output_args, "DL[IIzIoo]", TRANSFER,
                         handle, id, tag->size, tag->start,
                         message_format,
                         settled, more_flag);
  if (err) {
    pn_transport_logf(disp->transport,
                      "error posting transfer frame: %s: %s", pn_code(err),
                      pn_error_text(pn_data_error(disp->output_args)));
    return PN_ERR;
  }

  do { // send as many frames as possible without changing the 'more' flag...

  encode_performatives:
    pn_buffer_clear( disp->frame );
    pn_bytes_t buf = pn_buffer_bytes( disp->frame );
    buf.size = pn_buffer_available( disp->frame );

    ssize_t wr = pn_data_encode(disp->output_args, buf.start, buf.size);
    if (wr < 0) {
      if (wr == PN_OVERFLOW) {
        pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 );
        goto encode_performatives;
      }
      pn_transport_logf(disp->transport, "error posting frame: %s", pn_code(wr));
      return PN_ERR;
    }
    buf.size = wr;

    // check if we need to break up the outbound frame
    size_t available = disp->output_size;
    if (disp->remote_max_frame) {
      if ((available + buf.size) > disp->remote_max_frame - 8) {
        available = disp->remote_max_frame - 8 - buf.size;
        if (more_flag == false) {
          more_flag = true;
          goto compute_performatives;  // deal with flag change
        }
      } else if (more_flag == true && more == false) {
        // caller has no more, and this is the last frame
        more_flag = false;
        goto compute_performatives;
      }
    }

    if (pn_buffer_available( disp->frame ) < (available + buf.size)) {
      // not enough room for payload - try again...
      pn_buffer_ensure( disp->frame, available + buf.size );
      goto encode_performatives;
    }

    pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, available);

    memmove( buf.start + buf.size, disp->output_payload, available);
    disp->output_payload += available;
    disp->output_size -= available;
    buf.size += available;

    pn_frame_t frame = {disp->frame_type};
    frame.channel = ch;
    frame.payload = buf.start;
    frame.size = buf.size;

    size_t n;
    while (!(n = pn_write_frame(disp->output + disp->available,
                                disp->capacity - disp->available, frame))) {
      disp->capacity *= 2;
      disp->output = (char *) realloc(disp->output, disp->capacity);
    }
    disp->output_frames_ct += 1;
    framecount++;
    if (disp->trace & PN_TRACE_RAW) {
      pn_string_set(disp->scratch, "RAW: \"");
      pn_quote(disp->scratch, disp->output + disp->available, n);
      pn_string_addf(disp->scratch, "\"");
      pn_transport_log(disp->transport, pn_string_get(disp->scratch));
    }
    disp->available += n;
  } while (disp->output_size > 0 && framecount < frame_limit);

  disp->output_payload = NULL;
  return framecount;
}