(E-Mail Removed) (Michael Mezheritsky) writes:
> Hello,
> Does anybody know how to compose an HTTP packet from C-program on Linux?
Here is one quite minimal web server program written in C.
Take a look at it's source code.
This werver was originally designed to run on Linux/Unix
environment. I have not used this code for some time...
/*
* Minimal web server by Tomi Engdahl
* 27. May 1998
*
* Version history:
*
* Version 0.3
* - form support added
* - new MIME types added
*
* Version 0.2
* - 404 not found error added
*
* Version 0.1
* - original source code modified to access real files
*
* Based on the following source code:
* Minimal Web server by Richard Ames
* Published in Circuit Cellar INK Issue 91 February 1998
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#define HDR "HTTP/1.0 200 OK\r\n"
#define HDRNOTFOUND "HTTP/1.0 404 File not found\r\n"
#define HDRHTML "Content-type: text/html\r\n"
#define HDRJPEG "Content-type: image/jpeg\r\n"
#define HDRGIF "Content-type: image/gif\r\n"
#define HDRTEXT "Content-type: text/plain\r\n"
#define DEFAULTSOURCE "index.html"
#define INBUFFERSIZE 500
#define OUTBUFFERSIZE 5000
#define FORMREPLYNAME "control"
#define SYSCMDNAME "date"
void fileresourceroutine(int s2, char *filename)
{
char buf[OUTBUFFERSIZE]; /* holds outgoing response */
int retcod; /* general purpose return code */
struct stat stbuf; /* for unix file status */
int fhandle; /* for reading UNIX files */
char *extension; /* ptr to extension for requested source */
long filelen; /* size of requested resource */
retcod=stat(filename, &stbuf); /* determine size and check that exists */
filelen = (&stbuf)->st_size;
if (retcod == 0) {
write(s2, HDR, strlen(HDR)); /* write first response line */
printf("%s", HDR);
extension = filename; /* isolate extension */
while ((*extension) && (*extension != '.'))
extension++;
if (strcmp(".html", extension) == 0) { /* write type */
write(s2, HDRHTML, strlen(HDRHTML));
printf("%s", HDRHTML);
}
else if (strcmp(".jpg", extension) == 0) {
write(s2, HDRJPEG, strlen(HDRJPEG));
printf("%s", HDRJPEG);
}
else if (strcmp(".gif", extension) == 0) {
write(s2, HDRGIF, strlen(HDRGIF));
printf("%s", HDRJPEG);
}
else if (strcmp(".txt", extension) == 0) {
write(s2, HDRTEXT, strlen(HDRTEXT));
printf("%s", HDRJPEG);
}
sprintf(buf, "Content-length: %d\r\n\r\n", filelen);
write(s2, buf, strlen(buf));
printf("Content-length: %d\n", filelen);
fhandle = open(filename,O_RDONLY,0); /* open local resource */
if (fhandle >= 0) {
while (1) {
if ((retcod = read(fhandle, buf, 512)) > 0) {
write(s2, buf, retcod);
printf("Wrote %i byte of data\n",retcod);
}
else {
break;
}
}
close(fhandle);
printf("File closed.\n");
}
else printf("Error opening file\n");
}
else {
printf("File not found.\n");
write(s2, HDRNOTFOUND, strlen(HDR)); /* write response line */
printf("%s", HDRNOTFOUND);
}
}
void formroutine(int s2, char *filename, char *inbuf)
{
char buf[OUTBUFFERSIZE]; /* holds outgoing response */
char vbuffer[100]; /* stores value of the form field */
int retcod; /* general purpose return code */
/* sscanf(filename,"control?TextInput=%s",vbuffer); */
printf("DATA=%s\n",inbuf);
}
void execute_external(int s2, char *filename)
{
printf("Calling external command\n");
system("date > temp.txt");
fileresourceroutine(s2, "temp.txt");
}
main () {
char buf[INBUFFERSIZE]; /* holds incoming request, outgoing response */
char defaultsource[] = DEFAULTSOURCE;
char resourcename[80]; /* holds name of requested resource */
char *filename; /* pointer to requested resource */
char *extension; /* ptr to extension for requested source */
int remSize; /* hods size of address structure */
int retcod; /* general purpose return code */
int s; /* handle to listening socket */
int s2; /* handle to socket being serviced */
struct sockaddr_in locAddr; /* addr struct for local address */
struct sockaddr_in remAddr; /* addr struct for remote address */
printf("Sample Web Server v0.3\n");
s = socket(AF_INET, SOCK_STREAM, 0); /* create listening socket */
if (s<0) {
printf("Error opening socket\n");
return -1;
}
memset((void *) &locAddr, 0, sizeof(locAddr));
locAddr.sin_family = AF_INET;
locAddr.sin_addr.s_addr = htonl(INADDR_ANY);
locAddr.sin_port = htons(8080);
retcod = bind(s, (struct sockaddr *) &locAddr, sizeof(locAddr));
if (retcod < 0) {
printf("Error in bind\n");
close(s);
return -1;
}
retcod = listen (s, 5);
if (retcod < 0) {
printf("Error in listen\n");
close(s);
return -1;
}
while (1) {
remSize = sizeof(remAddr);
s2 = accept(s, (struct sockaddr *) &remAddr, &remSize);
if (s2 < 0) {
printf("Error in accept\n");
return -1;
}
retcod = read(s2, buf, sizeof(buf)); /* read request */
if (retcod >= 0)
buf[retcod] = 0; /* change to null terminated str */
printf("%s\n", buf); /* display request for debug */
sscanf(buf, "GET %s", resourcename); /* find resource */
filename = defaultsource; /* use this resource for default */
if (strcmp("/",resourcename) != 0) /* is this default request ? */
filename = resourcename + 1; /* no, skip past initial '/' */
printf("Resource filename: %s\n",filename);
if (strncmp(buf,"GET",3) ==0) { /* check that resource request */
if (strncmp(filename,FORMREPLYNAME,strlen(FORMREPLYNA ME)) == 0) {
formroutine(s2,filename,buf);
}
else if (strncmp(filename,SYSCMDNAME,strlen(SYSCMDNAME)) == 0) {
execute_external(s2, filename);
}
else {
fileresourceroutine(s2,filename);
}
}
if (strncmp(buf,"POST",4) == 0) { /* check that form posting */
formroutine(s2,filename,buf);
}
close(s2); /* close socket connection */
printf("Connection closed.\n\n");
}
return 0;
}
--
Tomi Engdahl (
http://www.iki.fi/then/)
Take a look at my electronics web links and documents at
http://www.epanorama.net/