Beispiel #1
0
/*{{{ application_set_url*/
gboolean application_set_url (Application *app, const gchar *url)
{
    if (app->uri)
        evhttp_uri_free (app->uri);

    // check if URL contains HTTP or HTTPS
    if (strlen (url) < 4 || !strcasestr (url, "http") || strcasestr (url, "http") != url) {
        // XXX: check config and decide HTTP or HTTPS ?
        gchar *tmp;

        tmp = g_strdup_printf ("http://%s", url);
        app->uri = evhttp_uri_parse (tmp);
        g_free (tmp);
    } else
        app->uri = evhttp_uri_parse (url);


    if (!app->uri) {
        LOG_err (APP_LOG, " URL (%s) is not valid!", url);

        application_exit (app);
        return FALSE;
    }

    conf_set_string (app->conf, "s3.host", evhttp_uri_get_host (app->uri));
    conf_set_int (app->conf, "s3.port", uri_get_port (app->uri));
    conf_set_boolean (app->conf, "s3.ssl", uri_is_https (app->uri));

    return TRUE;
}
Beispiel #2
0
http_request::http_request(struct event_base *base, const char *url, enum evhttp_cmd_type type)
	: m_base(base), m_type(type), m_cn(NULL), m_req(NULL), m_buffer(NULL)
{
#if 0
	struct evhttp_uri *uri = evhttp_uri_parse(url);
	if (!uri)
		throw std::runtime_error("Can't parse uri");
	m_host = evhttp_uri_get_host(uri);
	m_port = evhttp_uri_get_port(uri);
	if (m_port == -1)
		m_port = 80;
	if (evhttp_uri_get_query(uri))
		m_query = evhttp_uri_get_query(uri);
	else
		m_query = "/";
	printf("query: \"%s\"\n", evhttp_uri_get_query(uri));
	evhttp_uri_free(uri);
#else
	if (!parse_uri(url))
		throw std::runtime_error("Can't parse uri");
#endif

	m_buffer = evbuffer_new();

//	renew_request(ctx);
}
/** Construct Function **/
void *http_request_new(struct event_base* base, const char *url, int req_get_flag, \
                       const char *content_type, const char* data)
{
    int len = 0;
    if (req_get_flag == REQUEST_GET_FLAG) {
        len = sizeof(struct http_request_get);
    } else if(req_get_flag == REQUEST_POST_FLAG) {
        len = sizeof(struct http_request_post);
    }
    
    struct http_request_get *http_req_get = calloc(1, len);
    http_req_get->uri = evhttp_uri_parse(url);
    //    print_uri_parts_info(http_req_get->uri);
    
    http_req_get->base = base;
    
    if (req_get_flag == REQUEST_POST_FLAG) {
        struct http_request_post *http_req_post = (struct http_request_post *)http_req_get;
        if (content_type == NULL) {
            content_type = HTTP_CONTENT_TYPE_URL_ENCODED;
        }
        http_req_post->content_type = strdup(content_type);
        
        if (data == NULL) {
            http_req_post->post_data = NULL;
        } else {
            http_req_post->post_data = strdup(data);
        }
    }
    
    return http_req_get;
}
Beispiel #4
0
int get_canonic_origin(const char* o, char *co, int sz)
{
	int ret = -1;

	if(o && o[0] && co) {
		co[0]=0;
		struct evhttp_uri *uri = evhttp_uri_parse(o);
		if(uri) {
			const char *scheme = evhttp_uri_get_scheme(uri);
			if(scheme && scheme[0]) {
				size_t schlen = strlen(scheme);
				if((schlen<(size_t)sz) && (schlen<STUN_MAX_ORIGIN_SIZE)) {
					const char *host = evhttp_uri_get_host(uri);
					if(host && host[0]) {
						char otmp[STUN_MAX_ORIGIN_SIZE+STUN_MAX_ORIGIN_SIZE];
						ns_bcopy(scheme,otmp,schlen);
						otmp[schlen]=0;

						{
							unsigned char *s = (unsigned char*)otmp;
							while(*s) {
								*s = (unsigned char)tolower((int)*s);
								++s;
							}
						}

						int port = evhttp_uri_get_port(uri);
						if(port<1) {
							port = get_default_protocol_port(otmp, schlen);
						}
						if(port>0)
							snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s:%d",host,port);
						else
							snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s",host);

						{
							unsigned char *s = (unsigned char*)otmp + schlen + 3;
							while(*s) {
								*s = (unsigned char)tolower((int)*s);
								++s;
							}
						}

						strncpy(co,otmp,sz);
						co[sz]=0;
						ret = 0;
					}
				}
			}
			evhttp_uri_free(uri);
		}
	}

	if(ret<0) {
		strncpy(co,o,sz);
		co[sz]=0;
	}

	return ret;
}
Beispiel #5
0
void
create_request(const char *url) {
    struct evhttp_uri *http_uri = NULL;
    const char *host;
    struct bufferevent *bev;
    struct evhttp_connection *evcon = NULL;
    struct evhttp_request *req;


    struct evkeyvalq *output_headers;

    http_uri = evhttp_uri_parse(url);
    if (NULL != http_uri) {
        host = evhttp_uri_get_host(http_uri);
        if (NULL != host) {

            bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
            evcon = evhttp_connection_base_bufferevent_new(base, dnsbase, bev, host, HTTP_PORT);
            if (NULL != evcon) {

                evhttp_connection_set_timeout(evcon, TIMEOUT);

                req = evhttp_request_new(http_request_done, bev);
                if (NULL != req) {
                    output_headers = evhttp_request_get_output_headers(req);

                    evhttp_add_header(output_headers, "Accept", "text/plain;q=0.8");
                    evhttp_add_header(output_headers, "Host", host);
                    evhttp_add_header(output_headers, "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
                    evhttp_add_header(output_headers, "Connection", "close");

                    if (0 == evhttp_make_request(evcon, req, EVHTTP_REQ_GET, url)) {
                        ++n_pending_requests;
                    } else {
                        evhttp_request_free(req);
                        fprintf(stderr, "evhttp_make_request() failed\n");
                    }
                    //evhttp_request_free(req);
                } else {
                    fprintf(stderr, "evhttp_request_new() failed\n");
                }

                //evhttp_connection_free(evcon);
            } else {
                fprintf(stderr, "evhttp_connection_base_bufferevent_new() failed\n");
            }


        } else {
            fprintf(stderr, "url must have a host %s\n", url);
        }
        evhttp_uri_free(http_uri);
    } else {
        fprintf(stderr, "malformed url %s\n", url);
    }

}
Beispiel #6
0
static void http_metrics_request_cb(struct evhttp_request *req, void *arg)
{
    struct http *http = (struct http *)arg;
    struct evbuffer *evb = NULL;
    const char *uri = NULL;
    struct evhttp_uri *decoded = NULL;
    const char *query;
    struct metric_history *mh;

    uri = evhttp_request_get_uri(req);

    /* Decode the URI */
    decoded = evhttp_uri_parse(uri);
    if (!decoded)
    {
        evhttp_send_error(req, HTTP_BADREQUEST, 0);
        goto exit;
    }

    query = evhttp_uri_get_query(decoded);

    printf("metrics request %s\n", query ? query : "null");

    /* This holds the content we're sending. */
    evb = evbuffer_new();

    mh = http_find_metrics_from_query(http->metrics, query);
    if (!mh)
    {
        printf("Series not found in query: %s\n", query);
        http_format_error_response(evb, "metric not found");
    }
    else
    {
        http_format_metric_response(evb,mh);
    }

    /* add headers */
    evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "application/json");

    /* send the response */
    evhttp_send_reply(req, 200, "OK", evb);

exit:
    if (decoded)
        evhttp_uri_free(decoded);

    if (evb)
        evbuffer_free(evb);
}
Beispiel #7
0
void gen_handler(struct evhttp_request *req, void *arg)
{
    DBG();
    /*struct evbuffer *evb = evbuffer_new(); */

    const char *uri = evhttp_request_get_uri(req);
    struct evhttp_uri *decoded_uri = NULL;
    const char *path;
    char *decoded_path;

    /* Decode the URI */
    decoded_uri = evhttp_uri_parse(uri);
    if (!decoded_uri) {
        reply_error(req, HTTP_BADREQUEST, "Bad URI: %s", uri);
        return;
    }

    path = evhttp_uri_get_path(decoded_uri);
    if (!path) {
        logging(LOG_INFO, "request path is nil, replace it as /");
        path = "/";
    }

    decoded_path = evhttp_uridecode(path, 0, NULL);

    uint64_t chunkid;
    char *slash = strchr(path + 1, '/');
    *slash = '\0';
    const char *op = path + 1;
    sscanf(slash + 1, "%" SCNu64, &chunkid);

    logging(LOG_INFO, "%s, %" PRIu64, op, chunkid);

    if (strcmp(op, "put") == 0) {
        write_chunk(chunkid, req);
    } else if (strcmp(op, "get") == 0) {
        read_chunk(chunkid, req);
    } else {
        reply_error(req, HTTP_NOTFOUND, "not found: %s", uri);
        return;
    }
}
/* Post Request Function */
void http_requset_post_cb(struct evhttp_request *req, void *arg)
{
    struct http_request_post *http_req_post = (struct http_request_post *)arg;
    switch(req->response_code)
    {
        case HTTP_OK:
        {
            struct evbuffer* buf = evhttp_request_get_input_buffer(req);
            size_t len = evbuffer_get_length(buf);
            printf("print the head info:\n");
            print_request_head_info(req->output_headers);
            
            printf("len:%zu  body size:%zu\n", len, req->body_size);
            char *tmp = malloc(len+1);
            memcpy(tmp, evbuffer_pullup(buf, -1), len);
            tmp[len] = '\0';
            printf("print the body:\n");
            printf("HTML BODY:%s\n", tmp);
            free(tmp);
            
            event_base_loopexit(http_req_post->base, 0);
            break;
        }
        case HTTP_MOVEPERM:
            printf("%s", "the uri moved permanently\n");
            break;
        case HTTP_MOVETEMP:
        {
            const char *new_location = evhttp_find_header(req->input_headers, "Location");
            struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
            evhttp_uri_free(http_req_post->uri);
            http_req_post->uri = new_uri;
            start_url_request((struct http_request_get *)http_req_post, REQUEST_POST_FLAG);
            return;
        }
            
        default:
            event_base_loopexit(http_req_post->base, 0);
            return;
    }
}
Beispiel #9
0
static void http_list_request_cb(struct evhttp_request *req, void *arg)
{
    // struct http *http = (struct http *)arg;
    struct evbuffer *evb = NULL;
    const char *uri = NULL;
    struct evhttp_uri *decoded = NULL;
    const char *query;

    uri = evhttp_request_get_uri(req);

    /* Decode the URI */
    decoded = evhttp_uri_parse(uri);
    if (!decoded)
    {
        evhttp_send_error(req, HTTP_BADREQUEST, 0);
        goto exit;
    }

    query = evhttp_uri_get_query(decoded);

    printf("list request %s\n", query ? query : "null");

    /* This holds the content we're sending. */
    evb = evbuffer_new();

    http_format_list_response(evb);

    /* add headers */
    evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "application/json");

    /* send the response */
    evhttp_send_reply(req, 200, "OK", evb);

