本文主要是介绍mongoose httpserver webcommand,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
说明
在mongoose http server的基础上允许在URL栏输入command,返回输出结果
eg:
localhost:8000/command:
ls
其中/command:
为关键字代表之后的为要执行的命令
main_webcommand.c
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved#include <signal.h>
#include "mongoose.h"static int s_debug_level = MG_LL_INFO;
static const char *s_root_dir = ".";
static const char *s_listening_address = "http://0.0.0.0:8000";
static const char *s_enable_hexdump = "no";
static const char *s_ssi_pattern = "#.html";
static const char *s_upload_dir = NULL; // File uploads disabled by default// Handle interrupts, like Ctrl-C
static int s_signo;
static void signal_handler(int signo) {s_signo = signo;
}// Event handler for the listening connection.
// Simply serve static files from `s_root_dir`
static void cb(struct mg_connection *c, int ev, void *ev_data) {if (ev == MG_EV_HTTP_MSG) {struct mg_http_message *hm = ev_data, send_hm; memset(&send_hm, 0, sizeof(send_hm));if (mg_match(hm->uri, mg_str("/upload"), NULL)) {// Serve file uploadif (s_upload_dir == NULL) {mg_http_reply(c, 403, "", "Denied: file upload directory not set\n");} else {struct mg_http_part part;size_t pos = 0, total_bytes = 0, num_files = 0;while ((pos = mg_http_next_multipart(hm->body, pos, &part)) > 0) {char path[MG_PATH_MAX];MG_INFO(("Chunk name: [%.*s] filename: [%.*s] length: %lu bytes",part.name.len, part.name.ptr, part.filename.len,part.filename.ptr, part.body.len));mg_snprintf(path, sizeof(path), "%s/%.*s", s_upload_dir,part.filename.len, part.filename.ptr);if (mg_path_is_sane(path)) {mg_file_write(&mg_fs_posix, path, part.body.ptr, part.body.len);total_bytes += part.body.len;num_files++;} else {MG_ERROR(("Rejecting dangerous path %s", path));}}mg_http_reply(c, 200, "", "Uploaded %lu files, %lu bytes\n", num_files,total_bytes);}} else {// Serve web root directorystruct mg_http_serve_opts opts = {0};opts.root_dir = s_root_dir;opts.ssi_pattern = s_ssi_pattern;if (hm->uri.len > 9 && strncmp("/command:", hm->uri.ptr, 9) == 0){#define URI_SIZE 256char command[URI_SIZE] = {'\0'};mg_url_decode(hm->uri.ptr+9, hm->uri.len-9, command, URI_SIZE, 0);#undef URI_SIZEFILE* o_cmd = popen(command, "r");if (!o_cmd){MG_ERROR(("exec command failed"));mg_http_reply(c, 500, "", "");goto end;}// #define BUFSIZ 10char* out_buf = calloc(1 , BUFSIZ);if (!out_buf){MG_ERROR(("mem failed"));mg_http_reply(c, 503, "", "");goto end;}int n_read = fread(out_buf, 1, BUFSIZ-1, o_cmd);int content_len = 0;if (out_buf[0] != '\0') {mg_http_reply(c, 200, "", "%s", out_buf);content_len += n_read;} else {mg_http_reply(c, 200, "", "you command has no output or command error");}while (!feof(o_cmd)){n_read = fread(out_buf, 1, BUFSIZ-1, o_cmd);out_buf[n_read] = 0;mg_http_write_chunk(c, out_buf, n_read);content_len += n_read;}if (content_len){char cont_len_str[11] = {0};snprintf(cont_len_str, 10, "%d", content_len);mg_http_parse((const char*)c->send.buf, c->send.len, &send_hm);struct mg_str* cl = mg_http_get_header(&send_hm, "Content-Length");memcpy((void*)(cl->ptr), cont_len_str, strlen(cont_len_str));}free(out_buf);end: // that's okpclose(o_cmd);}else{mg_http_serve_dir(c, hm, &opts);}}// Log requestMG_INFO(("%.*s %.*s %lu -> %.*s %lu", hm->method.len, hm->method.ptr,hm->uri.len, hm->uri.ptr, hm->body.len, 3, c->send.buf + 9,c->send.len));}
}static void usage(const char *prog) {fprintf(stderr,"Mongoose v.%s\n""Usage: %s OPTIONS\n"" -H yes|no - enable traffic hexdump, default: '%s'\n"" -S PAT - SSI filename pattern, default: '%s'\n"" -d DIR - directory to serve, default: '%s'\n"" -l ADDR - listening address, default: '%s'\n"" -u DIR - file upload directory, default: unset\n"" -v LEVEL - debug level, from 0 to 4, default: %d\n",MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir,s_listening_address, s_debug_level);exit(EXIT_FAILURE);
}int main(int argc, char *argv[]) {char path[MG_PATH_MAX] = ".";struct mg_mgr mgr;struct mg_connection *c;int i;// Parse command-line flagsfor (i = 1; i < argc; i++) {if (strcmp(argv[i], "-d") == 0) {s_root_dir = argv[++i];} else if (strcmp(argv[i], "-H") == 0) {s_enable_hexdump = argv[++i];} else if (strcmp(argv[i], "-S") == 0) {s_ssi_pattern = argv[++i];} else if (strcmp(argv[i], "-l") == 0) {s_listening_address = argv[++i];} else if (strcmp(argv[i], "-u") == 0) {s_upload_dir = argv[++i];} else if (strcmp(argv[i], "-v") == 0) {s_debug_level = atoi(argv[++i]);} else {usage(argv[0]);}}// Root directory must not contain double dots. Make it absolute// Do the conversion only if the root dir spec does not contain overridesif (strchr(s_root_dir, ',') == NULL) {realpath(s_root_dir, path);s_root_dir = path;}// Initialise stuffsignal(SIGINT, signal_handler);signal(SIGTERM, signal_handler);mg_log_set(s_debug_level);mg_mgr_init(&mgr);if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT",s_listening_address));exit(EXIT_FAILURE);}if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;// Start infinite event loopMG_INFO(("Mongoose version : v%s", MG_VERSION));MG_INFO(("Listening on : %s", s_listening_address));MG_INFO(("Web root : [%s]", s_root_dir));MG_INFO(("Upload dir : [%s]", s_upload_dir ? s_upload_dir : "unset"));while (s_signo == 0) mg_mgr_poll(&mgr, 1000);mg_mgr_free(&mgr);MG_INFO(("Exiting on signal %d", s_signo));return 0;
}
参考链接:
https://github.com/cesanta/mongoose/blob/master/examples/http-server/main.c
这篇关于mongoose httpserver webcommand的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!