Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Commit

Permalink
Added new virtualhost examples and functions
Browse files Browse the repository at this point in the history
- added examples/example_vhost.c which shows, in detail, how to use
  evhtp vhosts and aliases.

- Added new function evhtp_add_aliases(). Much like add_alias, this
  allows for a variable number of aliases to be added within one call.

- some error logging updates
  • Loading branch information
NathanFrench committed Nov 28, 2017
1 parent 5f62354 commit 3467382
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 17 deletions.
65 changes: 49 additions & 16 deletions evhtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2950,12 +2950,13 @@ htp__ssl_get_scache_ent_(evhtp_ssl_t * ssl, evhtp_ssl_data_t * sid, int sid_len,
evhtp_ssl_sess_t * sess;

connection = (evhtp_connection_t * )SSL_get_app_data(ssl);

if (connection->htp == NULL)
{
return NULL; /* We have no way of getting ssl_cfg */
}
cfg = connection->htp->ssl_cfg;
sess = NULL;
cfg = connection->htp->ssl_cfg;
sess = NULL;

if (cfg->scache_get)
{
Expand Down Expand Up @@ -4799,21 +4800,22 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_cfg_t * cfg)
SSL_CTX_set_options(htp->ssl_ctx, cfg->ssl_opts);

#ifndef OPENSSL_NO_ECDH
if (cfg->named_curve != NULL)
{
if (cfg->named_curve != NULL) {
EC_KEY * ecdh = NULL;
int nid = 0;

nid = OBJ_sn2nid(cfg->named_curve);
if (nid == 0)
{
fprintf(stderr, "ECDH initialization failed: unknown curve %s\n", cfg->named_curve);
nid = OBJ_sn2nid(cfg->named_curve);

if (nid == 0) {
log_error("ECDH initialization failed: unknown curve %s", cfg->named_curve);
}

ecdh = EC_KEY_new_by_curve_name(nid);
if (ecdh == NULL)
{
fprintf(stderr, "ECDH initialization failed for curve %s\n", cfg->named_curve);

if (ecdh == NULL) {
log_error("ECDH initialization failed for curve %s", cfg->named_curve);
}

SSL_CTX_set_tmp_ecdh(htp->ssl_ctx, ecdh);
EC_KEY_free(ecdh);
}
Expand All @@ -4825,6 +4827,7 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_cfg_t * cfg)
DH * dh;

fh = fopen(cfg->dhparams, "r");

if (fh != NULL)
{
dh = PEM_read_DHparams(fh, NULL, NULL, NULL);
Expand All @@ -4833,17 +4836,21 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_cfg_t * cfg)
SSL_CTX_set_tmp_dh(htp->ssl_ctx, dh);
DH_free(dh);
} else {
fprintf(stderr, "DH initialization failed: unable to parse file %s\n", cfg->dhparams);
log_error("DH initialization failed: unable to parse file %s", cfg->dhparams);
}

fclose(fh);
} else {
fprintf(stderr, "DH initialization failed: unable to open file %s\n", cfg->dhparams);
log_error("DH initialization failed: unable to open file %s", cfg->dhparams);
}
}
#endif /* OPENSSL_NO_DH */

if (cfg->ciphers != NULL) {
SSL_CTX_set_cipher_list(htp->ssl_ctx, cfg->ciphers);
if (SSL_CTX_set_cipher_list(htp->ssl_ctx, cfg->ciphers) == 0) {
log_error("set_cipher_list");
return -1;
}
}

SSL_CTX_load_verify_locations(htp->ssl_ctx, cfg->cafile, cfg->capath);
Expand All @@ -4858,8 +4865,7 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_cfg_t * cfg)
#endif
}

if (cfg->verify_depth)
{
if (cfg->verify_depth) {
SSL_CTX_set_verify_depth(htp->ssl_ctx, cfg->verify_depth);
}

Expand Down Expand Up @@ -5158,6 +5164,8 @@ evhtp_add_alias(evhtp_t * evhtp, const char * name)
return -1;
}

log_debug("Adding %s to aliases", name);

alias->alias = htp__strdup_(name);
evhtp_alloc_assert(alias->alias);

Expand All @@ -5166,6 +5174,31 @@ evhtp_add_alias(evhtp_t * evhtp, const char * name)
return 0;
}

int
evhtp_add_aliases(evhtp_t * htp, const char * name, ...) {
va_list argp;
size_t len;

if (evhtp_add_alias(htp, name) == -1) {
return -1;
}

va_start(argp, name);
{
const char * p;

while ((p = va_arg(argp, const char *)) != NULL) {
if (evhtp_add_alias(htp, p) == -1) {
log_error("Unable to add %s alias", p);
return -1;
}
}
}
va_end(argp);

return 0;
}

int
evhtp_add_vhost(evhtp_t * evhtp, const char * name, evhtp_t * vhost)
{
Expand Down
4 changes: 3 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_executable(test_vhost EXCLUDE_FROM_ALL test_vhost.c)
add_executable(test_client EXCLUDE_FROM_ALL test_client.c)
add_executable(test_query EXCLUDE_FROM_ALL test_query.c)
add_executable(test_perf EXCLUDE_FROM_ALL test_perf.c)
add_executable(example_vhost EXCLUDE_FROM_ALL example_vhost.c)

if (NOT EVHTP_DISABLE_EVTHR)
add_executable(test_proxy EXCLUDE_FROM_ALL test_proxy.c)
Expand All @@ -19,7 +20,8 @@ target_link_libraries(test_vhost evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})
target_link_libraries(test_client evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})
target_link_libraries(test_query evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})
target_link_libraries(test_perf evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})
target_link_libraries(example_vhost evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})

