Пример #1
0
int
pubsub_to_pubsub_main_path(char *source_address, int source_port, char *target_address, int target_port, int (*cb)(char *data, struct evbuffer *evb, char **target_path, void *arg), void *cbarg, char *target_path)
{

    event_init();

    struct evhttp_connection *evhttp_source_connection = NULL;
    struct evhttp_connection *evhttp_target_connection = NULL;
    struct evhttp_request *evhttp_source_request = NULL;
    
    fprintf(stdout, "connecting to http://%s:%d/sub\n", source_address, source_port);
    evhttp_source_connection = evhttp_connection_new(source_address, source_port);
    if (evhttp_source_connection == NULL) {
        fprintf(stdout, "FAILED CONNECT TO SOURCE %s:%d\n", source_address, source_port);
        exit(1);
    }

    fprintf(stdout, "connecting to http://%s:%d/pub\n", target_address, target_port);
    evhttp_target_connection = evhttp_connection_new(target_address, target_port);
    if (evhttp_target_connection == NULL) {
        fprintf(stdout, "FAILED CONNECT TO TARGET %s:%d\n", target_address, target_port);
        exit(1);
    }

    struct global_data *data;
    data = calloc(1, sizeof(*data));
    data->evhttp_target_connection = evhttp_target_connection;
    data->target_address = target_address;
    data->target_path = calloc(4096, sizeof(char *));
    strcpy(data->target_path, target_path);
    data->cb = cb;
    data->cbarg = cbarg;

    evhttp_source_request = evhttp_request_new(http_chunked_request_done, data);
    evhttp_add_header(evhttp_source_request->output_headers, "Host", source_address);
    evhttp_request_set_chunked_cb(evhttp_source_request, source_callback);

    if (evhttp_make_request(evhttp_source_connection, evhttp_source_request, EVHTTP_REQ_GET, "/sub") == -1) {
        fprintf(stdout, "FAILED make_request to source\n");
        exit(1);
    }

    event_dispatch();
    evhttp_connection_free(evhttp_source_connection);
    evhttp_connection_free(evhttp_target_connection);
    fprintf(stdout, "EXITING\n");

    return 0;
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
static void
http_close_detection(int with_delay)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	
	test_ok = 0;
	fprintf(stdout, "Testing Connection Close Detection%s: ",
		with_delay ? " (with delay)" : "");

	http = http_setup(&port, NULL);

	/* 2 second timeout */
	evhttp_set_timeout(http, 2);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	delayed_client = evcon;

	/*
	 * At this point, we want to schedule a request to the HTTP
	 * server using our make request method.
	 */

	req = evhttp_request_new(close_detect_cb, evcon);

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon,
	    req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	if (test_ok != 1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* at this point, the http server should have no connection */
	if (TAILQ_FIRST(&http->connections) != NULL) {
		fprintf(stdout, "FAILED (left connections)\n");
		exit(1);
	}

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	fprintf(stdout, "OK\n");
}
Пример #4
0
struct evhttp_connection *
mkconn(char *host, short port)
{
	struct evhttp_connection *conn;

	if((conn = evhttp_connection_new(host, port)) == nil)
		panic("evhttp_connection_new");
		
	return conn;
}
Пример #5
0
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);
}
Пример #6
0
static void
http_dispatcher_test(void)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;

	test_ok = 0;
	fprintf(stdout, "Testing HTTP Dispatcher: ");

	http = http_setup(&port, NULL);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* also bind to local host */
	evhttp_connection_set_local_address(evcon, "127.0.0.1");

	/*
	 * At this point, we want to schedule an HTTP GET request
	 * server using our make request method.
	 */

	req = evhttp_request_new(http_dispatcher_test_done, NULL);
	if (req == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");
	
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	if (test_ok != 1) {
		fprintf(stdout, "FAILED: %d\n", test_ok);
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
Пример #7
0
static void
http_post_test(void)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;

	test_ok = 0;
	fprintf(stdout, "Testing HTTP POST Request: ");

	http = http_setup(&port, NULL);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/*
	 * At this point, we want to schedule an HTTP POST request
	 * server using our make request method.
	 */

	req = evhttp_request_new(http_postrequest_done, NULL);
	if (req == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");
	evbuffer_add_printf(req->output_buffer, POST_DATA);
	
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	if (test_ok != 1) {
		fprintf(stdout, "FAILED: %d\n", test_ok);
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
Пример #8
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;
}
Пример #9
0
void
mkhttp(runner *run)
{
    struct evhttp_connection *evcon;

    evcon = evhttp_connection_new(http_hostname, http_port);
    if(evcon == nil)
        panic("evhttp_connection_new");

    evhttp_connection_set_closecb(evcon, &closecb, run);
    /*
        note: we manage our own per-request timeouts, since the underlying
        library does not give us enough error reporting fidelity
    */
    run->evcon = evcon;
}
Пример #10
0
static void
http_negative_content_length_test(void)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	
	test_ok = 0;
	fprintf(stdout, "Testing HTTP Negative Content Length: ");

	http = http_setup(&port, NULL);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/*
	 * At this point, we want to schedule a request to the HTTP
	 * server using our make request method.
	 */

	req = evhttp_request_new(http_request_bad, NULL);

	/* Cause the response to have a negative content-length */
	evhttp_add_header(req->output_headers, "X-Negative", "makeitso");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	evhttp_free(http);

	if (test_ok != 1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	fprintf(stdout, "OK\n");
}
Пример #11
0
struct evhttp_connection *
mkhttp()
{
	struct evhttp_connection *evcon;

	evcon = evhttp_connection_new(http_hostname, http_port);
	if(evcon == nil)
		panic("evhttp_connection_new");

	evhttp_connection_set_closecb(evcon, &closecb, nil);
	/*
		note: we manage our own per-request timeouts, since the underlying
		library does not give us enough error reporting fidelity
	*/

	/* also set some socket options manually. */


	return(evcon);
}
Пример #12
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());
}
Пример #13
0
END_TEST

#if HAVE_EVHTTP_H
START_TEST(test_http) {
    struct parent_msg msg = {};
    const char *errstr = NULL;
    extern char *http_host, *http_path;
    static struct event_base *base;
    struct evhttp *httpd;
    extern struct evhttp_request *lreq;
    extern struct evhttp_connection *evcon;
    extern int status;
    extern short http_port;
    int sock = -1;

    // check for ipv4 before running the test
    mark_point();
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	return;
    else
	close(sock);

    // this assumes libevent can connect to localhost
    // sounds silly, but I've seen it fail...
    http_host = "127.0.0.1";
    http_path = "/cgi-bin/test.cgi";
    event_set_log_callback(&fake_log_cb);

    mark_point();
    base = event_init();
    httpd = evhttp_new(base);
    for (http_port = 8080; http_port < 8090; http_port++) {
        if (evhttp_bind_socket(httpd, http_host, http_port) != -1)
	    break;
    }
    fail_unless (http_port < 8090, "failed to start httpd on %s", http_host);

    // If either of these two fail then we're screwed anyway
    mark_point();
    http_connect();

    mark_point();
    http_request(&msg, 0);

    mark_point();
    strlcpy(msg.name, "eth0", IFNAMSIZ);
    msg.proto = PROTO_CDP;
    msg.decode = (1 << PEER_HOSTNAME)|(1 << PEER_PORTNAME);
    msg.peer[PEER_HOSTNAME] = strdup("router");
    msg.peer[PEER_PORTNAME] = strdup("Fas'tEthernet42/64");
    http_request(&msg, 0);

    mark_point();
    errstr = "HTTP request failed";
    my_log(CRIT, "check");
    WRAP_FATAL_START();
    http_reply(lreq, NULL);
    WRAP_FATAL_END();
    fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
	"incorrect message logged: %s", check_wrap_errstr);

    mark_point();
    lreq->response_code = 200;
    http_reply(lreq, NULL);
    fail_unless (status == EXIT_SUCCESS,
	"incorrect exit status returned: %d", status);

    mark_point();
    lreq->response_code = 404;
    errstr = "HTTP error 404 received";
    my_log(CRIT, "check");
    http_reply(lreq, NULL);
    fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
	"incorrect message logged: %s", check_wrap_errstr);
    fail_unless (status == EXIT_FAILURE,
	"incorrect exit status returned: %d", status);

    mark_point();
    evhttp_connection_free(evcon);
    lreq = NULL;


    mark_point();
    errstr = "failed";
    my_log(CRIT, "check");
    evcon = evhttp_connection_new("256.256.256.256", 0);
    WRAP_FATAL_START();
    http_request(&msg, 0);
    WRAP_FATAL_END();
    fail_unless (strstr(check_wrap_errstr, errstr) != NULL,
	"incorrect message logged: %s", check_wrap_errstr);
    evhttp_connection_free(evcon);

    mark_point();
    errstr = "failed";
    my_log(CRIT, "check");
    evcon = evhttp_connection_new("localhost", 0);
    WRAP_FATAL_START();
    http_request(&msg, 0);
    http_dispatch();
    WRAP_FATAL_END();
    fail_unless (strstr(check_wrap_errstr, errstr) != NULL,
	"incorrect message logged: %s", check_wrap_errstr);

    mark_point();
    // free the active connection
    evhttp_connection_free(evcon);
    lreq = NULL;
    evcon = evhttp_connection_new(http_host, 80);
    http_dispatch();

    evhttp_free(httpd);
    event_base_free(base);
    peer_free(msg.peer);
}
Пример #14
0
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;
}
Пример #15
0
static void do_info(struct evhttp_request* req, void* userdata)
{
    // Check request method
    if(req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_HEAD)
    {
        evhttp_send_error(req, 405, "Method Not Allowed");
        return;
    }

    // Allocate userdata structure
    struct req_data* d;
    if(!(d = (struct req_data*) malloc(sizeof(struct req_data))))
    {
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): couldn't malloc req_data\n");
        return;
    }

    memset(d, 0, sizeof(struct req_data));
    d->req = req;

    // Parse url query parameters
    char * decoded_uri;
    if(!(decoded_uri = evhttp_decode_uri(req->uri)))
    {
        free_req_data(&d);
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): couldn't decode uri\n");
        return;
    }

    if(!(d->query_args = (struct evkeyvalq*) malloc(sizeof(struct evkeyvalq))))
    {
        free_req_data(&d);
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): couldn't malloc evkeyvalq\n");
        return;
    }

    memset(d->query_args, 0, sizeof(struct evkeyvalq));
    evhttp_parse_query(decoded_uri, d->query_args);
    free(decoded_uri);

    // find id field; build request
    
    const char* id = evhttp_find_header(d->query_args, "id");

    if(!id || strlen(id)>20)
    {
        free_req_data(&d);
        evhttp_send_error(req, 404, "Not Found");
        return;
    }

    struct evhttp_request* api_req;

    if(!(api_req = evhttp_request_new(got_api, d)))
    {
        free_req_data(&d);
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): couldn't alloc evhttp_request");
        return;
    }
    
    char api_url[64];
    sprintf(api_url, "/api/event/show/%s.xml", id);
    evhttp_add_header(api_req->output_headers, "host", "api.justin.tv");
    printf("%s\n", api_url);
    // issue request

    if(!(d->conn = evhttp_connection_new("api.justin.tv", 80)))
    {
        evhttp_request_free(api_req);
        free_req_data(&d);
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): couldn't alloc evhttp_connection\n");
        return;
    }

    if(evhttp_make_request(d->conn, api_req, EVHTTP_REQ_GET, api_url) == -1)
    {
        free_req_data(&d);
        evhttp_send_error(req, 500, "Internal Server Error");
        fprintf(stderr, "info.c:do_info(): error making api request\n");
    }
}
Пример #16
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;
}
Пример #17
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;

  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;
}
Пример #18
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;
}
Пример #19
0
static void
http_connection_test(int persistent)
{
	short port = -1;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	
	test_ok = 0;
	fprintf(stdout, "Testing Request Connection Pipeline %s: ",
	    persistent ? "(persistent)" : "");

	http = http_setup(&port, NULL);

	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/*
	 * At this point, we want to schedule a request to the HTTP
	 * server using our make request method.
	 */

	req = evhttp_request_new(http_request_done, NULL);

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	if (test_ok != 1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* try to make another request over the same connection */
	test_ok = 0;
	
	req = evhttp_request_new(http_request_done, NULL);

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Host", "somehost");

	/* 
	 * if our connections are not supposed to be persistent; request
	 * a close from the server.
	 */
	if (!persistent)
		evhttp_add_header(req->output_headers, "Connection", "close");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	/* make another request: request empty reply */
	test_ok = 0;
	
	req = evhttp_request_new(http_request_empty_done, NULL);

	/* Add the information that we care about */
	evhttp_add_header(req->output_headers, "Empty", "itis");

	/* We give ownership of the request to the connection */
	if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	event_dispatch();

	if (test_ok != 1) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	fprintf(stdout, "OK\n");
}
Пример #20
0
static void
http_chunked_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;
	struct timeval tv_start, tv_end;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	int i;

	test_ok = 0;
	fprintf(stdout, "Testing Chunked HTTP Reply: ");

	http = http_setup(&port, NULL);

	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, 
	    http_chunked_readcb, http_chunked_writecb,
	    http_chunked_errorcb, NULL);

	http_request =
	    "GET /chunked HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));

	evutil_gettimeofday(&tv_start, NULL);
	
	event_dispatch();

	evutil_gettimeofday(&tv_end, NULL);
	evutil_timersub(&tv_end, &tv_start, &tv_end);

	if (tv_end.tv_sec >= 1) {
		fprintf(stdout, "FAILED (time)\n");
		exit (1);
	}


	if (test_ok != 2) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* now try again with the regular connection object */
	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* make two requests to check the keepalive behavior */
	for (i = 0; i < 2; i++) {
		test_ok = 0;
		req = evhttp_request_new(http_chunked_request_done, NULL);

		/* Add the information that we care about */
		evhttp_add_header(req->output_headers, "Host", "somehost");

		/* We give ownership of the request to the connection */
		if (evhttp_make_request(evcon, req,
			EVHTTP_REQ_GET, "/chunked") == -1) {
			fprintf(stdout, "FAILED\n");
			exit(1);
		}

		event_dispatch();

		if (test_ok != 1) {
			fprintf(stdout, "FAILED\n");
			exit(1);
		}
	}

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	fprintf(stdout, "OK\n");
}