exit:
    if (decoded)
        evhttp_uri_free(decoded);

    if (evb)
        evbuffer_free(evb);

}
Beispiel #10
0
static void on_srv_request (struct evhttp_request *req, void *ctx)
{
    struct evbuffer *in;
    gchar *dir = (gchar *) ctx;
    gchar *path, *decoded_path;
    const gchar *tmp;
    const char *uri = evhttp_request_get_uri(req);
    struct evhttp_uri *decoded = NULL;
    struct evbuffer *evb = NULL;
    char buf[BUFFER_SIZE];
    FILE *f;
    size_t bytes_read;
    size_t total_bytes = 0;

    in = evhttp_request_get_input_buffer (req);

    decoded = evhttp_uri_parse(uri);
    g_assert (decoded);
    tmp = evhttp_uri_get_path (decoded);
    g_assert (tmp);
    decoded_path = evhttp_uridecode(tmp, 0, NULL);

    evb = evbuffer_new();

    path = g_strdup_printf ("%s/%s", dir, decoded_path);
    LOG_debug (POOL_TEST, "SRV: received %d bytes. Req: %s, path: %s", evbuffer_get_length (in), evhttp_request_get_uri (req), path);

    f = fopen (path, "r");
    g_assert (f);

    while ((bytes_read = fread (buf, 1, BUFFER_SIZE, f)) > 0) {
        evbuffer_add (evb, buf, bytes_read);
        total_bytes += bytes_read;
    }
    evhttp_send_reply(req, 200, "OK", evb);

    LOG_debug (POOL_TEST, "Total bytes sent: %u", total_bytes);

    fclose(f);
    evbuffer_free(evb);
}
Beispiel #11
0
static void http_document_request_cb(struct evhttp_request *req, void *arg)
{
    struct evbuffer *evb = NULL;
    struct http *http = (struct http *) arg;
    const char *docroot = http->docroot;
    const char *uri = evhttp_request_get_uri(req);
    struct evhttp_uri *decoded = NULL;
    const char *path;
    char *decoded_path;
    char *whole_path = NULL;
    size_t len;
    int fd = -1;
    struct stat st;

    if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
    {
        evhttp_send_error(req, HTTP_BADREQUEST, 0);
        return;
    }

    printf("GET: %s\n",  uri);

    /* Decode the URI */
    decoded = evhttp_uri_parse(uri);
    if (!decoded)
    {
        evhttp_send_error(req, HTTP_BADREQUEST, 0);
        return;
    }

    /* Let's see what path the user asked for. */
    path = evhttp_uri_get_path(decoded);
    if (!path) path = "/";

    /* We need to decode it, to see what path the user really wanted. */
    decoded_path = evhttp_uridecode(path, 0, NULL);
    if (decoded_path == NULL)
        goto err;

    /* Don't allow any ".."s in the path, to avoid exposing stuff outside
     * of the docroot.  This test is both overzealous and underzealous:
     * it forbids aceptable paths like "/this/one..here", but it doesn't
     * do anything to prevent symlink following." */
    if (strstr(decoded_path, ".."))
        goto err;

    len = strlen(decoded_path) + strlen(docroot) + 2;
    if (!(whole_path = malloc(len)))
    {
        goto err;
    }

    snprintf(whole_path, len, "%s/%s", docroot, decoded_path);

    if (stat(whole_path, &st) < 0)
    {
        goto err;
    }

    /* This holds the content we're sending. */
    evb = evbuffer_new();

    if (S_ISDIR(st.st_mode))
    {
        /* TODO: send index.html if the request is for a directory */
        goto err;
    }
    else
    {
        /* Otherwise it's a file; add it to the buffer to get
         * sent via sendfile */
        const char *type = guess_content_type(decoded_path);
        if ((fd = open(whole_path, O_RDONLY)) < 0)
        {
            goto err;
        }

        if (fstat(fd, &st) < 0)
        {
            /* Make sure the length still matches, now that we
             * opened the file :/ */
            goto err;
        }

        evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", type);

        /* TODO: does this read the whole thing into memory??  well, we are only going to be
         * serving small files out of the static content directory, so its probably OK. */
        evbuffer_add_file(evb, fd, 0, st.st_size);
    }

    evhttp_send_reply(req, 200, "OK", evb);
    goto done;

err:
    evhttp_send_error(req, 404, "Document was not found");
    if (fd >= 0)
        close(fd);

done:
    if (decoded)
        evhttp_uri_free(decoded);

    if (decoded_path)
        free(decoded_path);

    if (whole_path)
        free(whole_path);

    if (evb)
        evbuffer_free(evb);
}
Beispiel #12
0
static
void
cd_StaticRequest (struct evhttp_request* request, CDServer* server)
{
    int         error   = HTTP_OK;
    const char* message = "OK";

    const char*        uri     = evhttp_request_get_uri(request);
    struct evhttp_uri* decoded = evhttp_uri_parse(uri);

    if (evhttp_request_get_command(request) != EVHTTP_REQ_GET) {
        error   = HTTP_BADMETHOD;
        message = "Invalid request method";

        goto end;
    }

    if (!decoded || strstr(evhttp_uri_get_path(decoded), "..")) {
        error   = HTTP_BADREQUEST;
        message = "Bad request";

        goto end;
    }

    DO {
        CDString* path = CD_CreateStringFromFormat("%s/%s", server->config->cache.httpd.root,
        evhttp_uri_get_path(decoded) ? evhttp_uri_get_path(decoded) : "index.html");

        if (CD_IsDirectory(CD_StringContent(path))) {
            CD_AppendCString(path, "/index.html");
        }

        if (!CD_IsReadable(CD_StringContent(path))) {
            error   = HTTP_NOTFOUND;
            message = "File not found";

            CD_DestroyString(path);

            goto end;
        }

        struct evbuffer* buffer = evbuffer_new();
        int              fd     = open(CD_StringContent(path), O_RDONLY);

        evhttp_add_header(evhttp_request_get_output_headers(request),
        "Content-Type", cd_GuessContentType(CD_StringContent(path)));

        evbuffer_add_file(buffer, fd, 0, CD_FileSize(CD_StringContent(path)));

        evhttp_send_reply(request, HTTP_OK, "OK", buffer);

        evbuffer_free(buffer);
        CD_DestroyString(path);
    }

end: {
        if (decoded) {
            evhttp_uri_free(decoded);
        }

        if (error != HTTP_OK) {
            evhttp_send_error(request, error, message);
        }
    }
}
Beispiel #13
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;
}
Beispiel #14
0
/**
 * Callback used for search request
 */
