commit
f780da068a
@ -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
|
CLOUD_FOUNDRY_CLI_URL=http://cli.run.pivotal.io/stable?release=linux64-binary&source=github
|
||||||
|
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# #
|
# #
|
||||||
# This section contains configuration properties #
|
# This section contains configuration properties #
|
||||||
@ -171,11 +170,13 @@ COPY_SOURCE_ISO=true
|
|||||||
# lua - scripting language
|
# lua - scripting language
|
||||||
# static_get - portable binaries for Linux (http://s.minos.io)
|
# static_get - portable binaries for Linux (http://s.minos.io)
|
||||||
# cf_cli - CLoud Foundry CLI (command line interface)
|
# cf_cli - CLoud Foundry CLI (command line interface)
|
||||||
|
# nweb - simple mini http server
|
||||||
#
|
#
|
||||||
# Refer to the README file for more information.
|
# 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=glibc_full,links,dropbear,java,felix,mll_utils,lua,static_get,cf_cli
|
||||||
#OVERLAY_BUNDLES=cf_cli
|
#OVERLAY_BUNDLES=cf_cli
|
||||||
|
OVERLAY_BUNDLES=nweb
|
||||||
|
|
||||||
# This property enables the standard penguin boot logo in the upper left corner
|
# 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
|
# of the screen. The property is used in 'xx_build_kernel.sh'. The default value
|
||||||
|
@ -63,6 +63,12 @@ Currently available overlay bundles:
|
|||||||
* Lua - The Lua Scripting Language 5.3. Requires ~ 800kb additional
|
* Lua - The Lua Scripting Language 5.3. Requires ~ 800kb additional
|
||||||
space. Use the "lua" command to run an interactive lua interpreter
|
space. Use the "lua" command to run an interactive lua interpreter
|
||||||
|
|
||||||
|
* nweb - nweb is a very small and easy to use webserver
|
||||||
|
run it using 'nweb 80 /srv/www'
|
||||||
|
to portforward port 8080 on the host to port 80 on the guest (minimal)
|
||||||
|
add '-net nic,model=e1000 -net user,hostfwd=tcp::8080-:80' to the cmd in
|
||||||
|
qemu64.sh and qemu32.sh
|
||||||
|
|
||||||
### ### ###
|
### ### ###
|
||||||
|
|
||||||
I only provide the build scripts. It's entirely up to you to configure and
|
I only provide the build scripts. It's entirely up to you to configure and
|
||||||
|
39
src/minimal_overlay/bundles/nweb/bundle.sh
Executable file
39
src/minimal_overlay/bundles/nweb/bundle.sh
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
SRC_DIR=$(pwd)
|
||||||
|
|
||||||
|
# Find the main source directory
|
||||||
|
cd ../../..
|
||||||
|
MAIN_SRC_DIR=$(pwd)
|
||||||
|
cd $SRC_DIR
|
||||||
|
|
||||||
|
# Read the 'CFLAGS' property from '.config'
|
||||||
|
CFLAGS="$(grep -i ^CFLAGS $MAIN_SRC_DIR/.config | cut -f2 -d'=')"
|
||||||
|
|
||||||
|
echo "removing previous work area"
|
||||||
|
rm -rf $MAIN_SRC_DIR/work/overlay/nweb
|
||||||
|
mkdir -p $MAIN_SRC_DIR/work/overlay/nweb
|
||||||
|
cd $MAIN_SRC_DIR/work/overlay/nweb
|
||||||
|
|
||||||
|
# nweb
|
||||||
|
cc $CFLAGS $SRC_DIR/nweb23.c -o nweb
|
||||||
|
|
||||||
|
# client
|
||||||
|
#cc $CFLAGS $SRC_DIR/client.c -o client
|
||||||
|
|
||||||
|
echo "nweb has been build."
|
||||||
|
|
||||||
|
DESTDIR="$MAIN_SRC_DIR/work/src/minimal_overlay/rootfs"
|
||||||
|
|
||||||
|
install -d -m755 "$DESTDIR/usr"
|
||||||
|
install -d -m755 "$DESTDIR/usr/bin"
|
||||||
|
install -m755 nweb "$DESTDIR/usr/bin/nweb"
|
||||||
|
#install -m755 client "$DESTDIR/usr/bin/client"
|
||||||
|
install -d -m755 "$DESTDIR/srv/www" # FHS compliant location
|
||||||
|
install -m644 "$SRC_DIR/index.html" "$DESTDIR/srv/www/index.html"
|
||||||
|
install -m644 "$SRC_DIR/favicon.ico" "$DESTDIR/srv/www/favicon.ico"
|
||||||
|
install -d -m755 "$DESTDIR/etc"
|
||||||
|
install -d -m755 "$DESTDIR/etc/autorun"
|
||||||
|
install -m755 "$SRC_DIR/nweb.sh" "$DESTDIR/etc/autorun/90_nweb.sh"
|
||||||
|
|
||||||
|
echo "nweb has been installed."
|
||||||
|
echo "it will be autostarted on boot"
|
50
src/minimal_overlay/bundles/nweb/client.c
Normal file
50
src/minimal_overlay/bundles/nweb/client.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
BIN
src/minimal_overlay/bundles/nweb/favicon.ico
Normal file
BIN
src/minimal_overlay/bundles/nweb/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
14
src/minimal_overlay/bundles/nweb/index.html
Normal file
14
src/minimal_overlay/bundles/nweb/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>nweb</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1><image src="favicon.ico"></image> nweb test page</h1>
|
||||||
|
<hr>
|
||||||
|
<p>It works!</p>
|
||||||
|
<p>You can edit this file in /srv/www/index.html</p>
|
||||||
|
<p>All rights go to the original author of nweb Nigel Griffiths nag@uk.ibm.com</p>
|
||||||
|
<p>Feedback is welcome to Nigel Griffiths nag@uk.ibm.com</p>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
3
src/minimal_overlay/bundles/nweb/nweb.sh
Normal file
3
src/minimal_overlay/bundles/nweb/nweb.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
echo "starting nweb on port 80 serving /srv/www"
|
||||||
|
nweb 80 /srv/www
|
204
src/minimal_overlay/bundles/nweb/nweb23.c
Normal file
204
src/minimal_overlay/bundles/nweb/nweb23.c
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#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<html><head>\n<title>403 Forbidden</title>\n</head><body>\n<h1>Forbidden</h1>\nThe requested URL, file type or operation is not allowed on this simple static file webserver.\n</body></html>\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<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\nThe requested URL was not found on this server.\n</body></html>\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<ret;i++) /* remove CF and LF characters */
|
||||||
|
if(buffer[i] == '\r' || buffer[i] == '\n')
|
||||||
|
buffer[i]='*';
|
||||||
|
logger(LOG,"request",buffer,hit);
|
||||||
|
if( strncmp(buffer,"GET ",4) && strncmp(buffer,"get ",4) ) {
|
||||||
|
logger(FORBIDDEN,"Only simple GET operation supported",buffer,fd);
|
||||||
|
}
|
||||||
|
for(i=4;i<BUFSIZE;i++) { /* null terminate after the second space to ignore extra stuff */
|
||||||
|
if(buffer[i] == ' ') { /* string is "GET URL " +lots of other stuff */
|
||||||
|
buffer[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(j=0;j<i-1;j++) /* check for illegal parent directory use .. */
|
||||||
|
if(buffer[j] == '.' && buffer[j+1] == '.') {
|
||||||
|
logger(FORBIDDEN,"Parent directory (..) path names not supported",buffer,fd);
|
||||||
|
}
|
||||||
|
if( !strncmp(&buffer[0],"GET /\0",6) || !strncmp(&buffer[0],"get /\0",6) ) /* convert no filename to index file */
|
||||||
|
(void)strcpy(buffer,"GET /index.html");
|
||||||
|
|
||||||
|
/* work out the file type and check we support it */
|
||||||
|
buflen=strlen(buffer);
|
||||||
|
fstr = (char *)0;
|
||||||
|
for(i=0;extensions[i].ext != 0;i++) {
|
||||||
|
len = strlen(extensions[i].ext);
|
||||||
|
if( !strncmp(&buffer[buflen-len], extensions[i].ext, len)) {
|
||||||
|
fstr =extensions[i].filetype;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fstr == 0) logger(FORBIDDEN,"file extension type not supported",buffer,fd);
|
||||||
|
|
||||||
|
if(( file_fd = open(&buffer[5],O_RDONLY)) == -1) { /* open the file for reading */
|
||||||
|
logger(NOTFOUND, "failed to open file",&buffer[5],fd);
|
||||||
|
}
|
||||||
|
logger(LOG,"SEND",&buffer[5],hit);
|
||||||
|
len = (long)lseek(file_fd, (off_t)0, SEEK_END); /* lseek to the file end to find the length */
|
||||||
|
(void)lseek(file_fd, (off_t)0, SEEK_SET); /* lseek back to the file start ready for reading */
|
||||||
|
(void)sprintf(buffer,"HTTP/1.1 200 OK\nServer: nweb/%d.0\nContent-Length: %ld\nConnection: close\nContent-Type: %s\n\n", VERSION, len, fstr); /* Header + a blank line */
|
||||||
|
logger(LOG,"Header",buffer,hit);
|
||||||
|
(void)write(fd,buffer,strlen(buffer));
|
||||||
|
|
||||||
|
/* send file in 8KB block - last block may be smaller */
|
||||||
|
while ( (ret = read(file_fd, buffer, BUFSIZE)) > 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user