示例#1
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);
}
示例#2
0
bool CHttpParser::setHttpRequest(struct evhttp_request *req)
{
    if (NULL != m_pEventBuf)
    {
        evbuffer_free(m_pEventBuf);
        m_pEventBuf = NULL;
    }

    m_strPostMsg.clear();
    m_strQuery.clear();

    m_pEventBuf = evbuffer_new();
    if (NULL == m_pEventBuf)
    {
        Q_Printf("%s", "evbuffer_new error.");
        return false;
    }

    m_Req = req;

    struct evbuffer *pBuf = evhttp_request_get_input_buffer(m_Req);
    size_t iLens = evbuffer_get_length(pBuf);
    if (iLens > 0)
    {
        m_strPostMsg.append((const char *)evbuffer_pullup(pBuf, (ev_ssize_t)iLens), iLens);
        evbuffer_drain(pBuf, iLens);
    }

    const struct evhttp_uri *pUri = evhttp_request_get_evhttp_uri(m_Req);
    const char *pszQuery = evhttp_uri_get_query(pUri);
    m_strQuery = (NULL == pszQuery ? "" : pszQuery);

    return true;
}
示例#3
0
文件: xBlog.cpp 项目: iomato/xblog
void xBlog::HttpParseURL(struct evhttp_request *req, struct evkeyvalq *evMyheader)
{
    const char *xBlog_query;

    xBlog_query = evhttp_uri_get_query(evhttp_request_get_evhttp_uri(req));
    evhttp_parse_query_str(xBlog_query, evMyheader);
}
示例#4
0
/*
 * Get request URI query
 * @return [String]
 * @return [nil]
 */