static void search_request_cb(struct evhttp_request *req, void *arg)
{
	std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();

	if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
	{
		// evbuffer_add_printf(evb, "Invalid query request! Needs to be GET\n");
		std::cerr << "Invalid query request! Needs to be GET" << std::endl;
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
	}
	else
	{
		struct evbuffer *evb = NULL;
		const char *uri = evhttp_request_get_uri(req);
		struct evhttp_uri *decoded = NULL;
		// const char *path = NULL;
		const char *query = NULL;
		// struct evkeyvalq *headers;
		// struct evkeyval *header;

		printf("Got a GET request for %s\n",  uri);

		// Decode the URI
		decoded = evhttp_uri_parse(uri);
		if (!decoded) {
			printf("It's not a good URI. Sending BADREQUEST\n");
			evhttp_send_error(req, HTTP_BADREQUEST, 0);
			return;
		}

		// path = evhttp_uri_get_path(decoded);
		// std::cout << path << std::endl;

		query = evhttp_uri_get_query(decoded);
		// std::cout << query << std::endl;

		// This holds the content we're sending
		evb = evbuffer_new();

		/*
		headers = evhttp_request_get_input_headers(req);
		for (header = headers->tqh_first; header;
			header = header->next.tqe_next) {
			printf("  %s: %s\n", header->key, header->value);
		}
		*/

		struct evkeyvalq params;	// create storage for your key->value pairs
		struct evkeyval *param;		// iterator

		int result = evhttp_parse_query_str(query, &params);

		if (result == 0)
		{
			std::string query;
			unsigned int start = 0;
			unsigned int offset = 0;

			for (param = params.tqh_first; param; param = param->next.tqe_next)
			{
				std::string key(param->key);
				std::string value(param->value);

				// std::cout << key << " " << value << std::endl;

				if (key.compare(zsearch::server::GET_SEARCH_QUERY_KEY) == 0)
				{
					query = value;
				}

				if (key.compare(zsearch::server::GET_SEARCH_START_KEY) == 0)
				{
					try
					{
						start = ZUtil::getUInt(value);
					}
					catch (const string& e)
					{
						// do nothing
					}
				}

				if (key.compare(zsearch::server::GET_SEARCH_OFFSET_KEY) == 0)
				{
					try
					{
						offset = ZUtil::getUInt(value);
					}
					catch (const string& e)
					{
						// do nothing
					}
				}
			}

			std::cout << "searching for " << query << " with start " << start << " and offset " << offset << std::endl;

			auto docIdSet = engine->search(query, start, offset);

			if (docIdSet.size())
			{
				for (auto docId : docIdSet)
				{
					evbuffer_add_printf(evb, "%u ", docId);
				}
			}

			evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/html");
			evhttp_send_reply(req, 200, "OK", evb);

		}
		else
		{
			evhttp_send_error(req, HTTP_BADREQUEST, 0);
		}

		evhttp_clear_headers(&params);


		if (decoded)
		{
			evhttp_uri_free(decoded);
		}

		if (evb)
		{
			evbuffer_free(evb);
		}
	}

	std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
	std::chrono::nanoseconds timeTaken = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0);
	std::cout << ZUtil::printTimeTaken(timeTaken) << std::endl;
}
int main (int argc, char *argv[])
{
    gchar *in_dir;
    GList *tmp;
    struct evhttp_uri *uri;
    struct timeval tv;

    log_level = LOG_debug;

    event_set_mem_functions (g_malloc, g_realloc, g_free);
    // init SSL libraries
    CRYPTO_set_mem_functions (g_malloc0, g_realloc, g_free);
    ENGINE_load_builtin_engines ();
    ENGINE_register_all_complete ();
    ERR_load_crypto_strings ();
    OpenSSL_add_all_algorithms ();

    SSL_load_error_strings ();
    SSL_library_init ();
    if (!RAND_poll ()) {
        fprintf(stderr, "RAND_poll() failed.\n");
        return 1;
    }
    g_random_set_seed (time (NULL));

    in_dir = g_dir_make_tmp (NULL, NULL);
    g_assert (in_dir);

    app = g_new0 (Application, 1);
    app->files_count = 10;
    app->evbase = event_base_new ();
	app->dns_base = evdns_base_new (app->evbase, 1);

        app->conf = conf_create ();
        conf_add_boolean (app->conf, "log.use_syslog", TRUE);
        
        conf_add_uint (app->conf, "auth.ttl", 85800);
        
        conf_add_int (app->conf, "pool.writers", 2);
        conf_add_int (app->conf, "pool.readers", 2);
        conf_add_int (app->conf, "pool.operations", 4);
        conf_add_uint (app->conf, "pool.max_requests_per_pool", 100);

        conf_add_int (app->conf, "connection.timeout", 20);
        conf_add_int (app->conf, "connection.retries", -1);

        conf_add_uint (app->conf, "filesystem.dir_cache_max_time", 5);
        conf_add_boolean (app->conf, "filesystem.cache_enabled", TRUE);
        conf_add_string (app->conf, "filesystem.cache_dir", "/tmp/hydrafs");
        conf_add_string (app->conf, "filesystem.cache_dir_max_size", "1Gb");

        conf_add_boolean (app->conf, "statistics.enabled", TRUE);
        conf_add_int (app->conf, "statistics.port", 8011);

    conf_add_string (app->conf, "auth.user", "test:tester");
    conf_add_string (app->conf, "auth.key", "testing");
    uri = evhttp_uri_parse ("https://10.0.0.104:8080/auth/v1.0");
    
    app->ssl_ctx = SSL_CTX_new (TLSv1_client_method ());
    
    app->stats = hfs_stats_srv_create (app);
    app->auth_client = auth_client_create (app, uri);

    app->http = http_client_create (app);

    // start server
     start_srv (app->evbase, in_dir);

    app->timeout = evtimer_new (app->evbase, on_output_timer, NULL);

    evutil_timerclear(&tv);
    tv.tv_sec = 0;
    tv.tv_usec = 500;
    event_add (app->timeout, &tv);

    event_base_dispatch (app->evbase);

    evhttp_uri_free (uri);
    event_del (app->timeout);
    event_free (app->timeout);

    evhttp_free (app->http_srv);
    auth_client_destroy (app->auth_client);

    evdns_base_free (app->dns_base, 0);
    event_base_free (app->evbase);

    conf_destroy (app->conf);
    g_free (app);

    return 0;
}
Beispiel #16
0
/* This callback gets invoked when we get any http request that doesn't match
 * any other callback.  Like any evhttp server callback, it has a simple job:
 * it must eventually call evhttp_send_error() or evhttp_send_reply().
 */
