/* * This file is an example of how to embed web-server functionality * into existing application. * Compilation line: * cc example.c shttpd.c -DEMBEDDED */ #ifdef _WIN32 #include #define snprintf _snprintf #pragma comment(lib,"ws2_32") #else #include #include #endif #include #include #include #include #include #include #include "shttpd.h" static int index_html(struct shttpd_arg_t *arg) { int n = 0; int *p = arg->user_data; /* integer passed to us */ FILE *fp; const char *value, *fname, *data, *host, *addr; /* Change the value of integer variable */ if ((value = shttpd_get_var(arg, "name1")) != NULL) *p = atoi(value); n += snprintf(arg->buf + n, arg->buflen - n, "%s", "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n\r\n"); n += snprintf(arg->buf + n, arg->buflen - n, "

Welcome to embedded" " example of SHTTPD v. %s

", shttpd_version()); n += snprintf(arg->buf + n, arg->buflen - n, "

Internal int variable value: [%d]

", *p); n += snprintf(arg->buf + n, arg->buflen - n, "%s", "
" "Enter new value: " "" "" "
    " "
  • Protected page (guest:guest)" "
  • Output 1Mb of data" "
  • Aliased /etc directory" "
  • On-disk file (Makefile)"); host = shttpd_get_header(arg, "Host"); n += snprintf(arg->buf + n, arg->buflen - n, "
  • 'Host' header value: [%s]", host ? host : "NOT SET"); n += snprintf(arg->buf + n, arg->buflen - n, "
  • This example shows that it is possible to POST " "big volumes of data, and save it into a file"); /* Save POSTed data */ if ((fname = shttpd_get_var(arg, "filename")) != NULL) { if ((fp = fopen(fname, "w+")) != NULL) { if ((data = shttpd_get_var(arg, "data")) == NULL) { n += snprintf(arg->buf + n, arg->buflen - n, "

    Could not get data

    "); } else if (fwrite(data, strlen(data), 1, fp) != 1) { n += snprintf(arg->buf + n, arg->buflen - n, "

    Could not write data: %s

    ", strerror(errno)); } (void) fclose(fp); } else { n += snprintf(arg->buf + n, arg->buflen - n, "

    Error opening %s: %s

    ", fname, strerror(errno)); } } n += snprintf(arg->buf + n, arg->buflen - n, "
    " "

    Enter file name to store POSTed data: " "" "

    Data to be stored:
    " "
    " "

    ", fname ? fname : ""); n += snprintf(arg->buf + n, arg->buflen - n, ""); assert(n < (int)arg->buflen); arg->last = 1; return (n); } static int secret_html(struct shttpd_arg_t *arg) { int n = 0; n = snprintf(arg->buf, arg->buflen, "%s", "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" "\r\n

    This is a protected page"); arg->last = 1; return (n); } static int huge_html(struct shttpd_arg_t *arg) { int state = (int) arg->state, n = 0; #define BYTES_TO_OUTPUT 100000 if (state == 0) { n = snprintf(arg->buf, arg->buflen, "%s", "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"); } for (; n < (int) arg->buflen; n++, state++) { arg->buf[n] = state % 72 ? 'A' : '\n'; if (state > BYTES_TO_OUTPUT) { arg->last = 1; break; } } arg->state = (void *) state; return (n); } int main(int argc, char *argv[]) { int sock, data = 1234567; struct shttpd_ctx *ctx; /* Get rid of warnings */ argc = argc; argv = argv; /* * Initialize SHTTPD context. * Attach folder c:\ to the URL /my_c (for windows), and * /etc/ to URL /my_etc (for UNIX). These are Apache-like aliases. * Set WWW root to current directory. */ ctx = shttpd_init(NULL, "aliases", "c:\\/->/my_c,/etc/->/my_etc", "document_root", ".", NULL); /* Let pass 'data' variable to callback, user can change it */ shttpd_register_url(ctx, "/", &index_html, (void *) &data); shttpd_register_url(ctx, "/abc.html", &index_html, (void *) &data); /* Show how to use password protection */ shttpd_register_url(ctx, "/secret", &secret_html, (void *) &data); shttpd_protect_url(ctx, "/secret", "passfile"); /* Show how to use stateful big data transfer */ shttpd_register_url(ctx, "/huge", &huge_html, NULL); /* Open listening socket */ sock = shttpd_open_port(9000); shttpd_listen(ctx, sock); /* Serve connections infinitely until someone kills us */ for (;;) shttpd_poll(ctx, 1000); /* Probably unreached, because we will be killed by signal */ shttpd_fini(ctx); return (EXIT_SUCCESS); }