summaryrefslogtreecommitdiff
path: root/recipes-core/lighttpd/lighttpd
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-core/lighttpd/lighttpd')
-rw-r--r--recipes-core/lighttpd/lighttpd/0001-lighttpd-pcre-use-pkg-config.patch41
-rw-r--r--recipes-core/lighttpd/lighttpd/0002_extended_tls_conf.patch110
-rw-r--r--recipes-core/lighttpd/lighttpd/0004_fastcgi_env_with_unixsocket.patch57
-rw-r--r--recipes-core/lighttpd/lighttpd/lighttpd.conf209
-rw-r--r--recipes-core/lighttpd/lighttpd/lighttpd.init34
-rw-r--r--recipes-core/lighttpd/lighttpd/lighttpd_custom_images_setup57
-rw-r--r--recipes-core/lighttpd/lighttpd/lighttpd_nrs.conf66
7 files changed, 574 insertions, 0 deletions
diff --git a/recipes-core/lighttpd/lighttpd/0001-lighttpd-pcre-use-pkg-config.patch b/recipes-core/lighttpd/lighttpd/0001-lighttpd-pcre-use-pkg-config.patch
new file mode 100644
index 0000000..48be920
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/0001-lighttpd-pcre-use-pkg-config.patch
@@ -0,0 +1,41 @@
+From 22afc5d9aaa215c3c87ba21c77d47da44ab3b113 Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex.kanavin@gmail.com>
+Date: Fri, 26 Aug 2016 18:20:32 +0300
+Subject: [PATCH] Use pkg-config for pcre dependency instead of -config script.
+
+RP 2014/5/22
+Upstream-Status: Pending
+Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+---
+ configure.ac | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 5383cec..c29a902 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -651,10 +651,18 @@ AC_ARG_WITH([pcre],
+ )
+ AC_MSG_RESULT([$WITH_PCRE])
+
+-if test "$WITH_PCRE" != no; then
+- if test "$WITH_PCRE" != yes; then
+- PCRE_LIB="-L$WITH_PCRE/lib -lpcre"
+- CPPFLAGS="$CPPFLAGS -I$WITH_PCRE/include"
++if test "$WITH_PCRE" != "no"; then
++ PKG_CHECK_MODULES(PCREPKG, [libpcre], [
++ PCRE_LIB=${PCREPKG_LIBS}
++ CPPFLAGS="$CPPFLAGS ${PCREPKG_CFLAGS}"
++ ], [
++ AC_MSG_ERROR([pcre pkgconfig not found, install the pcre-devel package or build with --without-pcre])
++ ])
++
++ if test x"$PCRE_LIB" != x; then
++ AC_DEFINE([HAVE_LIBPCRE], [1], [libpcre])
++ AC_DEFINE([HAVE_PCRE_H], [1], [pcre.h])
++ AC_SUBST(PCRE_LIB)
+ else
+ AC_PATH_PROG([PCRECONFIG], [pcre-config])
+ if test -n "$PCRECONFIG"; then
+--
+2.15.0
diff --git a/recipes-core/lighttpd/lighttpd/0002_extended_tls_conf.patch b/recipes-core/lighttpd/lighttpd/0002_extended_tls_conf.patch
new file mode 100644
index 0000000..1a216dd
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/0002_extended_tls_conf.patch
@@ -0,0 +1,110 @@
+diff --git a/src/base.h b/src/base.h
+index 134fc41..f2d849e 100644
+--- a/src/base.h
++++ b/src/base.h
+@@ -289,6 +289,9 @@ typedef struct {
+ unsigned short ssl_empty_fragments; /* whether to not set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
+ unsigned short ssl_use_sslv2;
+ unsigned short ssl_use_sslv3;
++ unsigned short ssl_use_tlsv1;
++ unsigned short ssl_use_tlsv1_1;
++ unsigned short ssl_use_tlsv1_2;
+ unsigned short ssl_verifyclient;
+ unsigned short ssl_verifyclient_enforce;
+ unsigned short ssl_verifyclient_depth;
+diff --git a/src/configfile.c b/src/configfile.c
+index bba6925..bbedd77 100644
+--- a/src/configfile.c
++++ b/src/configfile.c
+@@ -146,6 +146,10 @@ static int config_insert(server *srv) {
+ { "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */
+ { "ssl.read-ahead", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */
+
++ { "ssl.use-tlsv1", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 80 */
++ { "ssl.use-tlsv1_1", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 81 */
++ { "ssl.use-tlsv1_2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 82 */
++
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ };
+
+@@ -226,6 +230,9 @@ static int config_insert(server *srv) {
+ s->ssl_empty_fragments = 0;
+ s->ssl_use_sslv2 = 0;
+ s->ssl_use_sslv3 = 0;
++ s->ssl_use_tlsv1 = 0;
++ s->ssl_use_tlsv1_1 = 0;
++ s->ssl_use_tlsv1_2 = 1;
+ s->use_ipv6 = (i == 0) ? 0 : srv->config_storage[0]->use_ipv6;
+ s->set_v6only = (i == 0) ? 1 : srv->config_storage[0]->set_v6only;
+ s->defer_accept = (i == 0) ? 0 : srv->config_storage[0]->defer_accept;
+@@ -318,6 +325,9 @@ static int config_insert(server *srv) {
+ cv[76].destination = &(s->stream_request_body);
+ cv[77].destination = &(s->stream_response_body);
+ cv[79].destination = &(s->ssl_read_ahead);
++ cv[80].destination = &(s->ssl_use_tlsv1);
++ cv[81].destination = &(s->ssl_use_tlsv1_1);
++ cv[82].destination = &(s->ssl_use_tlsv1_2);
+
+ srv->config_storage[i] = s;
+
+@@ -536,6 +546,9 @@ int config_setup_connection(server *srv, connection *con) {
+ PATCH(ssl_empty_fragments);
+ PATCH(ssl_use_sslv2);
+ PATCH(ssl_use_sslv3);
++ PATCH(ssl_use_tlsv1);
++ PATCH(ssl_use_tlsv1_1);
++ PATCH(ssl_use_tlsv1_2);
+ PATCH(etag_use_inode);
+ PATCH(etag_use_mtime);
+ PATCH(etag_use_size);
+@@ -615,6 +628,12 @@ int config_patch_connection(server *srv, connection *con) {
+ PATCH(ssl_use_sslv2);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv3"))) {
+ PATCH(ssl_use_sslv3);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1"))) {
++ PATCH(ssl_use_tlsv1);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1_1"))) {
++ PATCH(ssl_use_tlsv1_1);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1_2"))) {
++ PATCH(ssl_use_tlsv1_2);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.cipher-list"))) {
+ PATCH(ssl_cipher_list);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) {
+diff --git a/src/network.c b/src/network.c
+index 4295fe9..a3f9ec3 100644
+--- a/src/network.c
++++ b/src/network.c
+@@ -859,6 +859,33 @@ int network_init(server *srv) {
+ }
+ }
+
++ if (!s->ssl_use_tlsv1) {
++ /* disable TLSv1 */
++ if (!(SSL_OP_NO_TLSv1 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
++ ERR_error_string(ERR_get_error(), NULL));
++ return -1;
++ }
++ }
++
++ if (!s->ssl_use_tlsv1_1) {
++ /* disable TLSv1.1 */
++ if (!(SSL_OP_NO_TLSv1_1 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1_1))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
++ ERR_error_string(ERR_get_error(), NULL));
++ return -1;
++ }
++ }
++
++ if (!s->ssl_use_tlsv1_2) {
++ /* disable TLSv1.2 */
++ if (!(SSL_OP_NO_TLSv1_2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1_2))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
++ ERR_error_string(ERR_get_error(), NULL));
++ return -1;
++ }
++ }
++
+ if (!buffer_string_is_empty(s->ssl_cipher_list)) {
+ /* Disable support for low encryption ciphers */
+ if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
diff --git a/recipes-core/lighttpd/lighttpd/0004_fastcgi_env_with_unixsocket.patch b/recipes-core/lighttpd/lighttpd/0004_fastcgi_env_with_unixsocket.patch
new file mode 100644
index 0000000..c265066
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/0004_fastcgi_env_with_unixsocket.patch
@@ -0,0 +1,57 @@
+From bdfb7f9c6ab29d2de3576f8bd845fa871bb44ead Mon Sep 17 00:00:00 2001
+From: Serhii Voloshynov <serhii.voloshynov@globallogic.com>
+Date: Tue, 6 Nov 2018 13:50:04 +0200
+Subject: [PATCH] patch
+
+---
+ src/http-header-glue.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/http-header-glue.c b/src/http-header-glue.c
+index 1916ca6..d4f42ad 100644
+--- a/src/http-header-glue.c
++++ b/src/http-header-glue.c
+@@ -1457,6 +1457,8 @@ int http_cgi_headers (server *srv, connection *con, http_cgi_opts *opts, http_cg
+ rc |= cb(vdata, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
+ }
+
++ if (srv_sock->addr.plain.sa_family != AF_UNIX) {
++
+ addr = &srv_sock->addr;
+ li_utostrn(buf, sizeof(buf), sock_addr_get_port(addr));
+ rc |= cb(vdata, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
+@@ -1482,6 +1484,7 @@ int http_cgi_headers (server *srv, connection *con, http_cgi_opts *opts, http_cg
+ }
+ force_assert(s);
+ rc |= cb(vdata, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
++ }
+
+ if (!buffer_string_is_empty(con->server_name)) {
+ size_t len = buffer_string_length(con->server_name);
+@@ -1497,15 +1500,23 @@ int http_cgi_headers (server *srv, connection *con, http_cgi_opts *opts, http_cg
+ rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"),
+ con->server_name->ptr, len);
+ } else {
++ if (srv_sock->addr.plain.sa_family != AF_UNIX) {
+ /* set to be same as SERVER_ADDR (above) */
+ rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
+ }
++ }
++ if (srv_sock->addr.plain.sa_family == AF_UNIX) {
++ rc |= cb(vdata, CONST_STR_LEN("SERVER_IPC"), CONST_STR_LEN("yes"));
++ }
++
++ if (srv_sock->addr.plain.sa_family != AF_UNIX) {
+
+ rc |= cb(vdata, CONST_STR_LEN("REMOTE_ADDR"),
+ CONST_BUF_LEN(con->dst_addr_buf));
+
+ li_utostrn(buf, sizeof(buf), sock_addr_get_port(&con->dst_addr));
+ rc |= cb(vdata, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
++ }
+
+ for (n = 0; n < con->request.headers->used; n++) {
+ data_string *ds = (data_string *)con->request.headers->data[n];
+--
+2.7.4
+
diff --git a/recipes-core/lighttpd/lighttpd/lighttpd.conf b/recipes-core/lighttpd/lighttpd/lighttpd.conf
new file mode 100644
index 0000000..a3e02da
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/lighttpd.conf
@@ -0,0 +1,209 @@
+# lighttpd configuration file for the rcell
+# include config file (/var/run/config/lighttpd_port.conf) generated at start up
+#
+# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $
+
+#IMPORT PORT SETTINGS
+include "/var/run/config/lighttpd_port.conf"
+
+## local access from startup scripts and apps
+$SERVER["socket"] == "/var/run/api/http.sock" { }
+
+## modules
+server.modules = (
+ "mod_rewrite",
+ "mod_redirect",
+ "mod_proxy",
+ "mod_alias",
+ "mod_access",
+ "mod_fastcgi",
+ "mod_accesslog",
+ "mod_openssl",
+ "mod_setenv")
+
+
+## static document-root
+server.document-root = "/var/www/"
+setenv.add-response-header = ( "Access-Control-Allow-Origin" => "*",
+ "Content-Security-Policy" => "default-src 'self'; script-src 'unsafe-inline' 'unsafe-eval' 'self'; style-src 'unsafe-inline' https://fonts.googleapis.com 'self'; font-src https://fonts.gstatic.com 'self'; connect-src 'self'; img-src 'self' data:",
+ "X-Frame-Options" =>"SAMEORIGIN",
+ "X-XSS-Protection" => "1; mode=block",
+ "X-Content-Type-Options" => "nosniff",
+ "Referrer-Policy" => "strict-origin-when-cross-origin",
+ "Feature-Policy" => "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; payment 'none'; usb 'none'",
+ "Strict-Transport-Security" => "max-age=31536000",
+ "Cache-Control" => "no-cache"
+)
+server.socket-perms = "0760"
+
+## where to send error-messages to
+#server.errorlog = "/var/log/lighttpd.error.log"
+server.errorlog-use-syslog = "enable"
+
+# disable stat cache
+server.stat-cache-engine = "disable"
+
+## where to send access log
+#accesslog.filename = "/var/log/lighttpd.access.log"
+accesslog.use-syslog = "enable"
+
+## enable debugging
+#debug.log-request-header = "enable"
+#debug.log-response-header = "enable"
+#debug.log-request-handling = "enable"
+#debug.log-file-not-found = "enable"
+#debug.log-condition-handling = "enable"
+
+## where to upload files
+server.upload-dirs = ( "/var/volatile/tmp" )
+
+# files to check for if .../ is requested
+index-file.names = ( "index.php", "index.html",
+ "index.htm", "default.htm" )
+
+# mimetype mapping
+mimetype.assign = (
+ ".pdf" => "application/pdf",
+ ".sig" => "application/pgp-signature",
+ ".spl" => "application/futuresplash",
+ ".class" => "application/octet-stream",
+ ".ps" => "application/postscript",
+ ".torrent" => "application/x-bittorrent",
+ ".dvi" => "application/x-dvi",
+ ".pac" => "application/x-ns-proxy-autoconfig",
+ ".swf" => "application/x-shockwave-flash",
+ ".tar.gz" => "application/x-tgz",
+ ".tgz" => "application/x-tgz",
+ ".tar" => "application/x-tar",
+ ".xhtml" => "application/xhtml+xml",
+ ".xht" => "application/xhtml+xml",
+ ".zip" => "application/zip",
+ ".mp3" => "audio/mpeg",
+ ".m3u" => "audio/x-mpegurl",
+ ".wma" => "audio/x-ms-wma",
+ ".wax" => "audio/x-ms-wax",
+ ".ogg" => "application/ogg",
+ ".wav" => "audio/x-wav",
+ ".gif" => "image/gif",
+ ".jpg" => "image/jpeg",
+ ".jpeg" => "image/jpeg",
+ ".png" => "image/png",
+ ".svg" => "image/svg+xml",
+ ".ico" => "image/x-icon",
+ ".xbm" => "image/x-xbitmap",
+ ".xpm" => "image/x-xpixmap",
+ ".xwd" => "image/x-xwindowdump",
+ ".css" => "text/css",
+ ".html" => "text/html",
+ ".htm" => "text/html",
+ ".asc" => "text/plain",
+ ".c" => "text/plain",
+ ".cpp" => "text/plain",
+ ".log" => "text/plain",
+ ".conf" => "text/plain",
+ ".text" => "text/plain",
+ ".txt" => "text/plain",
+ ".dtd" => "text/xml",
+ ".xml" => "text/xml",
+ ".mpeg" => "video/mpeg",
+ ".mpg" => "video/mpeg",
+ ".mov" => "video/quicktime",
+ ".qt" => "video/quicktime",
+ ".avi" => "video/x-msvideo",
+ ".asf" => "video/x-ms-asf",
+ ".asx" => "video/x-ms-asf",
+ ".wmv" => "video/x-ms-wmv",
+ ".bz2" => "application/x-bzip",
+ ".tbz" => "application/x-bzip-compressed-tar",
+ ".tar.bz2" => "application/x-bzip-compressed-tar",
+ ".mib" => "application/text",
+ ".js" => "application/javascript"
+ )
+
+## deny access the file-extensions
+url.access-deny = ( "~", ".inc" )
+
+# send a different Server: header
+server.tag = ""
+
+#server.error-handler-404 = "/index.html"
+
+#Range request are requests of one or more sub-ranges of a file.
+#Range requests are very helpful for resuming interrupted downloads and fetching small portions of huge files.
+#Note: Adobe Acrobat Reader can crash when it tries to open a PDF file if range requests are enabled.
+$HTTP["url"] =~ "\.pdf$" {
+ server.range-requests = "disable"
+}
+
+##
+# which extensions should not be handle via static-file transfer
+#
+# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
+static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
+
+## to help the rc.scripts
+server.pid-file = "/var/run/lighttpd.pid"
+
+# Restrict server process to non priveleged user
+server.username = "www"
+server.groupname = "www"
+
+# server limit POST size in kilobytes (60MB for firmware update)
+server.max-request-size = 113246
+
+# server limits
+server.max-keep-alive-requests = 16
+server.max-keep-alive-idle = 15
+server.max-read-idle = 60
+server.max-write-idle = 360
+
+##
+## Format: <errorfile-prefix><status-code>.html
+## -> ..../status-404.html for 'File not found'
+server.errorfile-prefix = "/var/www/errors/status-"
+
+## virtual directory listings
+#dir-listing.activate = "enable"
+
+#IMPORTED CONFIGS WILL HANDLE SETTING HTTP/HTTPS
+
+#### fastcgi module
+fastcgi.server = ( "/" =>
+ ( "authorizer" =>
+ (
+ "mode" => "authorizer",
+ "check-local" => "disable",
+ "socket" => "/var/run/api/rcell_api.sock",
+ "docroot" => "/var/www"
+ )
+ )
+)
+
+
+$HTTP["url"] =~ "/static/js" {
+ setenv.add-response-header = ( "Content-Encoding" => "gzip")
+ mimetype.assign = ("" => "text/javascript" )
+ } else $HTTP["url"] =~ "/help/template/scripts" {
+ setenv.add-response-header = ( "Content-Encoding" => "gzip")
+ mimetype.assign = ("" => "text/javascript" )
+ } else $HTTP["url"] =~ "/help/whxdata/" {
+ setenv.add-response-header = ( "Content-Encoding" => "gzip")
+ mimetype.assign = ("" => "text/javascript" )
+ } else $HTTP["url"] =~ "/help/template/Azure_Blue_MTS_1/layout.css" {
+ setenv.add-response-header = ( "Content-Encoding" => "gzip")
+ mimetype.assign = ("" => "text/css" )
+ } else $HTTP["url"] =~ "^/api" {
+ fastcgi.server = ( "/api" =>
+ ( "api" =>
+ (
+ "mode" => "responder",
+ "check-local" => "disable",
+ "socket" => "/var/run/api/rcell_api.sock"
+ )
+ )
+ )
+}
+
+#INCLUDE DIPSERVICE SETTINGS
+include "/var/run/config/lighttpd_dipservice.conf"
+include "/var/run/config/lighttpd_custom_images.conf"
diff --git a/recipes-core/lighttpd/lighttpd/lighttpd.init b/recipes-core/lighttpd/lighttpd/lighttpd.init
new file mode 100644
index 0000000..bf89a60
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/lighttpd.init
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/lighttpd
+NAME=lighttpd
+DESC="Lighttpd Web Server"
+OPTS="-f /etc/lighttpd.conf"
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC: "
+ start-stop-daemon --start -x "$DAEMON" -- $OPTS
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop -x "$DAEMON"
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop -x "$DAEMON"
+ sleep 1
+ start-stop-daemon --start -x "$DAEMON" -- $OPTS
+ echo "$NAME."
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/recipes-core/lighttpd/lighttpd/lighttpd_custom_images_setup b/recipes-core/lighttpd/lighttpd/lighttpd_custom_images_setup
new file mode 100644
index 0000000..ecd5f46
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/lighttpd_custom_images_setup
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Detects mime types for UI Customization images and generates according Lighttpd config fragment
+
+CONFIG_PATH="/var/run/config/lighttpd_custom_images.conf"
+IMAGE_PATH="/var/www/static/images/"
+MAGIC_DB_PATH="/usr/share/misc/magic-images.mgc"
+shopt -s nullglob
+
+echoerr() {
+ echo "$@" 1>&2
+}
+
+generate_mime_assign() {
+ local IMAGE="$1"
+ local OUTPUT=$(file -ib "$IMAGE" --magic-file "$MAGIC_DB_PATH")
+ local CONTENT_TYPE
+
+ if [ "$?" -ne "0" ] || [[ "$OUTPUT" == "" ]] || [[ "$OUTPUT" == *"cannot open"* ]]; then
+ echoerr "Failed to run file(1): ${?}; ${OUTPUT}"
+ return 1
+ fi
+
+ CONTENT_TYPE="$OUTPUT"
+ cat <<END
+\$HTTP["url"] =~ "/static/images/$IMAGE" {
+ mimetype.assign = ("" => "$CONTENT_TYPE")
+ }
+END
+}
+
+process_files() {
+ local INDENT=" "
+ local ELSE_STRING=""
+ local FRAGMENT
+
+ for IMAGE in custom_*; do
+ INDENT=" "
+
+ FRAGMENT=$(generate_mime_assign $IMAGE)
+ if [ "$?" -eq "0" ]; then
+ echo "${INDENT}${ELSE_STRING}${FRAGMENT}" >> "$CONFIG_PATH"
+ ELSE_STRING="else "
+ fi
+ done
+}
+
+echo "Generating $CONFIG_PATH"
+
+# truncate and write head
+cat > "$CONFIG_PATH" <<END
+\$HTTP["url"] =~ "/static/images/custom_" {
+END
+
+cd "$IMAGE_PATH" && process_files
+
+# write tail (closing brace)
+echo "}" >> "$CONFIG_PATH"
diff --git a/recipes-core/lighttpd/lighttpd/lighttpd_nrs.conf b/recipes-core/lighttpd/lighttpd/lighttpd_nrs.conf
new file mode 100644
index 0000000..8c23747
--- /dev/null
+++ b/recipes-core/lighttpd/lighttpd/lighttpd_nrs.conf
@@ -0,0 +1,66 @@
+server.modules = ( "mod_expire" )
+server.bind = "127.0.0.1"
+server.port = 1882
+server.document-root = "/var/www/node-red/node-red-stub"
+server.max-keep-alive-requests = 0
+expire.url = ( "/" => "access 0 days" )
+server.errorlog-use-syslog = "enable"
+server.upload-dirs = ( "/var/volatile/tmp" )
+index-file.names = ( "index.html" )
+server.pid-file = "/var/run/lighttpd_nrs.pid"
+server.errorfile-prefix = "/var/www/node-red/node-red-errors/status-"
+mimetype.assign = (
+ ".pdf" => "application/pdf",
+ ".sig" => "application/pgp-signature",
+ ".spl" => "application/futuresplash",
+ ".class" => "application/octet-stream",
+ ".ps" => "application/postscript",
+ ".torrent" => "application/x-bittorrent",
+ ".dvi" => "application/x-dvi",
+ ".gz" => "application/x-gzip",
+ ".pac" => "application/x-ns-proxy-autoconfig",
+ ".swf" => "application/x-shockwave-flash",
+ ".tar.gz" => "application/x-tgz",
+ ".tgz" => "application/x-tgz",
+ ".tar" => "application/x-tar",
+ ".xhtml" => "application/xhtml+xml",
+ ".xht" => "application/xhtml+xml",
+ ".zip" => "application/zip",
+ ".mp3" => "audio/mpeg",
+ ".m3u" => "audio/x-mpegurl",
+ ".wma" => "audio/x-ms-wma",
+ ".wax" => "audio/x-ms-wax",
+ ".ogg" => "application/ogg",
+ ".wav" => "audio/x-wav",
+ ".gif" => "image/gif",
+ ".jpg" => "image/jpeg",
+ ".jpeg" => "image/jpeg",
+ ".png" => "image/png",
+ ".xbm" => "image/x-xbitmap",
+ ".xpm" => "image/x-xpixmap",
+ ".xwd" => "image/x-xwindowdump",
+ ".css" => "text/css",
+ ".html" => "text/html",
+ ".htm" => "text/html",
+ ".js" => "text/javascript",
+ ".asc" => "text/plain",
+ ".c" => "text/plain",
+ ".cpp" => "text/plain",
+ ".log" => "text/plain",
+ ".conf" => "text/plain",
+ ".text" => "text/plain",
+ ".txt" => "text/plain",
+ ".dtd" => "text/xml",
+ ".xml" => "text/xml",
+ ".mpeg" => "video/mpeg",
+ ".mpg" => "video/mpeg",
+ ".mov" => "video/quicktime",
+ ".qt" => "video/quicktime",
+ ".avi" => "video/x-msvideo",
+ ".asf" => "video/x-ms-asf",
+ ".asx" => "video/x-ms-asf",
+ ".wmv" => "video/x-ms-wmv",
+ ".bz2" => "application/x-bzip",
+ ".tbz" => "application/x-bzip-compressed-tar",
+ ".tar.bz2" => "application/x-bzip-compressed-tar"
+)