static void
send_document_cb(struct evhttp_request *req, void *arg)
{
	struct evbuffer *evb = NULL;
	const char *docroot = arg;
	const char *uri = evhttp_request_get_uri(req);
	struct evhttp_uri *decoded = NULL;
	const char *path;
	char *decoded_path;
	char *whole_path = NULL;
	size_t len;
	int fd = -1;
	struct stat st;

	if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
		dump_request_cb(req, arg);
		return;
	}

	printf("Got a GET request for <%s>\n",  uri);

	/* Decode the URI */
	decoded = evhttp_uri_parse(uri);
	if (!decoded) {
		printf("It's not a good URI. Sending BADREQUEST\n");
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
		return;
	}

	/* Let's see what path the user asked for. */
	path = evhttp_uri_get_path(decoded);
	if (!path) path = "/";

	/* We need to decode it, to see what path the user really wanted. */
	decoded_path = evhttp_uridecode(path, 0, NULL);
	if (decoded_path == NULL)
		goto err;
	/* Don't allow any ".."s in the path, to avoid exposing stuff outside
	 * of the docroot.  This test is both overzealous and underzealous:
	 * it forbids aceptable paths like "/this/one..here", but it doesn't
	 * do anything to prevent symlink following." */
	if (strstr(decoded_path, ".."))
		goto err;

	len = strlen(decoded_path)+strlen(docroot)+2;
	if (!(whole_path = malloc(len))) {
		perror("malloc");
		goto err;
	}
	evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);

	if (stat(whole_path, &st)<0) {
		goto err;
	}

	/* This holds the content we're sending. */
	evb = evbuffer_new();

	if (S_ISDIR(st.st_mode)) {
		/* If it's a directory, read the comments and make a little
		 * index page */
#ifdef WIN32
		HANDLE d;
		WIN32_FIND_DATAA ent;
		char *pattern;
		size_t dirlen;
#else
		DIR *d;
		struct dirent *ent;
#endif
		const char *trailing_slash = "";

		if (!strlen(path) || path[strlen(path)-1] != '/')
			trailing_slash = "/";

#ifdef WIN32
		dirlen = strlen(whole_path);
		pattern = malloc(dirlen+3);
		memcpy(pattern, whole_path, dirlen);
		pattern[dirlen] = '\\';
		pattern[dirlen+1] = '*';
		pattern[dirlen+2] = '\0';
		d = FindFirstFileA(pattern, &ent);
		free(pattern);
		if (d == INVALID_HANDLE_VALUE)
			goto err;
#else
		if (!(d = opendir(whole_path)))
			goto err;
#endif

		evbuffer_add_printf(evb, "<html>\n <head>\n"
		    "  <title>%s</title>\n"
		    "  <base href='%s%s%s'>\n"
		    " </head>\n"
		    " <body>\n"
		    "  <h1>%s</h1>\n"
		    "  <ul>\n",
		    decoded_path, /* XXX html-escape this. */
		    uri_root, path, /* XXX html-escape this? */
		    trailing_slash,
		    decoded_path /* XXX html-escape this */);
#ifdef WIN32
		do {
			const char *name = ent.cFileName;
#else
		while ((ent = readdir(d))) {
			const char *name = ent->d_name;
#endif
			evbuffer_add_printf(evb,
			    "    <li><a href=\"%s\">%s</a>\n",
			    name, name);/* XXX escape this */
#ifdef WIN32
		} while (FindNextFileA(d, &ent));
#else
		}
#endif
		evbuffer_add_printf(evb, "</ul></body></html>\n");
#ifdef WIN32
		FindClose(d);
#else
		closedir(d);
#endif
		evhttp_add_header(evhttp_request_get_output_headers(req),
		    "Content-Type", "text/html");
	} else {
static void static_list_request_cb(struct evhttp_request *req, void *arg)
{
	struct evbuffer *evb = NULL;
	struct evhttp_uri *decoded = NULL;
	const char *path;
	char *decoded_path;
	int fd = -1;
	struct stat st;
	char uri_root[512] = {0};
	struct evhttp_bound_socket *handle = (struct evhttp_bound_socket *)arg;

	size_t len;
	char *whole_path = NULL;

	const char *uri = evhttp_request_get_uri(req);
	get_uri_root(handle, uri_root, sizeof(uri_root));


	decoded = evhttp_uri_parse(uri);
	if (decoded == NULL) {
		LOG(LOG_ERROR, "%s", "evhttp_decode_uri error");
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
		exit(1);
	}

	path = evhttp_uri_get_path(decoded);
	if (!path) path = "/";

	decoded_path = evhttp_uridecode(path, 0, NULL);
	if (decoded_path == NULL)
		goto err;

	if (strstr(decoded_path, ".."))
		goto err;

	len = strlen(decoded_path)+strlen(docroot)+2;
	if (!(whole_path = malloc(len))) {
		perror("malloc");
		goto err;
	}
	evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);

	if (stat(whole_path, &st)<0) {
		goto err;
	}

	evb = evbuffer_new();

	if (S_ISDIR(st.st_mode)) {
		DIR *d;
		struct dirent *ent;

		const char *trailing_slash = "";

		if (!strlen(path) || path[strlen(path)-1] != '/')
			trailing_slash = "/";

		if (!(d = opendir(whole_path)))
			goto err;

		evbuffer_add_printf(evb, "<html>\n <head>\n"
		    "  <title>%s</title>\n"
		    "  <base href='%s%s%s'>\n"
		    " </head>\n"
		    " <body>\n"
		    "  <h1>%s</h1>\n"
		    "  <ul>\n",
		    decoded_path, /* XXX html-escape this. */
		    uri_root, path, /* XXX html-escape this? */
		    trailing_slash,
		    decoded_path /* XXX html-escape this */);

		while((ent = readdir(d))) {
			const char *name = ent->d_name;
			evbuffer_add_printf(evb, "    <li><a href=\"%s\">%s</a>\n", name, name);
			evbuffer_add_printf(evb, "</ul></body></html>\n");
		}
		closedir(d);
		evhttp_add_header(evhttp_request_get_output_headers(req), "Content-type", "text/html");
	} else {
		const char *type = guess_content_type(decoded_path);
		if ((fd = open(whole_path, O_RDONLY)) < 0) {
			perror("open");
			goto err;
		}

		if (fstat(fd, &st)<0) {
					/* Make sure the length still matches, now that we
					 * opened the file :/ */
					perror("fstat");
					goto err;
		}

		evhttp_add_header(evhttp_request_get_output_headers(req),
			    "Content-Type", type);

		evbuffer_add_file(evb, fd, 0, st.st_size);
	}

	evhttp_send_reply(req, HTTP_OK, "OK", evb);
	goto done;

err:
	evhttp_send_error(req, HTTP_NOTFOUND, "Document was not found");
	if (fd>=0)
		close(fd);

done:
	if (decoded)
		evhttp_uri_free(decoded);
	if (decoded_path)
		free(decoded_path);
	if (whole_path)
		free(whole_path);
	if (evb)
		evbuffer_free(evb);
}
Beispiel #18
0
/**
 * This callback gets invoked when we get any http request that doesn't match
 * any other callback.  Like any evhttp server callback, it has a simple job:
 * it must eventually call evhttp_send_error() or evhttp_send_reply().
 */
