Esempio n. 1
0
	URLConnection::~URLConnection()
	{
		if( mConnection )
		{
			evhttp_connection_free( mConnection );
		}
	}
Esempio n. 2
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");
}
Esempio n. 3
0
void IoEvConnection_free(IoEvConnection *self)
{	
	if (CONN(self))
	{
		evhttp_connection_free(CONN(self));
		IoObject_setDataPointer_(self, 0x0);
	}
}
 static void HHVM_METHOD(EventHttpRequest, closeConnection) {
     struct evhttp_connection *conn;
     EventHttpRequestResourceData *resource_data = FETCH_RESOURCE(this_, EventHttpRequestResourceData, s_event_http_request);
     conn = evhttp_request_get_connection((evhttp_request_t *) resource_data->getInternalResourceData());
     if(conn != NULL){
         evhttp_connection_free(conn);
     }
 }
Esempio n. 5
0
// destory S3HttpConnection
void s3http_connection_destroy (gpointer data)
{
    S3HttpConnection *con = (S3HttpConnection *) data;

    evhttp_connection_free (con->evcon);
    g_free (con->bucket_name);
    g_free (con);
}
Esempio n. 6
0
http_request::~http_request()
{

	if (m_cn)
		evhttp_connection_free(m_cn);

	if (m_buffer)
		evbuffer_free(m_buffer);

}
Esempio n. 7
0
void
timeoutcb(int fd, short what, void *arg)
{
	struct request *req =(struct request *)arg;

	/* re-establish the connection */
	evhttp_connection_free(req->evcon);
	req->evcon = mkhttp();

	complete(Timeout, req);
}
Esempio n. 8
0
LibEventHttpClient::~LibEventHttpClient() {
  clear();

  // reset all per-connection data structures
  if (m_conn) {
    evhttp_connection_free(m_conn);
  }
  if (m_eventBase) {
    event_base_free(m_eventBase);
  }
}
Esempio n. 9
0
void
timeoutcb(int fd, short what, void *arg)
{
    runner *run = (runner *)arg;
    debug("timeoutcb()\n");

    /* re-establish the connection */
    evhttp_connection_free(run->evcon);
    mkhttp(run);

    complete(Timeout, run);
}
Esempio n. 10
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");
}
Esempio n. 11
0
void
donecb(struct evhttp_request *req, void *arg)
{
	Call *call;
	Run *run;

	call = (Call*)arg;
	run = call->run;

	if(run->cachedconn == nil)
		run->cachedconn = call->conn;
	else
		evhttp_connection_free(call->conn);
}
Esempio n. 12
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");
}
Esempio n. 13
0
File: rpc.c Progetto: dyustc/searaft
static void http_request_done(struct evhttp_request *req, void *ctx) {
    struct client_rpc_callback_with_data *m_ctx = 
        (struct client_rpc_callback_with_data *)ctx;
    rpc_callback client_cb = m_ctx->cb;
    void *data = m_ctx->data;
    struct evhttp_connection *evcon = m_ctx->evcon;

    free(m_ctx);
    if(req == NULL) {
        client_cb(NULL, "(req=NULL) Unknown error occurred while remote procedure", data);
        return;
    }
    int res_code = evhttp_request_get_response_code(req);
    char *res_code_line = "Internal server error";
    printf("Got response for req %p with ctx = %p res_code = %d\n", 
            req, ctx, res_code);
    if(res_code == 500) {
        client_cb(NULL, res_code_line, data);
    } else if(res_code != HTTP_OK) {
        if(res_code == 0) {
            client_cb(NULL, "host not reachable", data);
        } else {
            client_cb(NULL, "communication error", data);
        }
    } else {
        char *json = read_req_buffer(req);
        if(!json) {
            client_cb(NULL, "(json=NULL) Unknown error occurred while remote procedure", data);
            return;
        }

        char *err = NULL;
        struct data_t *result = deserialize_result(json, &err);

        client_cb(result, err, data);

        if(result) {
            free_data_t(result);
        }
        if(err) {
            free(err);
        }
        if(json) {
            free(json);
        }
    }
    if(evcon) {
        evhttp_connection_free(evcon);
    }
}
Esempio n. 14
0
void
complete(int how, runner *run)
{
    struct request *req = run->req;
    save_request(how, run);

    evtimer_del(&req->timeoutev);
    debug("complete(): evtimer_del(&req->timeoutev);\n");

    /* enqueue the next one */
    if(params.count<0 || counts.conns<params.count){
        // re-scheduling is handled by the callback
        if(!qps_enabled()){
            if(!rpc_enabled() || req->evcon_reqno<params.rpc){
                dispatch(run, req->evcon_reqno + 1);
            }else{
                // re-establish the connection
                evhttp_connection_free(run->evcon);
                mkhttp(run);
                dispatch(run, 1);
            }
        }
    }else{
        /* We'll count this as a close. I guess that's ok. */
        evhttp_connection_free(req->evcon);
        if(--params.concurrency == 0){
            evtimer_del(&reportev);
            debug("last call to reportcb\n");
            reportcb(0, 0, nil);  /* issue a last report */
        }
    }

    if(!qps_enabled())
      // FIXME possible memory leak
      free(req);
}
Esempio n. 15
0
int
pubsub_to_pubsub_main(char *source_address, int source_port, void (*cb)(char *data, void *arg), void *cbarg)
{

    event_init();

    struct evhttp_connection *evhttp_source_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);
    }

    struct global_data *data;
    data = calloc(1, sizeof(*data));
    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");
        evhttp_connection_free(evhttp_source_connection);
        return 1;
    }

    event_dispatch();
    evhttp_connection_free(evhttp_source_connection);
    fprintf(stdout, "EXITING\n");
    return 0;
}
Esempio n. 16
0
    void URLConnection::setAddress( const std::string& address, int port )
    ///
    /// Set the host address to be used for this request
    ///
    /// @param address
    ///     Host Address
    ///
    /// @param port
    ///     Host Port
    ///
    {
		if( mConnection )
		{
			evhttp_connection_free( mConnection );
		}
        mConnection = evhttp_connection_base_new(mEventBase, NULL, address.c_str(), port);
    }
