mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-07 16:54:13 +01:00
Remove remnants of the old HTTP server
This commit is contained in:
parent
6e5a837c21
commit
49f9ce8e5b
@ -1,102 +0,0 @@
|
|||||||
/* 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
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RDR_SUBSTITUTINGINSTREAM_H__
|
|
||||||
#define __RDR_SUBSTITUTINGINSTREAM_H__
|
|
||||||
|
|
||||||
#include <rdr/InStream.h>
|
|
||||||
#include <rdr/Exception.h>
|
|
||||||
|
|
||||||
namespace rdr {
|
|
||||||
|
|
||||||
class Substitutor {
|
|
||||||
public:
|
|
||||||
virtual char* substitute(const char* varName) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SubstitutingInStream : public InStream {
|
|
||||||
public:
|
|
||||||
SubstitutingInStream(InStream* underlying_, Substitutor* s,
|
|
||||||
int maxVarNameLen_)
|
|
||||||
: underlying(underlying_), dollar(0), substitutor(s), subst(0),
|
|
||||||
maxVarNameLen(maxVarNameLen_)
|
|
||||||
{
|
|
||||||
ptr = end = underlying->getptr();
|
|
||||||
varName = new char[maxVarNameLen+1];
|
|
||||||
}
|
|
||||||
~SubstitutingInStream() {
|
|
||||||
delete underlying;
|
|
||||||
delete [] varName;
|
|
||||||
delete [] subst;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pos() { return underlying->pos(); }
|
|
||||||
|
|
||||||
virtual int overrun(int itemSize, int nItems, bool wait=true) {
|
|
||||||
if (itemSize != 1)
|
|
||||||
throw new rdr::Exception("SubstitutingInStream: itemSize must be 1");
|
|
||||||
|
|
||||||
if (subst) {
|
|
||||||
delete [] subst;
|
|
||||||
subst = 0;
|
|
||||||
} else {
|
|
||||||
underlying->setptr(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
underlying->check(1);
|
|
||||||
ptr = underlying->getptr();
|
|
||||||
end = underlying->getend();
|
|
||||||
dollar = (const U8*)memchr(ptr, '$', end-ptr);
|
|
||||||
if (dollar) {
|
|
||||||
if (dollar == ptr) {
|
|
||||||
try {
|
|
||||||
int i = 0;
|
|
||||||
while (i < maxVarNameLen) {
|
|
||||||
varName[i++] = underlying->readS8();
|
|
||||||
varName[i] = 0;
|
|
||||||
subst = substitutor->substitute(varName);
|
|
||||||
if (subst) {
|
|
||||||
ptr = (U8*)subst;
|
|
||||||
end = (U8*)subst + strlen(subst);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (EndOfStream&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subst)
|
|
||||||
dollar = (const U8*)memchr(ptr+1, '$', end-ptr-1);
|
|
||||||
}
|
|
||||||
if (!subst && dollar) end = dollar;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemSize * nItems > end - ptr)
|
|
||||||
nItems = (end - ptr) / itemSize;
|
|
||||||
|
|
||||||
return nItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
InStream* underlying;
|
|
||||||
const U8* dollar;
|
|
||||||
Substitutor* substitutor;
|
|
||||||
char* varName;
|
|
||||||
char* subst;
|
|
||||||
int maxVarNameLen;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -22,7 +22,6 @@ set(RFB_SOURCES
|
|||||||
EncCache.cxx
|
EncCache.cxx
|
||||||
EncodeManager.cxx
|
EncodeManager.cxx
|
||||||
Encoder.cxx
|
Encoder.cxx
|
||||||
HTTPServer.cxx
|
|
||||||
HextileDecoder.cxx
|
HextileDecoder.cxx
|
||||||
HextileEncoder.cxx
|
HextileEncoder.cxx
|
||||||
JpegCompressor.cxx
|
JpegCompressor.cxx
|
||||||
|
@ -1,424 +0,0 @@
|
|||||||
/* 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
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rfb/HTTPServer.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
#include <rdr/MemOutStream.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
using namespace rdr;
|
|
||||||
|
|
||||||
static LogWriter vlog("HTTPServer");
|
|
||||||
|
|
||||||
const int clientWaitTimeMillis = 20000;
|
|
||||||
const int idleTimeoutSecs = 5 * 60;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// -=- LineReader
|
|
||||||
// Helper class which is repeatedly called until a line has been read
|
|
||||||
// (lines end in \n or \r\n).
|
|
||||||
// Returns true when line complete, and resets internal state so that
|
|
||||||
// next read() call will start reading a new line.
|
|
||||||
// Only one buffer is kept - process line before reading next line!
|
|
||||||
//
|
|
||||||
|
|
||||||
class LineReader : public CharArray {
|
|
||||||
public:
|
|
||||||
LineReader(InStream& is_, int l)
|
|
||||||
: CharArray(l), is(is_), pos(0), len(l), bufferOverrun(false) {}
|
|
||||||
|
|
||||||
// Returns true if line complete, false otherwise
|
|
||||||
bool read() {
|
|
||||||
while (is.checkNoWait(1)) {
|
|
||||||
char c = is.readU8();
|
|
||||||
|
|
||||||
if (c == '\n') {
|
|
||||||
if (pos && (buf[pos-1] == '\r'))
|
|
||||||
pos--;
|
|
||||||
bufferOverrun = false;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
pos = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos == (len-1)) {
|
|
||||||
bufferOverrun = true;
|
|
||||||
buf[pos] = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[pos++] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool didBufferOverrun() const {return bufferOverrun;}
|
|
||||||
protected:
|
|
||||||
InStream& is;
|
|
||||||
int pos, len;
|
|
||||||
bool bufferOverrun;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// -=- HTTPServer::Session
|
|
||||||
// Manages the internal state for an HTTP session.
|
|
||||||
// processHTTP returns true when request has completed,
|
|
||||||
// indicating that socket & session data can be deleted.
|
|
||||||
//
|
|
||||||
|
|
||||||
class rfb::HTTPServer::Session {
|
|
||||||
public:
|
|
||||||
Session(network::Socket& s, rfb::HTTPServer& srv)
|
|
||||||
: contentType(0), contentLength(-1), lastModified(-1),
|
|
||||||
line(s.inStream(), 256), sock(s),
|
|
||||||
server(srv), state(ReadRequestLine), lastActive(time(0)) {
|
|
||||||
}
|
|
||||||
~Session() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeResponse(int result, const char* text);
|
|
||||||
bool writeResponse(int code);
|
|
||||||
|
|
||||||
bool processHTTP();
|
|
||||||
|
|
||||||
network::Socket* getSock() const {return &sock;}
|
|
||||||
|
|
||||||
int checkIdleTimeout();
|
|
||||||
protected:
|
|
||||||
CharArray uri;
|
|
||||||
const char* contentType;
|
|
||||||
int contentLength;
|
|
||||||
time_t lastModified;
|
|
||||||
LineReader line;
|
|
||||||
network::Socket& sock;
|
|
||||||
rfb::HTTPServer& server;
|
|
||||||
enum {ReadRequestLine, ReadHeaders, WriteResponse} state;
|
|
||||||
enum {GetRequest, HeadRequest} request;
|
|
||||||
time_t lastActive;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// - Internal helper routines
|
|
||||||
|
|
||||||
void
|
|
||||||
copyStream(InStream& is, OutStream& os) {
|
|
||||||
try {
|
|
||||||
while (1) {
|
|
||||||
os.writeU8(is.readU8());
|
|
||||||
}
|
|
||||||
} catch (rdr::EndOfStream&) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeLine(OutStream& os, const char* text) {
|
|
||||||
os.writeBytes(text, strlen(text));
|
|
||||||
os.writeBytes("\r\n", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// - Write an HTTP-compliant response to the client
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
HTTPServer::Session::writeResponse(int result, const char* text) {
|
|
||||||
char buffer[1024];
|
|
||||||
if (strlen(text) > 512)
|
|
||||||
throw new rdr::Exception("Internal error - HTTP response text too big");
|
|
||||||
sprintf(buffer, "%s %d %s", "HTTP/1.1", result, text);
|
|
||||||
OutStream& os=sock.outStream();
|
|
||||||
writeLine(os, buffer);
|
|
||||||
writeLine(os, "Server: KasmVNC/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) {
|
|
||||||
if (!contentType)
|
|
||||||
contentType = guessContentType(uri.buf, "text/html");
|
|
||||||
os.writeBytes(contentType, strlen(contentType));
|
|
||||||
} else {
|
|
||||||
os.writeBytes("text/html", 9);
|
|
||||||
}
|
|
||||||
os.writeBytes("\r\n", 2);
|
|
||||||
writeLine(os, "");
|
|
||||||
if (result != 200) {
|
|
||||||
writeLine(os, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">");
|
|
||||||
writeLine(os, "<HTML><HEAD>");
|
|
||||||
sprintf(buffer, "<TITLE>%d %s</TITLE>", result, text);
|
|
||||||
writeLine(os, buffer);
|
|
||||||
writeLine(os, "</HEAD><BODY><H1>");
|
|
||||||
writeLine(os, text);
|
|
||||||
writeLine(os, "</H1></BODY></HTML>");
|
|
||||||
sock.outStream().flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
HTTPServer::Session::writeResponse(int code) {
|
|
||||||
switch (code) {
|
|
||||||
case 200: writeResponse(code, "OK"); break;
|
|
||||||
case 400: writeResponse(code, "Bad Request"); break;
|
|
||||||
case 404: writeResponse(code, "Not Found"); break;
|
|
||||||
case 501: writeResponse(code, "Not Implemented"); break;
|
|
||||||
default: writeResponse(500, "Unknown Error"); break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This return code is passed straight out of processHTTP().
|
|
||||||
// true indicates that the request has been completely processed.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - Main HTTP request processing routine
|
|
||||||
|
|
||||||
bool
|
|
||||||
HTTPServer::Session::processHTTP() {
|
|
||||||
lastActive = time(0);
|
|
||||||
|
|
||||||
while (sock.inStream().checkNoWait(1)) {
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
|
|
||||||
// Reading the Request-Line
|
|
||||||
case ReadRequestLine:
|
|
||||||
|
|
||||||
// Either read a line, or run out of incoming data
|
|
||||||
if (!line.read())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// We have read a line! Skip it if it's blank
|
|
||||||
if (strlen(line.buf) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// The line contains a request to process.
|
|
||||||
{
|
|
||||||
char method[16], path[128], version[16];
|
|
||||||
int matched = sscanf(line.buf, "%15s%127s%15s",
|
|
||||||
method, path, version);
|
|
||||||
if (matched != 3)
|
|
||||||
return writeResponse(400);
|
|
||||||
|
|
||||||
// Store the required "method"
|
|
||||||
if (strcmp(method, "GET") == 0)
|
|
||||||
request = GetRequest;
|
|
||||||
else if (strcmp(method, "HEAD") == 0)
|
|
||||||
request = HeadRequest;
|
|
||||||
else
|
|
||||||
return writeResponse(501);
|
|
||||||
|
|
||||||
// Store the URI to the "document"
|
|
||||||
uri.buf = strDup(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move on to reading the request headers
|
|
||||||
state = ReadHeaders;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Reading the request headers
|
|
||||||
case ReadHeaders:
|
|
||||||
|
|
||||||
// Try to read a line
|
|
||||||
if (!line.read())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Skip headers until we hit a blank line
|
|
||||||
if (strlen(line.buf) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Headers ended - write the response!
|
|
||||||
{
|
|
||||||
CharArray address(sock.getPeerAddress());
|
|
||||||
vlog.info("getting %s for %s", uri.buf, address.buf);
|
|
||||||
contentLength = -1;
|
|
||||||
lastModified = -1;
|
|
||||||
InStream* data = server.getFile(uri.buf, &contentType, &contentLength,
|
|
||||||
&lastModified);
|
|
||||||
if (!data)
|
|
||||||
return writeResponse(404);
|
|
||||||
|
|
||||||
try {
|
|
||||||
writeResponse(200);
|
|
||||||
if (request == GetRequest)
|
|
||||||
copyStream(*data, sock.outStream());
|
|
||||||
sock.outStream().flush();
|
|
||||||
} catch (rdr::Exception& e) {
|
|
||||||
vlog.error("error writing HTTP document:%s", e.str());
|
|
||||||
}
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The operation is complete!
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw rdr::Exception("invalid HTTPSession state!");
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicate that we're still processing the HTTP request.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int HTTPServer::Session::checkIdleTimeout() {
|
|
||||||
time_t now = time(0);
|
|
||||||
int timeout = (lastActive + idleTimeoutSecs) - now;
|
|
||||||
if (timeout > 0)
|
|
||||||
return secsToMillis(timeout);
|
|
||||||
sock.shutdown();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -=- Constructor / destructor
|
|
||||||
|
|
||||||
HTTPServer::HTTPServer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
HTTPServer::~HTTPServer() {
|
|
||||||
std::list<Session*>::iterator i;
|
|
||||||
for (i=sessions.begin(); i!=sessions.end(); i++)
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- SocketServer interface implementation
|
|
||||||
|
|
||||||
void
|
|
||||||
HTTPServer::addSocket(network::Socket* sock, bool) {
|
|
||||||
Session* s = new Session(*sock, *this);
|
|
||||||
if (!s) {
|
|
||||||
sock->shutdown();
|
|
||||||
} else {
|
|
||||||
sock->inStream().setTimeout(clientWaitTimeMillis);
|
|
||||||
sock->outStream().setTimeout(clientWaitTimeMillis);
|
|
||||||
sessions.push_front(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::processSocketReadEvent(network::Socket* sock) {
|
|
||||||
std::list<Session*>::iterator i;
|
|
||||||
for (i=sessions.begin(); i!=sessions.end(); i++) {
|
|
||||||
if ((*i)->getSock() == sock) {
|
|
||||||
try {
|
|
||||||
if ((*i)->processHTTP()) {
|
|
||||||
vlog.info("completed HTTP request");
|
|
||||||
sock->shutdown();
|
|
||||||
}
|
|
||||||
} catch (rdr::Exception& e) {
|
|
||||||
vlog.error("untrapped: %s", e.str());
|
|
||||||
sock->shutdown();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw rdr::Exception("invalid Socket in HTTPServer");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
HTTPServer::processSocketWriteEvent(network::Socket* sock) {
|
|
||||||
std::list<Session*>::iterator i;
|
|
||||||
for (i=sessions.begin(); i!=sessions.end(); i++) {
|
|
||||||
if ((*i)->getSock() == sock) {
|
|
||||||
try {
|
|
||||||
sock->outStream().flush();
|
|
||||||
} catch (rdr::Exception& e) {
|
|
||||||
vlog.error("untrapped: %s", e.str());
|
|
||||||
sock->shutdown();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw rdr::Exception("invalid Socket in HTTPServer");
|
|
||||||
}
|
|
||||||
|
|
||||||
void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
|
|
||||||
{
|
|
||||||
sockets->clear();
|
|
||||||
std::list<Session*>::iterator ci;
|
|
||||||
for (ci = sessions.begin(); ci != sessions.end(); ci++) {
|
|
||||||
sockets->push_back((*ci)->getSock());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int HTTPServer::checkTimeouts() {
|
|
||||||
std::list<Session*>::iterator ci;
|
|
||||||
int timeout = 0;
|
|
||||||
for (ci = sessions.begin(); ci != sessions.end(); ci++) {
|
|
||||||
soonestTimeout(&timeout, (*ci)->checkIdleTimeout());
|
|
||||||
}
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -=- Default getFile implementation
|
|
||||||
|
|
||||||
InStream*
|
|
||||||
HTTPServer::getFile(const char* name, const char** contentType,
|
|
||||||
int* contentLength, time_t* lastModified)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
HTTPServer::guessContentType(const char* name, const char* defType) {
|
|
||||||
CharArray file, ext;
|
|
||||||
if (!strSplit(name, '.', &file.buf, &ext.buf))
|
|
||||||
return defType;
|
|
||||||
if (strcasecmp(ext.buf, "html") == 0 ||
|
|
||||||
strcasecmp(ext.buf, "htm") == 0) {
|
|
||||||
return "text/html";
|
|
||||||
} else if (strcasecmp(ext.buf, "txt") == 0) {
|
|
||||||
return "text/plain";
|
|
||||||
} else if (strcasecmp(ext.buf, "gif") == 0) {
|
|
||||||
return "image/gif";
|
|
||||||
} else if (strcasecmp(ext.buf, "jpg") == 0) {
|
|
||||||
return "image/jpeg";
|
|
||||||
} else if (strcasecmp(ext.buf, "jar") == 0) {
|
|
||||||
return "application/java-archive";
|
|
||||||
} else if (strcasecmp(ext.buf, "exe") == 0) {
|
|
||||||
return "application/octet-stream";
|
|
||||||
}
|
|
||||||
return defType;
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
/* 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
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -=- HTTPServer.h
|
|
||||||
|
|
||||||
// Single-threaded HTTP server implementation.
|
|
||||||
// All I/O is handled by the processSocketEvent routine,
|
|
||||||
// which is called by the main-loop of the VNC server whenever
|
|
||||||
// there is an event on an HTTP socket.
|
|
||||||
|
|
||||||
#ifndef __RFB_HTTP_SERVER_H__
|
|
||||||
#define __RFB_HTTP_SERVER_H__
|
|
||||||
|
|
||||||
#include <rdr/MemInStream.h>
|
|
||||||
#include <rfb/UpdateTracker.h>
|
|
||||||
#include <rfb/Configuration.h>
|
|
||||||
#include <network/Socket.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
class HTTPServer : public network::SocketServer {
|
|
||||||
public:
|
|
||||||
// -=- Constructors
|
|
||||||
|
|
||||||
// - HTTPServer(files)
|
|
||||||
// Create an HTTP server which will use the getFile method
|
|
||||||
// to satisfy HTTP GET requests.
|
|
||||||
HTTPServer();
|
|
||||||
|
|
||||||
virtual ~HTTPServer();
|
|
||||||
|
|
||||||
// SocketServer interface
|
|
||||||
|
|
||||||
// addSocket()
|
|
||||||
// This causes the server to perform HTTP protocol on the
|
|
||||||
// supplied socket.
|
|
||||||
virtual void addSocket(network::Socket* sock, bool outgoing=false);
|
|
||||||
|
|
||||||
// removeSocket()
|
|
||||||
// Could clean up socket-specific resources here.
|
|
||||||
virtual void removeSocket(network::Socket* sock);
|
|
||||||
|
|
||||||
// getSockets() gets a list of sockets. This can be used to generate an
|
|
||||||
// fd_set for calling select().
|
|
||||||
virtual void getSockets(std::list<network::Socket*>* sockets);
|
|
||||||
|
|
||||||
// processSocketReadEvent()
|
|
||||||
// The platform-specific side of the server implementation calls
|
|
||||||
// this method whenever data arrives on one of the active
|
|
||||||
// network sockets.
|
|
||||||
virtual void processSocketReadEvent(network::Socket* sock);
|
|
||||||
|
|
||||||
// processSocketWriteEvent()
|
|
||||||
// Similar to processSocketReadEvent(), but called when it is
|
|
||||||
// possible to write more data to a socket.
|
|
||||||
virtual void processSocketWriteEvent(network::Socket* sock);
|
|
||||||
|
|
||||||
// Check for socket timeouts
|
|
||||||
virtual int checkTimeouts();
|
|
||||||
|
|
||||||
|
|
||||||
// -=- File interface
|
|
||||||
|
|
||||||
// - getFile is passed the path portion of a URL and returns an
|
|
||||||
// InStream containing the data to return. If the requested
|
|
||||||
// file is available then the contentType should be set to the
|
|
||||||
// type of the file, or left untouched if the file type is to
|
|
||||||
// be determined automatically by HTTPServer.
|
|
||||||
// If the file is not available then null is returned.
|
|
||||||
// Overridden getFile functions should call the default version
|
|
||||||
// if they do not recognise a path name.
|
|
||||||
// NB: The caller assumes ownership of the returned InStream.
|
|
||||||
// NB: The contentType is statically allocated by the getFile impl.
|
|
||||||
// NB: contentType is *guaranteed* to be valid when getFile is called.
|
|
||||||
|
|
||||||
virtual rdr::InStream* getFile(const char* name, const char** contentType,
|
|
||||||
int* contentLength, time_t* lastModified);
|
|
||||||
|
|
||||||
// - guessContentType is passed the name of a file and returns the
|
|
||||||
// name of an HTTP content type, based on the file's extension. If
|
|
||||||
// the extension isn't recognised then defType is returned. This can
|
|
||||||
// be used from getFile to easily default to the supplied contentType,
|
|
||||||
// or by passing zero in to determine whether a type is recognised or
|
|
||||||
// not.
|
|
||||||
|
|
||||||
static const char* guessContentType(const char* name, const char* defType);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Session;
|
|
||||||
std::list<Session*> sessions;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -33,8 +33,6 @@ if($slashndx>=0) {
|
|||||||
$exedir = substr($0, 0, $slashndx+1);
|
$exedir = substr($0, 0, $slashndx+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$vncClasses = "";
|
|
||||||
|
|
||||||
&SanityCheck();
|
&SanityCheck();
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -44,9 +42,6 @@ $vncClasses = "";
|
|||||||
|
|
||||||
$geometry = "1024x768";
|
$geometry = "1024x768";
|
||||||
#$depth = 16;
|
#$depth = 16;
|
||||||
$vncJavaFiles = (((-d "$vncClasses") && "$vncClasses") ||
|
|
||||||
((-d "/usr/share/vnc/classes") && "/usr/share/vnc/classes") ||
|
|
||||||
((-d "/usr/local/vnc/classes") && "/usr/local/vnc/classes"));
|
|
||||||
|
|
||||||
$vncUserDir = "$ENV{HOME}/.vnc";
|
$vncUserDir = "$ENV{HOME}/.vnc";
|
||||||
$vncUserConfig = "$vncUserDir/config";
|
$vncUserConfig = "$vncUserDir/config";
|
||||||
@ -206,7 +201,6 @@ my %config;
|
|||||||
# We set some reasonable defaults. Config file settings
|
# We set some reasonable defaults. Config file settings
|
||||||
# override these where present.
|
# override these where present.
|
||||||
$default_opts{desktop} = "edString($desktopName);
|
$default_opts{desktop} = "edString($desktopName);
|
||||||
$default_opts{httpd} = $vncJavaFiles if ($vncJavaFiles);
|
|
||||||
$default_opts{auth} = "edString($xauthorityFile);
|
$default_opts{auth} = "edString($xauthorityFile);
|
||||||
$default_opts{geometry} = $geometry if ($geometry);
|
$default_opts{geometry} = $geometry if ($geometry);
|
||||||
$default_opts{depth} = $depth if ($depth);
|
$default_opts{depth} = $depth if ($depth);
|
||||||
@ -848,7 +842,6 @@ sub SanityCheck
|
|||||||
foreach $cmd ("Xvnc","vncpasswd") {
|
foreach $cmd ("Xvnc","vncpasswd") {
|
||||||
for (split(/:/,$ENV{PATH})) {
|
for (split(/:/,$ENV{PATH})) {
|
||||||
if (-x "$_/$cmd") {
|
if (-x "$_/$cmd") {
|
||||||
$vncClasses = "$_/../vnc/classes";
|
|
||||||
next cmd2;
|
next cmd2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -860,7 +853,6 @@ sub SanityCheck
|
|||||||
foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
|
foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
|
||||||
for (split(/:/,$ENV{PATH})) {
|
for (split(/:/,$ENV{PATH})) {
|
||||||
if (-x "$cmd") {
|
if (-x "$cmd") {
|
||||||
$vncClasses = $exedir."../vnc/classes";
|
|
||||||
next cmd3;
|
next cmd3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include <network/Socket.h>
|
#include <network/Socket.h>
|
||||||
#include <rfb/Exception.h>
|
#include <rfb/Exception.h>
|
||||||
#include <rfb/VNCServerST.h>
|
#include <rfb/VNCServerST.h>
|
||||||
#include <rfb/HTTPServer.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
#include <rfb/LogWriter.h>
|
||||||
#include <rfb/Configuration.h>
|
#include <rfb/Configuration.h>
|
||||||
#include <rfb/ServerCore.h>
|
#include <rfb/ServerCore.h>
|
||||||
@ -67,54 +66,13 @@ IntParameter queryConnectTimeout("QueryConnectTimeout",
|
|||||||
"rejecting the connection",
|
"rejecting the connection",
|
||||||
10);
|
10);
|
||||||
|
|
||||||
class FileHTTPServer : public rfb::HTTPServer {
|
|
||||||
public:
|
|
||||||
FileHTTPServer(XserverDesktop* d) : desktop(d) {}
|
|
||||||
virtual ~FileHTTPServer() {}
|
|
||||||
|
|
||||||
virtual rdr::InStream* getFile(const char* name, const char** contentType,
|
|
||||||
int* contentLength, time_t* lastModified)
|
|
||||||
{
|
|
||||||
if (name[0] != '/' || strstr(name, "..") != 0) {
|
|
||||||
vlog.info("http request was for invalid file name");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(name, "/") == 0) name = "/index.vnc";
|
|
||||||
|
|
||||||
CharArray httpDirStr(httpDir.getData());
|
|
||||||
CharArray fname(strlen(httpDirStr.buf)+strlen(name)+1);
|
|
||||||
sprintf(fname.buf, "%s%s", httpDirStr.buf, name);
|
|
||||||
int fd = open(fname.buf, O_RDONLY);
|
|
||||||
if (fd < 0) return 0;
|
|
||||||
rdr::InStream* is = new rdr::FdInStream(fd, -1, 0, true);
|
|
||||||
*contentType = guessContentType(name, *contentType);
|
|
||||||
if (strlen(name) > 4 && strcasecmp(&name[strlen(name)-4], ".vnc") == 0) {
|
|
||||||
is = new rdr::SubstitutingInStream(is, desktop, 20);
|
|
||||||
*contentType = "text/html";
|
|
||||||
} else {
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fd, &st) == 0) {
|
|
||||||
*contentLength = st.st_size;
|
|
||||||
*lastModified = st.st_mtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
XserverDesktop* desktop;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
XserverDesktop::XserverDesktop(int screenIndex_,
|
XserverDesktop::XserverDesktop(int screenIndex_,
|
||||||
std::list<network::SocketListener*> listeners_,
|
std::list<network::SocketListener*> listeners_,
|
||||||
std::list<network::SocketListener*> httpListeners_,
|
|
||||||
const char* name, const rfb::PixelFormat &pf,
|
const char* name, const rfb::PixelFormat &pf,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
void* fbptr, int stride)
|
void* fbptr, int stride)
|
||||||
: screenIndex(screenIndex_),
|
: screenIndex(screenIndex_),
|
||||||
server(0), httpServer(0),
|
server(0), listeners(listeners_),
|
||||||
listeners(listeners_), httpListeners(httpListeners_),
|
|
||||||
directFbptr(true),
|
directFbptr(true),
|
||||||
queryConnectId(0), queryConnectTimer(this)
|
queryConnectId(0), queryConnectTimer(this)
|
||||||
{
|
{
|
||||||
@ -124,20 +82,11 @@ XserverDesktop::XserverDesktop(int screenIndex_,
|
|||||||
setFramebuffer(width, height, fbptr, stride);
|
setFramebuffer(width, height, fbptr, stride);
|
||||||
server->setQueryConnectionHandler(this);
|
server->setQueryConnectionHandler(this);
|
||||||
|
|
||||||
if (!httpListeners.empty ())
|
|
||||||
httpServer = new FileHTTPServer(this);
|
|
||||||
|
|
||||||
for (std::list<SocketListener*>::iterator i = listeners.begin();
|
for (std::list<SocketListener*>::iterator i = listeners.begin();
|
||||||
i != listeners.end();
|
i != listeners.end();
|
||||||
i++) {
|
i++) {
|
||||||
vncSetNotifyFd((*i)->getFd(), screenIndex, true, false);
|
vncSetNotifyFd((*i)->getFd(), screenIndex, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<SocketListener*>::iterator i = httpListeners.begin();
|
|
||||||
i != httpListeners.end();
|
|
||||||
i++) {
|
|
||||||
vncSetNotifyFd((*i)->getFd(), screenIndex, true, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XserverDesktop::~XserverDesktop()
|
XserverDesktop::~XserverDesktop()
|
||||||
@ -147,14 +96,8 @@ XserverDesktop::~XserverDesktop()
|
|||||||
delete listeners.back();
|
delete listeners.back();
|
||||||
listeners.pop_back();
|
listeners.pop_back();
|
||||||
}
|
}
|
||||||
while (!httpListeners.empty()) {
|
|
||||||
vncRemoveNotifyFd(listeners.back()->getFd());
|
|
||||||
delete httpListeners.back();
|
|
||||||
httpListeners.pop_back();
|
|
||||||
}
|
|
||||||
if (!directFbptr)
|
if (!directFbptr)
|
||||||
delete [] data;
|
delete [] data;
|
||||||
delete httpServer;
|
|
||||||
delete server;
|
delete server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,56 +144,6 @@ void XserverDesktop::refreshScreenLayout()
|
|||||||
server->setScreenLayout(::computeScreenLayout(&outputIdMap));
|
server->setScreenLayout(::computeScreenLayout(&outputIdMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
char* XserverDesktop::substitute(const char* varName)
|
|
||||||
{
|
|
||||||
if (strcmp(varName, "$$") == 0) {
|
|
||||||
return rfb::strDup("$");
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$PORT") == 0) {
|
|
||||||
char* str = new char[10];
|
|
||||||
sprintf(str, "%d", listeners.empty () ? 0 : (*listeners.begin ())->getMyPort());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$WIDTH") == 0) {
|
|
||||||
char* str = new char[10];
|
|
||||||
sprintf(str, "%d", width());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$HEIGHT") == 0) {
|
|
||||||
char* str = new char[10];
|
|
||||||
sprintf(str, "%d", height());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$APPLETWIDTH") == 0) {
|
|
||||||
char* str = new char[10];
|
|
||||||
sprintf(str, "%d", width());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$APPLETHEIGHT") == 0) {
|
|
||||||
char* str = new char[10];
|
|
||||||
sprintf(str, "%d", height());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$DESKTOP") == 0) {
|
|
||||||
return rfb::strDup(server->getName());
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$DISPLAY") == 0) {
|
|
||||||
struct utsname uts;
|
|
||||||
uname(&uts);
|
|
||||||
char* str = new char[256];
|
|
||||||
strncpy(str, uts.nodename, 240);
|
|
||||||
str[239] = '\0'; /* Ensure string is zero-terminated */
|
|
||||||
strcat(str, ":");
|
|
||||||
strncat(str, vncGetDisplay(), 10);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (strcmp(varName, "$USER") == 0) {
|
|
||||||
struct passwd* user = getpwuid(getuid());
|
|
||||||
return rfb::strDup(user ? user->pw_name : "?");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rfb::VNCServerST::queryResult
|
rfb::VNCServerST::queryResult
|
||||||
XserverDesktop::queryConnection(network::Socket* sock,
|
XserverDesktop::queryConnection(network::Socket* sock,
|
||||||
const char* userName,
|
const char* userName,
|
||||||
@ -370,14 +263,10 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
|
|||||||
if (read) {
|
if (read) {
|
||||||
if (handleListenerEvent(fd, &listeners, server))
|
if (handleListenerEvent(fd, &listeners, server))
|
||||||
return;
|
return;
|
||||||
if (handleListenerEvent(fd, &httpListeners, httpServer))
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handleSocketEvent(fd, server, read, write))
|
if (handleSocketEvent(fd, server, read, write))
|
||||||
return;
|
return;
|
||||||
if (handleSocketEvent(fd, httpServer, read, write))
|
|
||||||
return;
|
|
||||||
|
|
||||||
vlog.error("Cannot find file descriptor for socket event");
|
vlog.error("Cannot find file descriptor for socket event");
|
||||||
} catch (rdr::Exception& e) {
|
} catch (rdr::Exception& e) {
|
||||||
@ -458,21 +347,6 @@ void XserverDesktop::blockHandler(int* timeout)
|
|||||||
vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0);
|
vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (httpServer) {
|
|
||||||
httpServer->getSockets(&sockets);
|
|
||||||
for (i = sockets.begin(); i != sockets.end(); i++) {
|
|
||||||
int fd = (*i)->getFd();
|
|
||||||
if ((*i)->isShutdown()) {
|
|
||||||
vlog.debug("http client gone, sock %d",fd);
|
|
||||||
vncRemoveNotifyFd(fd);
|
|
||||||
httpServer->removeSocket(*i);
|
|
||||||
delete (*i);
|
|
||||||
} else {
|
|
||||||
/* Update existing NotifyFD to listen for write (or not) */
|
|
||||||
vncSetNotifyFd(fd, screenIndex, true, (*i)->outStream().bufferUsage() > 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are responsible for propagating mouse movement between clients
|
// We are responsible for propagating mouse movement between clients
|
||||||
int cursorX, cursorY;
|
int cursorX, cursorY;
|
||||||
|
@ -32,11 +32,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <rfb/SDesktop.h>
|
#include <rfb/SDesktop.h>
|
||||||
#include <rfb/HTTPServer.h>
|
|
||||||
#include <rfb/PixelBuffer.h>
|
#include <rfb/PixelBuffer.h>
|
||||||
#include <rfb/Configuration.h>
|
#include <rfb/Configuration.h>
|
||||||
#include <rfb/VNCServerST.h>
|
#include <rfb/VNCServerST.h>
|
||||||
#include <rdr/SubstitutingInStream.h>
|
|
||||||
#include <unixcommon.h>
|
#include <unixcommon.h>
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
|
|
||||||
@ -47,14 +45,12 @@ namespace rfb {
|
|||||||
namespace network { class SocketListener; class Socket; class SocketServer; }
|
namespace network { class SocketListener; class Socket; class SocketServer; }
|
||||||
|
|
||||||
class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
|
class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
|
||||||
public rdr::Substitutor,
|
|
||||||
public rfb::VNCServerST::QueryConnectionHandler,
|
public rfb::VNCServerST::QueryConnectionHandler,
|
||||||
public rfb::Timer::Callback {
|
public rfb::Timer::Callback {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XserverDesktop(int screenIndex,
|
XserverDesktop(int screenIndex,
|
||||||
std::list<network::SocketListener*> listeners_,
|
std::list<network::SocketListener*> listeners_,
|
||||||
std::list<network::SocketListener*> httpListeners_,
|
|
||||||
const char* name, const rfb::PixelFormat &pf,
|
const char* name, const rfb::PixelFormat &pf,
|
||||||
int width, int height, void* fbptr, int stride);
|
int width, int height, void* fbptr, int stride);
|
||||||
virtual ~XserverDesktop();
|
virtual ~XserverDesktop();
|
||||||
@ -99,9 +95,6 @@ public:
|
|||||||
// rfb::PixelBuffer callbacks
|
// rfb::PixelBuffer callbacks
|
||||||
virtual void grabRegion(const rfb::Region& r);
|
virtual void grabRegion(const rfb::Region& r);
|
||||||
|
|
||||||
// rdr::Substitutor callback
|
|
||||||
virtual char* substitute(const char* varName);
|
|
||||||
|
|
||||||
// rfb::VNCServerST::QueryConnectionHandler callback
|
// rfb::VNCServerST::QueryConnectionHandler callback
|
||||||
virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
|
virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
|
||||||
const char* userName,
|
const char* userName,
|
||||||
@ -121,9 +114,7 @@ private:
|
|||||||
|
|
||||||
int screenIndex;
|
int screenIndex;
|
||||||
rfb::VNCServerST* server;
|
rfb::VNCServerST* server;
|
||||||
rfb::HTTPServer* httpServer;
|
|
||||||
std::list<network::SocketListener*> listeners;
|
std::list<network::SocketListener*> listeners;
|
||||||
std::list<network::SocketListener*> httpListeners;
|
|
||||||
bool directFbptr;
|
bool directFbptr;
|
||||||
|
|
||||||
uint32_t queryConnectId;
|
uint32_t queryConnectId;
|
||||||
|
@ -193,7 +193,6 @@ void vncExtensionInit(void)
|
|||||||
|
|
||||||
if (!desktop[scr]) {
|
if (!desktop[scr]) {
|
||||||
std::list<network::SocketListener*> listeners;
|
std::list<network::SocketListener*> listeners;
|
||||||
std::list<network::SocketListener*> httpListeners;
|
|
||||||
if (scr == 0 && vncInetdSock != -1) {
|
if (scr == 0 && vncInetdSock != -1) {
|
||||||
if (network::isSocketListening(vncInetdSock))
|
if (network::isSocketListening(vncInetdSock))
|
||||||
{
|
{
|
||||||
@ -247,7 +246,6 @@ void vncExtensionInit(void)
|
|||||||
vncSetGlueContext(scr);
|
vncSetGlueContext(scr);
|
||||||
desktop[scr] = new XserverDesktop(scr,
|
desktop[scr] = new XserverDesktop(scr,
|
||||||
listeners,
|
listeners,
|
||||||
httpListeners,
|
|
||||||
desktopNameStr.buf,
|
desktopNameStr.buf,
|
||||||
pf,
|
pf,
|
||||||
vncGetScreenWidth(),
|
vncGetScreenWidth(),
|
||||||
|
@ -314,21 +314,6 @@ void SDisplay::clientCutText(const char* text, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Point SDisplay::getFbSize() {
|
|
||||||
bool startAndStop = !core;
|
|
||||||
|
|
||||||
// If not started, do minimal initialisation to get desktop size.
|
|
||||||
if (startAndStop)
|
|
||||||
recreatePixelBuffer();
|
|
||||||
Point result = Point(pb->width(), pb->height());
|
|
||||||
|
|
||||||
// Destroy the initialised structures.
|
|
||||||
if (startAndStop)
|
|
||||||
stopCore();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SDisplay::notifyClipboardChanged(const char* text, int len) {
|
SDisplay::notifyClipboardChanged(const char* text, int len) {
|
||||||
vlog.debug("clipboard text changed");
|
vlog.debug("clipboard text changed");
|
||||||
|
@ -86,12 +86,6 @@ namespace rfb {
|
|||||||
|
|
||||||
void setStatusLocation(bool* status) {statusLocation = status;}
|
void setStatusLocation(bool* status) {statusLocation = status;}
|
||||||
|
|
||||||
// -=- Used (indirectly) by JavaViewer to get desktop size
|
|
||||||
|
|
||||||
Point getFbSize();
|
|
||||||
|
|
||||||
friend class SDisplayCore;
|
|
||||||
|
|
||||||
static IntParameter updateMethod;
|
static IntParameter updateMethod;
|
||||||
static BoolParameter disableLocalInputs;
|
static BoolParameter disableLocalInputs;
|
||||||
static StringParameter disconnectAction;
|
static StringParameter disconnectAction;
|
||||||
|
Loading…
Reference in New Issue
Block a user