static void generic_request_cb(struct evhttp_request *req, void *arg)
{
	std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();

	// if this is not a GET request error out
	if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
	{
		std::cerr << "Invalid request! Needs to be GET" << std::endl;
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
	}
	else
	{
		struct evbuffer *evb = NULL;
		const char *docroot = (char *) arg;
		const char *uri = evhttp_request_get_uri(req);
		struct evhttp_uri *decoded = NULL;
		const char *path;
		char *decoded_path;
		char *whole_path = NULL;
		size_t len;
		int fd = -1;
		struct stat st;

		printf("Got a GET request for %s\n",  uri);

		// Decode the URI
		decoded = evhttp_uri_parse(uri);
		if (!decoded)
		{
			printf("It's not a good URI. Sending BADREQUEST\n");
			evhttp_send_error(req, HTTP_BADREQUEST, 0);
			return;
		}

		// Let's see what path the user asked for
		path = evhttp_uri_get_path(decoded);
		if (!path)
		{
			path = zsearch::server::ROOT.c_str();
		}

		// We need to decode it, to see what path the user really wanted
		decoded_path = evhttp_uridecode(path, 0, NULL);

		bool error = false;

		if (decoded_path == NULL)
		{
			error = true;
		}
		else
		{
			// This holds the content we're sending
			evb = evbuffer_new();

			// add headers
			evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/html");

			if (zsearch::server::POST_HTM.compare(decoded_path) == 0)
			{
				len = strlen(decoded_path)+strlen(docroot)+2;
				whole_path = (char *) malloc(len);

				if (whole_path)
				{
					evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);

					if (stat(whole_path, &st)<0)
					{
						error = true;
					}
					else
					{
						if ((fd = open(whole_path, O_RDONLY)) < 0)
						{
							perror("open");
							error = true;

						}
						else
						{
							if (fstat(fd, &st)<0)
							{
								// Make sure the length still matches, now that we opened the file :/
								perror("fstat");
								error = true;
							}
							else
							{
								evbuffer_add_file(evb, fd, 0, st.st_size);
							}
						}
					}
				}
				else
				{
					perror("malloc");
					error = true;
				}
			}
			else // if (ROOT.compare(decoded_path) == 0)
			{
				evbuffer_add_printf(evb, "Invalid request <br />\n");
				evbuffer_add_printf(evb, "%s to post data manually or %s to post via api<br />\n", zsearch::server::POST_HTM.c_str(), zsearch::server::INDEX_PATH.c_str());
				evbuffer_add_printf(evb, "%s to search <br />\n", zsearch::server::SEARCH_PATH.c_str());
				evbuffer_add_printf(evb, "%s to get document by id <br />\n", zsearch::server::DOC_PATH.c_str());
			}
		}

		if (error)
		{
			if (fd >= 0)
				close(fd);

			evhttp_send_error(req, 404, "Document not found.");
		}
		else
		{
			evhttp_send_reply(req, 200, "OK", evb);
		}

		if (decoded)
			evhttp_uri_free(decoded);
		if (decoded_path)
			free(decoded_path);
		if (whole_path)
			free(whole_path);
		if (evb)
			evbuffer_free(evb);
	}

	std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
	std::chrono::nanoseconds timeTaken = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0);
	std::cout << ZUtil::printTimeTaken(timeTaken) << std::endl;
}
Beispiel #19
0
/**
 * Callback used for doc request
 */
