├── README.md ├── client.c ├── favicon.ico ├── index.html ├── nigel.jpg ├── nweb ├── nweb.log ├── nweb23.c ├── nweb23_Fedora_17_64 ├── nweb23_RHEL63_64 ├── nweb23_SLES_11_64 ├── nweb23_aix6_1_7 ├── nweb23_openSUSU_12_1_64 ├── nweb23_raspberry_pi ├── nweb23_ubuntu_12_4_32 └── nweb23_ubuntu_12_4_64 /README.md: -------------------------------------------------------------------------------- 1 | nweb README for version 23 2 | 3 | 1) Bug fixed - was duplicating errors in the nweb.log file 4 | - thanks to Kieran Grant for stopping this and pointing out the fix. 5 | 6 | 2) Added support for favicon.ico - if nothing elase this will stop annoying 7 | errors in the log file. Most browsers on first encountering a webpage 8 | also ask for this file. The name mean favourite icon - Wikipedia has 9 | more on this. It is a tiny Bit Map image (normally called .bmp and 10 | BMP editors can be used to create one - I used Windows Paint) 11 | I uses a very simple 16x16 pixels and 256 colour to keep the size and 12 | complexity down. 13 | To add support I added .ico file extension to the allowed extensions 14 | data structure and the sample favicon.ico file. 15 | This is then displyed by the browser at the little graphic next to 16 | the URL. The one I made looks like this withe blue background. 17 | +---+ 18 | |n | 19 | |Web| 20 | +---+ 21 | 22 | 3) As 1) removed a few lines, I managed to add 2) and still stay at 200 lines. 23 | 24 | 25 | The code: 26 | nweb23.c -- the source code version 23 27 | client.c -- sample client end source code 28 | 29 | nweb executable files for: 30 | AIX 6.1 TL7 fnd AIX 7 TL1 POWER 31 | Ubuntu 12.4 for x86_64 Intel/AMD 64 bit 32 | Ubuntu 12.4 for x86_32 Intel/AMD 32 bit 33 | Fedora 17 Linux for x86_64 Intel/AMD 64 bit 34 | OpenSUSE 12.1 for x86_64 Intel/AMD 64 bit 35 | Red Hat RHEL 6.3 for x86_64 Intel/AMD 64 bit 36 | SUSE SLES 11 for x86_64 Intel/AMD 64 bit 37 | Debian Squeeze for ARM on Raspberry Pi 38 | 39 | Minimum test website 40 | index.html -- test very bascis web page 41 | nigel.jpg -- test image file 42 | favicon.ico -- the favourite icon bit map file 43 | 44 | 45 | ----------------- 46 | 47 | nweb README for version 22 48 | 49 | The nweb download file includes: 50 | 51 | README -- this file 52 | 53 | 54 | This file contains lots of hints & tips on compiling and running the nweb code 55 | 56 | 57 | nweb22.c 58 | ======== 59 | The 22 is the version number. 60 | nweb stands for Nigel's Web server but I some times call it a nano 61 | web server (i.e. very small). 62 | 63 | This nweb is a web server that will respond to simple web browser 64 | requests for static files. 65 | This version is exactly 200 lines long. 66 | I started with a target 100 lines and it worked fine too but then 67 | added comments, file type checks, 68 | security checks, sensible directory checks and logging. 69 | 70 | To compile this you need a basic C compiler use: cc nweb22.c -o nweb 71 | If you want it to run faster you could include optimisation: 72 | cc -O2 nweb22.c -o nweb 73 | 74 | Then to run it as root for the test files: 75 | 1) Place the index.html file and nigel.jpg in to a sensible directory 76 | Note: not any system directories like / or /tmp 77 | A director in /home would be a good idea - below we use /home/nigel/web 78 | 79 | 2) Make these files readable 80 | chmod ugo+r /home/nigel/web 81 | 82 | 3) Decide the port number 83 | Port number 80 is the web server default and assumed by web browsers. 84 | you might have to be the root user to use that port number. 85 | If the machine is already running a web server then it will 86 | probably be using port 80 so you can't us 80. 87 | I test using port 8181 but you have to make up your mind. 88 | 89 | 4) Start the nweb server: /home/nigel/bin/nweb 80 /home/nigel/web 90 | or if using 8181 /home/nigel/bin/nweb 8181 /home/nigel/web 91 | 92 | If the program and files are all in /home/nigel/all 93 | You could use: 94 | cd /home/nigel/all 95 | rm -f nweb.log 96 | ./nweb 80 . 97 | ps -ef | grep nweb 98 | tail -f nweb.log 99 | 100 | See below for explanations for the rm, ps and tail 101 | 102 | 5) Note that any suitable files in the directory 2nd argument above 103 | could be served by the nmon web server - so don't have anything secret 104 | in that directory! 105 | 106 | 6) Use a browser to test it if using port 80 on a machine hostname 107 | of abc123.com browser to: 108 | http://abc123.com/index.html 109 | 110 | If using port 8181 111 | http://abc123.com:8181/index.html 112 | 113 | 7) Running nweb as a regualr user 114 | You can run nweb as a regular user on some operating systems but not all. 115 | I find using sudo works on some: 116 | sudo /home/nigel/bin/nweb 80 /home/nigel/web 117 | 118 | If you try and the log file reports socect connections errors worth 119 | trying the 8181 port or higher numbers. This is because 120 | lower port numbers are reserved for root user use. 121 | 122 | 8) VERY IMPORTANT 123 | nweb will behave like a daemon process, so it disconnects from the 124 | users command shell, goes into the back ground, closes input and 125 | output I/O & protects itself from you logging off. 126 | It will look like it stopped, when it is in fact still running in 127 | the background - check with ps -ef | grep nweb 128 | Also note you will not see errors or warnings messages 129 | - they go in the log file. 130 | 131 | Look in the nweb.log file for problems starting up or browsers connecting 132 | and requesting pages with: cat nweb.log 133 | or: tail -f nweb.log 134 | 135 | I find it good to remove the nweb.log before I start nweb or it is easy to get confused with previous error messages in the log. 136 | 137 | 9) As nweb runs as a daemon process it will try to run forever and not 138 | conntected to your user or terminal session. Logging out will not 139 | effect it. To stop nweb you have to stop it by a KILL signal. 140 | Find the nweb process with: ps -ef | grep nweb 141 | Then use: kill -9 PID 142 | to stop the nweb process. 143 | 144 | 145 | 10) nweb.log Log file - what to look for 146 | Good example 147 | Here is an edited down sample nweb.log file. 148 | Note the first line = "starting" looks good as there is no following error. 149 | 150 | ---- 151 | INFO: nweb starting:8181:8913126 152 | INFO: request:GET /index.html HTTP/1.1 [[1KB of deleted request stuff here]]:2 153 | INFO: SEND:index.html:2 154 | INFO: Header:HTTP/1.1 200 OK 155 | Server: nweb/21.0 156 | Content-Length: 239 157 | Connection: close 158 | Content-Type: text/html 159 | 160 | INFO: request:GET /nigel.jpg HTTP/1.1 [[1KB of deleted request stuff here]]:3 161 | INFO: SEND:nigel.jpg:3 162 | INFO: Header:HTTP/1.1 200 OK 163 | Server: nweb/21.0 164 | Content-Length: 10184 165 | Connection: close 166 | Content-Type: image/jpg 167 | ---- 168 | 169 | Bad example 170 | A failure to start due to the port number is not aallowed or in use looks like: 171 | 172 | INFO: nweb starting:80:8323296 173 | ERROR: system call:bind Errno=13 exiting pid=8323296 174 | 175 | ---- 176 | 177 | 178 | client.c 179 | ======== 180 | 181 | This client.c program is designed to fake being a web browser. 182 | It sends the expected requests to the web server over a network 183 | socket connection and displays the results as text rather than 184 | graphically displaying the results. In the code you will have to 185 | change the two lines as below to match your web server or nweb server. 186 | 187 | /* YOU WILL HAVE TO CHANGE THESE TWO LINES TO MATCH YOUR CONFIG */ 188 | #define PORT 8181 /* Port number as an integer - web server default is 80 */ 189 | #define IP_ADDRESS "192.168.0.8" /* IP Address as a string */ 190 | 191 | The default is to request the /index.html from the web server. 192 | If you want to request another file then change the GET line as below: 193 | 194 | char *command = "GET /index.html HTTP/1.0 \r\n\r\n" ; 195 | 196 | To, for example: 197 | 198 | char *command = "GET /nigel.jpg HTTP/1.0 \r\n\r\n" ; 199 | 200 | 201 | Then compile the program with: cc client.c -o client 202 | 203 | I save the output in to a file as putting a non-test file like .jpg to the 204 | terminal screen can cause chaos: client >output 205 | 206 | Then edit the output file: vi output 207 | 208 | In real life, the interaction of web browser and web server can be 209 | much more complex. 210 | 1) The web browser can tell the web server about its name, version 211 | and capabilities. 212 | 2) The web server can send complex file types line JavaScript or Java 213 | programs or other active components. 214 | 3) They can maintain a longer connection over the socket for efficiency. 215 | 216 | 4) Below is an example of my Firefox brower requesting an index.html file. 217 | I have added newline characters to make it readable - it is 1300 bytes long! 218 | I have no idea what most of it is about. 219 | You will have to read the The World Wide Web Consortium (W3C) at 220 | http://www.w3.org for all the details. 221 | 222 | GET /index.html HTTP/1.1**Host: myserver.home.com:80**User-Agent: Mozilla/5.0 223 | (W indows; U; Windows NT 5.1; en-GB; rv:1.9.2.28) Gecko/20120306 Firefox/3.6.28 224 | (.NET CLR 3.5.30729)**Ac cept: image/png,image/*;q=0.8,*/*;q=0.5**Accept-Language: 225 | en-gb,en;q=0.5**Accept-Encoding: gzip,defla te**Accept-Charset: ISO-8859-1,utf-8; 226 | q=0.7,*;q=0.7**Keep-Alive: 115**Connection: keep-alive**Referer: 227 | http://myserver.uk.home.com:8181/index.html**Cookie: 228 | __utma=101107545.1790272076.1316019590.13289002 55.1328908680.164; 229 | __utmz=101107545.1328566199.157.46.utmcsr=t.co|utmccn=(referral)|utmcmd=referral| 230 | u tmcct=/iTJx4DO1; UnicaNIODID=ZBr8gm79vIG-XKeoGGb; W3SSO_ACCESS=abc.home.com; 231 | ISP=70fdfc95 d93011d783e4de784ea97766-70fdfc95d93011d783e4de784ea97766-f67749a8b899e8ceed7e940b8c4bf189; 232 | Prof ile=2000121913394303111032836125|EN|866|866.BDF|en-GB; 233 | __unam=693fb60-1337f162b72-11770d11-5; WLS_ intra_USERID=nigel@hotmail.com; 234 | ipcInfo=cc%3Duk%3Blc%3Den%3Bac%3Dall; iwm1p=214617669; bprememberme=nigel@ hotmail.com; 235 | EPSPROFILE=EE2355DFE16AE020BE6C62FCB6BF5602; DWPERM=Xa.2/Xb.Xzso3-U35t8RWKvqBreGaQMgsP_RG 236 | Fl1124oIt-L-OPJIdSautkBN0D4NUp9JLlpUqPqB6CWOo-pgrJwhxNvvSfPAajgetaA2MOYwHfQPXPTRG9zwOMMR57EHQtXhOy5Om yzanyZthvVClm6uxvbwh0isEQ2Mm_9g2l7NjcA3RJdjuLaB3qlljOmyVuhDjBkgdNEb3PgYcCpbiu1FUzXrhPalhgsbAj7NBkaY88 Yyg/Xc./Xd./Xf./Xg.1696801 237 | 238 | 239 | I hope this has been instructive, thanks, Nigel Griffiths 240 | 241 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* YOU WILL HAVE TO CHANGE THESE TWO LINES TO MATCH YOUR CONFIG */ 11 | #define PORT 8181 /* Port number as an integer - web server default is 80 */ 12 | #define IP_ADDRESS "192.168.0.8" /* IP Address as a string */ 13 | 14 | char *command = "GET /index.html HTTP/1.0 \r\n\r\n" ; 15 | /* Note: spaces are delimiters and VERY important */ 16 | 17 | #define BUFSIZE 8196 18 | 19 | pexit(char * msg) 20 | { 21 | perror(msg); 22 | exit(1); 23 | } 24 | 25 | main() 26 | { 27 | int i,sockfd; 28 | char buffer[BUFSIZE]; 29 | static struct sockaddr_in serv_addr; 30 | 31 | printf("client trying to connect to %s and port %d\n",IP_ADDRESS,PORT); 32 | if((sockfd = socket(AF_INET, SOCK_STREAM,0)) <0) 33 | pexit("socket() failed"); 34 | 35 | serv_addr.sin_family = AF_INET; 36 | serv_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS); 37 | serv_addr.sin_port = htons(PORT); 38 | 39 | /* Connect tot he socket offered by the web server */ 40 | if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <0) 41 | pexit("connect() failed"); 42 | 43 | /* Now the sockfd can be used to communicate to the server the GET request */ 44 | printf("Send bytes=%d %s\n",strlen(command), command); 45 | write(sockfd, command, strlen(command)); 46 | 47 | /* This displays the raw HTML file (if index.html) as received by the browser */ 48 | while( (i=read(sockfd,buffer,BUFSIZE)) > 0) 49 | write(1,buffer,i); 50 | } 51 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | nweb 3 | 4 | 5 |