static VALUE t_get_uri_query(VALUE self) {
    Libevent_HttpRequest *http_request;
    const char *query;

    Data_Get_Struct(self, Libevent_HttpRequest, http_request);

    query = evhttp_uri_get_query(http_request->ev_request->uri_elems);

    return(query ? rb_str_new2(query) : Qnil);
}
示例#5
0
static void stat_srv_on_gen_cb (struct evhttp_request *req, void *ctx)
{
    StatSrv *stat_srv = (StatSrv *) ctx;
    const gchar *query;
    
    query = evhttp_uri_get_query (evhttp_request_get_evhttp_uri (req));
    
    LOG_debug (STAT_LOG, "Unhandled request to: %s", query);

    (void) stat_srv;
    evhttp_send_reply (req, HTTP_NOTFOUND, "Not found", NULL);
}
static void parseRequest(RequestInfo& requestInfo) {
  const struct evhttp_uri* uri = evhttp_request_get_evhttp_uri(requestInfo.req);
  /*const*/ struct evhttp_connection* conn = evhttp_request_get_connection(requestInfo.req);
  
  requestInfo.method = evhttp_request_get_command(requestInfo.req);
  requestInfo.uriHost = evhttp_uri_get_host(uri);
  requestInfo.uriPath = evhttp_uri_get_path(uri);
  requestInfo.uriQuery = evhttp_uri_get_query(uri);
  requestInfo.uriScheme = evhttp_uri_get_scheme(uri);
  requestInfo.requestHeaders = evhttp_request_get_input_headers(requestInfo.req);
  requestInfo.requestBody = evhttp_request_get_input_buffer(requestInfo.req);
  evhttp_connection_get_peer(conn, &requestInfo.remoteAddress, (ev_uint16_t*) &requestInfo.remotePort);
}
示例#7
0
文件: http.c 项目: pearsonalan/stats
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);
}
示例#8
0
文件: http.c 项目: pearsonalan/stats
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);

}
示例#9
0
文件: http.c 项目: snip/aprsc
static void http_counterdata(struct evhttp_request *r, const char *uri)
{
	char *json;
	const char *query;
	
	query = evhttp_uri_get_query(evhttp_request_get_evhttp_uri(r));
	hlog(LOG_DEBUG, "counterdata query: %s", query);
	
	json = cdata_json_string(query);
	if (!json) {
		evhttp_send_error(r, HTTP_BADREQUEST, "Bad request, no such counter");
		return;
	}
	
	struct evkeyvalq *headers = evhttp_request_get_output_headers(r);
	http_header_base(headers, tick);
	evhttp_add_header(headers, "Content-Type", "application/json; charset=UTF-8");
	evhttp_add_header(headers, "Cache-Control", "max-age=58");
	
	http_send_reply_ok(r, headers, json, strlen(json), 1);
	hfree(json);
}
示例#10
0
文件: main.c 项目: TheRook/BitEvent
void tracker(struct evhttp_request *req, struct config *confg){
	char * info_hash=0x00,
		 * client_ip=0x00,
		 * event=0x00;
	int    client_port=0,
		   left = 0,
		   compact = 0,
		   numwant = 0,
		   peer_worth = 0,
		   uploaded = 0,
		   downloaded = 0;
	ev_uint16_t scoket_client_port=0x00;
	uint32_t client_ip_addr=0;

	//evhttp is strange sometimes...
	struct evkeyvalq GET;
	const struct evhttp_uri *uri = evhttp_request_get_evhttp_uri(req);
	char *query = evhttp_uri_get_query(uri);
	evhttp_parse_query_str(query, &GET);

	info_hash=evhttp_find_header(&GET, "info_hash");
	if(info_hash){
		event=evhttp_find_header(&GET, "event");
		left = getInt(&GET,"left");
		//Only return a peer list if the client needs one.
		//So the client must have something left to download and not completed or stopped.
		//If the event is empty or non-present,  return a list of peers.
		if(left &&
		        (!event ||
		         event[0] == 0x00 ||
		                          (strcmp(event, "completed") == 0 &&
		        		           strcmp(event, "stopped") == 0))){
			//Build a list of peers for the response:
			compact = getInt(&GET,"compact");
			numwant = getInt(&GET,"numwant");
			view_peer_list(confg, req, info_hash, numwant, compact);
		}

		client_ip = evhttp_find_header(&GET, "Ip");
		if(client_ip){
			client_ip_addr=inet_addr(client_ip);
		}else{
			//for compatibility, try a non-standard case
			client_ip = evhttp_find_header(&GET, "ip");
			if(client_ip){
				client_ip_addr=inet_addr(client_ip);
			}
		}

		if(client_ip_addr<=0){
			//Looks like we got an invalid ip address as a GET param,  recovering...
			evhttp_connection_get_peer(req->evcon,
									   &client_ip,
									   &scoket_client_port);
			client_ip_addr=inet_addr(client_ip);
		}

		client_port = getInt(&GET,"port");
		//port 0 is valid...  and is used by no one, ever.
		if(client_port > 0 && client_port < 65536 && client_port != 80 && client_port != 443){
			uploaded = getInt(&GET,"uploaded");
			//Process event:
			if(event){
				if(strcmp(event, "stopped") == 0 ){
					peer_worth=-1;
				}else if(strcmp(event, "completed") == 0){
					//This peer has every chunk,  they are valuable
					peer_worth=2;
				}else if(strcmp(event, "started") == 0){
					//This peer has nothing
					peer_worth=0;
				}else{
					//Probably better than nothing.
					peer_worth=1;
				}
			}else{
				peer_worth=1;
			}
			downloaded = getInt(&GET,"downloaded");
			if(uploaded>downloaded){
				//This peer is healthy! (Or lying...)
				peer_worth++;
			}
			if(peer_worth >= 0){
				//Add the peer to the db, The recorded peer_worth is from 0-3
				control_add_peer(confg, peer_worth, client_ip_addr, client_port, info_hash);
			}else if(peer_worth < 0){
				//This peer is worth less than
				control_remove_peer(confg, client_ip_addr, client_port, info_hash);
			}
		}else{
			//todo error invalid port
		}
	}else{
		//todo error; no info_hash
	}
}
示例#11
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;
}
示例#12
0
static void
handle_request(void *ctx) {
  conn_t *conn = ctx;
  struct evbuffer *rsps = evbuffer_new();
  struct state *s = conn->state;

  if (strcmp(conn->method, "GET") == 0) {

    if (strcmp(conn->url, "/getproxies") == 0) 
      get_proxies(rsps);

    else if (strcmp(conn->url, "/getlists") == 0) 
      get_lists(rsps);

    else if (strncmp(conn->url, "/query?", 7) == 0)
      query(rsps, evhttp_decode_uri(conn->url + 7));

    else if (strcmp(conn->url, "/getlog") == 0) 
      get_log(rsps);

    else if (strcmp(conn->url, "/gettrylist") == 0) 
      get_trylist(rsps);

    else if (strcmp(conn->url, "/getversion") == 0) 
      evbuffer_add_printf(rsps, VERSION);

  }
  else if (strcmp(conn->method, "POST") == 0) {

    struct evkeyvalq kv;
    struct evhttp_uri *uri = evhttp_uri_parse_with_flags(conn->url, 0);

    evhttp_parse_query_str(evhttp_uri_get_query(uri), &kv);

    char *cont;
    if (s->length) 
      cont = s->body;

    const char *path = evhttp_uri_get_path(uri);

    if (strcmp(path, "/addrule") == 0 || strcmp(path, "/rmrule") == 0) {

      struct evkeyvalq kvc;
      evhttp_parse_query_str(cont, &kvc);

      char *list = evhttp_decode_uri(evhttp_find_header(&kvc, "list"));
      char *rule = evhttp_decode_uri(evhttp_find_header(&kvc, "rule"));

      if (get_domain(rule) == NULL) 
	evbuffer_add_printf(rsps, "Invalid rule.");
      
      else {
	if (strcmp(path, "/addrule") == 0)
	  update_rule(list, rule);
      
	else 
	  remove_rule(list, rule);

	evbuffer_add_printf(rsps, "OK");
      }
      free(list);
      free(rule);

      free(cont);
    }

    else if (strcmp(path, "/flush") == 0) {
      flush_list();
      evbuffer_add_printf(rsps, "OK");
    }
    else if (strcmp(path, "/rmlog") == 0) {
      rm_log(rsps);
    }
    else if (strcmp(path, "/purgetrylist") == 0) {
      purgetrylist(rsps);
    }

    evhttp_uri_free(uri);
  }
  ret(conn->be_client, rsps);
  evbuffer_free(rsps);

}
示例#13
0
文件: bloom.c 项目: qzm1218/bloom
//Main
int main(int argc, char *argv[])
{
    //Get args
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <snapshot_file>\n", argv[0]);
        return 1;
    }
    snap_path = argv[1];

    //Allocate memory
    fprintf(stderr, "Allocating arena with size %.2f MBytes ...\n", (float)m / CHAR_BIT / MEGA);
    Bloom = malloc( (m + ( CHAR_BIT - 1)) / CHAR_BIT ); // Ceil byte length: bytes = bits + 7 / 8


    //Load or create snapshot file
    if (!access(snap_path, F_OK)) {
        fputs("Loading snapshot...\n", stderr);
        if (LoadSnap(Bloom, snap_path)) {
            fputs("Unable to load snapshot!\n", stderr);
            return -1;
        }
        fputs("Snapshot loaded.\n", stderr);
    } else {
        fputs("Initializing new file storage...\n", stderr);
        size_t shouldwrite = (m + (CHAR_BIT - 1)) / CHAR_BIT;
        memset(Bloom, 0, shouldwrite); 

        if (SaveSnap(Bloom, snap_path)) {
            fputs("Unable to save initial snapshot!\n", stderr);
            return -1;
        }
        fputs("Initial snapshot written.\n", stderr);
    }


    void OnReq(struct evhttp_request *req, void *arg)
    {
        struct evbuffer *OutBuf = evhttp_request_get_output_buffer(req);
        if (!OutBuf) {
            evhttp_send_reply(req, HTTP_BADREQUEST, "Bad Request", OutBuf);
            return;
        }
        struct evkeyvalq *Headers = evhttp_request_get_output_headers(req);
        if (!Headers) {
            evhttp_send_reply(req, HTTP_INTERNAL, "Internal Error", OutBuf);
            return;
        }
        const struct evhttp_uri *HTTPURI =  evhttp_request_get_evhttp_uri(req);
        if (!HTTPURI) {
            evhttp_send_reply(req, HTTP_BADREQUEST, "Bad Request", OutBuf);
            return;
        }
        const char *path =  evhttp_uri_get_path(HTTPURI);
        if (!path) {
            evhttp_send_reply(req, HTTP_BADREQUEST, "Bad Request", OutBuf);
        }
        const char *query_string = evhttp_uri_get_query(HTTPURI);
        if (!query_string) {
            evhttp_send_reply(req, HTTP_BADREQUEST, "Element Required", OutBuf);
            return;
        }
        struct evkeyvalq params;
        evhttp_parse_query_str(query_string, &params);
        const char *element = evhttp_find_header(&params, "e");
        if (!element) {
            evhttp_clear_headers(&params);
            evhttp_send_reply(req, HTTP_BADREQUEST, "Element Required", OutBuf);
            return;
        }

        int i;
        const char* (*Operation)(bloom_cell *, size_t []) = NULL;
        for (i=0; i< sizeof HandlerTable/ sizeof HandlerTable[0] ; i++)
            if (strncmp(HandlerTable[i][0], path, STR_MAX) == 0) {
                Operation = HandlerTable[i][1];
                break;
            }
        if (!Operation) {
            evhttp_clear_headers(&params);
            evhttp_send_reply(req, HTTP_NOTFOUND, "Not Found", OutBuf);
            return;
        }

        const char *response = Operation(Bloom, Hashes(element));

        evhttp_add_header(Headers, MIME_TYPE);
        evbuffer_add_printf(OutBuf, response);
        evhttp_send_reply(req, HTTP_OK, "OK", OutBuf);
        evhttp_clear_headers(&params);
    };

    if (!(base = event_base_new()))
        crash("Couldn't create an event_base: exiting\n", -1);

    if (!(http = evhttp_new(base)))
        crash("Couldn't create evhttp. Exiting.\n", -1);
    evhttp_set_gencb(http, OnReq, NULL);

    if (!(handle = evhttp_bind_socket_with_handle(http, BIND_ADDRESS, BIND_PORT)))
        crash("couldn't bind to port 8888. Exiting.\n", -1);

    if (signal(SIGINT, term_handler) == SIG_ERR)
        crash("Unable to set SIGINT handler!", -1);

    if (signal(SIGTERM, term_handler) == SIG_ERR)
        crash("Unable to set SIGTERM handler!", -1);

    if (signal(SIGCHLD, child_collector) == SIG_ERR)
        crash("Unable to set SIGCHLD handler!", -1);
    
    //This signal handled by event loop in order to avoid malloc deadlock
    if ((dump_event = evsignal_new(base, SIGUSR1, dump_handler, NULL)) == NULL)
        crash("Unable to create SIGUSR1 handler!", -1);
    else 
        if (event_add(dump_event, NULL) == -1)
            crash("Unable to add SIGUSR1 handler!", -1);

    if (event_base_dispatch(base) == -1)
        crash("Failed to run message loop.\n", -1);

    fputs("Exiting...\n", stderr);
    SaveSnap(Bloom, snap_path);
    evhttp_del_accept_socket(http, handle);
    evhttp_free(http);
    event_free(dump_event);
    event_base_free(base);
    free(Bloom);
    return 0;
}
示例#14
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);
}
示例#15
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;
}
示例#16
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;
}