static void doc_request_cb(struct evhttp_request *req, void *arg)
{
	std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();

	if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
	{
		std::cerr << "Invalid query request! Needs to be GET" << std::endl;
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
	}
	else
	{
		struct evbuffer *evb = NULL;
		const char *uri = evhttp_request_get_uri(req);
		struct evhttp_uri *decoded = NULL;
		// const char *path = NULL;
		const char *query = NULL;

		printf("Got a GET request for %s\n",  uri);

		// Decode the URI
		decoded = evhttp_uri_parse(uri);

		if (!decoded)
		{
			printf("It's not a good URI. Sending BADREQUEST\n");
			evhttp_send_error(req, HTTP_BADREQUEST, 0);
			return;
		}

		// path = evhttp_uri_get_path(decoded);
		// std::cout << path << std::endl;

		query = evhttp_uri_get_query(decoded);
		// std::cout << query << std::endl;

		// This holds the content we're sending
		evb = evbuffer_new();

		struct evkeyvalq params;	// create storage for your key->value pairs
		struct evkeyval *param;		// iterator

		int result = evhttp_parse_query_str(query, &params);

		if (result == 0)
		{
			bool found = false;

			for (param = params.tqh_first; param; param = param->next.tqe_next)
			{
				std::string key(param->key);
				std::string value(param->value);

				// printf("%s %s\n", key.c_str(), value.c_str());

				if (key.compare(zsearch::server::DOC_ID_KEY) == 0)
				{
					unsigned int docId = 0;

					try
					{
						docId = ZUtil::getUInt(value);

						std::cout << "retrieving document " << value << std::endl;

						std::shared_ptr<IDocument> document = make_shared<DocumentImpl>();

						if (engine->getDoc(docId, document))
						{
							std::stringstream ss;
							document->write(ss);
							const std::string docStr = ss.str();
							// cout << docStr << endl;

							evbuffer_add(evb, docStr.data(), docStr.size());
							found = true;
						}
					}

					// TODO: consider splitting out the errors so we know if the problem is getting the docId or in the engine

					catch (const std::string& e)
					{
						// no need to do anything here
						// evbuffer_add_printf(evb, "Invalid docId\n");
						// evbuffer_add_printf(evb, e.c_str());
					}

					break; // break out of looping through parameters
				}
			}

			if (found)
			{
				evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/xml");
				evhttp_send_reply(req, 200, "OK", evb);
			}
			else
			{
				/*
				evbuffer_add_printf(evb, "Document not found or invalid docId");
				evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/html");
				*/

				evhttp_send_error(req, 404, "Document not found.");
			}

		}
		else
		{
			evhttp_send_error(req, HTTP_BADREQUEST, 0);
		}

		evhttp_clear_headers(&params);


		if (decoded)
		{
			evhttp_uri_free(decoded);
		}

		if (evb)
		{
			evbuffer_free(evb);
		}
	}

	std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
	std::chrono::nanoseconds timeTaken = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0);
	std::cout << ZUtil::printTimeTaken(timeTaken) << std::endl;
}
void NFCHttpServer::listener_cb(struct evhttp_request* req, void* arg)
{
    NFCHttpServer* pNet = (NFCHttpServer*) arg;
    NFHttpRequest request;
    request.req = req;
    //uri
    const char* uri = evhttp_request_get_uri(req);
    //std::cout << "Got a GET request:" << uri << std::endl;

    //get decodeUri
    struct evhttp_uri* decoded = evhttp_uri_parse(uri);
    if (!decoded)
    {
        printf("It's not a good URI. Sending BADREQUEST\n");
        evhttp_send_error(req, HTTP_BADREQUEST, 0);
        return;
    }
    const char* decode1 = evhttp_uri_get_path(decoded);
    if (!decode1)
        decode1 = "/";

    //The returned string must be freed by the caller.
    const char* decodeUri = evhttp_uridecode(decode1, 0, NULL);

    if (decodeUri == NULL)
    {
        printf("uri decode error\n");
        evhttp_send_error(req, HTTP_BADREQUEST, "uri decode error");
        return;
    }
    std::string strUri;
    if (decodeUri[0] == '/')
    {
        strUri = decodeUri;
        strUri.erase(0, 1);
        decodeUri = strUri.c_str();
    }
    //get strCommand
    auto cmdList = Split(strUri, "/");
    std::string strCommand = "";
    if (cmdList.size() > 0)
    {
        strCommand = cmdList[0];
    }

    request.url = decodeUri;

    // call cb
    if (pNet->mRecvCB)
    {
        pNet->mRecvCB(request, strCommand, decodeUri);
    } else
    {
        pNet->ResponseMsg(request, "mRecvCB empty", NFWebStatus::WEB_ERROR);
    }



    //close
    /*{
    if (decoded)
    evhttp_uri_free(decoded);
    if (decodeUri)
    free(decodeUri);
    if (eventBuffer)
    evbuffer_free(eventBuffer);
    }*/
}
Beispiel #21
0
int main (int argc, char *argv[])
{
    struct event_base *evbase;
    struct evdns_base *dns_base;
    int i;
    int test_id = -1;
    struct evhttp_uri *uri;

    event_set_mem_functions (g_malloc, g_realloc, g_free);

    evbase = event_base_new ();
	dns_base = evdns_base_new (evbase, 1);

    app = g_new0 (Application, 1);
    app->evbase = evbase;
	app->dns_base = dns_base;
    app->stats = hfs_stats_srv_create (app);

        app->conf = conf_create ();
        conf_add_boolean (app->conf, "log.use_syslog", TRUE);
        
        conf_add_uint (app->conf, "auth.ttl", 85800);
        
        conf_add_int (app->conf, "pool.writers", 2);
        conf_add_int (app->conf, "pool.readers", 2);
        conf_add_int (app->conf, "pool.operations", 4);
        conf_add_uint (app->conf, "pool.max_requests_per_pool", 100);

        conf_add_int (app->conf, "connection.timeout", 20);
        conf_add_int (app->conf, "connection.retries", -1);

        conf_add_uint (app->conf, "filesystem.dir_cache_max_time", 5);
        conf_add_boolean (app->conf, "filesystem.cache_enabled", TRUE);
        conf_add_string (app->conf, "filesystem.cache_dir", "/tmp/hydrafs");
        conf_add_string (app->conf, "filesystem.cache_dir_max_size", "1Gb");

        conf_add_boolean (app->conf, "statistics.enabled", TRUE);
        conf_add_int (app->conf, "statistics.port", 8011);

    conf_add_string (app->conf, "auth.user", "test");
    conf_add_string (app->conf, "auth.key", "test");
    uri = evhttp_uri_parse ("http://127.0.0.1:8011/get_auth");
    app->auth_client = auth_client_create (app, uri);
    
    if (argc > 1)
        test_id = atoi (argv[1]);

    if (test_id >= 0)
        // run_responce_test (evbase, dns_base, test_id);
        run_request_test (evbase, dns_base, test_id);
    else {
        for (i = 0; i < TID_last_test; i++) {
            run_responce_test (evbase, dns_base, i);
        }
    }

    evdns_base_free (dns_base, 0);
    event_base_free (evbase);

    return 0;
}
Beispiel #22
0
static void stat_srv_on_stats_cb (struct evhttp_request *req, void *ctx)
{
    StatSrv *stat_srv = (StatSrv *) ctx;
    struct evbuffer *evb = NULL;
    gint ref = 0;
    GString *str;
    struct evhttp_uri *uri;
    guint32 total_inodes, file_num, dir_num;
    guint64 read_ops, write_ops, readdir_ops, lookup_ops;
    guint32 cache_entries;
    guint64 total_cache_size, cache_hits, cache_miss;
    struct tm *cur_p;
    struct tm cur;
    time_t now;
    char ts[50];

    uri = evhttp_uri_parse (evhttp_request_get_uri (req));
    LOG_debug (STAT_LOG, "Incoming request: %s from %s:%d", 
        evhttp_request_get_uri (req), req->remote_host, req->remote_port);

    if (uri) {
        const gchar *query;
        
        query = evhttp_uri_get_query (uri);
        if (query) {
            const gchar *refresh = NULL;
            struct evkeyvalq q_params;
            
            TAILQ_INIT (&q_params);
            evhttp_parse_query_str (query, &q_params);
            refresh = http_find_header (&q_params, "refresh");
            if (refresh)
                ref = atoi (refresh);

            evhttp_clear_headers (&q_params);
        }
        evhttp_uri_free (uri);
    }

    str = g_string_new (NULL);
    
    now = time (NULL);
    localtime_r (&now, &cur);
    cur_p = &cur;
    if (!strftime (ts, sizeof (ts), "%H:%M:%S", cur_p))
        ts[0] = '\0';

    g_string_append_printf (str, "RioFS version: %s Uptime: %u sec, Now: %s, Log level: %d, Dir cache time: %u sec<BR>", 
        VERSION, (guint32)(now - stat_srv->boot_time), ts, log_level,
        conf_get_uint (application_get_conf (stat_srv->app), "filesystem.dir_cache_max_time"));

    // DirTree
    dir_tree_get_stats (application_get_dir_tree (stat_srv->app), &total_inodes, &file_num, &dir_num);
    g_string_append_printf (str, "<BR>DirTree: <BR>-Total inodes: %u, Total files: %u, Total directories: %u<BR>",
        total_inodes, file_num, dir_num);

    // Fuse
    rfuse_get_stats (application_get_rfuse (stat_srv->app), &read_ops, &write_ops, &readdir_ops, &lookup_ops);
    g_string_append_printf (str, "<BR>Fuse: <BR>-Read ops: %"G_GUINT64_FORMAT", Write ops: %"G_GUINT64_FORMAT
        ", Readdir ops: %"G_GUINT64_FORMAT", Lookup ops: %"G_GUINT64_FORMAT"<BR>",
        read_ops, write_ops, readdir_ops, lookup_ops);

    // CacheMng
    cache_mng_get_stats (application_get_cache_mng (stat_srv->app), &cache_entries, &total_cache_size, &cache_hits, &cache_miss);
    g_string_append_printf (str, "<BR>CacheMng: <BR>-Total entries: %"G_GUINT32_FORMAT", Total cache size: %"G_GUINT64_FORMAT
        " bytes, Cache hits: %"G_GUINT64_FORMAT", Cache misses: %"G_GUINT64_FORMAT" <BR>", 
        cache_entries, total_cache_size, cache_hits, cache_miss);
    
    g_string_append_printf (str, "<BR>Read workers (%d): <BR>", 
        client_pool_get_client_count (application_get_read_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_read_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Write workers (%d): <BR>",
        client_pool_get_client_count (application_get_write_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_write_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Op workers (%d): <BR>",
        client_pool_get_client_count (application_get_ops_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_ops_client_pool (stat_srv->app), str, &print_format_http);

    g_string_append_printf (str, "<BR><BR>Operation history (%u max items): <BR>",
        conf_get_uint (application_get_conf (stat_srv->app), "statistics.history_size"));
    g_queue_foreach (stat_srv->q_op_history, (GFunc) stat_srv_print_history_item, str);

    evb = evbuffer_new ();

    evbuffer_add_printf (evb, "<HTTP>");
    if (ref) {
        evbuffer_add_printf (evb, "<HEAD><meta http-equiv=\"refresh\" content=\"%d\"></HEAD>", ref);
    }
    evbuffer_add_printf (evb, "<BODY>");
    evbuffer_add (evb, str->str, str->len);
    evbuffer_add_printf (evb, "</BODY></HTTP>");
    evhttp_send_reply (req, HTTP_OK, "OK", evb);
    evbuffer_free (evb);

    g_string_free (str, TRUE);
}
static int encode_request_to_file_path(const char* uri, char** whole_path) {
	const char *path;
	char *decoded_path;
	struct evhttp_uri *decoded = NULL;
	struct stat st;
	size_t len;

	*whole_path = NULL;

	decoded = evhttp_uri_parse(uri);
	if (!decoded) {
		printf("It's not a good URI. Sending 404.\n");
		return 0;
	}

	/* Let's see what path the user asked for. */
	path = evhttp_uri_get_path(decoded);
	if (!path) {
		path = "/";
	}

	/* We need to decode it, to see what path the user really wanted. */
	decoded_path = evhttp_uridecode(path, 0, NULL);
	if (decoded_path == NULL) {
		return 0;
	}

	len = strlen(decoded_path) + strlen(doc_root) + 15;
	*whole_path = (char*)malloc(len);
	if (!*whole_path) {
		perror("malloc");
		evhttp_uri_free(decoded);
		free(decoded_path);
		return 0;
	}
	evutil_snprintf(*whole_path, len, "%s%s", doc_root, decoded_path);

	if (stat(*whole_path, &st) < 0) {
		evhttp_uri_free(decoded);
		free(decoded_path);
		return 0;
	}

	if (S_ISDIR(st.st_mode)) {
		
		// Find index.html of this page
		if ((*whole_path)[strlen(*whole_path) - 1] == '/') {
			strcat(*whole_path, "index.html");
		} else {
			strcat(*whole_path, "/index.html");
		}

		if (stat(*whole_path, &st) < 0) {
			evhttp_uri_free(decoded);
			free(decoded_path);
			return 0;
		}
	}
	evhttp_uri_free(decoded);
	free(decoded_path);
	return st.st_size;
}