diff --git a/src/.config b/src/.config
index d9d62ed13..bf00fa412 100644
--- a/src/.config
+++ b/src/.config
@@ -86,7 +86,6 @@ STATIC_GET_SOURCE_URL=http://s.minos.io/s
#
CLOUD_FOUNDRY_CLI_URL=http://cli.run.pivotal.io/stable?release=linux64-binary&source=github
-
####################################################
# #
# This section contains configuration properties #
@@ -171,11 +170,13 @@ COPY_SOURCE_ISO=true
# lua - scripting language
# static_get - portable binaries for Linux (http://s.minos.io)
# cf_cli - CLoud Foundry CLI (command line interface)
+# nweb - simple mini http server
#
# Refer to the README file for more information.
#
#OVERLAY_BUNDLES=glibc_full,links,dropbear,java,felix,mll_utils,lua,static_get,cf_cli
#OVERLAY_BUNDLES=cf_cli
+OVERLY_BUNDLES=nweb
# This property enables the standard penguin boot logo in the upper left corner
# of the screen. The property is used in 'xx_build_kernel.sh'. The default value
diff --git a/src/README b/src/README
index f0f32fbf8..0968a783f 100644
--- a/src/README
+++ b/src/README
@@ -63,6 +63,8 @@ Currently available overlay bundles:
* Lua - The Lua Scripting Language 5.3. Requires ~ 800kb additional
space. Use the "lua" command to run an interactive lua interpreter
+* nweb - nweb is a very small and easy to use webserver
+
### ### ###
I only provide the build scripts. It's entirely up to you to configure and
diff --git a/src/minimal_overlay/bundles/nweb/bundle.sh b/src/minimal_overlay/bundles/nweb/bundle.sh
new file mode 100755
index 000000000..def88ed6b
--- /dev/null
+++ b/src/minimal_overlay/bundles/nweb/bundle.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+SRC_DIR=$(pwd)
+
+# Find the main source directory
+cd ../../..
+MAIN_SRC_DIR=$(pwd)
+cd $SRC_DIR
+
+cd $MAIN_SRC_DIR/work/overlay/nweb
+
+# nweb
+cc -O2 $(SRC_DIR)/nweb23.c -o nweb
+
+# client
+#cc -O2 $(SRC_DIR)/client.c -o client
+
+echo "nweb has been build."
+
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr"
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/bin"
+install -m755 nweb "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/bin/nweb"
+#install -m755 client "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/bin/client"
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/srv/www" # FHS compliant location
+install -m022 "$(SRC_DIR)/index.html" "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/svc/www/index.html"
+install -m022 "$(SRC_DIR)/favicon.ico" "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/svc/www/favicon.ico"
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/share"
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/share/man"
+install -d -m755 "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/share/man/man8"
+install -m022 "$(SRC_DIR)/nweb.8" "$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs/usr/share/man/man8/nweb.8"
+
+echo "nweb has been installed."
+echo "type 'man nweb' to see what it can do on your mimial system"
+
diff --git a/src/minimal_overlay/bundles/nweb/client.c b/src/minimal_overlay/bundles/nweb/client.c
new file mode 100644
index 000000000..55887f9a9
--- /dev/null
+++ b/src/minimal_overlay/bundles/nweb/client.c
@@ -0,0 +1,50 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* YOU WILL HAVE TO CHANGE THESE TWO LINES TO MATCH YOUR CONFIG */
+#define PORT 8181 /* Port number as an integer - web server default is 80 */
+#define IP_ADDRESS "192.168.0.8" /* IP Address as a string */
+
+char *command = "GET /index.html HTTP/1.0 \r\n\r\n" ;
+/* Note: spaces are delimiters and VERY important */
+
+#define BUFSIZE 8196
+
+pexit(char * msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+main()
+{
+int i,sockfd;
+char buffer[BUFSIZE];
+static struct sockaddr_in serv_addr;
+
+ printf("client trying to connect to %s and port %d\n",IP_ADDRESS,PORT);
+ if((sockfd = socket(AF_INET, SOCK_STREAM,0)) <0)
+ pexit("socket() failed");
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
+ serv_addr.sin_port = htons(PORT);
+
+ /* Connect tot he socket offered by the web server */
+ if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <0)
+ pexit("connect() failed");
+
+ /* Now the sockfd can be used to communicate to the server the GET request */
+ printf("Send bytes=%d %s\n",strlen(command), command);
+ write(sockfd, command, strlen(command));
+
+ /* This displays the raw HTML file (if index.html) as received by the browser */
+ while( (i=read(sockfd,buffer,BUFSIZE)) > 0)
+ write(1,buffer,i);
+}
diff --git a/src/minimal_overlay/bundles/nweb/favicon.ico b/src/minimal_overlay/bundles/nweb/favicon.ico
new file mode 100644
index 000000000..c7a2123c1
Binary files /dev/null and b/src/minimal_overlay/bundles/nweb/favicon.ico differ
diff --git a/src/minimal_overlay/bundles/nweb/index.html b/src/minimal_overlay/bundles/nweb/index.html
new file mode 100644
index 000000000..d99085b24
--- /dev/null
+++ b/src/minimal_overlay/bundles/nweb/index.html
@@ -0,0 +1,13 @@
+
+
+nweb
+
+
+nweb test page
+
+It works!
+All rights go to the original author of nweb Nigel Griffiths nag@uk.ibm.com
+Feedback is welcome to Nigel Griffiths nag@uk.ibm.com
+
+
+
diff --git a/src/minimal_overlay/bundles/nweb/nweb.8 b/src/minimal_overlay/bundles/nweb/nweb.8
new file mode 100644
index 000000000..047e0763c
--- /dev/null
+++ b/src/minimal_overlay/bundles/nweb/nweb.8
@@ -0,0 +1,25 @@
+.TH NWEB 8 "June 19, 2017"
+.SH NAME
+nweb \- small and very safe mini web server
+.SH SYNPOSIS
+.B nweb
+[\fIport\fR]
+[\fItopdir\fR]
+.SH DESCRIPTION
+nweb only servers out file/web pages with extensions named below and only from the named directory or its sub-directories.
+
+There is no fancy features = safe and secure.
+
+Only Supports: gif jpg jpeg png ico zip gz tar htm html
+
+Not Supported: URLs including "..", Java, Javascript, CGI
+
+Not Supported: directories / /etc /bin /lib /tmp /usr /dev /sbin
+
+No warranty given or implied
+
+Nigel Griffiths nag@uk.ibm.com
+.SH EXAMPLES
+ "nweb 8181 /srv/www &"
+
+Runs nweb on port 8181 serving files in /srv/www
diff --git a/src/minimal_overlay/bundles/nweb/nweb23.c b/src/minimal_overlay/bundles/nweb/nweb23.c
new file mode 100644
index 000000000..da5a6d3b1
--- /dev/null
+++ b/src/minimal_overlay/bundles/nweb/nweb23.c
@@ -0,0 +1,204 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define VERSION 23
+#define BUFSIZE 8096
+#define ERROR 42
+#define LOG 44
+#define FORBIDDEN 403
+#define NOTFOUND 404
+
+#ifndef SIGCLD
+# define SIGCLD SIGCHLD
+#endif
+
+struct {
+ char *ext;
+ char *filetype;
+} extensions [] = {
+ {"gif", "image/gif" },
+ {"jpg", "image/jpg" },
+ {"jpeg","image/jpeg"},
+ {"png", "image/png" },
+ {"ico", "image/ico" },
+ {"zip", "image/zip" },
+ {"gz", "image/gz" },
+ {"tar", "image/tar" },
+ {"htm", "text/html" },
+ {"html","text/html" },
+ {0,0} };
+
+void logger(int type, char *s1, char *s2, int socket_fd)
+{
+ int fd ;
+ char logbuffer[BUFSIZE*2];
+
+ switch (type) {
+ case ERROR: (void)sprintf(logbuffer,"ERROR: %s:%s Errno=%d exiting pid=%d",s1, s2, errno,getpid());
+ break;
+ case FORBIDDEN:
+ (void)write(socket_fd, "HTTP/1.1 403 Forbidden\nContent-Length: 185\nConnection: close\nContent-Type: text/html\n\n\n403 Forbidden\n\nForbidden
\nThe requested URL, file type or operation is not allowed on this simple static file webserver.\n\n",271);
+ (void)sprintf(logbuffer,"FORBIDDEN: %s:%s",s1, s2);
+ break;
+ case NOTFOUND:
+ (void)write(socket_fd, "HTTP/1.1 404 Not Found\nContent-Length: 136\nConnection: close\nContent-Type: text/html\n\n\n404 Not Found\n\nNot Found
\nThe requested URL was not found on this server.\n\n",224);
+ (void)sprintf(logbuffer,"NOT FOUND: %s:%s",s1, s2);
+ break;
+ case LOG: (void)sprintf(logbuffer," INFO: %s:%s:%d",s1, s2,socket_fd); break;
+ }
+ /* No checks here, nothing can be done with a failure anyway */
+ if((fd = open("nweb.log", O_CREAT| O_WRONLY | O_APPEND,0644)) >= 0) {
+ (void)write(fd,logbuffer,strlen(logbuffer));
+ (void)write(fd,"\n",1);
+ (void)close(fd);
+ }
+ if(type == ERROR || type == NOTFOUND || type == FORBIDDEN) exit(3);
+}
+
+/* this is a child web server process, so we can exit on errors */
+void web(int fd, int hit)
+{
+ int j, file_fd, buflen;
+ long i, ret, len;
+ char * fstr;
+ static char buffer[BUFSIZE+1]; /* static so zero filled */
+
+ ret =read(fd,buffer,BUFSIZE); /* read Web request in one go */
+ if(ret == 0 || ret == -1) { /* read failure stop now */
+ logger(FORBIDDEN,"failed to read browser request","",fd);
+ }
+ if(ret > 0 && ret < BUFSIZE) /* return code is valid chars */
+ buffer[ret]=0; /* terminate the buffer */
+ else buffer[0]=0;
+ for(i=0;i 0 ) {
+ (void)write(fd,buffer,ret);
+ }
+ sleep(1); /* allow socket to drain before signalling the socket is closed */
+ close(fd);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int i, port, pid, listenfd, socketfd, hit;
+ socklen_t length;
+ static struct sockaddr_in cli_addr; /* static = initialised to zeros */
+ static struct sockaddr_in serv_addr; /* static = initialised to zeros */
+
+ if( argc < 3 || argc > 3 || !strcmp(argv[1], "-?") ) {
+ (void)printf("hint: nweb Port-Number Top-Directory\t\tversion %d\n\n"
+ "\tnweb is a small and very safe mini web server\n"
+ "\tnweb only servers out file/web pages with extensions named below\n"
+ "\t and only from the named directory or its sub-directories.\n"
+ "\tThere is no fancy features = safe and secure.\n\n"
+ "\tExample: nweb 8181 /home/nwebdir &\n\n"
+ "\tOnly Supports:", VERSION);
+ for(i=0;extensions[i].ext != 0;i++)
+ (void)printf(" %s",extensions[i].ext);
+
+ (void)printf("\n\tNot Supported: URLs including \"..\", Java, Javascript, CGI\n"
+ "\tNot Supported: directories / /etc /bin /lib /tmp /usr /dev /sbin \n"
+ "\tNo warranty given or implied\n\tNigel Griffiths nag@uk.ibm.com\n" );
+ exit(0);
+ }
+ if( !strncmp(argv[2],"/" ,2 ) || !strncmp(argv[2],"/etc", 5 ) ||
+ !strncmp(argv[2],"/bin",5 ) || !strncmp(argv[2],"/lib", 5 ) ||
+ !strncmp(argv[2],"/tmp",5 ) || !strncmp(argv[2],"/usr", 5 ) ||
+ !strncmp(argv[2],"/dev",5 ) || !strncmp(argv[2],"/sbin",6) ){
+ (void)printf("ERROR: Bad top directory %s, see nweb -?\n",argv[2]);
+ exit(3);
+ }
+ if(chdir(argv[2]) == -1){
+ (void)printf("ERROR: Can't Change to directory %s\n",argv[2]);
+ exit(4);
+ }
+ /* Become deamon + unstopable and no zombies children (= no wait()) */
+ if(fork() != 0)
+ return 0; /* parent returns OK to shell */
+ (void)signal(SIGCLD, SIG_IGN); /* ignore child death */
+ (void)signal(SIGHUP, SIG_IGN); /* ignore terminal hangups */
+ for(i=0;i<32;i++)
+ (void)close(i); /* close open files */
+ (void)setpgrp(); /* break away from process group */
+ logger(LOG,"nweb starting",argv[1],getpid());
+ /* setup the network socket */
+ if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0)
+ logger(ERROR, "system call","socket",0);
+ port = atoi(argv[1]);
+ if(port < 0 || port >60000)
+ logger(ERROR,"Invalid port number (try 1->60000)",argv[1],0);
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(port);
+ if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0)
+ logger(ERROR,"system call","bind",0);
+ if( listen(listenfd,64) <0)
+ logger(ERROR,"system call","listen",0);
+ for(hit=1; ;hit++) {
+ length = sizeof(cli_addr);
+ if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0)
+ logger(ERROR,"system call","accept",0);
+ if((pid = fork()) < 0) {
+ logger(ERROR,"system call","fork",0);
+ }
+ else {
+ if(pid == 0) { /* child */
+ (void)close(listenfd);
+ web(socketfd,hit); /* never returns */
+ } else { /* parent */
+ (void)close(socketfd);
+ }
+ }
+ }
+}