Example #1
0
static void filter_query_into(struct evbuffer *buf, const char *full_url)
{
	struct evkeyvalq params;
	const char *val;

	/* FIXME: Remember that passthrough thing we do if
	 * there's _any_ alt=... format specifier? Yeah, that one.
	 * Great idea. Now we get to jump through hoops dropping it from
	 * the next/previous links.
	 *
	 * Just go make passthrough an explicit url parameter, and teach
	 * /list how to deal with alt=atom, so we don't have to do this.
	 */

	memset(&params, 0, sizeof(params));
	if (evhttp_parse_query_str(full_url, &params) == -1) {
		/* Bad idea, we're kind of committed to this :( */
		return;
	}

	/* If we'd dig into the internals we could just iterate the parameters
	 * and skip alt=... As it is, we'll just pick start-index and
	 * max-results. Those are the only ones /list? will pass to Google
	 * anyway
	 */
	if ((val = evhttp_find_header(&params, "start-index")) != NULL) {
		evbuffer_add_printf(buf, "start-index=%s&", val);
	}

	if ((val = evhttp_find_header(&params, "max-results")) != NULL) {
		evbuffer_add_printf(buf, "max-results=%s&", val);
	}

	evhttp_clear_headers(&params);
}
Example #2
0
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);
}
Example #3
0
static struct metric_history * http_find_metrics_from_query(struct metrics *m, const char *query)
{
    struct metric_history *mh = NULL;
    struct evkeyvalq params;
    const char *metric_name;

    if (query)
    {
        memset(&params, 0, sizeof(params));

        if (evhttp_parse_query_str(query, &params) == 0)
        {
            metric_name = evhttp_find_header(&params,"series");
            if (metric_name != NULL)
            {
                printf("query is for %s\n", metric_name);
                mh = metrics_find_metric(m,metric_name);
            }
        }

        evhttp_clear_headers(&params);
    }

    return mh;
}
Example #4
0
void xBlog::GetHttpPostData(struct evhttp_request *req, struct evkeyvalq *evdata)
{
    evbuffer *pevBuf = evhttp_request_get_input_buffer(req);
    int data_len = evbuffer_get_length(pevBuf);

    char *pbuffer = (char *) malloc(data_len + 1);
    memset(pbuffer, 0, data_len + 1);

    evbuffer_copyout(pevBuf, pbuffer, data_len);
    log_debug("%s\r\n", pbuffer);
    evhttp_parse_query_str(pbuffer, evdata);
    free(pbuffer);
}
Example #5
0
	HttpQuery(struct evhttp_request *req){
		_has_post = false;
		if(evhttp_request_get_command(req) == EVHTTP_REQ_POST){
			evbuffer *body_evb = evhttp_request_get_input_buffer(req);
			size_t len = evbuffer_get_length(body_evb);
			if(len > 0){
				_has_post = true;
				char *data = (char *)malloc(len + 1);
				evbuffer_copyout(body_evb, data, len);
				data[len] = '\0';
				evhttp_parse_query_str(data, &_post);
				free(data);
			}
		}
		evhttp_parse_query(evhttp_request_get_uri(req), &_get);
	}
Example #6
0
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
	}
}
Example #7
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);

}
Example #8
0
void servlet(struct evhttp_request *req, struct evbuffer *evb, const char *get_query) {
    /*dbi_conn conn;
    dbi_result result;           
    unsigned int idnumber;
    char *fullname;
    
    dbi_initialize(NULL);
    conn = dbi_conn_new("mysql");    
    dbi_conn_set_option(conn, "host", "localhost");
    dbi_conn_set_option(conn, "username", "root");
    dbi_conn_set_option(conn, "password", "root");
    dbi_conn_set_option(conn, "dbname", "test");
    dbi_conn_set_option(conn, "encoding", "UTF-8");
    if (dbi_conn_connect(conn) < 0) {
      printf("Could not connect");
    } else {
        result = dbi_conn_queryf(conn, "SELECT id, name FROM test");
        
        if (result) {
            printf("dbi_result_get_numrows: %u", dbi_result_get_numrows(result));
            
            while (dbi_result_next_row(result)) {
                idnumber = dbi_result_get_uint(result, "id");
                fullname = dbi_result_get_string(result, "name");
                printf("%i. %s", idnumber, fullname);
            }
        
            dbi_result_free(result);
        }
        
        dbi_conn_close(conn);      
    }*/
    

    
    time_t now;
    time(&now);
    const char *value;
    struct evkeyvalq params;
    char *data;
    size_t len;


    if (evhttp_request_get_command(req) == EVHTTP_REQ_GET) {
        evhttp_parse_query_str(get_query, &params);
        value = evhttp_find_header(&params, "first_name");
    } else {
        len = evbuffer_get_length(evhttp_request_get_input_buffer(req));
        struct evbuffer *in_evb = evhttp_request_get_input_buffer(req);
        data = malloc(len + 1);
        evbuffer_copyout(in_evb, data, len);
        data[len] = '\0';
        evhttp_parse_query_str(data, &params);
        value = evhttp_find_header(&params, "first_name");
    }

    
    evbuffer_add_printf(evb, "<html>\n <head>\n"
	    "  <title>C servlet</title>\n"
	    " </head>\n"
	    " <body>\n"
	    "  <h1>C servlet</h1>\n"
	    " <p>Current time is: %s (GMT)</p>" 
	    " <p>First name is: %s</p>\n<hr>\n"
	    "<form action=\"/servlet\" method=\"POST\">\n"
	    "First name <input type=\"text\" name=\"first_name\">"
	    "<input type=\"submit\" value=\"send via post\">"
	    "</form>\n"
	    "<p>COOKIE: %s</p>"
	    "<p><a href=\"/servlet?first_name=John\">GET with parameters</a></p>"
	    "</body><html>", 
	    ctime(&now),
        value,
	    http_get_cookie(req, "CSESSID"));
    evhttp_add_header(evhttp_request_get_output_headers(req),
	    "Content-Type", "text/html");
	evhttp_add_header(evhttp_request_get_output_headers(req),
	    "Set-Cookie", "CSESSID=435J43L523J4TTYYY; Path=/; Domain=intranet2.local");
	evhttp_add_header(evhttp_request_get_output_headers(req),
	    "Set-Cookie", "[email protected]; Path=/; Domain=intranet2.local");
	evhttp_add_header(evhttp_request_get_output_headers(req),
	    "Server", "green httpd");
	evhttp_send_reply(req, 200, "OK", evb);
	
	if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
	    evhttp_clear_headers(&params);
        free(data);
	}
}
Example #9
0
//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;
}
Example #10
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);
}
Example #11
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;
}
Example #12
0
/**
 * Call back used for a POST request
 */
