From 618aa7fedd874a3ed4fc894d6051f7d3ebca9b1d Mon Sep 17 00:00:00 2001 From: crs Date: Sun, 1 Feb 2004 20:56:52 +0000 Subject: [PATCH] Removed most HTTP stuff. It doesn't seem like the appropriate choice for server control. May later provide some other means for controlling the synergy server remotely. --- cmd/launcher/launcher.dsp | 4 +- cmd/synergys/Makefile.am | 2 - cmd/synergys/synergys.dsp | 4 +- configure.in | 1 - lib/Makefile.am | 1 - lib/http/CHTTPProtocol.cpp | 658 ------------------------------------- lib/http/CHTTPProtocol.h | 201 ----------- lib/http/Makefile.am | 39 --- lib/http/XHTTP.cpp | 135 -------- lib/http/XHTTP.h | 82 ----- lib/http/http.dsp | 110 ------- lib/server/server.dsp | 4 +- synergy.dsw | 18 - 13 files changed, 6 insertions(+), 1253 deletions(-) delete mode 100644 lib/http/CHTTPProtocol.cpp delete mode 100644 lib/http/CHTTPProtocol.h delete mode 100644 lib/http/Makefile.am delete mode 100644 lib/http/XHTTP.cpp delete mode 100644 lib/http/XHTTP.h delete mode 100644 lib/http/http.dsp diff --git a/cmd/launcher/launcher.dsp b/cmd/launcher/launcher.dsp index 730a701c..afb8ed89 100644 --- a/cmd/launcher/launcher.dsp +++ b/cmd/launcher/launcher.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c +# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 diff --git a/cmd/synergys/Makefile.am b/cmd/synergys/Makefile.am index b3384ce6..f2c30e76 100644 --- a/cmd/synergys/Makefile.am +++ b/cmd/synergys/Makefile.am @@ -45,7 +45,6 @@ synergys_LDADD = \ $(DEPTH)/lib/platform/libplatform.a \ $(DEPTH)/lib/synergy/libsynergy.a \ $(DEPTH)/lib/net/libnet.a \ - $(DEPTH)/lib/http/libhttp.a \ $(DEPTH)/lib/io/libio.a \ $(DEPTH)/lib/mt/libmt.a \ $(DEPTH)/lib/base/libbase.a \ @@ -63,7 +62,6 @@ INCLUDES = \ -I$(VDEPTH)/lib/base \ -I$(VDEPTH)/lib/mt \ -I$(VDEPTH)/lib/io \ - -I$(VDEPTH)/lib/http \ -I$(VDEPTH)/lib/net \ -I$(VDEPTH)/lib/synergy \ -I$(VDEPTH)/lib/platform \ diff --git a/cmd/synergys/synergys.dsp b/cmd/synergys/synergys.dsp index cbc3e626..989ba8c5 100644 --- a/cmd/synergys/synergys.dsp +++ b/cmd/synergys/synergys.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c +# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 diff --git a/configure.in b/configure.in index cb0e2a6c..999fb1b7 100644 --- a/configure.in +++ b/configure.in @@ -107,7 +107,6 @@ lib/base/Makefile lib/common/Makefile lib/mt/Makefile lib/io/Makefile -lib/http/Makefile lib/net/Makefile lib/synergy/Makefile lib/platform/Makefile diff --git a/lib/Makefile.am b/lib/Makefile.am index cababc3e..b0701a61 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -21,7 +21,6 @@ SUBDIRS = \ base \ mt \ io \ - http \ net \ synergy \ platform \ diff --git a/lib/http/CHTTPProtocol.cpp b/lib/http/CHTTPProtocol.cpp deleted file mode 100644 index ae385d6d..00000000 --- a/lib/http/CHTTPProtocol.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package 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. - */ - -#include "CHTTPProtocol.h" -#include "XHTTP.h" -#include "IInputStream.h" -#include "IOutputStream.h" -#include "CLog.h" -#include "stdsstream.h" -#include -#include -#include - -// -// CHTTPRequest -// - -CHTTPRequest::CHTTPRequest() -{ - // do nothing -} - -CHTTPRequest::~CHTTPRequest() -{ - // do nothing -} - -void -CHTTPRequest::insertHeader(const CString& name, const CString& value) -{ - CHeaderMap::iterator index = m_headerByName.find(name); - if (index != m_headerByName.end()) { - index->second->second = value; - } - else { - CHeaderList::iterator pos = m_headers.insert( - m_headers.end(), std::make_pair(name, value)); - m_headerByName.insert(std::make_pair(name, pos)); - } -} - -void -CHTTPRequest::appendHeader(const CString& name, const CString& value) -{ - CHeaderMap::iterator index = m_headerByName.find(name); - if (index != m_headerByName.end()) { - index->second->second += ","; - index->second->second += value; - } - else { - CHeaderList::iterator pos = m_headers.insert( - m_headers.end(), std::make_pair(name, value)); - m_headerByName.insert(std::make_pair(name, pos)); - } -} - -void -CHTTPRequest::eraseHeader(const CString& name) -{ - CHeaderMap::iterator index = m_headerByName.find(name); - if (index != m_headerByName.end()) { - m_headers.erase(index->second); - } -} - -bool -CHTTPRequest::isHeader(const CString& name) const -{ - return (m_headerByName.find(name) != m_headerByName.end()); -} - -CString -CHTTPRequest::getHeader(const CString& name) const -{ - CHeaderMap::const_iterator index = m_headerByName.find(name); - if (index != m_headerByName.end()) { - return index->second->second; - } - else { - return CString(); - } -} - - -// -// CHTTPProtocol -// - -CHTTPRequest* -CHTTPProtocol::readRequest(IInputStream* stream, UInt32 maxSize) -{ - CString scratch; - - // note if we should limit the request size - const bool checkSize = (maxSize > 0); - - // parse request line by line - CHTTPRequest* request = new CHTTPRequest; - try { - CString line; - - // read request line. accept and discard leading empty lines. - do { - line = readLine(stream, scratch); - if (checkSize) { - if (line.size() + 2 > maxSize) { - throw XHTTP(413); - } - maxSize -= line.size() + 2; - } - } while (line.empty()); - - // parse request line: - { - std::istringstream s(line); - s.exceptions(std::ios::goodbit); - CString version; - s >> request->m_method >> request->m_uri >> version; - if (!s || request->m_uri.empty() || version.find("HTTP/") != 0) { - LOG((CLOG_DEBUG1 "failed to parse HTTP request line: %s", line.c_str())); - throw XHTTP(400); - } - - // parse version - char dot; - s.str(version); - s.clear(); - s.ignore(5); - s >> request->m_majorVersion; - s.get(dot); - s >> request->m_minorVersion; - if (!s || dot != '.') { - LOG((CLOG_DEBUG1 "failed to parse HTTP request line: %s", line.c_str())); - throw XHTTP(400); - } - } - if (!isValidToken(request->m_method)) { - LOG((CLOG_DEBUG1 "invalid HTTP method: %s", line.c_str())); - throw XHTTP(400); - } - if (request->m_majorVersion < 1 || request->m_minorVersion < 0) { - LOG((CLOG_DEBUG1 "invalid HTTP version: %s", line.c_str())); - throw XHTTP(400); - } - - // parse headers - readHeaders(stream, request, false, scratch, - checkSize ? &maxSize : NULL); - - // HTTP/1.1 requests must have a Host header - if (request->m_majorVersion > 1 || - (request->m_majorVersion == 1 && request->m_minorVersion >= 1)) { - if (request->isHeader("Host") == 0) { - LOG((CLOG_DEBUG1 "Host header missing")); - throw XHTTP(400); - } - } - - // some methods may not have a body. ensure that the headers - // that indicate the body length do not exist for those methods - // and do exist for others. - if ((request->isHeader("Transfer-Encoding") || - request->isHeader("Content-Length")) == - (request->m_method == "GET" || - request->m_method == "HEAD")) { - LOG((CLOG_DEBUG1 "HTTP method (%s)/body mismatch", request->m_method.c_str())); - throw XHTTP(400); - } - - // prepare to read the body. the length of the body is - // determined using, in order: - // 1. Transfer-Encoding indicates a "chunked" transfer - // 2. Content-Length is present - // Content-Length is ignored for "chunked" transfers. - CString header; - if (!(header = request->getHeader("Transfer-Encoding")).empty()) { - // we only understand "chunked" encodings - if (!CStringUtil::CaselessCmp::equal(header, "chunked")) { - LOG((CLOG_DEBUG1 "unsupported Transfer-Encoding %s", header.c_str())); - throw XHTTP(501); - } - - // chunked encoding - UInt32 oldSize; - do { - oldSize = request->m_body.size(); - request->m_body += readChunk(stream, scratch, - checkSize ? &maxSize : NULL); - } while (request->m_body.size() != oldSize); - - // read footer - readHeaders(stream, request, true, scratch, - checkSize ? &maxSize : NULL); - - // remove "chunked" from Transfer-Encoding and set the - // Content-Length. - std::ostringstream s; - s << std::dec << request->m_body.size(); - request->eraseHeader("Transfer-Encoding"); - request->insertHeader("Content-Length", s.str()); - } - else if (!(header = request->getHeader("Content-Length")).empty()) { - // parse content-length - UInt32 length; - { - std::istringstream s(header); - s.exceptions(std::ios::goodbit); - s >> length; - if (!s) { - LOG((CLOG_DEBUG1 "cannot parse Content-Length", header.c_str())); - throw XHTTP(400); - } - } - - // check against expected size - if (checkSize && length > maxSize) { - throw XHTTP(413); - } - - // use content length - request->m_body = readBlock(stream, length, scratch); - if (request->m_body.size() != length) { - // length must match size of body - LOG((CLOG_DEBUG1 "Content-Length/actual length mismatch (%d vs %d)", length, request->m_body.size())); - throw XHTTP(400); - } - } - } - catch (...) { - delete request; - throw; - } - - return request; -} - -void -CHTTPProtocol::reply(IOutputStream* stream, CHTTPReply& reply) -{ - // suppress body for certain replies - bool hasBody = true; - if ((reply.m_status / 100) == 1 || - reply.m_status == 204 || - reply.m_status == 304) { - hasBody = false; - } - - // adjust headers - for (CHTTPReply::CHeaderList::iterator - index = reply.m_headers.begin(); - index != reply.m_headers.end(); ) { - const CString& header = index->first; - - // remove certain headers - if (CStringUtil::CaselessCmp::equal(header, "Content-Length") || - CStringUtil::CaselessCmp::equal(header, "Date") || - CStringUtil::CaselessCmp::equal(header, "Transfer-Encoding")) { - // FIXME -- Transfer-Encoding should be left as-is if - // not "chunked" and if the version is 1.1 or up. - index = reply.m_headers.erase(index); - } - - // keep as-is - else { - ++index; - } - } - - // write reply header - std::ostringstream s; - s << "HTTP/" << reply.m_majorVersion << "." << - reply.m_minorVersion << " " << - reply.m_status << " " << - reply.m_reason << "\r\n"; - - // get date - // FIXME -- should use C++ locale stuff but VC++ time_put is broken. - // FIXME -- double check that VC++ is broken - char date[30]; - { - const char* oldLocale = setlocale(LC_TIME, "C"); - time_t t = time(NULL); -#if HAVE_GMTIME_R - struct tm tm; - struct tm* tmp = &tm; - gmtime_r(&t, tmp); -#else - struct tm* tmp = gmtime(&t); -#endif - strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S GMT", tmp); - setlocale(LC_TIME, oldLocale); - } - - // write headers - s << "Date: " << date << "\r\n"; - for (CHTTPReply::CHeaderList::const_iterator - index = reply.m_headers.begin(); - index != reply.m_headers.end(); ++index) { - s << index->first << ": " << index->second << "\r\n"; - } - if (hasBody) { - s << "Content-Length: " << reply.m_body.size() << "\r\n"; - } - s << "Connection: close\r\n"; - - // write end of headers - s << "\r\n"; - - // write to stream - stream->write(s.str().data(), s.str().size()); - - // write body. replies to HEAD method never have a body (though - // they do have the Content-Length header). - if (hasBody && reply.m_method != "HEAD") { - stream->write(reply.m_body.data(), reply.m_body.size()); - } -} - -bool -CHTTPProtocol::parseFormData(const CHTTPRequest& request, CFormParts& parts) -{ - static const char formData[] = "multipart/form-data"; - static const char boundary[] = "boundary="; - static const char disposition[] = "Content-Disposition:"; - static const char nameAttr[] = "name="; - static const char quote[] = "\""; - - // find the Content-Type header - const CString contentType = request.getHeader("Content-Type"); - if (contentType.empty()) { - // missing required Content-Type header - return false; - } - - // parse type - CString::const_iterator index = std::search( - contentType.begin(), contentType.end(), - formData, formData + sizeof(formData) - 1, - CStringUtil::CaselessCmp::cmpEqual); - if (index == contentType.end()) { - // not form-data - return false; - } - index += sizeof(formData) - 1; - index = std::search(index, contentType.end(), - boundary, boundary + sizeof(boundary) - 1, - CStringUtil::CaselessCmp::cmpEqual); - if (index == contentType.end()) { - // no boundary - return false; - } - CString delimiter = contentType.c_str() + - (index - contentType.begin()) + - sizeof(boundary) - 1; - - // find first delimiter - const CString& body = request.m_body; - CString::size_type partIndex = body.find(delimiter); - if (partIndex == CString::npos) { - return false; - } - - // skip over it - partIndex += delimiter.size(); - - // prepend CRLF-- to delimiter - delimiter = "\r\n--" + delimiter; - - // parse parts until there are no more - for (;;) { - // is it the last part? - if (body.size() >= partIndex + 2 && - body[partIndex ] == '-' && - body[partIndex + 1] == '-') { - // found last part. ignore trailing data, if any. - return true; - } - - // find the end of this part - CString::size_type nextPart = body.find(delimiter, partIndex); - if (nextPart == CString::npos) { - // no terminator - return false; - } - - // find end of headers - CString::size_type endOfHeaders = body.find("\r\n\r\n", partIndex); - if (endOfHeaders == CString::npos || endOfHeaders > nextPart) { - // bad part - return false; - } - endOfHeaders += 2; - - // now find Content-Disposition - index = std::search(body.begin() + partIndex, - body.begin() + endOfHeaders, - disposition, - disposition + sizeof(disposition) - 1, - CStringUtil::CaselessCmp::cmpEqual); - if (index == contentType.begin() + endOfHeaders) { - // bad part - return false; - } - - // find the name in the Content-Disposition - CString::size_type endOfHeader = body.find("\r\n", - index - body.begin()); - if (endOfHeader >= endOfHeaders) { - // bad part - return false; - } - index = std::search(index, body.begin() + endOfHeader, - nameAttr, nameAttr + sizeof(nameAttr) - 1, - CStringUtil::CaselessCmp::cmpEqual); - if (index == body.begin() + endOfHeader) { - // no name - return false; - } - - // extract the name - CString name; - index += sizeof(nameAttr) - 1; - if (*index == quote[0]) { - // quoted name - ++index; - CString::size_type namePos = index - body.begin(); - index = std::search(index, body.begin() + endOfHeader, - quote, quote + 1, - CStringUtil::CaselessCmp::cmpEqual); - if (index == body.begin() + endOfHeader) { - // missing close quote - return false; - } - name = body.substr(namePos, index - body.begin() - namePos); - } - else { - // unquoted name - name = body.substr(index - body.begin(), - body.find_first_of(" \t\r\n")); - } - - // save part. add 2 to endOfHeaders to skip CRLF. - parts.insert(std::make_pair(name, body.substr(endOfHeaders + 2, - nextPart - (endOfHeaders + 2)))); - - // move to next part - partIndex = nextPart + delimiter.size(); - } - - // should've found the last delimiter inside the loop but we did not - return false; -} - -CString -CHTTPProtocol::readLine(IInputStream* stream, CString& tmpBuffer) -{ - // read up to and including a CRLF from stream, using whatever - // is in tmpBuffer as if it were at the head of the stream. - - for (;;) { - // scan tmpBuffer for CRLF - CString::size_type newline = tmpBuffer.find("\r\n"); - if (newline != CString::npos) { - // copy line without the CRLF - CString line = tmpBuffer.substr(0, newline); - - // discard line and CRLF from tmpBuffer - tmpBuffer.erase(0, newline + 2); - return line; - } - - // read more from stream - char buffer[4096]; - UInt32 n = stream->read(buffer, sizeof(buffer), -1.0); - if (n == 0) { - // stream is empty. return what's leftover. - CString line = tmpBuffer; - tmpBuffer.erase(); - return line; - } - - // append stream data - tmpBuffer.append(buffer, n); - } -} - -CString -CHTTPProtocol::readBlock(IInputStream* stream, - UInt32 numBytes, CString& tmpBuffer) -{ - CString data; - - // read numBytes from stream, using whatever is in tmpBuffer as - // if it were at the head of the stream. - if (tmpBuffer.size() > 0) { - // ignore stream if there's enough data in tmpBuffer - if (tmpBuffer.size() >= numBytes) { - data = tmpBuffer.substr(0, numBytes); - tmpBuffer.erase(0, numBytes); - return data; - } - - // move everything out of tmpBuffer into data - data = tmpBuffer; - tmpBuffer.erase(); - } - - // account for bytes read so far - assert(data.size() < numBytes); - numBytes -= data.size(); - - // read until we have all the requested data - while (numBytes > 0) { - // read max(4096, bytes_left) bytes into buffer - char buffer[4096]; - UInt32 n = sizeof(buffer); - if (n > numBytes) { - n = numBytes; - } - n = stream->read(buffer, n, -1.0); - - // if stream is empty then return what we've got so far - if (n == 0) { - break; - } - - // append stream data - data.append(buffer, n); - numBytes -= n; - } - - return data; -} - -CString -CHTTPProtocol::readChunk(IInputStream* stream, - CString& tmpBuffer, UInt32* maxSize) -{ - CString line; - - // get chunk header - line = readLine(stream, tmpBuffer); - - // parse chunk size - UInt32 size; - { - std::istringstream s(line); - s.exceptions(std::ios::goodbit); - s >> std::hex >> size; - if (!s) { - LOG((CLOG_DEBUG1 "cannot parse chunk size", line.c_str())); - throw XHTTP(400); - } - } - if (size == 0) { - return CString(); - } - - // check size - if (maxSize != NULL) { - if (line.size() + 2 + size + 2 > *maxSize) { - throw XHTTP(413); - } - maxSize -= line.size() + 2 + size + 2; - } - - // read size bytes - CString data = readBlock(stream, size, tmpBuffer); - if (data.size() != size) { - LOG((CLOG_DEBUG1 "expected/actual chunk size mismatch", size, data.size())); - throw XHTTP(400); - } - - // read an discard CRLF - line = readLine(stream, tmpBuffer); - if (!line.empty()) { - LOG((CLOG_DEBUG1 "missing CRLF after chunk")); - throw XHTTP(400); - } - - return data; -} - -void -CHTTPProtocol::readHeaders(IInputStream* stream, - CHTTPRequest* request, bool isFooter, - CString& tmpBuffer, UInt32* maxSize) -{ - // parse headers. done with headers when we get a blank line. - CString name; - CString line = readLine(stream, tmpBuffer); - while (!line.empty()) { - // check size - if (maxSize != NULL) { - if (line.size() + 2 > *maxSize) { - throw XHTTP(413); - } - *maxSize -= line.size() + 2; - } - - // if line starts with space or tab then append it to the - // previous header. if there is no previous header then - // throw. - if (line[0] == ' ' || line[0] == '\t') { - if (name.empty()) { - LOG((CLOG_DEBUG1 "first header is a continuation")); - throw XHTTP(400); - } - request->appendHeader(name, line); - } - - // line should have the form: :[] - else { - // parse - CString value; - std::istringstream s(line); - s.exceptions(std::ios::goodbit); - std::getline(s, name, ':'); - if (!s || !isValidToken(name)) { - LOG((CLOG_DEBUG1 "invalid header: %s", line.c_str())); - throw XHTTP(400); - } - std::getline(s, value); - - // check validity of name - if (isFooter) { - // FIXME -- only certain names are allowed in footers - // but which ones? - } - - request->appendHeader(name, value); - } - - // next header - line = readLine(stream, tmpBuffer); - } -} - -bool -CHTTPProtocol::isValidToken(const CString& token) -{ - return (token.find("()<>@,;:\\\"/[]?={} " - "\0\1\2\3\4\5\6\7" - "\10\11\12\13\14\15\16\17" - "\20\21\22\23\24\25\26\27" - "\30\31\32\33\34\35\36\37\177") == CString::npos); -} diff --git a/lib/http/CHTTPProtocol.h b/lib/http/CHTTPProtocol.h deleted file mode 100644 index 8c866455..00000000 --- a/lib/http/CHTTPProtocol.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package 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. - */ - -#ifndef CHTTPPROTOCOL_H -#define CHTTPPROTOCOL_H - -#include "CString.h" -#include "CStringUtil.h" -#include "BasicTypes.h" -#include "stdlist.h" -#include "stdmap.h" -#include "stdvector.h" - -class IInputStream; -class IOutputStream; - -//! HTTP request type -/*! -This class encapsulates an HTTP request. -*/ -class CHTTPRequest { -private: - typedef std::list > CHeaderList; -public: - //! Iterator on headers - /*! - An iterator on the headers. Each element is a std::pair; first is - the header name as a CString, second is the header value as a CString. - */ - typedef CHeaderList::const_iterator const_iterator; - - CHTTPRequest(); - ~CHTTPRequest(); - - //! @name manipulators - //@{ - - //! Insert header - /*! - Add a header by name replacing the existing header, if any. - Headers are sent in the order they're inserted. Replacing - a header does not change its original position in the order. - */ - void insertHeader(const CString& name, const CString& value); - - //! Append header - /*! - Append a header. Equivalent to insertHeader() if the header - doesn't exist, otherwise it appends a comma and the value to - the existing header. - */ - void appendHeader(const CString& name, const CString& value); - - //! Remove header - /*! - Remove a header by name. Does nothing if the header doesn't exist. - */ - void eraseHeader(const CString& name); - - //@} - //! @name accessors - //@{ - - //! Check header existence - /*! - Returns true iff the header exists. - */ - bool isHeader(const CString& name) const; - - //! Get header - /*! - Get a header by name. Returns the empty string if the header - doesn't exist. - */ - CString getHeader(const CString& name) const; - - // headers are iterated in the order they were added. - //! Get beginning header iterator - const_iterator begin() const { return m_headers.begin(); } - //! Get ending header iterator - const_iterator end() const { return m_headers.end(); } - - //@} - -public: - // note -- these members are public for convenience - //! The HTTP method - CString m_method; - //! The HTTP URI - CString m_uri; - //! The HTTP major version number - SInt32 m_majorVersion; - //! The HTTP minor version number - SInt32 m_minorVersion; - //! The HTTP body, after transfer decoding - CString m_body; - -private: - typedef std::map CHeaderMap; - - CHeaderList m_headers; - CHeaderMap m_headerByName; -}; - -//! HTTP reply type -/*! -This class encapsulates an HTTP reply. -*/ -class CHTTPReply { -public: - //! Header list - /*! - The type of the reply header list. Each pair is the header name - and value, respectively for first and second. - */ - typedef std::vector > CHeaderList; - - // note -- these members are public for convenience - //! The HTTP major version number - SInt32 m_majorVersion; - //! The HTTP minor version number - SInt32 m_minorVersion; - //! The HTTP status code - SInt32 m_status; - //! The HTTP reason phrase - CString m_reason; - //! The HTTP method - CString m_method; - //! The HTTP headers - CHeaderList m_headers; - //! The HTTP body - CString m_body; -}; - -//! HTTP protocol utilities -/*! -This class provides utility functions for HTTP. -*/ -class CHTTPProtocol { -public: - //! Multipart form parts - /*! - Each element is the contents of a multipart form part indexed by - it's name. - */ - typedef std::map CFormParts; - - //! Read HTTP request - /*! - Read and parse an HTTP request. The result is returned in a - CHTTPRequest which the client must delete. Throws an - XHTTP if there was a parse error. Throws an XIO exception - if there was a read error. If \c maxSize is greater than - zero and the request is larger than \c maxSize bytes then - throws XHTTP(413) (request entity too large). - */ - static CHTTPRequest* readRequest(IInputStream*, UInt32 maxSize = 0); - - //! Send HTTP response - /*! - Send an HTTP reply. The Content-Length and Date headers are set - automatically. - */ - static void reply(IOutputStream*, CHTTPReply&); - - //! Parse multipart form data - /*! - Parse a multipart/form-data body into its parts. Returns true - iff the entire body was correctly parsed. - */ - // FIXME -- name/value pairs insufficient to save part headers - static bool parseFormData(const CHTTPRequest&, - CFormParts& parts); - -private: - static CString readLine(IInputStream*, CString& tmpBuffer); - static CString readBlock(IInputStream*, - UInt32 numBytes, CString& tmpBuffer); - static CString readChunk(IInputStream*, CString& tmpBuffer, - UInt32* maxSize); - static void readHeaders(IInputStream*, - CHTTPRequest*, bool isFooter, - CString& tmpBuffer, - UInt32* maxSize); - - static bool isValidToken(const CString&); -}; - -#endif diff --git a/lib/http/Makefile.am b/lib/http/Makefile.am deleted file mode 100644 index c9abe536..00000000 --- a/lib/http/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -# synergy -- mouse and keyboard sharing utility -# Copyright (C) 2002 Chris Schoeneman -# -# This package is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# found in the file COPYING that should have accompanied this file. -# -# This package 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. - -## Process this file with automake to produce Makefile.in -NULL = -DEPTH = ../.. -VDEPTH = ./$(VPATH)/$(DEPTH) - -EXTRA_DIST = \ - http.dsp \ - $(NULL) - -MAINTAINERCLEANFILES = \ - Makefile.in \ - $(NULL) - -noinst_LIBRARIES = libhttp.a -libhttp_a_SOURCES = \ - CHTTPProtocol.cpp \ - XHTTP.cpp \ - CHTTPProtocol.h \ - XHTTP.h \ - $(NULL) -INCLUDES = \ - -I$(VDEPTH)/lib/common \ - -I$(VDEPTH)/lib/arch \ - -I$(VDEPTH)/lib/base \ - -I$(VDEPTH)/lib/mt \ - -I$(VDEPTH)/lib/io \ - $(NULL) diff --git a/lib/http/XHTTP.cpp b/lib/http/XHTTP.cpp deleted file mode 100644 index 9b146091..00000000 --- a/lib/http/XHTTP.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package 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. - */ - -#include "XHTTP.h" -#include "CHTTPProtocol.h" -#include "CStringUtil.h" -#include "stdsstream.h" - -// -// XHTTP -// - -XHTTP::XHTTP(SInt32 statusCode) : - XBase(), - m_status(statusCode), - m_reason(getReason(statusCode)) -{ - // do nothing -} - -XHTTP::XHTTP(SInt32 statusCode, const CString& reasonPhrase) : - XBase(), - m_status(statusCode), - m_reason(reasonPhrase) -{ - // do nothing -} - -XHTTP::~XHTTP() -{ - // do nothing -} - -SInt32 -XHTTP::getStatus() const -{ - return m_status; -} - -CString -XHTTP::getReason() const -{ - return m_reason; -} - -void -XHTTP::addHeaders(CHTTPReply&) const -{ - // do nothing -} - -CString -XHTTP::getWhat() const throw() -{ - const char* reason; - if (m_reason.empty()) { - reason = getReason(m_status); - } - else { - reason = m_reason.c_str(); - } - return format("XHTTP", "%{1} %{2}", - CStringUtil::print("%d", m_status).c_str(), - reason); -} - -const char* -XHTTP::getReason(SInt32 status) -{ - switch (status) { - case 300: return "Multiple Choices"; - case 301: return "Moved Permanently"; - case 302: return "Moved Temporarily"; - case 303: return "See Other"; - case 304: return "Not Modified"; - case 305: return "Use Proxy"; - case 400: return "Bad Request"; - case 401: return "Unauthorized"; - case 402: return "Payment Required"; - case 403: return "Forbidden"; - case 404: return "Not Found"; - case 405: return "Method Not Allowed"; - case 406: return "Not Acceptable"; - case 407: return "Proxy Authentication Required"; - case 408: return "Request Time-out"; - case 409: return "Conflict"; - case 410: return "Gone"; - case 411: return "Length Required"; - case 412: return "Precondition Failed"; - case 413: return "Request Entity Too Large"; - case 414: return "Request-URI Too Large"; - case 415: return "Unsupported Media Type"; - case 500: return "Internal Server Error"; - case 501: return "Not Implemented"; - case 502: return "Bad Gateway"; - case 503: return "Service Unavailable"; - case 504: return "Gateway Time-out"; - case 505: return "HTTP Version not supported"; - default: return ""; - } -} - - -// -// XHTTPAllow -// - -XHTTPAllow::XHTTPAllow(const CString& allowedMethods) : - XHTTP(405), - m_allowed(allowedMethods) -{ - // do nothing -} - -XHTTPAllow::~XHTTPAllow() -{ - // do nothing -} - -void -XHTTPAllow::addHeaders(CHTTPReply& reply) const -{ - reply.m_headers.push_back(std::make_pair(CString("Allow"), m_allowed)); -} diff --git a/lib/http/XHTTP.h b/lib/http/XHTTP.h deleted file mode 100644 index 2bd6ed73..00000000 --- a/lib/http/XHTTP.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * synergy -- mouse and keyboard sharing utility - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file COPYING that should have accompanied this file. - * - * This package 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. - */ - -#ifndef XHTTP_H -#define XHTTP_H - -#include "BasicTypes.h" -#include "XBase.h" - -class CHTTPReply; - -//! Generic HTTP exception -class XHTTP : public XBase { -public: - /*! - Use the HTTP \c statusCode as the failure reason. - */ - XHTTP(SInt32 statusCode); - /*! - Use the HTTP \c statusCode as the failure reason. Use \c reasonPhrase - as the human readable reason for the failure. - */ - XHTTP(SInt32 statusCode, const CString& reasonPhrase); - ~XHTTP(); - - //@{ - //! @name accessors - - //! Get the HTTP status code - SInt32 getStatus() const; - - //! Get the reason phrase - CString getReason() const; - - //! Modify reply for error - /*! - Override to modify an HTTP reply to further describe the error. - */ - virtual void addHeaders(CHTTPReply&) const; - - //@} - -protected: - virtual CString getWhat() const throw(); - -private: - static const char* getReason(SInt32 status); - -private: - SInt32 m_status; - CString m_reason; -}; - -//! HTTP exception indicating an unsupported method -class XHTTPAllow : public XHTTP { -public: - /*! - \c allowedMethods is added as an `Allow' header to a reply in - addHeaders(). - */ - XHTTPAllow(const CString& allowedMethods); - ~XHTTPAllow(); - - // XHTTP overrides - virtual void addHeaders(CHTTPReply&) const; - -private: - CString m_allowed; -}; - -#endif diff --git a/lib/http/http.dsp b/lib/http/http.dsp deleted file mode 100644 index 439b0616..00000000 --- a/lib/http/http.dsp +++ /dev/null @@ -1,110 +0,0 @@ -# Microsoft Developer Studio Project File - Name="http" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=http - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "http.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "http.mak" CFG="http - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "http - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "http - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "http - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\common" /I "..\arch" /I "..\base" /I "..\io" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "http - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\common" /I "..\arch" /I "..\base" /I "..\io" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "http - Win32 Release" -# Name "http - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\CHTTPProtocol.cpp -# End Source File -# Begin Source File - -SOURCE=.\XHTTP.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\CHTTPProtocol.h -# End Source File -# Begin Source File - -SOURCE=.\XHTTP.h -# End Source File -# End Group -# End Target -# End Project diff --git a/lib/server/server.dsp b/lib/server/server.dsp index 986fedf8..536b33d7 100644 --- a/lib/server/server.dsp +++ b/lib/server/server.dsp @@ -41,7 +41,7 @@ RSC=rc.exe # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\common" /I "..\arch" /I "..\base" /I "..\mt" /I "..\io" /I "..\http" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c +# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\common" /I "..\arch" /I "..\base" /I "..\mt" /I "..\io" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\common" /I "..\arch" /I "..\base" /I "..\mt" /I "..\io" /I "..\http" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\common" /I "..\arch" /I "..\base" /I "..\mt" /I "..\io" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" diff --git a/synergy.dsw b/synergy.dsw index 7148711f..63b402d9 100644 --- a/synergy.dsw +++ b/synergy.dsw @@ -84,18 +84,6 @@ Package=<4> ############################################################################### -Project: "http"=".\lib\HTTP\http.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Project: "io"=".\lib\io\io.dsp" - Package Owner=<4> Package=<5> @@ -126,9 +114,6 @@ Package=<4> Project_Dep_Name base End Project Dependency Begin Project Dependency - Project_Dep_Name http - End Project Dependency - Begin Project Dependency Project_Dep_Name io End Project Dependency Begin Project Dependency @@ -282,9 +267,6 @@ Package=<4> Project_Dep_Name base End Project Dependency Begin Project Dependency - Project_Dep_Name http - End Project Dependency - Begin Project Dependency Project_Dep_Name io End Project Dependency Begin Project Dependency