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(¶ms, 0, sizeof(params)); if (evhttp_parse_query_str(full_url, ¶ms) == -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(¶ms, "start-index")) != NULL) { evbuffer_add_printf(buf, "start-index=%s&", val); } if ((val = evhttp_find_header(¶ms, "max-results")) != NULL) { evbuffer_add_printf(buf, "max-results=%s&", val); } evhttp_clear_headers(¶ms); }
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); }
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(¶ms, 0, sizeof(params)); if (evhttp_parse_query_str(query, ¶ms) == 0) { metric_name = evhttp_find_header(¶ms,"series"); if (metric_name != NULL) { printf("query is for %s\n", metric_name); mh = metrics_find_metric(m,metric_name); } } evhttp_clear_headers(¶ms); } return mh; }
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); }
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); }
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 } }
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); }
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, ¶ms); value = evhttp_find_header(¶ms, "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, ¶ms); value = evhttp_find_header(¶ms, "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(¶ms); free(data); } }
//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, ¶ms); const char *element = evhttp_find_header(¶ms, "e"); if (!element) { evhttp_clear_headers(¶ms); 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(¶ms); 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(¶ms); }; 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; }
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); }
/** * 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, ¶ms); 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(¶ms); 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; }
/** * 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(), ¶ms); // 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(¶ms); 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; }
/** * 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, ¶ms); 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(¶ms); 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; }