static unsigned int vcl_push(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; char id[ID_LEN]; int status; GET_PRIV(core, vcl); assert(STARTS_WITH(request->url, "/vcl")); assert(request->method == M_POST || request->method == M_PUT); if (request->method == M_POST) snprintf(id, sizeof(id), "vcl%ju", (uintmax_t) time(NULL)); else snprintf(id, sizeof(id), "%s", arg); if (!strlen(id)) http_reply(request->connection, 400, "Bad URL?"); else { status = vcl_store(request, vcl, &vret, core, id); http_reply(request->connection, status, vret.answer); free(vret.answer); } return (0); }
static unsigned int vcl_listshow(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; GET_PRIV(core, vcl); assert(STARTS_WITH(request->url, "/vcl")); assert(request->method == M_GET); if (!arg) ipc_run(vcl->vadmin, &vret, "vcl.list"); else ipc_run(vcl->vadmin, &vret, "vcl.show %s", arg); if (vret.status == 200) http_reply(request->connection, 200, vret.answer); else http_reply(request->connection, 400, vret.answer); free(vret.answer); return (0); }
static unsigned int vcl_deploy(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; int ret; GET_PRIV(core, vcl); assert(STARTS_WITH(request->url, "/vcldeploy")); assert(request->method == M_PUT); ipc_run(vcl->vadmin, &vret, "vcl.use %s", arg); if (vret.status == 200) ret = vcl_persist_active(vcl->logger, arg, core); if (vret.status == 200 && ret) http_reply(request->connection, 500, "Deployed ok, but NOT PERSISTED."); else if (vret.status == 200) http_reply(request->connection, 200, vret.answer); else http_reply(request->connection, 500, vret.answer); free(vret.answer); return (0); }
static unsigned int vstat_push_test(struct http_request *request, const char *arg, void *data) { struct vstat_priv_t *vstat; struct agent_core_t *core = data; (void)arg; GET_PRIV(core, vstat); if (push_stats(vstat, &vstat->http) < 0) http_reply(request->connection, 500, "Stats pushing failed"); else http_reply(request->connection, 200, "Stats pushed"); return 0; }
static unsigned int vcl_active(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; char **tp, *tok[5]; char *p, *last; char *line; (void)arg; assert(STARTS_WITH(request->url, "/vclactive")); assert(request->method == M_GET); GET_PRIV(core, vcl); /* * vcl.list output: * * V3/4 : (active|available|discarded) (refcnt) (name) * V4.1 : (active|available|discarded) (state) \ * (busycnt|) (name) */ ipc_run(vcl->vadmin,&vret,"vcl.list"); if (vret.status == 400) { http_reply(request->connection, 500, vret.answer); free(vret.answer); return (0); } memset(tok, '\0', sizeof(tok)); for (p = vret.answer, last = NULL; (line = strtok_r(p, "\n", &last)); p = NULL) { if (strncmp("active", line, 6)) continue; last = NULL; for (p = line, tp = tok; tp < &tok[4] && (*tp = strtok_r(p, " ", &last)); p = NULL) { if (**tp != '\0') tp++; } } if (!tok[2] || !tok[3]) http_reply(request->connection, 500, "No active VCL"); else { strcpy(vret.answer, tok[3] ? tok[3] : tok[2]); http_reply(request->connection, 200, vret.answer); } free(vret.answer); return (0); }
static unsigned int vbackends_reply(struct http_request *request, void *data) { const char *arg; struct agent_core_t *core = data; struct agent_plugin_t *plug; struct vbackends_priv_t *vbackends; char *body; plug = plugin_find(core,"vbackends"); vbackends = plug->data; if (!strcmp(request->url, "/backendjson/") && request->method == M_GET) { backends_json(request, vbackends); return (1); } if (request->method == M_PUT) { char *mark; assert(((char *)request->data)[request->ndata] == '\0'); body = strdup(request->data); mark = strchr(body,'\n'); if (mark) *mark = '\0'; arg = request->url + strlen("/backend/"); assert(arg && *arg); run_and_respond(vbackends->vadmin, request->connection, "backend.set_health %s %s", arg, body); free(body); return (1); } http_reply(request->connection, 500, "Failed"); return (1); }
static unsigned int vstat_reply(struct http_request *request, const char *arg, void *data) { struct vstat_priv_t *vstat; struct agent_core_t *core = data; struct http_response *resp; (void)arg; GET_PRIV(core, vstat); if (check_reopen(&vstat->http)) { http_reply(request->connection, 500, "Couldn't open shmlog"); return 0; } do_json(vstat->http.vd, vstat->http.vsb); resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(vstat->http.vsb); resp->ndata = VSB_len(vstat->http.vsb); http_add_header(resp,"Content-Type","application/json"); send_response(resp); http_free_resp(resp); VSB_clear(vstat->http.vsb); return 0; }
int http_reply(const char *file, int line, enum http_status code, const char *fmt, ...) { const char *msg = NULL; va_list ap; int a; int b; switch (code) { #define XX(num, name, string) case num: msg = # string; break; HTTP_STATUS_MAP(XX) #undef XX default: return http_reply(file, line, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL); } fprintf(stderr, " => %d (%s:%d)\n", code, file, line); a = dprintf(STDOUT_FILENO, "HTTP/1.1 %d %s\r\n", code, msg); if (a < 0) return a; va_start(ap, fmt); b = vdprintf(STDOUT_FILENO, fmt ? fmt : "Content-Length: 0\r\n\r\n", ap); va_end(ap); return b < 0 ? b : a + b; }
do_cat(char *f, int fd) { char *extension = file_type(f); char *type = "text/plain"; FILE *fpsock, *fpfile; int c; int bytes = 0; if ( strcmp(extension,"html") == 0 ) type = "text/html"; else if ( strcmp(extension, "gif") == 0 ) type = "image/gif"; else if ( strcmp(extension, "jpg") == 0 ) type = "image/jpeg"; else if ( strcmp(extension, "jpeg") == 0 ) type = "image/jpeg"; fpsock = fdopen(fd, "w"); fpfile = fopen( f , "r"); if ( fpsock != NULL && fpfile != NULL ) { bytes = http_reply(fd,&fpsock,200,"OK",type,NULL); while( (c = getc(fpfile) ) != EOF ){ putc(c, fpsock); bytes++; } fclose(fpfile); fclose(fpsock); } server_bytes_sent += bytes; }
static unsigned int vban_reply(struct http_request *request, void *data) { struct agent_core_t *core = data; struct vban_priv_t *vban; char *body; GET_PRIV(core, vban); if (request->method == M_GET) { run_and_respond(vban->vadmin, request->connection, "ban.list"); return 0; } else { char *mark; assert(((char *)request->data)[request->ndata] == '\0'); body = strdup(request->data); mark = strchr(body,'\n'); if (mark) *mark = '\0'; if (strlen(request->url) == strlen("/ban")) run_and_respond(vban->vadmin, request->connection, "ban %s",body); else { const char *path = request->url + strlen("/ban"); if (request->ndata != 0) { http_reply(request->connection, 500, "Banning with both a url and request body? Pick one or the other please."); } else { assert(request->ndata == 0); run_and_respond(vban->vadmin, request->connection, "ban " BAN_SHORTHAND "%s",path); } } free(body); return 0; } return 0; }
int ir_http_set_data(void) { // format: data=CCNNPPLLLLLL..LL // CC - 1 byte command, 0x01 = start rec, 0x02 = play rec, 0x03 - save record // NN - 1 byte ir command (record) number, 0xff = play captured from buffer (for Save and Play commands) // PP - 1 byte lablel length in bytes (for Save command) // LL - win1251 chars of command label (for Save command) struct { unsigned char opcode; unsigned char rec_n; unsigned char label_len; } cmd; char label[32]; unsigned postlen; if(http.post_content_length - HTTP_POST_HDR_SIZE < (3<<1) ) return 0; // at least 3 hex byte must be posted http_post_data_part(req + HTTP_POST_HDR_SIZE, (void*)&cmd, sizeof cmd); switch(cmd.opcode) { case 0x01: ir_start_capture(); http_reply(200,"ok"); break; case 0x02: if(cmd.rec_n != 0xff && cmd.rec_n >= IR_COMMANDS_N) break; // validate cmd number ir_play_record(cmd.rec_n); http_reply(200,"ok"); break; case 0x03: if(cmd.rec_n >= IR_COMMANDS_N) break; // validate cmd number postlen = (sizeof cmd + cmd.label_len)<<1; if(http.post_content_length != HTTP_POST_HDR_SIZE + postlen) break; // check POST data length util_fill((void*)label, sizeof label, 0); // LBS 27.02.2012 - it was wrong function args sequence !!! if(cmd.label_len > 31) cmd.label_len = 31; // limit label length http_post_data_part(req + HTTP_POST_HDR_SIZE + sizeof cmd * 2, label, cmd.label_len); // read label ir_save_record(cmd.rec_n, label); http_redirect("/ir.html"); break; default: http_redirect("/ir.html"); break; } return 0; }
static unsigned int vcl_delete(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; GET_PRIV(core, vcl); assert(request->method == M_DELETE); assert(STARTS_WITH(request->url, "/vcl")); ipc_run(vcl->vadmin, &vret, "vcl.discard %s", arg); if (vret.status == 400 || vret.status == 106) http_reply(request->connection, 500, vret.answer); else http_reply(request->connection, 200, vret.answer); free(vret.answer); return (0); }
static int http_complete_login (RESTSESSION * r) { struct buf *response; if (r->client->state != CLIENT_STATE_IDLE_CONNECTED) return http_reply_need_auth (r); response = buf_new (); buf_append_data (response, "logged in!\n", 11); return http_reply (r, 200, response); }
/* * FIXME: Should be simplified/split up. */ static unsigned int vparams_reply(struct http_request *request, void *data) { const char *arg; struct agent_core_t *core = data; struct vparams_priv_t *vparams; char *body; GET_PRIV(core, vparams); if (!strcmp(request->url, "/paramjson/") && request->method == M_GET) { param_json(request, vparams); return 1; } if (request->method == M_GET) { if (!strcmp(request->url,"/param/")) { run_and_respond(vparams->vadmin, request->connection, "param.show"); return 1; } else { arg = request->url + strlen("/param/"); assert(arg && *arg); run_and_respond(vparams->vadmin, request->connection, "param.show %s", arg); return 1; } } else if (request->method == M_PUT) { char *mark; assert(((char *)request->data)[request->ndata] == '\0'); body = strdup(request->data); mark = strchr(body,'\n'); if (mark) *mark = '\0'; if (!strcmp(request->url, "/param/")) { run_and_respond(vparams->vadmin, request->connection, "param.set %s",body); } else { arg = request->url + strlen("/param/"); assert(arg && *arg); run_and_respond(vparams->vadmin, request->connection, "param.set %s %s",arg, body); } free(body); return 1; } http_reply(request->connection, 500, "Failed"); return 1; }
static unsigned int vcl_json(struct http_request *request, const char *arg, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct ipc_ret_t vret; struct vsb *json; struct http_response *resp; GET_PRIV(core, vcl); assert(STARTS_WITH(request->url, "/vcljson")); assert(request->method == M_GET); if (arg) { http_reply(request->connection, 404, "/vcljson takes no argument"); return (0); } ipc_run(vcl->vadmin, &vret, "vcl.list"); if (vret.status == 400) http_reply(request->connection, 500, vret.answer); else { json = vcl_list_json(vret.answer); assert(VSB_finish(json) == 0); resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(json); resp->ndata = VSB_len(json); http_add_header(resp, "Content-Type", "application/json"); send_response(resp); http_free_resp(resp); VSB_clear(json); VSB_delete(json); } free(vret.answer); return (0); }
/* handle built-in URLs here. Only one so far is "status" */ built_in(char *arg, int fd) { FILE *fp; if ( strcmp(arg,"status") != 0 ) return 0; http_reply(fd, &fp, 200, "OK", "text/plain",NULL); fprintf(fp,"Server started: %s", ctime(&server_started)); fprintf(fp,"Total requests: %d\n", server_requests); fprintf(fp,"Bytes sent out: %d\n", server_bytes_sent); fclose(fp); return 1; }
static unsigned int vstat_push_url(struct http_request *request, const char *arg, void *data) { struct vstat_priv_t *vstat; struct agent_core_t *core = data; (void)arg; GET_PRIV(core, vstat); pthread_rwlock_wrlock(&vstat->lck); if (vstat->push_url) free(vstat->push_url); DUP_OBJ(vstat->push_url, request->body, request->bodylen); logger(vstat->http.logger, "Got url: \"%s\"", vstat->push_url); pthread_rwlock_unlock(&vstat->lck); http_reply(request->connection, 200, "Url stored"); return (0); }
static void param_json(struct http_request *request, struct vparams_priv_t *vparams) { struct ipc_ret_t vret; char *tmp; ipc_run(vparams->vadmin, &vret, "param.show -l"); if (vret.status == 200) { tmp = vparams_show_json(vret.answer); struct http_response *resp = http_mkresp(request->connection, 200, tmp); http_add_header(resp,"Content-Type","application/json"); send_response(resp); free(tmp); http_free_resp(resp); } else { http_reply(request->connection, 500, vret.answer); } free(vret.answer); }
do_ls(char *dir, int fd) { DIR *dirptr; struct dirent *direntp; FILE *fp; int bytes = 0; bytes = http_reply(fd,&fp,200,"OK","text/plain",NULL); bytes += fprintf(fp,"Listing of Directory %s\n", dir); if ( (dirptr = opendir(dir)) != NULL ){ while( direntp = readdir(dirptr) ){ bytes += fprintf(fp, "%s\n", direntp->d_name); } closedir(dirptr); } fclose(fp); server_bytes_sent += bytes; }
static void backends_json(struct http_request *request, struct vbackends_priv_t *vbackends) { struct vsb *json; struct ipc_ret_t vret; ipc_run(vbackends->vadmin, &vret, "backend.list"); if (vret.status == 200) { json = VSB_new_auto(); assert(json); vbackends_show_json(json, vret.answer); AZ(VSB_finish(json)); struct http_response *resp = http_mkresp(request->connection, 200, VSB_data(json)); http_add_header(resp,"Content-Type","application/json"); send_response(resp); VSB_delete(json); http_free_resp(resp); } else http_reply(request->connection, 500, vret.answer); free(vret.answer); }
unsigned io_http_set_single_pulse(void) { struct { unsigned char ch; unsigned char duration; } data; data.duration = 0xaa; http_post_data((void*)&data, sizeof data); if(data.duration != 0xaa && data.ch < IO_MAX_CHANNEL) { struct io_setup_s *setup = &io_setup[data.ch]; if(setup->pulse_dur != data.duration) // save duration { setup->pulse_dur = data.duration; EEPROM_WRITE(&eeprom_io_setup[data.ch].pulse_dur, &setup->pulse_dur, sizeof eeprom_io_setup[0].pulse_dur); } io_start_pulse(data.ch); } //// http_redirect("/io.html"); http_reply(200, ""); // in 48/52/60/201/202 html used XHR, not submit return 0; }
void http1_1_handler(int clientDescriptor) { std::vector<std::string> lines = get_request_lines(clientDescriptor); std::vector<std::string> startString = split(lines[0], ' '); if (!check_request(clientDescriptor, lines, startString)) { return; } std::string requestPath = startString[1]; if (requestPath[0] == '/') { requestPath = requestPath.substr(1, requestPath.length() - 1); } for (size_t i = 1; i < requestPath.length(); ++i) { if (requestPath[i] == '.' && requestPath[i - 1] == '.') { process_error(clientDescriptor, FORBIDDEN); return; } } if (requestPath == "") { requestPath += homePageFile; } std::string mime = define_MIME(requestPath); if (mime == "none") { requestPath += ".html"; mime = "text/html"; } std::string fileBuf; FILE *file = popen(("python3 " + CGIPath + "cgi.py " + sitePath + requestPath + " " + CGIPath).c_str(), "r"); while (!feof(file)) { fileBuf += fgetc(file); } fileBuf.pop_back(); http_reply(clientDescriptor, OK, mime, fileBuf); wr_close(clientDescriptor); }
void http1_1_handler(int clientDescriptor) { std::vector<std::string> lines = get_request_lines(clientDescriptor); std::vector<std::string> startString = split(lines[0], ' '); if (!check_request(clientDescriptor, lines, startString)) { return; } std::string requestPath = startString[1]; if (requestPath[0] == '/') { requestPath = requestPath.substr(1, requestPath.length() - 1); } for (size_t i = 1; i < requestPath.length(); ++i) { if (requestPath[i] == '.' && requestPath[i - 1] == '.') { process_error(clientDescriptor, FORBIDDEN); return; } } if (requestPath == "") { requestPath += homePageFile; } std::string mime = define_MIME(requestPath); if (mime == "none") { requestPath += ".html"; mime = "text/html"; } std::string fileBuf; if (get_file(sitePath + requestPath, fileBuf) == -1) { process_error(clientDescriptor, NOT_FOUND); return; } http_reply(clientDescriptor, OK, mime, fileBuf); wr_close(clientDescriptor); }
static int answer_to_connection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t * upload_data_size, void **con_cls) { struct agent_core_t *core = (struct agent_core_t *)cls; struct http_priv_t *http; struct http_request request; struct connection_info_struct *con_info; (void)version; GET_PRIV(core, http); if (*con_cls == NULL) { ALLOC_OBJ(con_info); *con_cls = con_info; return (MHD_YES); } con_info = *con_cls; assert(core->config->userpass); log_request(connection, http, method, url); if (!strcmp(method, "OPTIONS")) { /* We need this for preflight requests (CORS). */ return (http_reply(connection, 200, NULL)); } else if (!strcmp(method, "GET") || !strcmp(method, "HEAD") || !strcmp(method, "DELETE")) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "DELETE")) request.method = M_DELETE; else request.method = M_GET; request.connection = connection; request.url = url; request.ndata = 0; if (find_listener(&request, http)) return (MHD_YES); } else if (!strcmp(method, "POST") || !strcmp(method, "PUT")) { if (*upload_data_size != 0) { if (*upload_data_size + con_info->progress >= RCV_BUFFER) { warnlog(http->logger, "Client input exceeded buffer size " "of %u bytes. Dropping client.", RCV_BUFFER); return (MHD_NO); } memcpy(con_info->answerstring + con_info->progress, upload_data, *upload_data_size); con_info->progress += *upload_data_size; *upload_data_size = 0; return (MHD_YES); } else if ((char *)con_info->answerstring != NULL) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "POST")) request.method = M_POST; else request.method = M_PUT; request.connection = connection; request.url = url; request.ndata = con_info->progress; request.data = con_info->answerstring; /* * FIXME */ ((char *)request.data)[con_info->progress] = '\0'; if (find_listener(&request, http)) return (MHD_YES); } } if (request.method == M_GET && !strcmp(url, "/")) { if (http->help_page == NULL) http->help_page = make_help(http); assert(http->help_page); return (http_reply(connection, 200, http->help_page)); } return (http_reply(connection, 500, "Failed")); }
static int on_message_complete(http_parser *parser) { struct http_state *state = parser->data; const char *addr = NULL; bool pathmatch = false; bool methmatch = false; int r = 0; if (state->req.status != 0) goto error; addr = getenv("REMOTE_ADDR"); fprintf(stderr, "%s %s %s", addr ? addr : "<unknown>", METHOD_NAMES[parser->method], state->req.path); for (size_t i = 0; state->dispatch[i].re && r == 0; i++) { const struct http_dispatch *d = &state->dispatch[i]; regmatch_t match[d->nmatches]; regex_t re = {}; memset(match, 0, sizeof(match)); r = regcomp(&re, d->re, REG_EXTENDED) == 0 ? 0 : -EINVAL; if (r != 0) { state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR; goto error; } if (regexec(&re, state->req.path, d->nmatches, match, 0) == 0) { pathmatch = true; if (((1 << parser->method) & d->methods) != 0) { methmatch = true; r = d->func(parser->method, state->req.path, state->req.body, match, state->misc); } } regfree(&re); } if (r > 0) goto egress; if (r == 0) { if (!pathmatch) state->req.status = HTTP_STATUS_NOT_FOUND; else if (!methmatch) state->req.status = HTTP_STATUS_METHOD_NOT_ALLOWED; else state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR; } else { state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR; } error: http_reply(__FILE__, __LINE__, state->req.status, NULL); egress: memset(&state->req, 0, sizeof(state->req)); return 0; }
static unsigned int vcl_reply(struct http_request *request, void *data) { struct agent_core_t *core = data; struct vcl_priv_t *vcl; struct http_response *resp; struct ipc_ret_t vret; char id[ID_LEN + 1]; int ret; int status; GET_PRIV(core, vcl); if (request->method == M_GET) { if (!strcmp(request->url, "/vclactive") || !strcmp(request->url,"/vclactive/")) { /* * vcl.list output: * * V3/4 : (active|available|discarded) (refcnt) (name) * V4.1 : (active|available|discarded) (state) \ * (busycnt|) (name) */ ipc_run(vcl->vadmin,&vret,"vcl.list"); if (vret.status == 400) { http_reply(request->connection, 500, vret.answer); } else { char **tp, *tok[5]; char *p, *last; char *line; memset(tok, '\0', sizeof(tok)); for (p = vret.answer, last = NULL; (line = strtok_r(p, "\n", &last)); p = NULL) { if (strncmp("active", line, 6)) continue; last = NULL; for (p = line, tp = tok; tp < &tok[4] && (*tp = strtok_r(p, " ", &last)); p = NULL) { if (**tp != '\0') tp++; } } if (!tok[2] || !tok[3]) { http_reply(request->connection, 500, "No active VCL"); } else { strcpy(vret.answer, tok[3] ? tok[3] : tok[2]); http_reply(request->connection, 200, vret.answer); } } free(vret.answer); return 0; } else if (!strcmp(request->url, "/vcl") || !strcmp(request->url,"/vcl/")) { ipc_run(vcl->vadmin, &vret, "vcl.list"); if (vret.status == 400) { http_reply(request->connection, 500, vret.answer); } else { http_reply(request->connection, 200, vret.answer); } free(vret.answer); return 0; } else if (!strncmp(request->url,"/vcl/",strlen("/vcl/"))) { ipc_run(vcl->vadmin, &vret, "vcl.show %s", request->url + strlen("/vcl/")); if (vret.status == 400) { http_reply(request->connection, 500, vret.answer); } else { http_reply(request->connection, 200, vret.answer); } free(vret.answer); return 0; } else if(!strcmp(request->url, "/vcljson/")) { struct vsb *json; ipc_run(vcl->vadmin, &vret, "vcl.list"); if (vret.status == 400) { http_reply(request->connection, 500, vret.answer); } else { json = vcl_list_json(vret.answer); assert(VSB_finish(json) == 0); resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(json); resp->ndata = VSB_len(json); http_add_header(resp, "Content-Type", "application/json"); send_response(resp); http_free_resp(resp); VSB_clear(json); VSB_delete(json); } free(vret.answer); return 0; } else { http_reply(request->connection, 500, "Invalid VCL-url."); return 0; } } else if (request->method == M_POST) { snprintf(id, sizeof(id), "%ju", (uintmax_t) time(NULL)); status = vcl_store(request, vcl, &vret, core, id); http_reply(request->connection, status, vret.answer); free(vret.answer); return 0; } else if (request->method == M_PUT) { if (!strncmp(request->url,"/vcl/",strlen("/vcl/"))) { if (strlen(request->url) >= 6) { status = vcl_store(request, vcl, &vret, core, request->url + strlen("/vcl/")); http_reply(request->connection, status, vret.answer); free(vret.answer); return 0; } else { http_reply(request->connection, 400, "Bad URL?"); return 0; } } else if (!strncmp(request->url, "/vcldeploy/",strlen("/vcldeploy/"))) { ipc_run(vcl->vadmin, &vret, "vcl.use %s", request->url + strlen("/vcldeploy/")); if (vret.status == 200) { ret = vcl_persist_active(vcl->logger, request->url + strlen("/vcldeploy/"), core); } if (vret.status == 200 && ret) http_reply(request->connection, 500, "Deployed ok, but NOT PERSISTED."); else if (vret.status == 200 && ret == 0) http_reply(request->connection, 200, vret.answer); else http_reply(request->connection, 500, vret.answer); free(vret.answer); return 0; } } else if (request->method == M_DELETE) { if (!strncmp(request->url, "/vcl/", strlen("/vcl/"))) { ipc_run(vcl->vadmin, &vret, "vcl.discard %s", request->url + strlen("/vcl/")); if (vret.status == 400 || vret.status == 106) { http_reply(request->connection, 500, vret.answer); } else { http_reply(request->connection, 200, vret.answer); } free(vret.answer); return 0; } } else { return http_reply(request->connection, 500, "Unknown request?"); } assert("Shouldn't get here" == NULL); return 0; }
int http_handle_request (RESTSESSION * r) { struct buf *b; char buf[512]; char *p; SPOTIFYSESSION *client; /* * r->httpreq->url has path that was requested * r->httpreq->authheader MIGHT be non-NULL and * have username:password in base64 * */ /* Default to process next command */ r->state = REST_STATE_LOAD_COMMAND; if ((client = spotify_find_http_client ()) == NULL) { /* Force auth if not sent or likely invalid */ if (!r->httpreq->authheader || strlen (r->httpreq->authheader) > 100) return http_reply_need_auth (r); memset (buf, 0, sizeof (buf)); b64decode (r->httpreq->authheader, buf); if ((p = strchr (buf, ':')) == NULL) { printf ("b64 decode failed '%s'\n", buf); return http_reply_need_auth (r); } *p++ = 0; strcpy (r->username, buf); strcpy (r->password, p); spotify_client_allocate (r); spotify_client_mark_for_http (r->client); if (r->client->state == CLIENT_STATE_IDLE_CONNECTED) return http_complete_login (r); r->state = REST_STATE_WAITING; r->httpreq->callback = http_complete_login; return 0; } if (0) { } else { b = buf_new (); sprintf (buf, "You're logged in as '%s' with password '%s'<br />\n", r->username, r->password); if (client) buf_append_data(b, buf, strlen (buf)); sprintf (buf, "The requested URL '%s' was not found!\n", r->httpreq->url); buf_append_data(b, buf, strlen (buf)); return http_reply (r, 404, b); } return 0; }
END_TEST #if HAVE_EVHTTP_H START_TEST(test_http) { struct parent_msg msg = {}; const char *errstr = NULL; extern char *http_host, *http_path; static struct event_base *base; struct evhttp *httpd; extern struct evhttp_request *lreq; extern struct evhttp_connection *evcon; extern int status; extern short http_port; int sock = -1; // check for ipv4 before running the test mark_point(); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) return; else close(sock); // this assumes libevent can connect to localhost // sounds silly, but I've seen it fail... http_host = "127.0.0.1"; http_path = "/cgi-bin/test.cgi"; event_set_log_callback(&fake_log_cb); mark_point(); base = event_init(); httpd = evhttp_new(base); for (http_port = 8080; http_port < 8090; http_port++) { if (evhttp_bind_socket(httpd, http_host, http_port) != -1) break; } fail_unless (http_port < 8090, "failed to start httpd on %s", http_host); // If either of these two fail then we're screwed anyway mark_point(); http_connect(); mark_point(); http_request(&msg, 0); mark_point(); strlcpy(msg.name, "eth0", IFNAMSIZ); msg.proto = PROTO_CDP; msg.decode = (1 << PEER_HOSTNAME)|(1 << PEER_PORTNAME); msg.peer[PEER_HOSTNAME] = strdup("router"); msg.peer[PEER_PORTNAME] = strdup("Fas'tEthernet42/64"); http_request(&msg, 0); mark_point(); errstr = "HTTP request failed"; my_log(CRIT, "check"); WRAP_FATAL_START(); http_reply(lreq, NULL); WRAP_FATAL_END(); fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0, "incorrect message logged: %s", check_wrap_errstr); mark_point(); lreq->response_code = 200; http_reply(lreq, NULL); fail_unless (status == EXIT_SUCCESS, "incorrect exit status returned: %d", status); mark_point(); lreq->response_code = 404; errstr = "HTTP error 404 received"; my_log(CRIT, "check"); http_reply(lreq, NULL); fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0, "incorrect message logged: %s", check_wrap_errstr); fail_unless (status == EXIT_FAILURE, "incorrect exit status returned: %d", status); mark_point(); evhttp_connection_free(evcon); lreq = NULL; mark_point(); errstr = "failed"; my_log(CRIT, "check"); evcon = evhttp_connection_new("256.256.256.256", 0); WRAP_FATAL_START(); http_request(&msg, 0); WRAP_FATAL_END(); fail_unless (strstr(check_wrap_errstr, errstr) != NULL, "incorrect message logged: %s", check_wrap_errstr); evhttp_connection_free(evcon); mark_point(); errstr = "failed"; my_log(CRIT, "check"); evcon = evhttp_connection_new("localhost", 0); WRAP_FATAL_START(); http_request(&msg, 0); http_dispatch(); WRAP_FATAL_END(); fail_unless (strstr(check_wrap_errstr, errstr) != NULL, "incorrect message logged: %s", check_wrap_errstr); mark_point(); // free the active connection evhttp_connection_free(evcon); lreq = NULL; evcon = evhttp_connection_new(http_host, 80); http_dispatch(); evhttp_free(httpd); event_base_free(base); peer_free(msg.peer); }
void process_error(int clientDescriptor, HttpResponse error) { std::string buf; get_file(std::to_string(error) + ".html", buf); http_reply(clientDescriptor, error, "text/html", buf); wr_close(clientDescriptor); }
static unsigned int vlog_reply(struct http_request *request, void *data) { struct vlog_req_priv vrp = { .limit = 10 }; int disp_status; char *p; char *tag = NULL; char *tag_re = NULL; struct VSL_data *vsl = NULL; struct VSLQ *vslq = NULL; struct VSL_cursor *c = NULL; enum VSL_grouping_e grouping = VSL_g_request; struct agent_core_t *core = data; p = next_slash(request->url + 1); if (p) { char *lim = strdup(p); assert(lim); char *tmp2 = strchr(lim, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; int j = sscanf(lim, "%u", &vrp.limit); if(j != 1) { free(lim); http_reply(request->connection, 500, "Not a number"); return 0; } free(lim); p = next_slash(p); } if (p) { tag = strdup(p); char *tmp2 = strchr(tag,'/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } if (p) { tag_re = strdup(p); char *tmp2 = strchr(tag_re, '/'); if (tmp2 && *tmp2) *tmp2 = '\0'; p = next_slash(p); } vrp.answer = VSB_new_auto(); assert(vrp.answer != NULL); vrp.vsm = VSM_New(); assert(vrp.vsm); if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) { VSB_printf(vrp.answer, "Error in creating shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (VSM_Open(vrp.vsm) != 0) { VSB_printf(vrp.answer, "Error in opening shmlog: %s", VSM_Error(vrp.vsm)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vsl = VSL_New(); assert(vsl); if (tag) { grouping = VSL_g_raw; if (VSL_Arg(vsl, 'i', tag) < 0) { VSB_printf(vrp.answer, "Unable to specify tag '%s': %s", tag, VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } if (tag_re) { VSL_Arg(vsl,'I', tag_re); } } c = VSL_CursorVSM(vsl, vrp.vsm, VSL_COPT_BATCH | VSL_COPT_TAILSTOP); if (c == NULL) { VSB_printf(vrp.answer, "Can't open log (%s)", VSL_Error(vsl)); VSB_finish(vrp.answer); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } vslq = VSLQ_New(vsl, &c, grouping, NULL); if (vslq == NULL) { VSB_clear(vrp.answer); VSB_printf(vrp.answer, "Error in creating query: %s", VSL_Error(vsl)); http_reply(request->connection, 500, VSB_data(vrp.answer)); goto cleanup; } VSB_printf(vrp.answer, "{ \"log\": ["); do { disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp); } while (disp_status == 1 && vrp.entries < vrp.limit); VSB_printf(vrp.answer, "\n] }\n"); assert(VSB_finish(vrp.answer) == 0); if (VSB_len(vrp.answer) > 1) { struct http_response *resp = http_mkresp(request->connection, 200, NULL); resp->data = VSB_data(vrp.answer); resp->ndata = VSB_len(vrp.answer); http_add_header(resp,"Content-Type","application/json"); send_response(resp); http_free_resp(resp); } else { http_reply(request->connection, 500, "FAIL"); } cleanup: free(tag); free(tag_re); VSB_delete(vrp.answer); if (vslq) VSLQ_Delete(&vslq); if (vsl) VSL_Delete(vsl); if (vrp.vsm) VSM_Delete(vrp.vsm); vrp.answer = NULL; return 0; } void vlog_init(struct agent_core_t *core) { struct agent_plugin_t *plug; struct vlog_priv_t *priv; ALLOC_OBJ(priv); plug = plugin_find(core,"vlog"); plug->data = priv; http_register_url(core, "/log", M_GET, vlog_reply, core); }