bool HTTPServerConnection::handleRequest(Request* request) { // This is a way to remotely shutdown the Server to which this // connection belongs. TicksClock::Ticks start, end, duration; double in_seconds; start = TicksClock::getTicks(); if (request_.address == "quit") { LOG(LogMessage::NORMAL) << "Server stop requested!"; my_service_->stop(); return false; } RequestStats* stats = my_service_->stats(); uint32_t timeToHandleRequest; uint32_t timeToParseRequest; uint32_t timeToEstablishConn; uint32_t reqsLastSec; stats->getStats(TicksClock::getTicks(), &reqsLastSec, &timeToHandleRequest, &timeToParseRequest, &timeToEstablishConn); if (request_.address == "stats") { ostringstream stats_stream; stats_stream << reqsLastSec; string stats_string = stats_stream.str(); m_write_.lock(); out_.write("HTTP/1.1 200 OK\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: Lab02a\r\n"); out_.write("Accept-Ranges: bytes\r\n"); ostringstream os; os << "Content-Length: " << stats_string.size() << "\r\n"; out_.write(os.str().c_str()); out_.write("Content-Type: text/html\r\n"); out_.write("\r\n"); out_.write(stats_string.c_str()); m_write_.unlock(); TicksClock::Ticks end = TicksClock::getTicks(); TicksClock::Ticks duration = end - start; in_seconds = duration / TicksClock::ticksPerSecond(); stats->updateTimeToHandleRequest(in_seconds); TicksClock::Ticks start = TicksClock::getTicks(); startWrite(); end = TicksClock::getTicks(); duration = end - start; in_seconds = duration / TicksClock::ticksPerSecond(); stats->updateTimeToHandleRequest(in_seconds); return true; } // If the request is for the root document, expand the name to // 'index.html' if (request_.address.empty()) { request_.address = "index.html"; } // Grab from or load the file to the cache. Buffer* buf; int error; FileCache::CacheHandle h = file_cache_->pin(request_.address, &buf, & error); if (h != 0) { m_write_.lock(); out_.write("HTTP/1.1 200 OK\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: Lab02a\r\n"); out_.write("Accept-Ranges: bytes\r\n"); ostringstream os; os << "Content-Length: " << buf->readSize() << "\r\n"; out_.write(os.str().c_str()); out_.write("Content-Type: text/html\r\n"); out_.write("\r\n"); // Copy from cache into the connection buffer. out_.copyFrom(buf); m_write_.unlock(); } else { // TODO // // differentiate between a server internal error (ie too many // sockets open), which should return a 500 and a file not found, // which should return a 404. perror("Can't serve request"); m_write_.lock(); ostringstream html_stream; html_stream <<"<HTML>\r\n"; html_stream <<"<HEAD><TITLE>400 Bad Request</TITLE></HEAD>\r\n"; html_stream <<"<BODY>Bad Request</BODY>\r\n"; html_stream <<"</HTML>\r\n"; html_stream <<"\r\n"; ostringstream os; os << "Content-Length: " << html_stream.str().size() << "\r\n"; out_.write("HTTP/1.1 503 Bad Request\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: MyServer\r\n"); out_.write("Connection: close\r\n"); out_.write("Transfer-Encoding: chunked\r\n"); out_.write(os.str().c_str()); out_.write("Content-Type: text/html; charset=iso-8859-1\r\n"); out_.write("\r\n"); out_.write(html_stream.str().c_str()); m_write_.unlock(); } end = TicksClock::getTicks(); duration = end - start; in_seconds = duration / TicksClock::ticksPerSecond(); stats->updateTimeToHandleRequest(in_seconds); stats->finishedRequest(ThreadPoolFast::ME(), TicksClock::getTicks()); start = TicksClock::getTicks(); startWrite(); end = TicksClock::getTicks(); duration = end - start; in_seconds = duration / TicksClock::ticksPerSecond(); stats->updateTimeToHandleRequest(in_seconds); return true; }
bool HTTPServerConnection::handleRequest(Request* request) { // This is a way to remotely shutdown the Server to which this // connection belongs. if (request_.address == "quit") { LOG(LogMessage::NORMAL) << "Server stop requested!"; io_service()->stop(); return false; } RequestStats* stats = io_service()->stats(); if (request_.address == "stats") { uint32_t reqsLastSec; stats->getStats(TicksClock::getTicks(), &reqsLastSec); ostringstream stats_stream; stats_stream << reqsLastSec; string stats_string = stats_stream.str(); m_write_.lock(); out_.write("HTTP/1.1 200 OK\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: Lab02a\r\n"); out_.write("Accept-Ranges: bytes\r\n"); ostringstream os; os << "Content-Length: " << stats_string.size() << "\r\n"; out_.write(os.str().c_str()); out_.write("Content-Type: text/html\r\n"); out_.write("\r\n"); out_.write(stats_string.c_str()); m_write_.unlock(); startWrite(); return true; } // If the request is for the root document, expand the name to // 'index.html' if (request_.address.empty()) { request_.address = "index.html"; } int fd = open(request_.address.c_str(), O_RDONLY); if (fd != -1) { struct stat stat_buf; fstat(fd, &stat_buf); m_write_.lock(); out_.write("HTTP/1.1 200 OK\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: Lab02a\r\n"); out_.write("Accept-Ranges: bytes\r\n"); ostringstream os; os << "Content-Length: " << stat_buf.st_size << "\r\n"; out_.write(os.str().c_str()); out_.write("Content-Type: text/html\r\n"); out_.write("\r\n"); out_.reserve(stat_buf.st_size); m_write_.unlock(); // This is going to break with files bigger than // Buffer::Blocksize bytes, But... let's leave it for now. int res = read(fd, out_.writePtr(), out_.writeSize()); if (res < 0) { perror("Error reading file"); exit(1); } ::close(fd); m_write_.lock(); out_.advance(res); m_write_.unlock(); } else { // TODO // // differentiate between a server internal error (ie too many // sockets open), which should return a 500 and a file not found, // which should return a 404. perror("Can't serve request"); m_write_.lock(); ostringstream html_stream; html_stream <<"<HTML>\r\n"; html_stream <<"<HEAD><TITLE>400 Bad Request</TITLE></HEAD>\r\n"; html_stream <<"<BODY>Bad Request</BODY>\r\n"; html_stream <<"</HTML>\r\n"; html_stream <<"\r\n"; ostringstream os; os << "Content-Length: " << html_stream.str().size() << "\r\n"; out_.write("HTTP/1.1 503 Bad Request\r\n"); out_.write("Date: Wed, 28 Oct 2009 15:24:11 GMT\r\n"); out_.write("Server: MyServer\r\n"); out_.write("Connection: close\r\n"); out_.write("Transfer-Encoding: chunked\r\n"); out_.write(os.str().c_str()); out_.write("Content-Type: text/html; charset=iso-8859-1\r\n"); out_.write("\r\n"); out_.write(html_stream.str().c_str()); m_write_.unlock(); } stats->finishedRequest(ThreadPoolFast::ME(), TicksClock::getTicks()); startWrite(); return true; }