Example #1
0
File: bench.c Project: hnkien/river
/**
 * pthread entry point, running the reader event base.
 */
void *
comet_run_readers(void *ptr) {

	struct reader_thread *rt = ptr;
	int i, j;
	rt->base = event_base_new();

	for(i = 0; i < rt->channel_count; ++i) {
		char *chan = rt->channels[i];
		char *url = calloc(strlen(chan) + 17, 1);
		sprintf(url, "/subscribe?name=%s", chan);

		for(j = 0; j < rt->reader_per_chan; ++j) {

			struct evhttp_connection *evcon = evhttp_connection_new(rt->hi->host, rt->hi->port);
			struct evhttp_request *evreq = evhttp_request_new(on_end_of_subscribe, rt);

			evhttp_connection_set_base(evcon, rt->base);
			evhttp_request_set_chunked_cb(evreq, on_http_message_chunk);
			evhttp_make_request(evcon, evreq, EVHTTP_REQ_GET, url);
			/* printf("[SUBSCRIBE: http://127.0.0.1:1234%s]\n", url); */
		}
	}
	event_base_dispatch(rt->base);
	return NULL;
}
TEvhttpClientChannel::TEvhttpClientChannel(const std::string& host,
                                           const std::string& path,
                                           const char* address,
                                           int port,
                                           struct event_base* eb)
  : host_(host), path_(path), recvBuf_(NULL), conn_(NULL) {
  conn_ = evhttp_connection_new(address, port);
  if (conn_ == NULL) {
    throw TException("evhttp_connection_new failed");
  }
  evhttp_connection_set_base(conn_, eb);
}
Example #3
0
IoObject *IoEvConnection_connect(IoEvConnection *self, IoObject *locals, IoMessage *m)
{
	IoEventManager *em = IoObject_getSlot_(self, IOSYMBOL("eventManager"));
	IoSeq *address = IoObject_seqGetSlot_(self, IOSYMBOL("address"));
	int port = IoObject_doubleGetSlot_(self, IOSYMBOL("port"));

	IOASSERT(CONN(self) == 0x0, "already have connection");
	IOASSERT(ISEEVENTMANAGER(em), "eventManager slot not set properly");

	//printf("IoEventManager_rawBase(em) = %p\n", (void *)IoEventManager_rawBase(em));

	IoObject_setDataPointer_(self, evhttp_connection_new(CSTRING(address), port));
	evhttp_connection_set_base(CONN(self), IoEventManager_rawBase(em));
	evhttp_connection_set_closecb(CONN(self), IoEvConnection_ConnectionCloseCallback, self);
	return self;
}
Example #4
0
void 
http_request::renew_request()
{
	/* free connections & request */
	if (m_cn)
		evhttp_connection_free(m_cn);

#if !defined(_EVENT_NUMERIC_VERSION) || _EVENT_NUMERIC_VERSION < 0x02000000
	m_cn = evhttp_connection_new(m_host.c_str(), m_port);
	evhttp_connection_set_base(m_cn, m_base);
#else
	m_cn = evhttp_connection_base_new(
		m_base, NULL, 
		m_host.c_str(),
		m_port);
#endif

	m_req = evhttp_request_new(http_request::download_callback, this);

	evhttp_make_request(m_cn, m_req, m_type, m_query.c_str());

	evhttp_add_header(m_req->output_headers,
                            "Host", m_host.c_str());
}
Example #5
0
bool LibEventHttpClient::send(const std::string &url,
                              const std::vector<std::string> &headers,
                              int timeoutSeconds, bool async,
                              const void *data /* = NULL */,
                              int size /* = 0 */) {
  clear();
  m_url = url;

  evhttp_request* request = evhttp_request_new(on_request_completed, this);

  // request headers
  bool keepalive = true;
  bool addHost = true;
  for (unsigned int i = 0; i < headers.size(); i++) {
    const std::string &header = headers[i];
    size_t pos = header.find(':');
    if (pos != std::string::npos && header[pos + 1] == ' ') {
      std::string name = header.substr(0, pos);
      if (strcasecmp(name.c_str(), "Connection") == 0) {
        keepalive = false;
      } else if (strcasecmp(name.c_str(), "Host") == 0) {
        addHost = false;
      }
      int ret = evhttp_add_header(request->output_headers,
                                  name.c_str(), header.c_str() + pos + 2);
      if (ret >= 0) {
        continue;
      }
    }
    Logger::Error("invalid request header: [%s]", header.c_str());
  }
  if (keepalive) {
    evhttp_add_header(request->output_headers, "Connection", "keep-alive");
  }
  if (addHost) {
    // REVIEW: libevent never sends a Host header (nor does it properly send
    // HTTP 400 for HTTP/1.1 requests without such a header), in blatant
    // violation of RFC2616; this should perhaps be fixed in the library
    // proper.  For now, add it if it wasn't set by the caller.
    if (m_port == 80) {
      evhttp_add_header(request->output_headers, "Host", m_address.c_str());
    } else {
      std::ostringstream ss;
      ss << m_address << ":" << m_port;
      evhttp_add_header(request->output_headers, "Host", ss.str().c_str());
    }
  }

  // post data
  if (data && size) {
    evbuffer_add(request->output_buffer, data, size);
  }

  // url
  evhttp_cmd_type cmd = data ? EVHTTP_REQ_POST : EVHTTP_REQ_GET;

  // if we have a cached connection, we need to pump the event loop to clear
  // any "connection closed" events that may be sitting there patiently.
  if (m_conn) {
    event_base_loop(m_eventBase, EVLOOP_NONBLOCK);
  }

  // even if we had an m_conn immediately above, it may have been cleared out
  // by onConnectionClosed().
  if (m_conn == nullptr) {
    m_conn = evhttp_connection_new(m_address.c_str(), m_port);
    evhttp_connection_set_closecb(m_conn, on_connection_closed, this);
    evhttp_connection_set_base(m_conn, m_eventBase);
  }

  int ret = evhttp_make_request(m_conn, request, cmd, url.c_str());
  if (ret != 0) {
    Logger::Error("evhttp_make_request failed");
    return false;
  }

  if (timeoutSeconds > 0) {
    struct timeval timeout;
    timeout.tv_sec = timeoutSeconds;
    timeout.tv_usec = 0;

    event_set(&m_eventTimeout, -1, 0, timer_callback, m_eventBase);
    event_base_set(m_eventBase, &m_eventTimeout);
    event_add(&m_eventTimeout, &timeout);
  }

  if (async) {
    m_thread = new AsyncFunc<LibEventHttpClient>
      (this, &LibEventHttpClient::sendImpl);
    m_thread->start();
  } else {
    IOStatusHelper io("libevent_http", m_address.c_str(), m_port);
    sendImpl();
  }
  return true;
}
Example #6
0
/* Thread: main (pairing) */
static int
send_pairing_request(struct remote_info *ri, char *req_uri, int family)
{
  struct evhttp_connection *evcon;
  struct evhttp_request *req;
  char *address;
  unsigned short port;
  int ret;

  switch (family)
    {
      case AF_INET:
	if (!ri->v4_address)
	  return -1;

	address = ri->v4_address;
	port = ri->v4_port;
	break;

      case AF_INET6:
	if (!ri->v6_address)
	  return -1;

	address = ri->v6_address;
	port = ri->v6_port;
	break;

      default:
	return -1;
    }

  evcon = evhttp_connection_new(address, port);
  if (!evcon)
    {
      DPRINTF(E_LOG, L_REMOTE, "Could not create connection for pairing with %s\n", ri->pi.name);

      return -1;
    }

  evhttp_connection_set_base(evcon, evbase_main);

  req = evhttp_request_new(pairing_request_cb, ri);
  if (!req)
    {
      DPRINTF(E_WARN, L_REMOTE, "Could not create HTTP request for pairing\n");

      goto request_fail;
    }

  ret = evhttp_make_request(evcon, req, EVHTTP_REQ_GET, req_uri);
  if (ret < 0)
    {
      DPRINTF(E_WARN, L_REMOTE, "Could not make pairing request\n");

      goto request_fail;
    }

  ri->evcon = evcon;

  return 0;

 request_fail:
  evhttp_connection_free(evcon);

  return -1;
}
bool LibEventHttpClient::send(const std::string &url,
                              const std::vector<std::string> &headers,
                              int timeoutSeconds, bool async,
                              const void *data /* = NULL */,
                              int size /* = 0 */) {
  clear();
  m_url = url;

  if (m_conn == NULL) {
    m_conn = evhttp_connection_new(m_address.c_str(), m_port);
    evhttp_connection_set_closecb(m_conn, on_connection_closed, this);
    evhttp_connection_set_base(m_conn, m_eventBase);
  }
  m_request = evhttp_request_new(on_request_completed, this);

  // REVIEW: libevent never sends a Host header (nor does it properly send HTTP
  // 400 for HTTP/1.1 requests without such a header), in blatent violation of
  // RFC2616; this should perhaps be fixed in the library proper.
  if (m_port == 80) {
    evhttp_add_header(m_request->output_headers, "Host", m_address.c_str());
  } else {
    std::ostringstream ss;
    ss << m_address << ":" << m_port;
    evhttp_add_header(m_request->output_headers, "Host", ss.str().c_str());
  }

  // request headers
  bool keepalive = true;
  for (unsigned int i = 0; i < headers.size(); i++) {
    const std::string &header = headers[i];
    size_t pos = header.find(':');
    if (pos != string::npos && header[pos + 1] == ' ') {
      string name = header.substr(0, pos);
      if (strcasecmp(name.c_str(), "Connection") == 0) {
        keepalive = false;
      }
      int ret = evhttp_add_header(m_request->output_headers,
                                  name.c_str(), header.c_str() + pos + 2);
      if (ret >= 0) {
        continue;
      }
    }
    Logger::Error("invalid request header: [%s]", header.c_str());
  }
  if (keepalive) {
    evhttp_add_header(m_request->output_headers, "Connection", "keep-alive");
  }

  // post data
  if (data && size) {
    evbuffer_add(m_request->output_buffer, data, size);
  }

  // url
  evhttp_cmd_type cmd = data ? EVHTTP_REQ_POST : EVHTTP_REQ_GET;
  int ret = evhttp_make_request(m_conn, m_request, cmd, url.c_str());
  if (ret != 0) {
    Logger::Error("evhttp_make_request failed");
    return false;
  }

  if (timeoutSeconds > 0) {
    struct timeval timeout;
    timeout.tv_sec = timeoutSeconds;
    timeout.tv_usec = 0;

    event_set(&m_eventTimeout, -1, 0, timer_callback, m_eventBase);
    event_base_set(m_eventBase, &m_eventTimeout);
    event_add(&m_eventTimeout, &timeout);
  }

  if (async) {
    m_thread = new AsyncFunc<LibEventHttpClient>
      (this, &LibEventHttpClient::sendImpl);
    m_thread->start();
  } else {
    sendImpl();
  }
  return true;
}
int
scan_metadata_icy(char *url, struct media_file_info *mfi)
{
  struct evhttp_connection *evcon;
  struct evhttp_request *req;
  struct icy_ctx *ctx;
  int ret;
  int i;

  status = ICY_INIT;

  /* We can set this straight away */
  mfi->url = strdup(url);

  ctx = (struct icy_ctx *)malloc(sizeof(struct icy_ctx));
  if (!ctx)
    {
      DPRINTF(E_LOG, L_SCAN, "Out of memory for ICY metadata context\n");

      goto no_icy;
    }
  memset(ctx, 0, sizeof(struct icy_ctx));

  ctx->url = evhttp_encode_uri(url);

  /* TODO https */
  av_url_split(NULL, 0, NULL, 0, ctx->hostname, sizeof(ctx->hostname), &ctx->port, ctx->path, sizeof(ctx->path), ctx->url);
  if (ctx->port < 0)
    ctx->port = 80;

  /* Resolve IP address */
  ret = resolve_address(ctx->hostname, ctx->address, sizeof(ctx->address));
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Could not find IP address of %s\n", ctx->hostname);

      return -1;
    }

  DPRINTF(E_DBG, L_SCAN, "URL %s converted to hostname %s, port %d, path %s, IP %s\n", ctx->url, ctx->hostname, ctx->port, ctx->path, ctx->address);

  /* Set up connection */
  evcon = evhttp_connection_new(ctx->address, (unsigned short)ctx->port);
  if (!evcon)
    {
      DPRINTF(E_LOG, L_SCAN, "Could not create connection to %s\n", ctx->hostname);

      goto no_icy;
    }
  evhttp_connection_set_base(evcon, evbase_main);
  evhttp_connection_set_timeout(evcon, ICY_TIMEOUT);
  
  /* Set up request */
  req = evhttp_request_new(scan_icy_request_cb, mfi);
  if (!req)
    {
      DPRINTF(E_LOG, L_SCAN, "Could not create request to %s\n", ctx->hostname);

      evhttp_connection_free(evcon);
      goto no_icy;
    }
  req->header_cb = scan_icy_header_cb;
  evhttp_add_header(req->output_headers, "Host", ctx->hostname);
  evhttp_add_header(req->output_headers, "Icy-MetaData", "1");

  /* Make request */
  status = ICY_WAITING;
  ret = evhttp_make_request(evcon, req, EVHTTP_REQ_GET, ctx->path);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Could not make request to %s\n", ctx->hostname);

      status = ICY_DONE;
      evhttp_connection_free(evcon);
      goto no_icy;
    }
  DPRINTF(E_INFO, L_SCAN, "Making request to %s asking for ICY (Shoutcast) metadata\n", url);

  /* Can't count on server support for ICY metadata, so
   * while waiting for a reply make a parallel call to scan_metadata_ffmpeg.
   * This call will also determine final return value.
   */
 no_icy:
  ret = scan_metadata_ffmpeg(url, mfi);

  /* Wait till ICY request completes or we reach timeout */
  for (i = 0; (status == ICY_WAITING) && (i <= ICY_TIMEOUT); i++)
    sleep(1);

  free_icy(ctx);

  DPRINTF(E_DBG, L_SCAN, "scan_metadata_icy exiting with status %d after waiting %d sec\n", status, i);

  return ret;
}