From 8328c939d1683081295cd9868085304e8d85521b Mon Sep 17 00:00:00 2001 From: Trumeet Date: Thu, 18 Nov 2021 15:49:29 -0800 Subject: First Commit --- .gitignore | 3 +++ CMakeLists.txt | 15 +++++++++++ LICENSE | 13 ++++++++++ README.md | 50 +++++++++++++++++++++++++++++++++++ main.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46f9d90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +cmake-build-debug/ +cmake-build-release/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d927a7d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.20) +project(mdrd C) +set(CMAKE_C_FLAGS_DEBUG + "${CMAKE_C_FLAGS_DEBUG} -g3 -O0 -fsanitize=address") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG + "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address") + +set(CMAKE_C_STANDARD 99) + +add_executable(mdrd main.c) + +include(FindPkgConfig) +pkg_check_modules(FCgi REQUIRED IMPORTED_TARGET "fcgi") +pkg_check_modules(CMark REQUIRED IMPORTED_TARGET "libcmark") +target_link_libraries(mdrd PRIVATE fcgi cmark) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..456c488 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md new file mode 100644 index 0000000..72efcdc --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# mdrd + +Simple CGI Markdown renderer. + +## Building + +Requirements: + +* cmark + +* fcgi + +* cmake + +* pkgconfig + +```shell +$ mkdir cmake-build-release/ +$ cd cmake-build-release/ +$ cmake -DCMAKE_BUILD_TYPE=Release .. +$ make -j mdrd +``` + +## Running + +Start a FCGI parent process: + +```shell +$ spawn-fcgi -p 8080 -n ./mdrd +``` + +Setup your web server with document root, fastcgi parameters and fastcgi port. Nginx example: + +``` +server { + root /path/to/markdown/root; + autoindex on; + index index.html index.md; + location ~ \.md$ { + include fastcgi_params; + fastcgi_pass 127.0.0.1:8080; + } +} +``` + +You are ready to go. + +## License + +WTFPL. Experimental project. No warranty. diff --git a/main.c b/main.c new file mode 100644 index 0000000..3790332 --- /dev/null +++ b/main.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +static void print_error(const char *error, ...) { + printf("Status: 500 Internal Server Error\r\n" + "Content-Type: text/html\r\n" + "\r\n" + "" + "" + "" + "Error" + "" + "" + "

The server encountered the following error(s) rendering your document:
"); + va_list args; + va_start(args, error); + vprintf(error, args); + va_end(args); + printf("

" + ""); +} + +int main() { + while (FCGI_Accept() >= 0) { + const char *doc_root = getenv("DOCUMENT_ROOT"); + if (doc_root == NULL) { + print_error("%s is not set. Check if you included fastcgi_params in your web server configuration.", + "DOCUMENT_ROOT"); + goto end; + } + const char *doc_uri = getenv("DOCUMENT_URI"); + if (doc_uri == NULL) { + print_error("%s is not set. Check if you included fastcgi_params in your web server configuration.", + "DOCUMENT_URI"); + goto end; + } + char *uri = calloc(strlen(doc_root) + 1 /* separator */ + strlen(doc_uri) + 1 /* \0 */, + sizeof(char)); + if (uri == NULL) { + int r = errno; + print_error("Cannot allocate memory: %s\n", strerror(r)); + goto end; + } + sprintf(uri, "%s/%s", doc_root, doc_uri); + FILE *file = fopen(uri, "r"); + if (file == NULL) { + int r = errno; + if (r == ENOENT) { + printf("Status: 404 Not Found\r\nContent-Type: text/plain\r\n\r\n"); + free(uri); + goto end; + } + print_error("Cannot open file %s: %s\n", uri, strerror(r)); + free(uri); + goto end; + } + free(uri); + cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT); + ssize_t bytes; + char buffer[1024]; + while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0) { + cmark_parser_feed(parser, buffer, bytes); + if (bytes < sizeof(buffer)) { + break; + } + } + cmark_node *document = cmark_parser_finish(parser); + cmark_parser_free(parser); + char *html = cmark_render_html(document, CMARK_OPT_DEFAULT); //cmark_markdown_to_html(buffer, strlen(buffer), 0); + cmark_node_free(document); + printf("Content-Type: text/html\r\n\r\n%s", html); + free(html); + fclose(file); + goto end; + end: + continue; + } + return 0; +} -- cgit v1.2.3