nweb Test page

6 | 7 |

8 | Not pretty but it should prove that nweb works :-) 9 |

10 | Feedback is welcome to Nigel Griffiths nag@uk.ibm.com 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /nigel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nigel.jpg -------------------------------------------------------------------------------- /nweb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb -------------------------------------------------------------------------------- /nweb.log: -------------------------------------------------------------------------------- 1 | INFO: nweb starting:8181:75600 2 | INFO: request:GET / HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8**User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:1 3 | INFO: SEND:index.html:1 4 | INFO: Header:HTTP/1.1 200 OK 5 | Server: nweb/23.0 6 | Content-Length: 239 7 | Connection: close 8 | Content-Type: text/html 9 | 10 | :1 11 | INFO: request:GET /nigel.jpg HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Accept: image/webp,*/*;q=0.8**User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Referer: http://localhost:8181/**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:2 12 | INFO: SEND:nigel.jpg:2 13 | INFO: Header:HTTP/1.1 200 OK 14 | Server: nweb/23.0 15 | Content-Length: 10184 16 | Connection: close 17 | Content-Type: image/jpg 18 | 19 | :2 20 | INFO: request:GET /favicon.ico HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Accept: */***User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:3 21 | INFO: SEND:favicon.ico:3 22 | INFO: Header:HTTP/1.1 200 OK 23 | Server: nweb/23.0 24 | Content-Length: 1334 25 | Connection: close 26 | Content-Type: image/ico 27 | 28 | :3 29 | INFO: request:GET / HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Cache-Control: no-cache**Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8**Pragma: no-cache**User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:4 30 | INFO: SEND:index.html:4 31 | INFO: Header:HTTP/1.1 200 OK 32 | Server: nweb/23.0 33 | Content-Length: 239 34 | Connection: close 35 | Content-Type: text/html 36 | 37 | :4 38 | INFO: request:GET /nigel.jpg HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Cache-Control: no-cache**Accept: image/webp,*/*;q=0.8**Pragma: no-cache**User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Referer: http://localhost:8181/**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:5 39 | INFO: SEND:nigel.jpg:5 40 | INFO: Header:HTTP/1.1 200 OK 41 | Server: nweb/23.0 42 | Content-Length: 10184 43 | Connection: close 44 | Content-Type: image/jpg 45 | 46 | :5 47 | INFO: request:GET /favicon.ico HTTP/1.1**Host: localhost:8181**Connection: keep-alive**Accept: */***User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36**Accept-Encoding: gzip,deflate,sdch**Accept-Language: en-US,en;q=0.8,sq;q=0.6**Cookie: request_method=GET; _demo_app_session=Q21ScllISEE1cXB0MUNOSTZsVmYydDErelB1TXdaV2pHWXMrZHlaaHdzZktqRFQyd0NIenNNYUJkMG9uTkVKTk9IUHROMjdVQzhoSkxQbURrYkJERlRaZDZFNHZJaUYwcTJmbFVjOW4wVVV5VmNnL2dSeFhhUW16ZTBFd2Q1RzIxd3hXUDd2VjdBZm5PRmhqS3FXR2NsakdBOU1VUWtTY1FHRzJSWE80U2J5RUtSVjNEa0JLYThwUmpCd0kxeGNDSjQ1Z2tqTno4MkpZcHRwT2ltVEhZVUhrYlZiUW9oazZFQkE1TC85VmhZVVpZajEyRUJZdytuSk1YYXNXQW5zOEs4Um1tOUZ0RXR6OWdvay9JWmgzZXpnRHZhK2tVTG9INS9sR3ZabHhyUEY3ZU5rcGdlUTJpamNqejU5VXhGbSstLVQ3Y1hjQXpUbVdLaXAvYVpYcFhYVEE9PQ%3D%3D--867ec6a3db6083bb44f64b69d14d39abb37cdaa6; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_37d007a56d816107ce5b52c10342db37=ankush%7C1394657749%7C7f2faf2a6daebb8c5dc4c0984f05802a; wp-settings-time-1=1394485000; cookies.js=1; _session_id=04089c91d8b191ff0f95af4955414445; __profilin=p%3Dt; _sample_app_session=TU1OWmxRYXJUemNSV3lYU24zK2hoTEFsOTBXOVhZQmplV3V2UklMNkJveFE1TWcyN1lCU21VVHJKVkpBVDZRQlN1Uyt2cVpFZC9DL1pTcTZzc1lRKzZVVGt2L3BNdEhtbG9sR0lsbkJvSWUycU8yV0QweHZPbmJGMVZFYmRzcG9MZ2luYVRTd3BJWkJDVGRmc0c4Vy94WHFkNE5RRWZFTDRPTWxVckZOOHhBOFJYUk5CWG5HY1YvbTFESFZ6YWhCLS12MkJOY1Y5L1dEQXpVREYzOTBWQUx3PT0%3D--052b32000e1c32b521bb6250db0230669cc007ec****:6 48 | INFO: SEND:favicon.ico:6 49 | INFO: Header:HTTP/1.1 200 OK 50 | Server: nweb/23.0 51 | Content-Length: 1334 52 | Connection: close 53 | Content-Type: image/ico 54 | 55 | :6 56 | FORBIDDEN: failed to read browser request: 57 | INFO: request:GET / HTTP/1.1**User-Agent: curl/7.30.0**Host: localhost:8181**Accept: */*****:8 58 | INFO: SEND:index.html:8 59 | INFO: Header:HTTP/1.1 200 OK 60 | Server: nweb/23.0 61 | Content-Length: 239 62 | Connection: close 63 | Content-Type: text/html 64 | 65 | :8 66 | INFO: request:GET / HTTP/1.1**User-Agent: curl/7.30.0**Host: localhost:8181**Accept: */*****:9 67 | INFO: SEND:index.html:9 68 | INFO: Header:HTTP/1.1 200 OK 69 | Server: nweb/23.0 70 | Content-Length: 239 71 | Connection: close 72 | Content-Type: text/html 73 | 74 | :9 75 | INFO: request:GET / HTTP/1.1**User-Agent: curl/7.30.0**Host: localhost:8181**Accept: */*****:10 76 | INFO: SEND:index.html:10 77 | INFO: Header:HTTP/1.1 200 OK 78 | Server: nweb/23.0 79 | Content-Length: 239 80 | Connection: close 81 | Content-Type: text/html 82 | 83 | :10 84 | INFO: request:GET / HTTP/1.1**User-Agent: curl/7.30.0**Host: localhost:8181**Accept: */*****:11 85 | INFO: SEND:index.html:11 86 | INFO: Header:HTTP/1.1 200 OK 87 | Server: nweb/23.0 88 | Content-Length: 239 89 | Connection: close 90 | Content-Type: text/html 91 | 92 | :11 93 | -------------------------------------------------------------------------------- /nweb23.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define VERSION 23 13 | #define BUFSIZE 8096 14 | #define ERROR 42 15 | #define LOG 44 16 | #define FORBIDDEN 403 17 | #define NOTFOUND 404 18 | 19 | #ifndef SIGCLD 20 | # define SIGCLD SIGCHLD 21 | #endif 22 | 23 | struct { 24 | char *ext; 25 | char *filetype; 26 | } extensions [] = { 27 | {"gif", "image/gif" }, 28 | {"jpg", "image/jpg" }, 29 | {"jpeg","image/jpeg"}, 30 | {"png", "image/png" }, 31 | {"ico", "image/ico" }, 32 | {"zip", "image/zip" }, 33 | {"gz", "image/gz" }, 34 | {"tar", "image/tar" }, 35 | {"htm", "text/html" }, 36 | {"html","text/html" }, 37 | {0,0} }; 38 | 39 | void logger(int type, char *s1, char *s2, int socket_fd) 40 | { 41 | int fd ; 42 | char logbuffer[BUFSIZE*2]; 43 | 44 | switch (type) { 45 | case ERROR: (void)sprintf(logbuffer,"ERROR: %s:%s Errno=%d exiting pid=%d",s1, s2, errno,getpid()); 46 | break; 47 | case FORBIDDEN: 48 | (void)write(socket_fd, "HTTP/1.1 403 Forbidden\nContent-Length: 185\nConnection: close\nContent-Type: text/html\n\n\n403 Forbidden\n\n

