Created
November 16, 2011 20:42
-
-
Save christophlsa/1371314 to your computer and use it in GitHub Desktop.
homework for the study
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* webserver.c */ | |
#include <cnaiapi.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include <stdbool.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/sendfile.h> | |
#include <errno.h> | |
#include <signal.h> | |
const char * HTDOCS = "htdocs/"; | |
const char * INDEX_FILE = "index.html"; | |
/* | |
* Writes a HTTP-Response to the connection | |
*/ | |
bool initialResponseLine(connection _conn, char * _httpVersion, char * _responseStatusCode, char * _reasonPhrase) | |
{ | |
char response[100] = "HTTP/"; | |
strcat(response, strcat(_httpVersion, " ")); | |
strcat(response, strcat(_responseStatusCode, " ")); | |
strcat(response, _reasonPhrase); | |
strcat(response, "\n"); | |
int ret = write(STDOUT_FILENO, response, strlen(response)); | |
if (ret < 0) { | |
return false; | |
} | |
return true; | |
} | |
const char * mimes[][2] = { | |
{".jpg", "image/jpeg"}, | |
{".jpeg", "image/jpeg"}, | |
{".html", "text/html"}, | |
{".htm", "text/html"}, | |
}; | |
// get mime type of file name | |
char * getMime(const char * file) { | |
char *ext = strrchr(file, '.'); | |
if (ext == NULL) | |
return "text/plain"; | |
int i; | |
for (i = 0; i < sizeof(mimes); i++) { | |
if (strcmp(ext, mimes[i][0]) == 0) { | |
return (char*)mimes[i][1]; | |
} | |
} | |
return "text/plain"; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
signal(SIGCLD, SIG_IGN); | |
connection conn; | |
appnum app = atoi(argv[1]); | |
// Holds the complete request | |
char requestBuffer[1024] = ""; | |
int requestLength = 0; | |
// Holds the requested file path, not it's content | |
char getBuffer[1024]; | |
// Holds the length of the path to the file | |
int getLength = 0; | |
while (true) { | |
conn = await_contact(app); | |
if (conn < 0) { | |
printf("Fehler bei der Verbindung\n"); | |
return 1; | |
} | |
// to connect clients simultaniously | |
pid_t pid = fork(); | |
// child creation unsuccessful | |
if (pid < 0) { | |
printf("Fehler in child creation\n"); | |
end_contact(conn); | |
} | |
else if (pid > 0) { | |
printf("Parent\n"); | |
end_contact(conn); | |
} | |
else { | |
// read input -> blocks the thread until data is recieved | |
// Holds the Request from Client | |
char readBuffer[1024]; | |
int l; | |
while ((l = read(conn, readBuffer, 1024))) { | |
if (l < 0) { | |
printf("%s\n", strerror(errno)); | |
//end_contact(conn); | |
exit(1); | |
} | |
strncat(requestBuffer, readBuffer, l); | |
memset(&readBuffer[0], 0, sizeof(readBuffer)); | |
char* requestEnd = strstr(requestBuffer, "\r\n\r\n"); | |
if (requestEnd != NULL) { | |
break; | |
} | |
} | |
// check for GET-Request | |
int isGet = strncmp("GET", requestBuffer, 3); | |
if (isGet != 0) { | |
initialResponseLine(conn, "1.0", "501", "Not Implemented"); | |
exit(1); | |
} | |
// parsing the request from 5. symbol in readBuffer from Client (start of path) | |
int i; | |
requestLength = strlen(requestBuffer); | |
printf("%d\n", requestLength); | |
for (i = 5; i < requestLength; i++) { | |
// check man page for comaprison | |
if (isspace(requestBuffer[i]) != false) { | |
break; | |
} | |
getBuffer[getLength++] = requestBuffer[i]; | |
} | |
// deliver requested file | |
// if only "/" take index.html | |
if ( strlen(getBuffer) == 0 ) { | |
strcat(getBuffer, INDEX_FILE); | |
} | |
char filePath[1024] = ""; | |
strcat(filePath, HTDOCS); | |
strcat(filePath, getBuffer); | |
// open file -> http://www.win-tux.de/c_018_025.htm#RxxobKap01802504002A2F1F02418C | |
int fd = open(filePath, O_RDONLY); | |
// if an error occurs -> 404 | |
if (fd < 0) { | |
initialResponseLine(conn, "1.0", "404", "Not Found\r"); | |
printf("%s\r", filePath); | |
exit(0); | |
} | |
struct stat st; | |
fstat (fd, &st); | |
char responseHeader[1024]; | |
int len = sprintf(responseHeader, "HTTP/1.0 200 OK\r\nOK\r\nContent-Type: %s\r\nContent-Length: %ld\r\n\r\n", getMime(filePath), st.st_size); | |
write(conn, responseHeader, len); | |
int r = sendfile(conn, fd, 0, st.st_size); | |
if (r < 0) { | |
printf("Fehler beim Datei senden: %s", strerror(errno)); | |
} | |
close(fd); | |
exit(0); | |
} | |
} | |
end_contact(conn); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment