The "rfb" library merged with VNC 4.1.1 code.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@522 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb/HTTPServer.cxx b/rfb/HTTPServer.cxx
index 3bac4f8..e40d480 100644
--- a/rfb/HTTPServer.cxx
+++ b/rfb/HTTPServer.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
- *
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ *
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -20,11 +20,6 @@
#include <rfb/LogWriter.h>
#include <rfb/util.h>
#include <rdr/MemOutStream.h>
-#include <time.h>
-
-// *** Shouldn't really link against this - only for ClientWaitTimeMillis
-// and IdleTimeout
-#include <rfb/ServerCore.h>
#ifdef WIN32
#define strcasecmp _stricmp
@@ -36,6 +31,9 @@
static LogWriter vlog("HTTPServer");
+const int clientWaitTimeMillis = 20000;
+const int idleTimeoutSecs = 5 * 60;
+
//
// -=- LineReader
@@ -94,7 +92,8 @@
class rfb::HTTPServer::Session {
public:
Session(network::Socket& s, rfb::HTTPServer& srv)
- : contentType(0), line(s.inStream(), 256), sock(s),
+ : contentType(0), contentLength(-1), lastModified(-1),
+ line(s.inStream(), 256), sock(s),
server(srv), state(ReadRequestLine), lastActive(time(0)) {
}
~Session() {
@@ -111,6 +110,8 @@
protected:
CharArray uri;
const char* contentType;
+ int contentLength;
+ time_t lastModified;
LineReader line;
network::Socket& sock;
rfb::HTTPServer& server;
@@ -140,6 +141,7 @@
// - Write an HTTP-compliant response to the client
+
void
HTTPServer::Session::writeResponse(int result, const char* text) {
char buffer[1024];
@@ -149,6 +151,19 @@
OutStream& os=sock.outStream();
writeLine(os, buffer);
writeLine(os, "Server: TightVNC/4.0");
+ time_t now = time(0);
+ struct tm* tm = gmtime(&now);
+ strftime(buffer, 1024, "Date: %a, %d %b %Y %H:%M:%S GMT", tm);
+ writeLine(os, buffer);
+ if (lastModified == (time_t)-1 || lastModified == 0)
+ lastModified = now;
+ tm = gmtime(&lastModified);
+ strftime(buffer, 1024, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT", tm);
+ writeLine(os, buffer);
+ if (contentLength != -1) {
+ sprintf(buffer,"Content-Length: %d",contentLength);
+ writeLine(os, buffer);
+ }
writeLine(os, "Connection: close");
os.writeBytes("Content-Type: ", 14);
if (result == 200) {
@@ -247,7 +262,10 @@
{
CharArray address(sock.getPeerAddress());
vlog.info("getting %s for %s", uri.buf, address.buf);
- InStream* data = server.getFile(uri.buf, &contentType);
+ contentLength = -1;
+ lastModified = -1;
+ InStream* data = server.getFile(uri.buf, &contentType, &contentLength,
+ &lastModified);
if (!data)
return writeResponse(404);
@@ -277,9 +295,9 @@
int HTTPServer::Session::checkIdleTimeout() {
time_t now = time(0);
- int timeout = (lastActive + rfb::Server::idleTimeout) - now;
+ int timeout = (lastActive + idleTimeoutSecs) - now;
if (timeout > 0)
- return timeout * 1000;
+ return secsToMillis(timeout);
sock.shutdown();
return 0;
}
@@ -291,28 +309,38 @@
HTTPServer::~HTTPServer() {
std::list<Session*>::iterator i;
- for (i=sessions.begin(); i!=sessions.end(); i++) {
- delete (*i)->getSock();
+ for (i=sessions.begin(); i!=sessions.end(); i++)
delete *i;
- }
}
// -=- SocketServer interface implementation
void
-HTTPServer::addClient(network::Socket* sock) {
+HTTPServer::addSocket(network::Socket* sock, bool) {
Session* s = new Session(*sock, *this);
if (!s) {
sock->shutdown();
} else {
- sock->inStream().setTimeout(rfb::Server::clientWaitTimeMillis);
- sock->outStream().setTimeout(rfb::Server::clientWaitTimeMillis);
+ sock->inStream().setTimeout(clientWaitTimeMillis);
+ sock->outStream().setTimeout(clientWaitTimeMillis);
sessions.push_front(s);
}
}
-bool
+void
+HTTPServer::removeSocket(network::Socket* sock) {
+ std::list<Session*>::iterator i;
+ for (i=sessions.begin(); i!=sessions.end(); i++) {
+ if ((*i)->getSock() == sock) {
+ delete *i;
+ sessions.erase(i);
+ return;
+ }
+ }
+}
+
+void
HTTPServer::processSocketEvent(network::Socket* sock) {
std::list<Session*>::iterator i;
for (i=sessions.begin(); i!=sessions.end(); i++) {
@@ -320,21 +348,16 @@
try {
if ((*i)->processHTTP()) {
vlog.info("completed HTTP request");
- delete *i;
- sessions.erase(i);
- break;
+ sock->shutdown();
}
- return true;
} catch (rdr::Exception& e) {
vlog.error("untrapped: %s", e.str());
- delete *i;
- sessions.erase(i);
- break;
+ sock->shutdown();
}
+ return;
}
}
- delete sock;
- return false;
+ throw rdr::Exception("invalid Socket in HTTPServer");
}
void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
@@ -359,7 +382,9 @@
// -=- Default getFile implementation
InStream*
-HTTPServer::getFile(const char* name, const char** contentType) {
+HTTPServer::getFile(const char* name, const char** contentType,
+ int* contentLength, time_t* lastModified)
+{
return 0;
}