Forbidden

\nThe requested URL, file type or operation is not allowed on this simple static file webserver.\n\n",271); 49 | (void)sprintf(logbuffer,"FORBIDDEN: %s:%s",s1, s2); 50 | break; 51 | case NOTFOUND: 52 | (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\n

Not Found

\nThe requested URL was not found on this server.\n\n",224); 53 | (void)sprintf(logbuffer,"NOT FOUND: %s:%s",s1, s2); 54 | break; 55 | case LOG: (void)sprintf(logbuffer," INFO: %s:%s:%d",s1, s2,socket_fd); break; 56 | } 57 | /* No checks here, nothing can be done with a failure anyway */ 58 | if((fd = open("nweb.log", O_CREAT| O_WRONLY | O_APPEND,0644)) >= 0) { 59 | (void)write(fd,logbuffer,strlen(logbuffer)); 60 | (void)write(fd,"\n",1); 61 | (void)close(fd); 62 | } 63 | if(type == ERROR || type == NOTFOUND || type == FORBIDDEN) exit(3); 64 | } 65 | 66 | /* this is a child web server process, so we can exit on errors */ 67 | void web(int fd, int hit) 68 | { 69 | int j, file_fd, buflen; 70 | long i, ret, len; 71 | char * fstr; 72 | static char buffer[BUFSIZE+1]; /* static so zero filled */ 73 | 74 | ret =read(fd,buffer,BUFSIZE); /* read Web request in one go */ 75 | if(ret == 0 || ret == -1) { /* read failure stop now */ 76 | logger(FORBIDDEN,"failed to read browser request","",fd); 77 | } 78 | if(ret > 0 && ret < BUFSIZE) /* return code is valid chars */ 79 | buffer[ret]=0; /* terminate the buffer */ 80 | else buffer[0]=0; 81 | for(i=0;i 0 ) { 125 | (void)write(fd,buffer,ret); 126 | } 127 | sleep(1); /* allow socket to drain before signalling the socket is closed */ 128 | close(fd); 129 | exit(1); 130 | } 131 | 132 | int main(int argc, char **argv) 133 | { 134 | int i, port, pid, listenfd, socketfd, hit; 135 | socklen_t length; 136 | static struct sockaddr_in cli_addr; /* static = initialised to zeros */ 137 | static struct sockaddr_in serv_addr; /* static = initialised to zeros */ 138 | 139 | if( argc < 3 || argc > 3 || !strcmp(argv[1], "-?") ) { 140 | (void)printf("hint: nweb Port-Number Top-Directory\t\tversion %d\n\n" 141 | "\tnweb is a small and very safe mini web server\n" 142 | "\tnweb only servers out file/web pages with extensions named below\n" 143 | "\t and only from the named directory or its sub-directories.\n" 144 | "\tThere is no fancy features = safe and secure.\n\n" 145 | "\tExample: nweb 8181 /home/nwebdir &\n\n" 146 | "\tOnly Supports:", VERSION); 147 | for(i=0;extensions[i].ext != 0;i++) 148 | (void)printf(" %s",extensions[i].ext); 149 | 150 | (void)printf("\n\tNot Supported: URLs including \"..\", Java, Javascript, CGI\n" 151 | "\tNot Supported: directories / /etc /bin /lib /tmp /usr /dev /sbin \n" 152 | "\tNo warranty given or implied\n\tNigel Griffiths nag@uk.ibm.com\n" ); 153 | exit(0); 154 | } 155 | if( !strncmp(argv[2],"/" ,2 ) || !strncmp(argv[2],"/etc", 5 ) || 156 | !strncmp(argv[2],"/bin",5 ) || !strncmp(argv[2],"/lib", 5 ) || 157 | !strncmp(argv[2],"/tmp",5 ) || !strncmp(argv[2],"/usr", 5 ) || 158 | !strncmp(argv[2],"/dev",5 ) || !strncmp(argv[2],"/sbin",6) ){ 159 | (void)printf("ERROR: Bad top directory %s, see nweb -?\n",argv[2]); 160 | exit(3); 161 | } 162 | if(chdir(argv[2]) == -1){ 163 | (void)printf("ERROR: Can't Change to directory %s\n",argv[2]); 164 | exit(4); 165 | } 166 | /* Become deamon + unstopable and no zombies children (= no wait()) */ 167 | if(fork() != 0) 168 | return 0; /* parent returns OK to shell */ 169 | (void)signal(SIGCLD, SIG_IGN); /* ignore child death */ 170 | (void)signal(SIGHUP, SIG_IGN); /* ignore terminal hangups */ 171 | for(i=0;i<32;i++) 172 | (void)close(i); /* close open files */ 173 | (void)setpgrp(); /* break away from process group */ 174 | logger(LOG,"nweb starting",argv[1],getpid()); 175 | /* setup the network socket */ 176 | if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0) 177 | logger(ERROR, "system call","socket",0); 178 | port = atoi(argv[1]); 179 | if(port < 0 || port >60000) 180 | logger(ERROR,"Invalid port number (try 1->60000)",argv[1],0); 181 | serv_addr.sin_family = AF_INET; 182 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 183 | serv_addr.sin_port = htons(port); 184 | if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0) 185 | logger(ERROR,"system call","bind",0); 186 | if( listen(listenfd,64) <0) 187 | logger(ERROR,"system call","listen",0); 188 | for(hit=1; ;hit++) { 189 | length = sizeof(cli_addr); 190 | if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) 191 | logger(ERROR,"system call","accept",0); 192 | if((pid = fork()) < 0) { 193 | logger(ERROR,"system call","fork",0); 194 | } 195 | else { 196 | if(pid == 0) { /* child */ 197 | (void)close(listenfd); 198 | web(socketfd,hit); /* never returns */ 199 | } else { /* parent */ 200 | (void)close(socketfd); 201 | } 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /nweb23_Fedora_17_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_Fedora_17_64 -------------------------------------------------------------------------------- /nweb23_RHEL63_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_RHEL63_64 -------------------------------------------------------------------------------- /nweb23_SLES_11_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_SLES_11_64 -------------------------------------------------------------------------------- /nweb23_aix6_1_7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_aix6_1_7 -------------------------------------------------------------------------------- /nweb23_openSUSU_12_1_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_openSUSU_12_1_64 -------------------------------------------------------------------------------- /nweb23_raspberry_pi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_raspberry_pi -------------------------------------------------------------------------------- /nweb23_ubuntu_12_4_32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_ubuntu_12_4_32 -------------------------------------------------------------------------------- /nweb23_ubuntu_12_4_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankushagarwal/nweb/867a6dd46298c882501f5c26d31ee821177542ab/nweb23_ubuntu_12_4_64 --------------------------------------------------------------------------------