add_dependencies(examples test_extensive test_basic test_vhost test_client test_query test_perf)
add_dependencies(examples example_vhost test_extensive test_basic test_vhost test_client test_query test_perf)


127 changes: 127 additions & 0 deletions examples/example_vhost.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>

#include "internal.h"
#include "../log.h"
#include "evhtp/evhtp.h"

#define make_response(cb) do { \
evbuffer_add_printf(req->buffer_out, \
"%s = host:%s, arg:%s\n", cb, \
evhtp_header_find(req->headers_in, "Host"), \
(char *)arg); \
} while (0)


static void
vhost_1__callback_(evhtp_request_t * req, void * arg) {
/* these should be our callbacks for our evhtp.io hosts */
make_response("vhost_1__callback_");

evhtp_send_reply(req, EVHTP_RES_OK);
}

static void
vhost_2__callback_(evhtp_request_t * req, void * arg) {
/* these should be our callbacks for our google hosts */
make_response("vhost_2__callback_");

evhtp_send_reply(req, EVHTP_RES_OK);
}

int
main(int argc, char ** argv) {
struct event_base * evbase;
evhtp_t * htp;
evhtp_t * htp_vhost_1;
evhtp_t * htp_vhost_2;

evbase = event_base_new();
evhtp_alloc_assert(evbase);

/* allocate our main evhtp structure which vhosts are
* nested under
*/
htp = evhtp_new(evbase, NULL);
evhtp_alloc_assert(htp);

/* create a evhtp structure for vhost_1 specific hostnames,
* this will match hostnames for 'evhtp.io'
* */
htp_vhost_1 = evhtp_new(evbase, NULL);
evhtp_alloc_assert(htp_vhost_1);

/* running a get on /vhost for htp_vhost_1 will be different
* from htp_vhost_2 due to the hostname we set below.
*/
evhtp_set_cb(htp_vhost_1, "/vhost", vhost_1__callback_, "evhtp.io domains");

/* create a evhtp structure for vhost_2 specific hostnames,
* this will match hostnames for 'google.com'
*/
htp_vhost_2 = evhtp_new(evbase, NULL);
evhtp_alloc_assert(htp_vhost_2);

/* running a get on /vhost for http_vhost_2 will be different
* from the http_vhost_1 due to the hostname we set below.
*/
evhtp_set_cb(htp_vhost_2, "/vhost", vhost_2__callback_, "google.com domains");

/* if Host: evhtp.io is present, the callbacks fro htp_vhost_1 are
* used. We do this by adding the vhost_1 evhtp to the main htp ctx.
*/
evhtp_add_vhost(htp, "evhtp.io", htp_vhost_1);

/* now lets set some virtual host aliases to evhtp.io */
evhtp_add_aliases(htp_vhost_1,
"www.evhtp.io",
"web.evhtp.io", NULL);

/* If Host: google.com is present, the callbacks for htp_vhost_2 are
* used instead. This must be attached to the main htp context.
*/
evhtp_add_vhost(htp, "google.com", htp_vhost_2);

/* now add some virtual host aliases for google.com */
evhtp_add_aliases(htp_vhost_2,
"www.google.com",
"web.google.com",
"inbox.google.com", NULL);

/* we can also append a single alias to vhost_2 like this */
evhtp_add_alias(htp_vhost_2, "gmail.google.com");

/* now bind and listen on our server */
evhtp_bind_socket(htp, "127.0.0.1", 0, 128);

{
struct sockaddr_in sin;
socklen_t len = sizeof(struct sockaddr);
uint16_t port;

getsockname(
evconnlistener_get_fd(htp->server),
(struct sockaddr *)&sin, &len);

port = ntohs(sin.sin_port);

log_info("[[ try the following commands and you should see 'evhtp.io domains' ]]");
log_info("=====================================================================");
log_info("curl -H'Host: evhtp.io' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: www.evhtp.io' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: web.evhtp.io' http://127.0.0.1:%d/vhost", port);
log_info("========================================================================");
log_info("[[ try the following commands and you should see 'google.com domains' ]]");
log_info("========================================================================");
log_info("curl -H'Host: google.com' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: www.google.com' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: web.google.com' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: inbox.google.com' http://127.0.0.1:%d/vhost", port);
log_info("curl -H'Host: gmail.google.com' http://127.0.0.1:%d/vhost", port);
}

event_base_loop(evbase, 0);
} /* main */
14 changes: 14 additions & 0 deletions include/evhtp/evhtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,20 @@ EVHTP_EXPORT int evhtp_add_vhost(evhtp_t * evhtp, const char * name, evhtp_t * v
*/
EVHTP_EXPORT int evhtp_add_alias(evhtp_t * evhtp, const char * name);


/**
* @brief set a variable number of aliases in one call
* @reference evhtp_add_alias
* @note last argument must be NULL terminated
*
* @param evhtp
* @param name
* @param ...
*
* @return 0 on success, -1 on error
*/
EVHTP_EXPORT int evhtp_add_aliases(evhtp_t * evhtp, const char * name, ...);

/**
* @brief Allocates a new key/value structure.
*
Expand Down

0 comments on commit 3467382

Please sign in to comment.