static void post_request_cb(struct evhttp_request *req, void *arg)
{
	std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();

	/*

	bool isPostRequest = false;
	const char *cmdtype = NULL;

	switch (evhttp_request_get_command(req))
	{
		case EVHTTP_REQ_GET: cmdtype = "GET"; break;
		case EVHTTP_REQ_POST: cmdtype = "POST"; isPostRequest = true; break;
		case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break;
		case EVHTTP_REQ_PUT: cmdtype = "PUT"; break;
		case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break;
		case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break;
		case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break;
		case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break;
		case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break;
		default: cmdtype = "unknown"; break;
	}

	if (!isPostRequest)
	{
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
	}
	*/

	if (evhttp_request_get_command(req) != EVHTTP_REQ_POST)
	{
		std::cerr << "Invalid request! Needs to be POST" << std::endl;
		evhttp_send_error(req, HTTP_BADREQUEST, 0);
	}
	else
	{
		struct evbuffer *evb = NULL;
		struct evkeyvalq *headers;
		struct evkeyval *header;
		struct evbuffer *buf;

		printf("Received a POST request for %s\nHeaders:\n", evhttp_request_get_uri(req));

		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);
		}

		buf = evhttp_request_get_input_buffer(req);

		std::string postData;

		while (evbuffer_get_length(buf))
		{
			int n;
			char cbuf[128];
			n = evbuffer_remove(buf, cbuf, sizeof(buf)-1);
			if (n > 0)
			{
				// (void) fwrite(cbuf, 1, n, stdout);
				postData.append(cbuf, n);
			}
		}

		// std::cout << "Post data: " << std::endl << postData << std::endl;

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

		// working code to return the parameters as plain text ...
		/*
		std::string postDataDecoded;

		if (result == 0)
		{
			for (param = params.tqh_first; param; param = param->next.tqe_next)
			{
				printf("%s %s\n", param->key, param->value);
				postDataDecoded.append(param->key);
				postDataDecoded.append(" ");
				postDataDecoded.append(param->value);
				postDataDecoded.append("\n");
			}

			evb = evbuffer_new();
			evbuffer_add_printf(evb, postDataDecoded.c_str());
			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);
		}
		*/

		// working code to decode and index data

		int result = evhttp_parse_query_str(postData.c_str(), &params);

		// if we were able to parse post data ok
		if (result == 0)
		{
			param = params.tqh_first;

			std::string key(param->key);
			std::string value(param->value);

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

			evb = evbuffer_new();

			// check that the first key is data
			if (key.compare(zsearch::server::POST_DATA_KEY) == 0)
			{
				try
				{
					std::shared_ptr<IDocument> document = std::make_shared<DocumentImpl>(value);
					unsigned int docId = engine->addDocument(document);
					std::cout << "Added document: " << docId << std::endl;
					evbuffer_add_printf(evb, "%d", docId);
				}
				catch (const std::string& e)
				{
					evbuffer_add_printf(evb, "Error parsing document. See documentation for more details\n");
					evbuffer_add_printf(evb, e.c_str());
				}
				catch (const std::exception& e)
				{
					evbuffer_add_printf(evb, "Error parsing document. See documentation for more details\n");
					evbuffer_add_printf(evb, e.what());
				}
			}
			else
			{
				evbuffer_add_printf(evb, "Invalid post data, first key must be in the form of data -> {xml}. See documentation for more details\n");
			}

			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 (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;
}
Example #13
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;
}