--- /dev/null
+/*
+ * mod_example_1.c: Example module for Apache HTTP Server 2.4
+ * A simple "Hello, world!" handler.
+ */
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "ap_config.h"
+
+static int example_handler(request_rec *r)
+{
+ /* First off, we need to check if this is a call for the "example-handler" handler.
+ * If it is, we accept it and do our things, if not, we simply return DECLINED,
+ * and the server will try somewhere else.
+ */
+ if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
+
+ /* Now that we are handling this request, we'll write out "Hello, world!" to the client.
+ * To do so, we must first set the appropriate content type, followed by our output.
+ */
+ ap_set_content_type(r, "text/html");
+ ap_rprintf(r, "Hello, world!");
+
+ /* Lastly, we must tell the server that we took care of this request and everything went fine.
+ * We do so by simply returning the value OK to the server.
+ */
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *pool)
+{
+ /* Create a hook in the request handler, so we get called when a request arrives */
+ ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+
+AP_DECLARE_MODULE(example) =
+{
+ STANDARD20_MODULE_STUFF,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ register_hooks /* Our hook registering function */
+};
--- /dev/null
+/*
+ * mod_example_2.c: Example module for Apache HTTP Server 2.4
+ * This module calculates and displays MD5 or SHA1 digests of files.
+ */
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "ap_config.h"
+#include "apr_md5.h"
+#include "apr_sha1.h"
+#include "apr_file_io.h"
+#include "apr_tables.h"
+
+static int example_handler(request_rec *r)
+{
+ int rc, exists;
+ apr_finfo_t finfo;
+ apr_file_t *file;
+ char *filename;
+ char buffer[256];
+ apr_size_t readBytes;
+ int n;
+ apr_table_t *GET;
+ apr_array_header_t *POST;
+ const char *digestType;
+
+
+ /* Check that the "example-handler" handler is being called. */
+ if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
+
+ /* Figure out which file is being requested by removing the .sum from it */
+ filename = apr_pstrdup(r->pool, r->filename);
+ filename[strlen(filename)-4] = 0; /* Cut off the last 4 characters. */
+
+ /* Figure out if the file we request a sum on exists and isn't a directory */
+ rc = apr_stat(&finfo, filename, APR_FINFO_MIN, r->pool);
+ if (rc == APR_SUCCESS) {
+ exists =
+ (
+ (finfo.filetype != APR_NOFILE)
+ && !(finfo.filetype & APR_DIR)
+ );
+ if (!exists) return HTTP_NOT_FOUND; /* Return a 404 if not found. */
+ }
+ /* If apr_stat failed, we're probably not allowed to check this file. */
+ else return HTTP_FORBIDDEN;
+
+ /* Parse the GET and, optionally, the POST data sent to us */
+
+ ap_args_to_table(r, &GET);
+ ap_parse_form_data(r, NULL, &POST, -1, 8192);
+
+ /* Set the appropriate content type */
+ ap_set_content_type(r, "text/html");
+
+ /* Print a title and some general information */
+ ap_rprintf(r, "<h2>Information on %s:</h2>", filename);
+ ap_rprintf(r, "<b>Size:</b> %" APR_OFF_T_FMT " bytes<br/>", finfo.size);
+
+ /* Get the digest type the client wants to see */
+ digestType = apr_table_get(GET, "digest");
+ if (!digestType) digestType = "MD5";
+
+
+ rc = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT, r->pool);
+ if (rc == APR_SUCCESS) {
+
+ /* Are we trying to calculate the MD5 or the SHA1 digest? */
+ if (!strcasecmp(digestType, "md5")) {
+ /* Calculate the MD5 sum of the file */
+ union {
+ char chr[16];
+ uint32_t num[4];
+ } digest;
+ apr_md5_ctx_t md5;
+ apr_md5_init(&md5);
+ readBytes = 256;
+ while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
+ apr_md5_update(&md5, buffer, readBytes);
+ }
+ apr_md5_final(digest.chr, &md5);
+
+ /* Print out the MD5 digest */
+ ap_rputs("<b>MD5: </b><code>", r);
+ for (n = 0; n < APR_MD5_DIGESTSIZE/4; n++) {
+ ap_rprintf(r, "%08x", digest.num[n]);
+ }
+ ap_rputs("</code>", r);
+ /* Print a link to the SHA1 version */
+ ap_rputs("<br/><a href='?digest=sha1'>View the SHA1 hash instead</a>", r);
+ }
+ else {
+ /* Calculate the SHA1 sum of the file */
+ union {
+ char chr[20];
+ uint32_t num[5];
+ } digest;
+ apr_sha1_ctx_t sha1;
+ apr_sha1_init(&sha1);
+ readBytes = 256;
+ while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
+ apr_sha1_update(&sha1, buffer, readBytes);
+ }
+ apr_sha1_final(digest.chr, &sha1);
+
+ /* Print out the SHA1 digest */
+ ap_rputs("<b>SHA1: </b><code>", r);
+ for (n = 0; n < APR_SHA1_DIGESTSIZE/4; n++) {
+ ap_rprintf(r, "%08x", digest.num[n]);
+ }
+ ap_rputs("</code>", r);
+
+ /* Print a link to the MD5 version */
+ ap_rputs("<br/><a href='?digest=md5'>View the MD5 hash instead</a>", r);
+ }
+ apr_file_close(file);
+
+ }
+ /* Let the server know that we responded to this request. */
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *pool)
+{
+ /* Create a hook in the request handler, so we get called when a request arrives */
+ ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+
+AP_DECLARE_MODULE(example) =
+{
+ STANDARD20_MODULE_STUFF,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ register_hooks /* Our hook registering function */
+};