void http_request_free(struct http_request_get *http_req_get, int req_get_flag)
{
    evhttp_connection_free(http_req_get->cn);
    evhttp_uri_free(http_req_get->uri);
    if (req_get_flag == REQUEST_GET_FLAG) {
        free(http_req_get);
    } else if(req_get_flag == REQUEST_POST_FLAG) {
        struct http_request_post *http_req_post = (struct http_request_post*)http_req_get;
        if (http_req_post->content_type) {
            free(http_req_post->content_type);
        }
        if (http_req_post->post_data) {
            free(http_req_post->post_data);
        }
        free(http_req_post);
    }
    http_req_get = NULL;
}
Esempio n. 18
0
void EvHttpSyncClient::close()
{
    FX_DEBUG("Close client");
    if (m_pConn)
    {
        evhttp_connection_free(m_pConn);
        m_pConn = NULL;
    }

    if (m_evbase && m_bOwnEventBase) 
    {
        event_base_loopbreak(m_evbase);
        event_base_free(m_evbase);
    }
    m_evbase = NULL;

    m_lastState = ST_DISCONNECTED;
    m_pLastRequest = NULL;
}
Esempio n. 19
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());
}
Esempio n. 20
0
TEvhttpClientChannel::~TEvhttpClientChannel() {
  if (conn_ != NULL) {
    evhttp_connection_free(conn_);
  }
}
Esempio n. 21
0
/* public functions */
int upnpc_init(upnpc_t * p, struct event_base * base, const char * multicastif,
               upnpc_callback_fn ready_cb, upnpc_callback_fn soap_cb, void * cb_data)
{
	int opt = 1;
	struct sockaddr_in addr;

	if(p == NULL || base == NULL)
		return UPNPC_ERR_INVALID_ARGS;
	memset(p, 0, sizeof(upnpc_t)); /* clean everything */
	p->base = base;
	p->ready_cb = ready_cb;
	p->soap_cb = soap_cb;
	p->cb_data = cb_data;
	p->ttl = 2;
	/* open the socket for SSDP */
	p->ssdp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(p->ssdp_socket < 0) {
		return UPNPC_ERR_SOCKET_FAILED;
	}
	/* set multicast TTL */
	if(setsockopt(p->ssdp_socket, IPPROTO_IP, IP_MULTICAST_TTL, &p->ttl, sizeof(p->ttl) < 0))
	{
		/* not a fatal error */
		debug_printf("setsockopt(%d, ..., IP_MULTICAST_TTL, ...) FAILED\n", p->ssdp_socket);
	}
	/* set REUSEADDR */
#ifdef _WIN32
	if(setsockopt(p->ssdp_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0) {
#else /* _WIN32 */
	if(setsockopt(p->ssdp_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
#endif /* _WIN32 */
		/* non fatal error ! */
		debug_printf("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ...) FAILED\n", p->ssdp_socket);
	}
	if(evutil_make_socket_nonblocking(p->ssdp_socket) < 0) {
		debug_printf("evutil_make_socket_nonblocking FAILED\n");
	}

	/* receive address */
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	/*addr.sin_port = htons(SSDP_PORT);*/

	if(multicastif) {
		struct in_addr mc_if;
		mc_if.s_addr = inet_addr(multicastif);
    	addr.sin_addr.s_addr = mc_if.s_addr;
		if(setsockopt(p->ssdp_socket, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
			PRINT_SOCKET_ERROR("setsockopt");
			/* non fatal error ! */
		}
	}

	/* bind the socket to the ssdp address in order to receive responses */
	if(bind(p->ssdp_socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0) {
		close(p->ssdp_socket);
		return UPNPC_ERR_BIND_FAILED;
	}
	return UPNPC_OK;
}

int upnpc_start(upnpc_t * p)
{
	struct timeval timeout;
	if(p == NULL || p->base == NULL)
		return UPNPC_ERR_INVALID_ARGS;
	/* event on SSDP */
	p->ev_ssdp_recv = event_new(p->base, p->ssdp_socket,
	                         EV_READ|EV_PERSIST,
	                         (event_callback_fn)upnpc_receive_and_parse_ssdp, p);
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;
	if(event_add(p->ev_ssdp_recv, &timeout)) {
		debug_printf("event_add FAILED\n");
	}
	p->ev_ssdp_writable = event_new(p->base, p->ssdp_socket,
	                             EV_WRITE,
	                             (event_callback_fn)upnpc_send_ssdp_msearch, p);
	if(event_add(p->ev_ssdp_writable, NULL)) {
		debug_printf("event_add FAILED\n");
	}
	return UPNPC_OK;
}

int upnpc_set_local_address(upnpc_t * p, const char * address, uint16_t port)
{
	if(!p || !address) return UPNPC_ERR_INVALID_ARGS;
	p->local_address = strdup(address);	/* TODO check error */
	p->local_port = port;
	return UPNPC_OK;
}

#ifdef ENABLE_UPNP_EVENTS
int upnpc_set_event_callback(upnpc_t * p, upnpc_event_callback_fn cb)
{
	if(!p || !cb) return UPNPC_ERR_INVALID_ARGS;
	p->value_changed_cb = cb;
	return UPNPC_OK;
}
#endif /* ENABLE_UPNP_EVENTS */

static void upnpc_device_finalize(upnpc_device_t * d)
{
	d->state = 0;
	free(d->root_desc_location);
	d->root_desc_location = NULL;
	free(d->control_cif_url);
	d->control_cif_url = NULL;
	free(d->event_cif_url);
	d->event_cif_url = NULL;
	free(d->cif_service_type);
	d->cif_service_type = NULL;
	free(d->control_conn_url);
	d->control_conn_url = NULL;
	free(d->event_conn_url);
	d->event_conn_url = NULL;
	free(d->conn_service_type);
	d->conn_service_type = NULL;
	if(d->desc_conn) {
		evhttp_connection_free(d->desc_conn);
		d->desc_conn = NULL;
	}
	if(d->soap_conn) {
		evhttp_connection_free(d->soap_conn);
		d->soap_conn = NULL;
	}
	ClearNameValueList(&d->soap_response_data);
#ifdef ENABLE_UPNP_EVENTS
	free(d->event_conn_sid);
	d->event_conn_sid = NULL;
#endif /* ENABLE_UPNP_EVENTS */
}
Esempio n. 22
0
int
http_client_request(struct http_client_ctx *ctx)
{
  struct evhttp_connection *evcon;
  struct evhttp_request *req;
  struct evkeyvalq *headers;
  char hostname[PATH_MAX];
  char path[PATH_MAX];
  char s[PATH_MAX];
  int port;
  int ret;

  ctx->ret = -1;

  av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), ctx->url);
  if (strlen(hostname) == 0)
    {
      DPRINTF(E_LOG, L_HTTP, "Error extracting hostname from URL: %s\n", ctx->url);

      return ctx->ret;
    }

  if (port <= 0)
    snprintf(s, PATH_MAX, "%s", hostname);
  else
    snprintf(s, PATH_MAX, "%s:%d", hostname, port);

  if (port <= 0)
    port = 80;

  if (strlen(path) == 0)
    {
      path[0] = '/';
      path[1] = '\0';
    }

  ctx->evbase = event_base_new();
  if (!ctx->evbase)
    {
      DPRINTF(E_LOG, L_HTTP, "Could not create or find http client event base\n");

      return ctx->ret;
    }

  evcon = evhttp_connection_base_new(ctx->evbase, NULL, hostname, (unsigned short)port);
  if (!evcon)
    {
      DPRINTF(E_LOG, L_HTTP, "Could not create connection to %s\n", hostname);

      event_base_free(ctx->evbase);
      return ctx->ret;
    }

  evhttp_connection_set_timeout(evcon, HTTP_CLIENT_TIMEOUT);
  
  /* Set up request */
  req = evhttp_request_new(request_cb, ctx);
  if (!req)
    {
      DPRINTF(E_LOG, L_HTTP, "Could not create request to %s\n", hostname);

      evhttp_connection_free(evcon);
      event_base_free(ctx->evbase);
      return ctx->ret;
    }

#ifndef HAVE_LIBEVENT2_OLD
  if (ctx->headers_only)
    evhttp_request_set_header_cb(req, request_header_cb);
#endif

  headers = evhttp_request_get_output_headers(req);
  evhttp_add_header(headers, "Host", s);
  evhttp_add_header(headers, "Content-Length", "0");
  evhttp_add_header(headers, "User-Agent", "forked-daapd/" VERSION);
  evhttp_add_header(headers, "Icy-MetaData", "1");

  /* Make request */
  DPRINTF(E_INFO, L_HTTP, "Making request for http://%s%s\n", s, path);

  ret = evhttp_make_request(evcon, req, EVHTTP_REQ_GET, path);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_HTTP, "Error making request for http://%s%s\n", s, path);

      evhttp_connection_free(evcon);
      event_base_free(ctx->evbase);
      return ctx->ret;
    }

  event_base_dispatch(ctx->evbase);

  evhttp_connection_free(evcon);
  event_base_free(ctx->evbase);

  return ctx->ret;
}
Esempio n. 23
0
int
main(int argc, char **argv)
{
	int r;

	struct evhttp_uri *http_uri = NULL;
	const char *url = NULL, *data_file = NULL;
	const char *crt = "/etc/ssl/certs/ca-certificates.crt";
	const char *scheme, *host, *path, *query;
	char uri[256];
	int port;
	int retries = 0;
	int timeout = -1;

	SSL_CTX *ssl_ctx = NULL;
	SSL *ssl = NULL;
	struct bufferevent *bev;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req;
	struct evkeyvalq *output_headers;
	struct evbuffer *output_buffer;

	int i;
	int ret = 0;
	enum { HTTP, HTTPS } type = HTTP;

	for (i = 1; i < argc; i++) {
		if (!strcmp("-url", argv[i])) {
			if (i < argc - 1) {
				url = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-crt", argv[i])) {
			if (i < argc - 1) {
				crt = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-ignore-cert", argv[i])) {
			ignore_cert = 1;
		} else if (!strcmp("-data", argv[i])) {
			if (i < argc - 1) {
				data_file = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-retries", argv[i])) {
			if (i < argc - 1) {
				retries = atoi(argv[i + 1]);
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-timeout", argv[i])) {
			if (i < argc - 1) {
				timeout = atoi(argv[i + 1]);
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-help", argv[i])) {
			syntax();
			goto error;
		}
	}

	if (!url) {
		syntax();
		goto error;
	}

#ifdef _WIN32
	{
		WORD wVersionRequested;
		WSADATA wsaData;
		int err;

		wVersionRequested = MAKEWORD(2, 2);

		err = WSAStartup(wVersionRequested, &wsaData);
		if (err != 0) {
			printf("WSAStartup failed with error: %d\n", err);
			goto error;
		}
	}
#endif // _WIN32

	http_uri = evhttp_uri_parse(url);
	if (http_uri == NULL) {
		err("malformed url");
		goto error;
	}

	scheme = evhttp_uri_get_scheme(http_uri);
	if (scheme == NULL || (strcasecmp(scheme, "https") != 0 &&
	                       strcasecmp(scheme, "http") != 0)) {
		err("url must be http or https");
		goto error;
	}

	host = evhttp_uri_get_host(http_uri);
	if (host == NULL) {
		err("url must have a host");
		goto error;
	}

	port = evhttp_uri_get_port(http_uri);
	if (port == -1) {
		port = (strcasecmp(scheme, "http") == 0) ? 80 : 443;
	}

	path = evhttp_uri_get_path(http_uri);
	if (strlen(path) == 0) {
		path = "/";
	}

	query = evhttp_uri_get_query(http_uri);
	if (query == NULL) {
		snprintf(uri, sizeof(uri) - 1, "%s", path);
	} else {
		snprintf(uri, sizeof(uri) - 1, "%s?%s", path, query);
	}
	uri[sizeof(uri) - 1] = '\0';

#if OPENSSL_VERSION_NUMBER < 0x10100000L
	// Initialize OpenSSL
	SSL_library_init();
	ERR_load_crypto_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
#endif

	/* This isn't strictly necessary... OpenSSL performs RAND_poll
	 * automatically on first use of random number generator. */
	r = RAND_poll();
	if (r == 0) {
		err_openssl("RAND_poll");
		goto error;
	}

	/* Create a new OpenSSL context */
	ssl_ctx = SSL_CTX_new(SSLv23_method());
	if (!ssl_ctx) {
		err_openssl("SSL_CTX_new");
		goto error;
	}

#ifndef _WIN32
	/* TODO: Add certificate loading on Windows as well */

	/* Attempt to use the system's trusted root certificates.
	 * (This path is only valid for Debian-based systems.) */
	if (1 != SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL)) {
		err_openssl("SSL_CTX_load_verify_locations");
		goto error;
	}
	/* Ask OpenSSL to verify the server certificate.  Note that this
	 * does NOT include verifying that the hostname is correct.
	 * So, by itself, this means anyone with any legitimate
	 * CA-issued certificate for any website, can impersonate any
	 * other website in the world.  This is not good.  See "The
	 * Most Dangerous Code in the World" article at
	 * https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html
	 */
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
	/* This is how we solve the problem mentioned in the previous
	 * comment.  We "wrap" OpenSSL's validation routine in our
	 * own routine, which also validates the hostname by calling
	 * the code provided by iSECPartners.  Note that even though
	 * the "Everything You've Always Wanted to Know About
	 * Certificate Validation With OpenSSL (But Were Afraid to
	 * Ask)" paper from iSECPartners says very explicitly not to
	 * call SSL_CTX_set_cert_verify_callback (at the bottom of
	 * page 2), what we're doing here is safe because our
	 * cert_verify_callback() calls X509_verify_cert(), which is
	 * OpenSSL's built-in routine which would have been called if
	 * we hadn't set the callback.  Therefore, we're just
	 * "wrapping" OpenSSL's routine, not replacing it. */
	SSL_CTX_set_cert_verify_callback(ssl_ctx, cert_verify_callback,
					  (void *) host);
#else // _WIN32
	(void)crt;
#endif // _WIN32

	// Create event base
	base = event_base_new();
	if (!base) {
		perror("event_base_new()");
		goto error;
	}

	// Create OpenSSL bufferevent and stack evhttp on top of it
	ssl = SSL_new(ssl_ctx);
	if (ssl == NULL) {
		err_openssl("SSL_new()");
		goto error;
	}

	#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	// Set hostname for SNI extension
	SSL_set_tlsext_host_name(ssl, host);
	#endif

	if (strcasecmp(scheme, "http") == 0) {
		bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
	} else {
		type = HTTPS;
		bev = bufferevent_openssl_socket_new(base, -1, ssl,
			BUFFEREVENT_SSL_CONNECTING,
			BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
	}

	if (bev == NULL) {
		fprintf(stderr, "bufferevent_openssl_socket_new() failed\n");
		goto error;
	}

	bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);

	// For simplicity, we let DNS resolution block. Everything else should be
	// asynchronous though.
	evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev,
		host, port);
	if (evcon == NULL) {
		fprintf(stderr, "evhttp_connection_base_bufferevent_new() failed\n");
		goto error;
	}

	if (retries > 0) {
		evhttp_connection_set_retries(evcon, retries);
	}
	if (timeout >= 0) {
		evhttp_connection_set_timeout(evcon, timeout);
	}

	// Fire off the request
	req = evhttp_request_new(http_request_done, bev);
	if (req == NULL) {
		fprintf(stderr, "evhttp_request_new() failed\n");
		goto error;
	}

	output_headers = evhttp_request_get_output_headers(req);
	evhttp_add_header(output_headers, "Host", host);
	evhttp_add_header(output_headers, "Connection", "close");

	if (data_file) {
		/* NOTE: In production code, you'd probably want to use
		 * evbuffer_add_file() or evbuffer_add_file_segment(), to
		 * avoid needless copying. */
		FILE * f = fopen(data_file, "rb");
		char buf[1024];
		size_t s;
		size_t bytes = 0;

		if (!f) {
			syntax();
			goto error;
		}

		output_buffer = evhttp_request_get_output_buffer(req);
		while ((s = fread(buf, 1, sizeof(buf), f)) > 0) {
			evbuffer_add(output_buffer, buf, s);
			bytes += s;
		}
		evutil_snprintf(buf, sizeof(buf)-1, "%lu", (unsigned long)bytes);
		evhttp_add_header(output_headers, "Content-Length", buf);
		fclose(f);
	}

	r = evhttp_make_request(evcon, req, data_file ? EVHTTP_REQ_POST : EVHTTP_REQ_GET, uri);
	if (r != 0) {
		fprintf(stderr, "evhttp_make_request() failed\n");
		goto error;
	}

	event_base_dispatch(base);
	goto cleanup;

error:
	ret = 1;
cleanup:
	if (evcon)
		evhttp_connection_free(evcon);
	if (http_uri)
		evhttp_uri_free(http_uri);
	event_base_free(base);

	if (ssl_ctx)
		SSL_CTX_free(ssl_ctx);
	if (type == HTTP && ssl)
		SSL_free(ssl);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	EVP_cleanup();
	ERR_free_strings();

#ifdef EVENT__HAVE_ERR_REMOVE_THREAD_STATE
	ERR_remove_thread_state(NULL);
#else
	ERR_remove_state(0);
#endif
	CRYPTO_cleanup_all_ex_data();

	sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
#endif /*OPENSSL_VERSION_NUMBER < 0x10100000L */

#ifdef _WIN32
	WSACleanup();
#endif

	return ret;
}
Esempio n. 24
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);
}
Esempio n. 25
0
/* Thread: main (pairing) */
static void
pairing_request_cb(struct evhttp_request *req, void *arg)
{
  struct remote_info *ri;
  uint8_t *response;
  char guid[17];
  int len;
  int i;
  int ret;

  ri = (struct remote_info *)arg;

  if (!req)
    goto cleanup;

  if (req->response_code != HTTP_OK)
    {
      DPRINTF(E_LOG, L_REMOTE, "Pairing failed with Remote %s/%s, HTTP response code %d\n", ri->pi.remote_id, ri->pi.name, req->response_code);

      goto cleanup;
    }

  if (EVBUFFER_LENGTH(req->input_buffer) < 8)
    {
      DPRINTF(E_LOG, L_REMOTE, "Remote %s/%s: pairing response too short\n", ri->pi.remote_id, ri->pi.name);

      goto cleanup;
    }

  response = EVBUFFER_DATA(req->input_buffer);

  if ((response[0] != 'c') || (response[1] != 'm') || (response[2] != 'p') || (response[3] != 'a'))
    {
      DPRINTF(E_LOG, L_REMOTE, "Remote %s/%s: unknown pairing response, expected cmpa\n", ri->pi.remote_id, ri->pi.name);

      goto cleanup;
    }

  len = (response[4] << 24) | (response[5] << 16) | (response[6] << 8) | (response[7]);
  if (EVBUFFER_LENGTH(req->input_buffer) < 8 + len)
    {
      DPRINTF(E_LOG, L_REMOTE, "Remote %s/%s: pairing response truncated (got %d expected %d)\n",
	      ri->pi.remote_id, ri->pi.name, (int)EVBUFFER_LENGTH(req->input_buffer), len + 8);

      goto cleanup;
    }

  response += 8;

  for (; len > 0; len--, response++)
    {
      if ((response[0] != 'c') || (response[1] != 'm') || (response[2] != 'p') || (response[3] != 'g'))
	continue;
      else
	{
	  len -= 8;
	  response += 8;

	  break;
	}
    }

  if (len < 8)
    {
      DPRINTF(E_LOG, L_REMOTE, "Remote %s/%s: cmpg truncated in pairing response\n", ri->pi.remote_id, ri->pi.name);

      goto cleanup;
    }

  for (i = 0; i < 8; i++)
    sprintf(guid + (2 * i), "%02X", response[i]);

  ri->pi.guid = strdup(guid);

  DPRINTF(E_INFO, L_REMOTE, "Pairing succeeded with Remote '%s' (id %s), GUID: %s\n", ri->pi.name, ri->pi.remote_id, guid);

  ret = db_pairing_add(&ri->pi);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_REMOTE, "Failed to register pairing!\n");

      goto cleanup;
    }

 cleanup:
  evhttp_connection_free(ri->evcon);
  free_remote(ri);
}
Esempio n. 26
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;
}
Esempio n. 27
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");
}
Esempio n. 28
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");
}
Esempio n. 29
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;
}
 virtual void TearDown() {
   evhttp_connection_free(connection_);
   //evhttp_request_free(request_);
   evdns_base_free(dnsbase_, 0);
   event_base_free(base_);
 }