1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
/* simple_httpd.C
* -- Copyright (C) 2003 by Herbert Straub
*
* Permission is granted to use at your own risk and distribute this software
* in source and binary forms provided the above copyright notice and this
* paragraph are preserved on all copies. This software is provided "as is"
* with no express or implied warranty.
*/
/*
* This little program implements a very simple http server (only for
* testing purposes). It usess: iosockinet, sockbuf, Fork.
*/
#include <config.h>
#include <socket++/fork.h>
#include <socket++/sockinet.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif
using namespace std;
int process_request (iosockinet *sock);
void get_filesize (const char *name, string &buffer);
int main (int argc, char **argv)
{
sockinetbuf sin (sockbuf::sock_stream);
Fork *pF;
sin.bind ();
cout << "localhost = " << sin.localhost() << endl;
cout << "localport = " << sin.localport() << endl;
sin.listen ();
for (;;) {
iosockinet *sock;
sock = new iosockinet (sin.accept ());
sockaddr_in *remote_sock = sock->rdbuf()->peeraddr().addr_in();
cout << "socksockaddr_in.addr() = " << remote_sock << endl;
cout << "port: " << ntohs(remote_sock->sin_port) << endl;
cout << "addr: " << hex << inet_ntoa(remote_sock->sin_addr) << endl;
cout << "peerhost: " << sock->rdbuf()->peerhost() << endl;
pF = new Fork (0, 1);
if (pF->is_child ()) {
sock->rdbuf()->keepalive (1);
process_request (sock);
return (0);
}
}
}
int process_request (iosockinet *sock)
{
string buffer;
string filename;
ifstream file;
try {
while (1) {
getline (*sock, buffer);
buffer[buffer.length()-1] = '\n';
cout << "buffer: " << buffer << endl;
if (sock->eof())
break;
// g++ < 3.0 : strncmp !!
if (strncmp (buffer.c_str(), "quit", 4) == 0)
//if (buffer.compare (0, 4, "quit") == 0)
break;
if (buffer.length() == 0)
break;
if (buffer[0] == '\n')
break;
// g++ < 3.0 : strncmp !!
if (strncmp (buffer.c_str(), "GET", 4) == 0)
//if (buffer.compare (0, 4, "GET") == 0)
filename.assign (buffer, 4, buffer.rfind (" HTTP")-3);
}
}
catch (sockerr s) {
cout << "catched " << endl;
goto END;
}
//filename.insert (0, ".");
filename.replace (filename.length()-1, 1, "");
cout << "Filename: " << filename << endl;
file.open (filename.c_str());
if (file.bad() || !file.is_open() || !file.good()) {
cout << "Error opening file: " << filename << endl;
goto END;
}
*sock << "HTTP/1.1 200 OK\r\n";
*sock << "Server: socket++ Testserver\r\n";
get_filesize (filename.c_str(), buffer);
*sock << "Content-Length: " << buffer << "\r\n";
*sock << "Connection: close\r\n";
*sock << "Content-Type: plain/text; charset=iso-8859-1\r\n";
*sock << "\r\n";
sock->flush();
try {
for (getline(file, buffer); !file.eof(); getline(file,buffer)) {
cout << "Sending Buffer: " << buffer << endl;
*sock << buffer << "\r\n";
}
sock->flush();
}
catch (sockerr e) {
cout << "Catched sockerr" << endl;
}
file.close ();
END:
try {
sock->rdbuf()->shutdown(sockbuf::shut_readwrite);
}
catch (...)
{
// if the client break the connection, then
// the shutdown method throws sockerr
}
delete sock;
return 0;
}
void get_filesize (const char *name, string &buffer)
{
struct stat buf;
#ifdef HAVE_SSTREAM
stringstream sb;
#else
strstream sb;
#endif
if (stat (name, &buf) == -1)
buf.st_size = 0;
sb << buf.st_size;
buffer = sb.rdbuf()->str();
}
|