trunk: sync from 1.4.3

make & cmake fixes
This commit is contained in:
Marian Krivos
2012-02-04 17:03:09 +00:00
parent 0afd04898b
commit 8b70c37260
55 changed files with 2797 additions and 2229 deletions

View File

@@ -1,60 +1,78 @@
// //
// ApacheApplication.h // ApacheApplication.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheApplication.h#2 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheApplication.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheApplication_INCLUDED //
#define ApacheConnector_ApacheApplication_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "ApacheRequestHandlerFactory.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/Util/Application.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/Mutex.h" // a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
class ApacheApplication: public Poco::Util::Application // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
{ // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
public: // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
ApacheApplication(); // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
/// Creates the ApacheApplication and sets the // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// ApacheChannel as the root logger channel. // DEALINGS IN THE SOFTWARE.
//
~ApacheApplication();
/// Destroys the ApacheApplication.
#ifndef ApacheConnector_ApacheApplication_INCLUDED
void setup(); #define ApacheConnector_ApacheApplication_INCLUDED
/// Initializes the application if called for the first
/// time; does nothing in later calls.
#include "ApacheRequestHandlerFactory.h"
ApacheRequestHandlerFactory& factory(); #include "Poco/Util/Application.h"
/// Returns the ApacheRequestHandlerFactory. #include "Poco/Mutex.h"
static ApacheApplication& instance();
/// Returns the application instance. class ApacheApplication: public Poco::Util::Application
{
private: public:
bool _ready; ApacheApplication();
ApacheRequestHandlerFactory _factory; /// Creates the ApacheApplication and sets the
Poco::FastMutex _mutex; /// ApacheChannel as the root logger channel.
};
~ApacheApplication();
/// Destroys the ApacheApplication.
//
// inlines void setup();
// /// Initializes the application if called for the first
inline ApacheRequestHandlerFactory& ApacheApplication::factory() /// time; does nothing in later calls.
{
return _factory; ApacheRequestHandlerFactory& factory();
} /// Returns the ApacheRequestHandlerFactory.
static ApacheApplication& instance();
#endif // ApacheConnector_ApacheApplication_INCLUDED /// Returns the application instance.
private:
bool _ready;
ApacheRequestHandlerFactory _factory;
Poco::FastMutex _mutex;
};
//
// inlines
//
inline ApacheRequestHandlerFactory& ApacheApplication::factory()
{
return _factory;
}
#endif // ApacheConnector_ApacheApplication_INCLUDED

View File

@@ -1,34 +1,52 @@
// //
// ApacheChannel.h // ApacheChannel.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheChannel.h#1 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheChannel.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheChannel_INCLUDED //
#define ApacheConnector_ApacheChannel_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "Poco/Channel.h" // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
class ApacheChannel: public Poco::Channel //
/// This class implements a logging channel // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// that uses the Apache logging facilities. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
{ // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
public: // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
ApacheChannel(); // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
~ApacheChannel(); // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
void log(const Poco::Message& msg); //
};
#ifndef ApacheConnector_ApacheChannel_INCLUDED
#endif // ApacheConnector_ApacheChannel_INCLUDED #define ApacheConnector_ApacheChannel_INCLUDED
#include "Poco/Channel.h"
class ApacheChannel: public Poco::Channel
/// This class implements a logging channel
/// that uses the Apache logging facilities.
{
public:
ApacheChannel();
~ApacheChannel();
void log(const Poco::Message& msg);
};
#endif // ApacheConnector_ApacheChannel_INCLUDED

View File

@@ -1,90 +1,108 @@
// //
// ApacheConnector.h // ApacheConnector.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheConnector.h#3 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheConnector.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheConnector_INCLUDED //
#define ApacheConnector_ApacheConnector_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include <string> // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
struct request_rec; //
class ApacheServerRequest; // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
class ApacheRequestRec // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
/// This class wraps an Apache request_rec. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
{ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
public: // DEALINGS IN THE SOFTWARE.
ApacheRequestRec(request_rec* _pRec); //
/// Creates the ApacheRequestRec;
bool haveRequestBody(); #ifndef ApacheConnector_ApacheConnector_INCLUDED
/// Returns true if the request contains a body. #define ApacheConnector_ApacheConnector_INCLUDED
int readRequest(char* buffer, int length);
/// Read up to length bytes from request body into buffer. #include <string>
/// Returns the number of bytes read, 0 if eof or -1 if an error occured.
void writeResponse(const char* buffer, int length); struct request_rec;
/// Writes the given characters as response to the given request_rec. class ApacheServerRequest;
void addHeader(const std::string& key, const std::string& value);
/// Adds the given key / value pair to the outgoing headers of the class ApacheRequestRec
/// http response. /// This class wraps an Apache request_rec.
{
void setContentType(const std::string& mediaType); public:
/// Sets the response content type. ApacheRequestRec(request_rec* _pRec);
/// Creates the ApacheRequestRec;
void redirect(const std::string& uri);
/// Redirects the response to the given uri. bool haveRequestBody();
/// Returns true if the request contains a body.
void sendErrorResponse(int status);
/// Sends an error response with the given HTTP status code. int readRequest(char* buffer, int length);
/// Read up to length bytes from request body into buffer.
int sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType); /// Returns the number of bytes read, 0 if eof or -1 if an error occured.
/// Sends the file given by fileName as response.
void writeResponse(const char* buffer, int length);
void copyHeaders(ApacheServerRequest& request); /// Writes the given characters as response to the given request_rec.
/// Copies the request uri and header fields from the Apache request
/// to the ApacheServerRequest. void addHeader(const std::string& key, const std::string& value);
/// Adds the given key / value pair to the outgoing headers of the
private: /// http response.
request_rec* _pRec;
}; void setContentType(const std::string& mediaType);
/// Sets the response content type.
class ApacheConnector void redirect(const std::string& uri, int status);
/// This class provides static methods wrapping the /// Redirects the response to the given uri.
/// Apache API.
{ void sendErrorResponse(int status);
public: /// Sends an error response with the given HTTP status code.
enum LogLevel
{ int sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType);
PRIO_FATAL = 1, /// A fatal error. The application will most likely terminate. This is the highest priority. /// Sends the file given by fileName as response.
PRIO_CRITICAL, /// A critical error. The application might not be able to continue running successfully.
PRIO_ERROR, /// An error. An operation did not complete successfully, but the application as a whole is not affected. void copyHeaders(ApacheServerRequest& request);
PRIO_WARNING, /// A warning. An operation completed with an unexpected result. /// Copies the request uri and header fields from the Apache request
PRIO_NOTICE, /// A notice, which is an information with just a higher priority. /// to the ApacheServerRequest.
PRIO_INFORMATION, /// An informational message, usually denoting the successful completion of an operation.
PRIO_DEBUG, /// A debugging message. private:
PRIO_TRACE /// A tracing message. This is the lowest priority. request_rec* _pRec;
}; };
static void log(const char* file, int line, int level, int status, const char* text);
/// Log the given message. class ApacheConnector
}; /// This class provides static methods wrapping the
/// Apache API.
{
#endif // ApacheConnector_ApacheConnector_INCLUDED public:
enum LogLevel
{
PRIO_FATAL = 1, /// A fatal error. The application will most likely terminate. This is the highest priority.
PRIO_CRITICAL, /// A critical error. The application might not be able to continue running successfully.
PRIO_ERROR, /// An error. An operation did not complete successfully, but the application as a whole is not affected.
PRIO_WARNING, /// A warning. An operation completed with an unexpected result.
PRIO_NOTICE, /// A notice, which is an information with just a higher priority.
PRIO_INFORMATION, /// An informational message, usually denoting the successful completion of an operation.
PRIO_DEBUG, /// A debugging message.
PRIO_TRACE /// A tracing message. This is the lowest priority.
};
static void log(const char* file, int line, int level, int status, const char* text);
/// Log the given message.
};
#endif // ApacheConnector_ApacheConnector_INCLUDED

View File

@@ -1,59 +1,77 @@
// //
// ApacheRequestHandlerFactory.h // ApacheRequestHandlerFactory.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheRequestHandlerFactory.h#5 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheRequestHandlerFactory.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheRequestHandlerFactory_INCLUDED //
#define ApacheConnector_ApacheRequestHandlerFactory_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "ApacheServerRequest.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/Net/HTTPRequestHandlerFactory.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/ClassLoader.h" // a source language processor.
#include "Poco/Mutex.h" //
#include <map> // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
class ApacheRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
{ // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
public: // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
ApacheRequestHandlerFactory(); // DEALINGS IN THE SOFTWARE.
/// Constructs the ApacheRequestHandlerFactory //
~ApacheRequestHandlerFactory();
/// Destructor of the ApacheRequestHandlerFactory #ifndef ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
#define ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
/// Creates a new request handler for the given HTTP request.
#include "ApacheServerRequest.h"
bool mustHandle(const std::string& uri); #include "Poco/Net/HTTPRequestHandlerFactory.h"
/// Returns 1 if the given uri must be handled by the #include "Poco/ClassLoader.h"
/// poco_mapper module, 0 otherwise. #include "Poco/Mutex.h"
#include <map>
void handleURIs(const std::string& uris);
/// Parses the given string for dllName, factoryName and the URIs to handle
/// by the request-handler class ApacheRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
void addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri); public:
/// Adds the request handler from the given dll with the given name and ApacheRequestHandlerFactory();
/// registers that handler with the given uri /// Constructs the ApacheRequestHandlerFactory
private: ~ApacheRequestHandlerFactory();
typedef std::map<std::string, Poco::Net::HTTPRequestHandlerFactory*> RequestHandlerFactories; /// Destructor of the ApacheRequestHandlerFactory
RequestHandlerFactories _requestHandlers; Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
Poco::ClassLoader<Poco::Net::HTTPRequestHandlerFactory> _loader; /// Creates a new request handler for the given HTTP request.
Poco::FastMutex _mutex;
}; bool mustHandle(const std::string& uri);
/// Returns 1 if the given uri must be handled by the
/// poco_mapper module, 0 otherwise.
#endif // ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
void handleURIs(const std::string& uris);
/// Parses the given string for dllName, factoryName and the URIs to handle
/// by the request-handler
void addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri);
/// Adds the request handler from the given dll with the given name and
/// registers that handler with the given uri
private:
typedef std::map<std::string, Poco::Net::HTTPRequestHandlerFactory*> RequestHandlerFactories;
RequestHandlerFactories _requestHandlers;
Poco::ClassLoader<Poco::Net::HTTPRequestHandlerFactory> _loader;
Poco::FastMutex _mutex;
};
#endif // ApacheConnector_ApacheRequestHandlerFactory_INCLUDED

View File

@@ -1,102 +1,120 @@
// //
// ApacheServerRequest.h // ApacheServerRequest.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheServerRequest.h#6 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheServerRequest.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheServerRequest_INCLUDED //
#define ApacheConnector_ApacheServerRequest_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "ApacheConnector.h" // all derivative works of the Software, unless such copies or derivative
#include "ApacheStream.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/Net/HTTPServerRequest.h" // a source language processor.
#include <set> //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
class ApacheServerResponse; // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
class ApacheServerRequest: public Poco::Net::HTTPServerRequest // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
{ // DEALINGS IN THE SOFTWARE.
public: //
ApacheServerRequest(
ApacheRequestRec* pApacheRequest,
const char* serverName, #ifndef ApacheConnector_ApacheServerRequest_INCLUDED
int serverPort, #define ApacheConnector_ApacheServerRequest_INCLUDED
const char* clientName,
int clientPort);
/// Creates a new ApacheServerRequest. #include "ApacheConnector.h"
#include "ApacheStream.h"
~ApacheServerRequest(); #include "Poco/Net/HTTPServerRequest.h"
/// Destroys the ApacheServerRequest. #include <set>
std::istream& stream();
/// Returns the input stream for reading class ApacheServerResponse;
/// the request body.
///
/// The stream is valid until the HTTPServerRequest class ApacheServerRequest: public Poco::Net::HTTPServerRequest
/// object is destroyed. {
public:
bool expectContinue() const; ApacheServerRequest(
/// Returns true if the client expects a ApacheRequestRec* pApacheRequest,
/// 100 Continue response. const char* serverName,
int serverPort,
const Poco::Net::SocketAddress& clientAddress() const; const char* clientName,
/// Returns the client's address. int clientPort);
/// Creates a new ApacheServerRequest.
const Poco::Net::SocketAddress& serverAddress() const;
/// Returns the server's address. ~ApacheServerRequest();
/// Destroys the ApacheServerRequest.
const Poco::Net::HTTPServerParams& serverParams() const;
/// Returns a reference to the server parameters. std::istream& stream();
/// Returns the input stream for reading
Poco::Net::HTTPServerResponse& response() const; /// the request body.
/// Returns a reference to the associated response ///
/// The stream is valid until the HTTPServerRequest
protected: /// object is destroyed.
void setResponse(ApacheServerResponse* pResponse);
bool expectContinue() const;
private: /// Returns true if the client expects a
ApacheRequestRec* _pApacheRequest; /// 100 Continue response.
ApacheServerResponse* _pResponse;
ApacheInputStream* _pStream; const Poco::Net::SocketAddress& clientAddress() const;
Poco::Net::SocketAddress _serverAddress; /// Returns the client's address.
Poco::Net::SocketAddress _clientAddress;
const Poco::Net::SocketAddress& serverAddress() const;
friend class ApacheServerResponse; /// Returns the server's address.
};
const Poco::Net::HTTPServerParams& serverParams() const;
/// Returns a reference to the server parameters.
//
// inlines Poco::Net::HTTPServerResponse& response() const;
// /// Returns a reference to the associated response
inline std::istream& ApacheServerRequest::stream()
{ protected:
poco_check_ptr (_pStream); void setResponse(ApacheServerResponse* pResponse);
return *_pStream; private:
} ApacheRequestRec* _pApacheRequest;
ApacheServerResponse* _pResponse;
ApacheInputStream* _pStream;
inline const Poco::Net::SocketAddress& ApacheServerRequest::clientAddress() const Poco::Net::SocketAddress _serverAddress;
{ Poco::Net::SocketAddress _clientAddress;
return _clientAddress;
} friend class ApacheServerResponse;
};
inline const Poco::Net::SocketAddress& ApacheServerRequest::serverAddress() const
{ //
return _serverAddress; // inlines
} //
inline std::istream& ApacheServerRequest::stream()
{
#endif // ApacheConnector_ApacheServerRequest_INCLUDED poco_check_ptr (_pStream);
return *_pStream;
}
inline const Poco::Net::SocketAddress& ApacheServerRequest::clientAddress() const
{
return _clientAddress;
}
inline const Poco::Net::SocketAddress& ApacheServerRequest::serverAddress() const
{
return _serverAddress;
}
#endif // ApacheConnector_ApacheServerRequest_INCLUDED

View File

@@ -1,124 +1,144 @@
// //
// ApacheServerResponse.h // ApacheServerResponse.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheServerResponse.h#6 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheServerResponse.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheServerResponse_INCLUDED //
#define ApacheConnector_ApacheServerResponse_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "ApacheConnector.h" // all derivative works of the Software, unless such copies or derivative
#include "ApacheStream.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/Net/Net.h" // a source language processor.
#include "Poco/Net/HTTPServerResponse.h" //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
class ApacheServerRequest; // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
class ApacheServerResponse: public Poco::Net::HTTPServerResponse // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// This subclass of HTTPResponse is used for // DEALINGS IN THE SOFTWARE.
/// representing server-side HTTP responses for apache. //
///
/// A ApacheServerResponse is passed to the
/// handleRequest() method of HTTPRequestHandler. #ifndef ApacheConnector_ApacheServerResponse_INCLUDED
/// #define ApacheConnector_ApacheServerResponse_INCLUDED
/// handleRequest() must set a status code
/// and optional reason phrase, set headers
/// as necessary, and provide a message body. #include "ApacheConnector.h"
{ #include "ApacheStream.h"
public: #include "Poco/Net/Net.h"
ApacheServerResponse(ApacheServerRequest* pRequest); #include "Poco/Net/HTTPServerResponse.h"
/// Creates the ApacheServerResponse.
~ApacheServerResponse(); class ApacheServerRequest;
/// Destroys the ApacheServerResponse.
void sendContinue(); class ApacheServerResponse: public Poco::Net::HTTPServerResponse
/// Sends a 100 Continue response to the /// This subclass of HTTPResponse is used for
/// client. /// representing server-side HTTP responses for apache.
///
void sendErrorResponse(int status); /// A ApacheServerResponse is passed to the
/// Sends an error response with the given /// handleRequest() method of HTTPRequestHandler.
/// status back to the client. ///
/// handleRequest() must set a status code
std::ostream& send(); /// and optional reason phrase, set headers
/// Sends the response header to the client and /// as necessary, and provide a message body.
/// returns an output stream for sending the {
/// response body. public:
/// ApacheServerResponse(ApacheServerRequest* pRequest);
/// The returned stream is valid until the response /// Creates the ApacheServerResponse.
/// object is destroyed.
/// ~ApacheServerResponse();
/// Must not be called after sendFile(), sendBuffer() /// Destroys the ApacheServerResponse.
/// or redirect() has been called.
void sendContinue();
void sendFile(const std::string& path, const std::string& mediaType); /// Sends a 100 Continue response to the
/// Sends the response header to the client, followed /// client.
/// by the content of the given file.
/// void sendErrorResponse(int status);
/// Must not be called after send(), sendBuffer() /// Sends an error response with the given
/// or redirect() has been called. /// status back to the client.
///
/// Throws a FileNotFoundException if the file std::ostream& send();
/// cannot be found, or an OpenFileException if /// Sends the response header to the client and
/// the file cannot be opened. /// returns an output stream for sending the
/// response body.
void sendBuffer(const void* pBuffer, std::size_t length); ///
/// Sends the response header to the client, followed /// The returned stream is valid until the response
/// by the contents of the given buffer. /// object is destroyed.
/// ///
/// The Content-Length header of the response is set /// Must not be called after sendFile(), sendBuffer()
/// to length and chunked transfer encoding is disabled. /// or redirect() has been called.
///
/// If both the HTTP message header and body (from the void sendFile(const std::string& path, const std::string& mediaType);
/// given buffer) fit into one single network packet, the /// Sends the response header to the client, followed
/// complete response can be sent in one network packet. /// by the content of the given file.
/// ///
/// Must not be called after send(), sendFile() /// Must not be called after send(), sendBuffer()
/// or redirect() has been called. /// or redirect() has been called.
///
void redirect(const std::string& uri); /// Throws a FileNotFoundException if the file
/// Sets the status code to 302 (Found) /// cannot be found, or an OpenFileException if
/// and sets the "Location" header field /// the file cannot be opened.
/// to the given URI, which according to
/// the HTTP specification, must be absolute. void sendBuffer(const void* pBuffer, std::size_t length);
/// /// Sends the response header to the client, followed
/// Must not be called after send() has been called. /// by the contents of the given buffer.
///
void requireAuthentication(const std::string& realm); /// The Content-Length header of the response is set
/// Sets the status code to 401 (Unauthorized) /// to length and chunked transfer encoding is disabled.
/// and sets the "WWW-Authenticate" header field ///
/// according to the given realm. /// If both the HTTP message header and body (from the
/// given buffer) fit into one single network packet, the
bool sent() const; /// complete response can be sent in one network packet.
/// Returns true if the response (header) has been sent. ///
/// Must not be called after send(), sendFile()
private: /// or redirect() has been called.
void initApacheOutputStream();
/// Initializes the ApacheOutputStram void redirect(const std::string& uri, Poco::Net::HTTPResponse::HTTPStatus status);
/// Sets the status code, which must be one of
ApacheOutputStream* _pStream; /// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302),
ApacheRequestRec* _pApacheRequest; /// or HTTP_SEE_OTHER (303),
}; /// and sets the "Location" header field
/// to the given URI, which according to
/// the HTTP specification, must be absolute.
// ///
// inlines /// Must not be called after send() has been called.
//
inline bool ApacheServerResponse::sent() const void requireAuthentication(const std::string& realm);
{ /// Sets the status code to 401 (Unauthorized)
return _pStream != 0; /// and sets the "WWW-Authenticate" header field
} /// according to the given realm.
bool sent() const;
#endif // ApacheConnector_ApacheServerResponse_INCLUDED /// Returns true if the response (header) has been sent.
private:
void initApacheOutputStream();
/// Initializes the ApacheOutputStram
ApacheOutputStream* _pStream;
ApacheRequestRec* _pApacheRequest;
};
//
// inlines
//
inline bool ApacheServerResponse::sent() const
{
return _pStream != 0;
}
#endif // ApacheConnector_ApacheServerResponse_INCLUDED

View File

@@ -1,107 +1,125 @@
// //
// ApacheStream.h // ApacheStream.h
// //
// $Id: //poco/Main/ApacheConnector/include/ApacheStream.h#5 $ // $Id: //poco/1.4/ApacheConnector/include/ApacheStream.h#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#ifndef ApacheConnector_ApacheStream_INCLUDED //
#define ApacheConnector_ApacheStream_INCLUDED // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
#include "ApacheConnector.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/BufferedStreamBuf.h" // works are solely in the form of machine-executable object code generated by
#include <istream> // a source language processor.
#include <ostream> //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
class ApacheStreamBuf: public Poco::BufferedStreamBuf // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
/// This is the streambuf class used for reading from and writing to a socket. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
{ // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
public: // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData = false); // DEALINGS IN THE SOFTWARE.
/// Creates a ApacheStreamBuf with the given socket. //
~ApacheStreamBuf();
/// Destroys the SocketStreamBuf. #ifndef ApacheConnector_ApacheStream_INCLUDED
#define ApacheConnector_ApacheStream_INCLUDED
protected:
int readFromDevice(char* buffer, std::streamsize length);
int writeToDevice(const char* buffer, std::streamsize length); #include "ApacheConnector.h"
#include "Poco/BufferedStreamBuf.h"
private: #include <istream>
enum #include <ostream>
{
STREAM_BUFFER_SIZE = 1024
}; class ApacheStreamBuf: public Poco::BufferedStreamBuf
/// This is the streambuf class used for reading from and writing to a socket.
ApacheRequestRec* _pApacheRequest; {
bool _haveData; public:
}; ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData = false);
/// Creates a ApacheStreamBuf with the given socket.
class ApacheIOS: public virtual std::ios ~ApacheStreamBuf();
/// The base class for ApacheStream, ApacheInputStream and /// Destroys the SocketStreamBuf.
/// ApacheOutputStream.
/// protected:
/// This class is needed to ensure the correct initialization int readFromDevice(char* buffer, std::streamsize length);
/// order of the stream buffer and base classes. int writeToDevice(const char* buffer, std::streamsize length);
{
public: private:
ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData = false); enum
/// Creates the ApacheIOS with the given socket. {
STREAM_BUFFER_SIZE = 1024
~ApacheIOS(); };
/// Destroys the ApacheIOS.
/// ApacheRequestRec* _pApacheRequest;
/// Flushes the buffer, but does not close the socket. bool _haveData;
};
ApacheStreamBuf* rdbuf();
/// Returns a pointer to the internal ApacheStreamBuf.
class ApacheIOS: public virtual std::ios
void close(); /// The base class for ApacheStream, ApacheInputStream and
/// Flushes the stream. /// ApacheOutputStream.
///
protected: /// This class is needed to ensure the correct initialization
ApacheStreamBuf _buf; /// order of the stream buffer and base classes.
}; {
public:
ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData = false);
class ApacheOutputStream: public ApacheIOS, public std::ostream /// Creates the ApacheIOS with the given socket.
/// An output stream for writing to an Apache response.
{ ~ApacheIOS();
public: /// Destroys the ApacheIOS.
ApacheOutputStream(ApacheRequestRec* pApacheRequest); ///
/// Creates the ApacheOutputStream with the given socket. /// Flushes the buffer, but does not close the socket.
~ApacheOutputStream(); ApacheStreamBuf* rdbuf();
/// Destroys the ApacheOutputStream. /// Returns a pointer to the internal ApacheStreamBuf.
///
/// Flushes the buffer. void close();
}; /// Flushes the stream.
protected:
class ApacheInputStream: public ApacheIOS, public std::istream ApacheStreamBuf _buf;
/// An input stream for reading from an Apache request. };
///
/// Using formatted input from a ApacheInputStream
/// is not recommended, due to the read-ahead behavior of class ApacheOutputStream: public ApacheIOS, public std::ostream
/// istream with formatted reads. /// An output stream for writing to an Apache response.
{ {
public: public:
ApacheInputStream(ApacheRequestRec* pApacheRequest); ApacheOutputStream(ApacheRequestRec* pApacheRequest);
/// Creates the ApacheInputStream with the given socket. /// Creates the ApacheOutputStream with the given socket.
~ApacheInputStream(); ~ApacheOutputStream();
/// Destroys the ApacheInputStream. /// Destroys the ApacheOutputStream.
}; ///
/// Flushes the buffer.
};
#endif // ApacheConnector_ApacheStream_INCLUDED
class ApacheInputStream: public ApacheIOS, public std::istream
/// An input stream for reading from an Apache request.
///
/// Using formatted input from a ApacheInputStream
/// is not recommended, due to the read-ahead behavior of
/// istream with formatted reads.
{
public:
ApacheInputStream(ApacheRequestRec* pApacheRequest);
/// Creates the ApacheInputStream with the given socket.
~ApacheInputStream();
/// Destroys the ApacheInputStream.
};
#endif // ApacheConnector_ApacheStream_INCLUDED

View File

@@ -1,188 +1,206 @@
// //
// FormServer.cpp // FormServer.cpp
// //
// $Id: //poco/Main/ApacheConnector/samples/FormServer/src/FormServer.cpp#2 $ // $Id: //poco/1.4/ApacheConnector/samples/FormServer/src/FormServer.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "Poco/Net/HTTPServer.h" //
#include "Poco/Net/HTTPRequestHandler.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Net/HTTPRequestHandlerFactory.h" // the above license grant, this restriction and the following disclaimer,
#include "Poco/Net/HTTPServerRequest.h" // must be included in all copies of the Software, in whole or in part, and
#include "Poco/Net/HTTPServerResponse.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/Net/HTMLForm.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/Net/PartHandler.h" // a source language processor.
#include "Poco/CountingStream.h" //
#include "Poco/NullStream.h" // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#include "Poco/StreamCopier.h" // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#include "Poco/ClassLibrary.h" // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
using Poco::Net::HTTPRequestHandler; // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
using Poco::Net::HTTPRequestHandlerFactory; // DEALINGS IN THE SOFTWARE.
using Poco::Net::HTTPServerRequest; //
using Poco::Net::HTTPServerResponse;
using Poco::Net::MessageHeader;
using Poco::Net::HTMLForm; #include "Poco/Net/HTTPServer.h"
using Poco::Net::NameValueCollection; #include "Poco/Net/HTTPRequestHandler.h"
using Poco::CountingInputStream; #include "Poco/Net/HTTPRequestHandlerFactory.h"
using Poco::NullOutputStream; #include "Poco/Net/HTTPServerRequest.h"
using Poco::StreamCopier; #include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTMLForm.h"
#include "Poco/Net/PartHandler.h"
class MyPartHandler: public Poco::Net::PartHandler #include "Poco/CountingStream.h"
{ #include "Poco/NullStream.h"
public: #include "Poco/StreamCopier.h"
MyPartHandler(): #include "Poco/ClassLibrary.h"
_length(0)
{
} using Poco::Net::HTTPRequestHandler;
using Poco::Net::HTTPRequestHandlerFactory;
void handlePart(const MessageHeader& header, std::istream& stream) using Poco::Net::HTTPServerRequest;
{ using Poco::Net::HTTPServerResponse;
_type = header.get("Content-Type", "(unspecified)"); using Poco::Net::MessageHeader;
if (header.has("Content-Disposition")) using Poco::Net::HTMLForm;
{ using Poco::Net::NameValueCollection;
std::string disp; using Poco::CountingInputStream;
NameValueCollection params; using Poco::NullOutputStream;
MessageHeader::splitParameters(header["Content-Disposition"], disp, params); using Poco::StreamCopier;
_name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
} class MyPartHandler: public Poco::Net::PartHandler
{
CountingInputStream istr(stream); public:
NullOutputStream ostr; MyPartHandler():
StreamCopier::copyStream(istr, ostr); _length(0)
_length = istr.chars(); {
} }
int length() const void handlePart(const MessageHeader& header, std::istream& stream)
{ {
return _length; _type = header.get("Content-Type", "(unspecified)");
} if (header.has("Content-Disposition"))
{
const std::string& name() const std::string disp;
{ NameValueCollection params;
return _name; MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
} _name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
const std::string& fileName() const }
{
return _fileName; CountingInputStream istr(stream);
} NullOutputStream ostr;
StreamCopier::copyStream(istr, ostr);
const std::string& contentType() const _length = istr.chars();
{ }
return _type;
} int length() const
{
private: return _length;
int _length; }
std::string _type;
std::string _name; const std::string& name() const
std::string _fileName; {
}; return _name;
}
class FormRequestHandler: public HTTPRequestHandler const std::string& fileName() const
/// Return a HTML document with the current date and time. {
{ return _fileName;
public: }
FormRequestHandler()
{ const std::string& contentType() const
} {
return _type;
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) }
{
MyPartHandler partHandler; private:
HTMLForm form(request, request.stream(), partHandler); int _length;
std::string _type;
response.setChunkedTransferEncoding(true); std::string _name;
response.setContentType("text/html"); std::string _fileName;
};
std::ostream& ostr = response.send();
ostr << class FormRequestHandler: public HTTPRequestHandler
"<html>\n" /// Return a HTML document with the current date and time.
"<head>\n" {
"<title>POCO Form Server Sample</title>\n" public:
"</head>\n" FormRequestHandler()
"<body>\n" {
"<h1>POCO Form Server Sample</h1>\n" }
"<h2>GET Form</h2>\n"
"<form method=\"GET\" action=\"/form\">\n" void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
"<input type=\"text\" name=\"text\" size=\"31\">\n" {
"<input type=\"submit\" value=\"GET\">\n" MyPartHandler partHandler;
"</form>\n" HTMLForm form(request, request.stream(), partHandler);
"<h2>POST Form</h2>\n"
"<form method=\"POST\" action=\"/form\">\n" response.setChunkedTransferEncoding(true);
"<input type=\"text\" name=\"text\" size=\"31\">\n" response.setContentType("text/html");
"<input type=\"submit\" value=\"POST\">\n"
"</form>\n" std::ostream& ostr = response.send();
"<h2>File Upload</h2>\n"
"<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n" ostr <<
"<input type=\"file\" name=\"file\" size=\"31\"> \n" "<html>\n"
"<input type=\"submit\" value=\"Upload\">\n" "<head>\n"
"</form>\n"; "<title>POCO Form Server Sample</title>\n"
"</head>\n"
ostr << "<h2>Request</h2><p>\n"; "<body>\n"
ostr << "Method: " << request.getMethod() << "<br>\n"; "<h1>POCO Form Server Sample</h1>\n"
ostr << "URI: " << request.getURI() << "<br>\n"; "<h2>GET Form</h2>\n"
NameValueCollection::ConstIterator it = request.begin(); "<form method=\"GET\" action=\"/form\">\n"
NameValueCollection::ConstIterator end = request.end(); "<input type=\"text\" name=\"text\" size=\"31\">\n"
for (; it != end; ++it) "<input type=\"submit\" value=\"GET\">\n"
{ "</form>\n"
ostr << it->first << ": " << it->second << "<br>\n"; "<h2>POST Form</h2>\n"
} "<form method=\"POST\" action=\"/form\">\n"
ostr << "</p>"; "<input type=\"text\" name=\"text\" size=\"31\">\n"
"<input type=\"submit\" value=\"POST\">\n"
if (!form.empty()) "</form>\n"
{ "<h2>File Upload</h2>\n"
ostr << "<h2>Form</h2><p>\n"; "<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n"
it = form.begin(); "<input type=\"file\" name=\"file\" size=\"31\"> \n"
end = form.end(); "<input type=\"submit\" value=\"Upload\">\n"
for (; it != end; ++it) "</form>\n";
{
ostr << it->first << ": " << it->second << "<br>\n"; ostr << "<h2>Request</h2><p>\n";
} ostr << "Method: " << request.getMethod() << "<br>\n";
ostr << "</p>"; ostr << "URI: " << request.getURI() << "<br>\n";
} NameValueCollection::ConstIterator it = request.begin();
NameValueCollection::ConstIterator end = request.end();
if (!partHandler.name().empty()) for (; it != end; ++it)
{ {
ostr << "<h2>Upload</h2><p>\n"; ostr << it->first << ": " << it->second << "<br>\n";
ostr << "Name: " << partHandler.name() << "<br>\n"; }
ostr << "File Name: " << partHandler.fileName() << "<br>\n"; ostr << "</p>";
ostr << "Type: " << partHandler.contentType() << "<br>\n";
ostr << "Size: " << partHandler.length() << "<br>\n"; if (!form.empty())
ostr << "</p>"; {
} ostr << "<h2>Form</h2><p>\n";
ostr << "</body>\n"; it = form.begin();
} end = form.end();
}; for (; it != end; ++it)
{
ostr << it->first << ": " << it->second << "<br>\n";
class FormRequestHandlerFactory: public HTTPRequestHandlerFactory }
{ ostr << "</p>";
public: }
FormRequestHandlerFactory()
{ if (!partHandler.name().empty())
} {
ostr << "<h2>Upload</h2><p>\n";
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) ostr << "Name: " << partHandler.name() << "<br>\n";
{ ostr << "File Name: " << partHandler.fileName() << "<br>\n";
return new FormRequestHandler; ostr << "Type: " << partHandler.contentType() << "<br>\n";
} ostr << "Size: " << partHandler.length() << "<br>\n";
}; ostr << "</p>";
}
ostr << "</body>\n";
POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory) }
POCO_EXPORT_CLASS(FormRequestHandlerFactory) };
POCO_END_MANIFEST
class FormRequestHandlerFactory: public HTTPRequestHandlerFactory
{
public:
FormRequestHandlerFactory()
{
}
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
return new FormRequestHandler;
}
};
POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory)
POCO_EXPORT_CLASS(FormRequestHandlerFactory)
POCO_END_MANIFEST

View File

@@ -1,77 +1,95 @@
// //
// TimeServer.cpp // TimeServer.cpp
// //
// $Id: //poco/Main/ApacheConnector/samples/TimeServer/src/TimeServer.cpp#1 $ // $Id: //poco/1.4/ApacheConnector/samples/TimeServer/src/TimeServer.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "Poco/Net/HTTPServer.h" //
#include "Poco/Net/HTTPRequestHandler.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Net/HTTPRequestHandlerFactory.h" // the above license grant, this restriction and the following disclaimer,
#include "Poco/Net/HTTPServerRequest.h" // must be included in all copies of the Software, in whole or in part, and
#include "Poco/Net/HTTPServerResponse.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/Timestamp.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/DateTimeFormatter.h" // a source language processor.
#include "Poco/DateTimeFormat.h" //
#include "Poco/ClassLibrary.h" // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
using Poco::Net::HTTPRequestHandler; // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
using Poco::Net::HTTPRequestHandlerFactory; // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
using Poco::Net::HTTPServerRequest; // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
using Poco::Net::HTTPServerResponse; // DEALINGS IN THE SOFTWARE.
using Poco::Timestamp; //
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
class TimeRequestHandler: public HTTPRequestHandler #include "Poco/Net/HTTPRequestHandlerFactory.h"
/// Return a HTML document with the current date and time. #include "Poco/Net/HTTPServerRequest.h"
{ #include "Poco/Net/HTTPServerResponse.h"
public: #include "Poco/Timestamp.h"
TimeRequestHandler() #include "Poco/DateTimeFormatter.h"
{ #include "Poco/DateTimeFormat.h"
} #include "Poco/ClassLibrary.h"
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
{ using Poco::Net::HTTPRequestHandler;
Timestamp now; using Poco::Net::HTTPRequestHandlerFactory;
std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); using Poco::Net::HTTPServerRequest;
using Poco::Net::HTTPServerResponse;
response.setChunkedTransferEncoding(true); using Poco::Timestamp;
response.setContentType("text/html"); using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
std::ostream& ostr = response.send();
ostr << "<html><head><title>TimeServer powered by POCO ApacheConnector</title>";
ostr << "<meta http-equiv=\"refresh\" content=\"1\"></head>"; class TimeRequestHandler: public HTTPRequestHandler
ostr << "<body><p style=\"text-align: center; font-size: 48px;\">"; /// Return a HTML document with the current date and time.
ostr << dt; {
ostr << "</p></body></html>"; public:
} TimeRequestHandler()
}; {
}
class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
{ {
public: Timestamp now;
TimeRequestHandlerFactory() std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
{
} response.setChunkedTransferEncoding(true);
response.setContentType("text/html");
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{ std::ostream& ostr = response.send();
return new TimeRequestHandler; ostr << "<html><head><title>TimeServer powered by POCO ApacheConnector</title>";
} ostr << "<meta http-equiv=\"refresh\" content=\"1\"></head>";
}; ostr << "<body><p style=\"text-align: center; font-size: 48px;\">";
ostr << dt;
ostr << "</p></body></html>";
POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory) }
POCO_EXPORT_CLASS(TimeRequestHandlerFactory) };
POCO_END_MANIFEST
class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory
{
public:
TimeRequestHandlerFactory()
{
}
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
return new TimeRequestHandler;
}
};
POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory)
POCO_EXPORT_CLASS(TimeRequestHandlerFactory)
POCO_END_MANIFEST

View File

@@ -1,57 +1,75 @@
// //
// ApacheApplication.cpp // ApacheApplication.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheApplication.cpp#2 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheApplication.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheApplication.h" //
#include "ApacheChannel.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Logger.h" // the above license grant, this restriction and the following disclaimer,
#include "Poco/SingletonHolder.h" // must be included in all copies of the Software, in whole or in part, and
#include <vector> // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
using Poco::Logger; //
using Poco::FastMutex; // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
ApacheApplication::ApacheApplication(): // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
_ready(false) // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
{ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Logger::root().setChannel(new ApacheChannel); // DEALINGS IN THE SOFTWARE.
} //
ApacheApplication::~ApacheApplication() #include "ApacheApplication.h"
{ #include "ApacheChannel.h"
Logger::shutdown(); #include "Poco/Logger.h"
} #include "Poco/SingletonHolder.h"
#include <vector>
void ApacheApplication::setup()
{ using Poco::Logger;
FastMutex::ScopedLock lock(_mutex); using Poco::FastMutex;
if (!_ready)
{ ApacheApplication::ApacheApplication():
std::vector<std::string> cmdLine; _ready(false)
cmdLine.push_back("mod_poco"); {
init(cmdLine); Logger::root().setChannel(new ApacheChannel);
_ready = true; }
}
}
ApacheApplication::~ApacheApplication()
{
ApacheApplication& ApacheApplication::instance() Logger::shutdown();
{ }
static Poco::SingletonHolder<ApacheApplication> sh;
return *sh.get();
} void ApacheApplication::setup()
{
FastMutex::ScopedLock lock(_mutex);
if (!_ready)
{
std::vector<std::string> cmdLine;
cmdLine.push_back("mod_poco");
init(cmdLine);
_ready = true;
}
}
ApacheApplication& ApacheApplication::instance()
{
static Poco::SingletonHolder<ApacheApplication> sh;
return *sh.get();
}

View File

@@ -1,33 +1,51 @@
// //
// ApacheApplication.cpp // ApacheApplication.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheChannel.cpp#1 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheChannel.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheChannel.h" //
#include "ApacheConnector.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Message.h" // the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
ApacheChannel::ApacheChannel() // works are solely in the form of machine-executable object code generated by
{ // a source language processor.
} //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ApacheChannel::~ApacheChannel() // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
{ // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
} // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
void ApacheChannel::log(const Poco::Message& msg) //
{
ApacheConnector::log(msg.getSource().c_str(), 0, msg.getPriority(), 0, msg.getText().c_str());
} #include "ApacheChannel.h"
#include "ApacheConnector.h"
#include "Poco/Message.h"
ApacheChannel::ApacheChannel()
{
}
ApacheChannel::~ApacheChannel()
{
}
void ApacheChannel::log(const Poco::Message& msg)
{
ApacheConnector::log(msg.getSource().c_str(), 0, msg.getPriority(), 0, msg.getText().c_str());
}

View File

@@ -1,291 +1,309 @@
// //
// ApacheConnector.cpp // ApacheConnector.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheConnector.cpp#6 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheConnector.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheConnector.h" //
#include "ApacheApplication.h" // The copyright notices in the Software and this entire statement, including
#include "ApacheServerRequest.h" // the above license grant, this restriction and the following disclaimer,
#include "ApacheServerResponse.h" // must be included in all copies of the Software, in whole or in part, and
#include "ApacheRequestHandlerFactory.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/Net/HTTPRequestHandler.h" // works are solely in the form of machine-executable object code generated by
#include "httpd.h" // a source language processor.
#include "http_connection.h" //
#include "http_config.h" // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#include "http_core.h" // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#include "http_protocol.h" // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
#include "http_log.h" // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
#include "apr.h" // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
#include "apr_lib.h" // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#include "apr_strings.h" // DEALINGS IN THE SOFTWARE.
#include "apr_buckets.h" //
#include "apr_file_info.h"
#include "apr_hash.h"
#define APR_WANT_STRFUNC #include "ApacheConnector.h"
#include "apr_want.h" #include "ApacheApplication.h"
#include "http_request.h" #include "ApacheServerRequest.h"
#include "util_filter.h" #include "ApacheServerResponse.h"
#include "ApacheRequestHandlerFactory.h"
#include <memory> #include "Poco/Net/HTTPRequestHandler.h"
#include <memory>
using Poco::Net::HTTPServerRequest; #include "httpd.h"
using Poco::Net::HTTPServerResponse; #include "http_connection.h"
using Poco::Net::HTTPRequestHandler; #include "http_config.h"
using Poco::Net::HTTPResponse; #include "http_core.h"
#include "http_protocol.h"
#include "http_log.h"
extern "C" module AP_MODULE_DECLARE_DATA poco_module; #include "apr.h"
#include "apr_lib.h"
#include "apr_strings.h"
ApacheRequestRec::ApacheRequestRec(request_rec* pRec): #include "apr_buckets.h"
_pRec(pRec) #include "apr_file_info.h"
{ #include "apr_hash.h"
} #define APR_WANT_STRFUNC
#include "apr_want.h"
#include "http_request.h"
bool ApacheRequestRec::haveRequestBody() #include "util_filter.h"
{
return ap_should_client_block(_pRec) != 0;
} using Poco::Net::HTTPServerRequest;
using Poco::Net::HTTPServerResponse;
using Poco::Net::HTTPRequestHandler;
int ApacheRequestRec::readRequest(char* buffer, int length) using Poco::Net::HTTPResponse;
{
return ap_get_client_block(_pRec, buffer, length);
} extern "C" module AP_MODULE_DECLARE_DATA poco_module;
void ApacheRequestRec::writeResponse(const char* buffer, int length) ApacheRequestRec::ApacheRequestRec(request_rec* pRec):
{ _pRec(pRec)
ap_rwrite(buffer, length, _pRec); {
} }
void ApacheRequestRec::redirect(const std::string& uri) bool ApacheRequestRec::haveRequestBody()
{ {
apr_table_set(_pRec->headers_out, "Location", uri.c_str()); return ap_should_client_block(_pRec) != 0;
_pRec->connection->keepalive = AP_CONN_CLOSE; }
_pRec->status = 302;
ap_set_keepalive(_pRec);
ap_send_error_response(_pRec, 0); int ApacheRequestRec::readRequest(char* buffer, int length)
} {
return ap_get_client_block(_pRec, buffer, length);
}
void ApacheRequestRec::sendErrorResponse(int status)
{
_pRec->connection->keepalive = AP_CONN_CLOSE; void ApacheRequestRec::writeResponse(const char* buffer, int length)
_pRec->status = status; {
ap_set_keepalive(_pRec); ap_rwrite(buffer, length, _pRec);
}
ap_send_error_response(_pRec, 0);
}
void ApacheRequestRec::redirect(const std::string& uri, int status)
{
void ApacheRequestRec::addHeader(const std::string& key, const std::string& value) apr_table_set(_pRec->headers_out, "Location", uri.c_str());
{ _pRec->connection->keepalive = AP_CONN_CLOSE;
const apr_array_header_t *arr = apr_table_elts(_pRec->headers_out); _pRec->status = status;
apr_table_add(const_cast<apr_table_t*>(reinterpret_cast<const apr_table_t*>(arr)), key.c_str(), value.c_str()); ap_set_keepalive(_pRec);
} ap_send_error_response(_pRec, 0);
}
void ApacheRequestRec::setContentType(const std::string& mediaType)
{ void ApacheRequestRec::sendErrorResponse(int status)
ap_set_content_type(_pRec, mediaType.c_str()); {
} _pRec->connection->keepalive = AP_CONN_CLOSE;
_pRec->status = status;
ap_set_keepalive(_pRec);
int ApacheRequestRec::sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType)
{ ap_send_error_response(_pRec, 0);
apr_file_t *thefile = 0; }
apr_finfo_t finfo;
apr_size_t nBytes;
void ApacheRequestRec::addHeader(const std::string& key, const std::string& value)
// setting content-type {
ap_set_content_type(_pRec, mediaType.c_str()); const apr_array_header_t *arr = apr_table_elts(_pRec->headers_out);
apr_table_add(const_cast<apr_table_t*>(reinterpret_cast<const apr_table_t*>(arr)), key.c_str(), value.c_str());
// opening file }
if (apr_file_open(&thefile, path.c_str(), APR_READ, APR_UREAD | APR_GREAD, _pRec->pool) == APR_SUCCESS)
{
// getting fileinfo void ApacheRequestRec::setContentType(const std::string& mediaType)
apr_file_info_get(&finfo, APR_FINFO_NORM, thefile); {
ap_set_content_type(_pRec, mediaType.c_str());
// setting last-updated & co }
ap_update_mtime(_pRec, finfo.mtime);
ap_set_last_modified(_pRec);
ap_set_content_length(_pRec, fileSize); int ApacheRequestRec::sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType)
{
// sending file apr_file_t *thefile = 0;
ap_send_fd(thefile, _pRec, 0, fileSize, &nBytes); apr_finfo_t finfo;
apr_size_t nBytes;
// well done
return 0; // setting content-type
} ap_set_content_type(_pRec, mediaType.c_str());
// file not opened successfully -> produce an exception in C++ code // opening file
return 1; if (apr_file_open(&thefile, path.c_str(), APR_READ, APR_UREAD | APR_GREAD, _pRec->pool) == APR_SUCCESS)
} {
// getting fileinfo
apr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
void ApacheRequestRec::copyHeaders(ApacheServerRequest& request)
{ // setting last-updated & co
const apr_array_header_t* arr = apr_table_elts(_pRec->headers_in); ap_update_mtime(_pRec, finfo.mtime);
const apr_table_entry_t* elts = (const apr_table_entry_t *)arr->elts; ap_set_last_modified(_pRec);
ap_set_content_length(_pRec, fileSize);
request.setMethod(_pRec->method);
request.setURI(_pRec->unparsed_uri); // sending file
ap_send_fd(thefile, _pRec, 0, fileSize, &nBytes);
// iterating over raw-headers and printing them
for (int i = 0; i < arr->nelts; i++) // well done
{ return 0;
request.add(elts[i].key, elts[i].val); }
}
} // file not opened successfully -> produce an exception in C++ code
return 1;
}
void ApacheConnector::log(const char* file, int line, int level, int status, const char *text)
{
ap_log_error(file, line, level, 0, NULL, text); void ApacheRequestRec::copyHeaders(ApacheServerRequest& request)
} {
const apr_array_header_t* arr = apr_table_elts(_pRec->headers_in);
const apr_table_entry_t* elts = (const apr_table_entry_t *)arr->elts;
extern "C" int ApacheConnector_handler(request_rec *r)
{ request.setMethod(_pRec->method);
ApacheRequestRec rec(r); request.setURI(_pRec->unparsed_uri);
ApacheApplication& app(ApacheApplication::instance());
// iterating over raw-headers and printing them
try for (int i = 0; i < arr->nelts; i++)
{ {
// ensure application is ready request.add(elts[i].key, elts[i].val);
app.setup(); }
}
// if the ApacheRequestHandler declines handling - we stop
// request handling here and let other modules do their job!
if (!app.factory().mustHandle(r->uri)) void ApacheConnector::log(const char* file, int line, int level, int status, const char *text)
return DECLINED; {
ap_log_error(file, line, level, 0, NULL, "%s", text);
apr_status_t rv; }
if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
return rv;
extern "C" int ApacheConnector_handler(request_rec *r)
std::auto_ptr<ApacheServerRequest> pRequest(new ApacheServerRequest( {
&rec, ApacheRequestRec rec(r);
r->connection->local_ip, ApacheApplication& app(ApacheApplication::instance());
r->connection->local_addr->port,
r->connection->remote_ip, try
r->connection->remote_addr->port)); {
// ensure application is ready
std::auto_ptr<ApacheServerResponse> pResponse(new ApacheServerResponse(pRequest.get())); app.setup();
// add header information to request // if the ApacheRequestHandler declines handling - we stop
rec.copyHeaders(*pRequest); // request handling here and let other modules do their job!
if (!app.factory().mustHandle(r->uri))
try return DECLINED;
{
std::auto_ptr<HTTPRequestHandler> pHandler(app.factory().createRequestHandler(*pRequest)); apr_status_t rv;
if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
if (pHandler.get()) return rv;
{
pHandler->handleRequest(*pRequest, *pResponse); std::auto_ptr<ApacheServerRequest> pRequest(new ApacheServerRequest(
} &rec,
else r->connection->local_ip,
{ r->connection->local_addr->port,
pResponse->sendErrorResponse(HTTP_NOT_IMPLEMENTED); r->connection->remote_ip,
} r->connection->remote_addr->port));
}
catch (...) std::auto_ptr<ApacheServerResponse> pResponse(new ApacheServerResponse(pRequest.get()));
{
pResponse->sendErrorResponse(HTTP_INTERNAL_SERVER_ERROR); // add header information to request
throw; rec.copyHeaders(*pRequest);
}
} try
catch (Poco::Exception& exc) {
{ std::auto_ptr<HTTPRequestHandler> pHandler(app.factory().createRequestHandler(*pRequest));
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
} if (pHandler.get())
catch (...) {
{ pHandler->handleRequest(*pRequest, *pResponse);
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception"); }
} else
return OK; {
} pResponse->sendErrorResponse(HTTP_NOT_IMPLEMENTED);
}
}
extern "C" void ApacheConnector_register_hooks(apr_pool_t *p) catch (...)
{ {
ap_hook_handler(ApacheConnector_handler, NULL, NULL, APR_HOOK_MIDDLE); pResponse->sendErrorResponse(HTTP_INTERNAL_SERVER_ERROR);
} throw;
}
}
extern "C" const char* ApacheConnector_uris(cmd_parms *cmd, void *in_dconf, const char *in_str) catch (Poco::Exception& exc)
{ {
try ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
{ }
ApacheApplication::instance().factory().handleURIs(in_str); catch (...)
} {
catch (Poco::Exception& exc) ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
{ }
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str()); return OK;
} }
catch (...)
{
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception"); extern "C" void ApacheConnector_register_hooks(apr_pool_t *p)
} {
return 0; ap_hook_handler(ApacheConnector_handler, NULL, NULL, APR_HOOK_MIDDLE);
} }
extern "C" const char* ApacheConnector_config(cmd_parms *cmd, void *in_dconf, const char *in_str) extern "C" const char* ApacheConnector_uris(cmd_parms *cmd, void *in_dconf, const char *in_str)
{ {
try try
{ {
ApacheApplication::instance().loadConfiguration(in_str); ApacheApplication::instance().factory().handleURIs(in_str);
} }
catch (Poco::Exception& exc) catch (Poco::Exception& exc)
{ {
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str()); ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
} }
catch (...) catch (...)
{ {
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception"); ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
} }
return 0; return 0;
} }
extern "C" const command_rec ApacheConnector_cmds[] = extern "C" const char* ApacheConnector_config(cmd_parms *cmd, void *in_dconf, const char *in_str)
{ {
AP_INIT_RAW_ARGS( try
"AddPocoRequestHandler", {
reinterpret_cast<cmd_func>(ApacheConnector_uris), ApacheApplication::instance().loadConfiguration(in_str);
NULL, }
RSRC_CONF, catch (Poco::Exception& exc)
"POCO RequestHandlerFactory class name followed by shared library path followed by a list of ' ' separated URIs that must be handled by this module."), {
AP_INIT_RAW_ARGS( ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
"AddPocoConfig", }
reinterpret_cast<cmd_func>(ApacheConnector_config), catch (...)
NULL, {
RSRC_CONF, ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
"Path of the POCO configuration file."), }
{ NULL } return 0;
}; }
module AP_MODULE_DECLARE_DATA poco_module = extern "C" const command_rec ApacheConnector_cmds[] =
{ {
STANDARD20_MODULE_STUFF, AP_INIT_RAW_ARGS(
NULL, "AddPocoRequestHandler",
NULL, reinterpret_cast<cmd_func>(ApacheConnector_uris),
NULL, NULL,
NULL, RSRC_CONF,
ApacheConnector_cmds, "POCO RequestHandlerFactory class name followed by shared library path followed by a list of ' ' separated URIs that must be handled by this module."),
ApacheConnector_register_hooks AP_INIT_RAW_ARGS(
}; "AddPocoConfig",
reinterpret_cast<cmd_func>(ApacheConnector_config),
NULL,
RSRC_CONF,
"Path of the POCO configuration file."),
{ NULL }
};
module AP_MODULE_DECLARE_DATA poco_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
ApacheConnector_cmds,
ApacheConnector_register_hooks
};

View File

@@ -1,118 +1,136 @@
// //
// ApacheRequestHandlerFactory.cpp // ApacheRequestHandlerFactory.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheRequestHandlerFactory.cpp#8 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheRequestHandlerFactory.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheRequestHandlerFactory.h" //
#include "ApacheConnector.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Net/HTTPRequestHandler.h" // the above license grant, this restriction and the following disclaimer,
#include "Poco/StringTokenizer.h" // must be included in all copies of the Software, in whole or in part, and
#include "Poco/Manifest.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/File.h" // works are solely in the form of machine-executable object code generated by
#include <vector> // a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
using Poco::StringTokenizer; // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
using Poco::FastMutex; // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ApacheRequestHandlerFactory::ApacheRequestHandlerFactory() // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
{ // DEALINGS IN THE SOFTWARE.
} //
ApacheRequestHandlerFactory::~ApacheRequestHandlerFactory() #include "ApacheRequestHandlerFactory.h"
{ #include "ApacheConnector.h"
} #include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Manifest.h"
Poco::Net::HTTPRequestHandler* ApacheRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) #include "Poco/File.h"
{ #include <vector>
FastMutex::ScopedLock lock(_mutex);
// only if the given uri is found in _uris we are using Poco::StringTokenizer;
// handling this request. using Poco::FastMutex;
RequestHandlerFactories::iterator it = _requestHandlers.begin();
RequestHandlerFactories::iterator itEnd = _requestHandlers.end();
std::string uri = request.getURI(); ApacheRequestHandlerFactory::ApacheRequestHandlerFactory()
{
// if any uri in our map is found at the beginning of the given }
// uri -> then we handle it!!
for (; it != itEnd; it++)
{ ApacheRequestHandlerFactory::~ApacheRequestHandlerFactory()
if (uri.find(it->first) == 0 || it->first.find(uri) == 0) {
{ }
return it->second->createRequestHandler(request);
}
} Poco::Net::HTTPRequestHandler* ApacheRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)
{
return 0; FastMutex::ScopedLock lock(_mutex);
}
// only if the given uri is found in _uris we are
// handling this request.
void ApacheRequestHandlerFactory::handleURIs(const std::string& uris) RequestHandlerFactories::iterator it = _requestHandlers.begin();
{ RequestHandlerFactories::iterator itEnd = _requestHandlers.end();
FastMutex::ScopedLock lock(_mutex); std::string uri = request.getURI();
StringTokenizer st(uris, " ", StringTokenizer::TOK_TRIM); // if any uri in our map is found at the beginning of the given
StringTokenizer::Iterator it = st.begin(); // uri -> then we handle it!!
StringTokenizer::Iterator itEnd = st.end(); for (; it != itEnd; it++)
std::string factoryName = (*it); {
it++; if (uri.find(it->first) == 0 || it->first.find(uri) == 0)
std::string dllName = (*it); {
it++; return it->second->createRequestHandler(request);
}
for (; it != itEnd; it++) }
{
addRequestHandlerFactory(dllName, factoryName, *it); return 0;
} }
}
void ApacheRequestHandlerFactory::handleURIs(const std::string& uris)
void ApacheRequestHandlerFactory::addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri) {
{ FastMutex::ScopedLock lock(_mutex);
try
{ StringTokenizer st(uris, " ", StringTokenizer::TOK_TRIM);
_loader.loadLibrary(dllPath); StringTokenizer::Iterator it = st.begin();
Poco::Net::HTTPRequestHandlerFactory* pFactory = _loader.classFor(factoryName).create(); StringTokenizer::Iterator itEnd = st.end();
_requestHandlers.insert(std::make_pair(uri, pFactory)); std::string factoryName = (*it);
} it++;
catch (Poco::Exception& exc) std::string dllName = (*it);
{ it++;
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
} for (; it != itEnd; it++)
} {
addRequestHandlerFactory(dllName, factoryName, *it);
}
bool ApacheRequestHandlerFactory::mustHandle(const std::string& uri) }
{
FastMutex::ScopedLock lock(_mutex);
void ApacheRequestHandlerFactory::addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri)
// only if the given uri is found in _uris we are {
// handling this request. try
RequestHandlerFactories::iterator it = _requestHandlers.begin(); {
RequestHandlerFactories::iterator itEnd = _requestHandlers.end(); _loader.loadLibrary(dllPath);
Poco::Net::HTTPRequestHandlerFactory* pFactory = _loader.classFor(factoryName).create();
// if any uri in our map is found at the beginning of the given _requestHandlers.insert(std::make_pair(uri, pFactory));
// uri -> then we handle it!! }
for (; it != itEnd; it++) catch (Poco::Exception& exc)
{ {
// dealing with both cases: ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
// handler is registered with: /download }
// uri: /download/xyz }
// uri: /download
if (uri.find(it->first) == 0 || it->first.find(uri) == 0)
return true; bool ApacheRequestHandlerFactory::mustHandle(const std::string& uri)
} {
FastMutex::ScopedLock lock(_mutex);
return false;
} // only if the given uri is found in _uris we are
// handling this request.
RequestHandlerFactories::iterator it = _requestHandlers.begin();
RequestHandlerFactories::iterator itEnd = _requestHandlers.end();
// if any uri in our map is found at the beginning of the given
// uri -> then we handle it!!
for (; it != itEnd; it++)
{
// dealing with both cases:
// handler is registered with: /download
// uri: /download/xyz
// uri: /download
if (uri.find(it->first) == 0 || it->first.find(uri) == 0)
return true;
}
return false;
}

View File

@@ -1,64 +1,82 @@
// //
// ApacheServerRequest.cpp // ApacheServerRequest.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheServerRequest.cpp#9 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheServerRequest.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheServerRequest.h" //
#include "ApacheServerResponse.h" // The copyright notices in the Software and this entire statement, including
#include "ApacheRequestHandlerFactory.h" // the above license grant, this restriction and the following disclaimer,
#include "Poco/Exception.h" // must be included in all copies of the Software, in whole or in part, and
#include <set> // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
ApacheServerRequest::ApacheServerRequest( //
ApacheRequestRec* pApacheRequest, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
const char* serverName, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
int serverPort, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
const char* clientName, // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
int clientPort): // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
_pApacheRequest(pApacheRequest), // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
_pResponse(0), // DEALINGS IN THE SOFTWARE.
_pStream(new ApacheInputStream(_pApacheRequest)), //
_serverAddress(serverName, serverPort),
_clientAddress(clientName, clientPort)
{ #include "ApacheServerRequest.h"
} #include "ApacheServerResponse.h"
#include "ApacheRequestHandlerFactory.h"
#include "Poco/Exception.h"
ApacheServerRequest::~ApacheServerRequest() #include <set>
{
delete _pStream;
} ApacheServerRequest::ApacheServerRequest(
ApacheRequestRec* pApacheRequest,
const char* serverName,
const Poco::Net::HTTPServerParams& ApacheServerRequest::serverParams() const int serverPort,
{ const char* clientName,
throw Poco::NotImplementedException("No HTTPServerParams available in Apache modules."); int clientPort):
} _pApacheRequest(pApacheRequest),
_pResponse(0),
_pStream(new ApacheInputStream(_pApacheRequest)),
Poco::Net::HTTPServerResponse& ApacheServerRequest::response() const _serverAddress(serverName, serverPort),
{ _clientAddress(clientName, clientPort)
return *_pResponse; {
} }
void ApacheServerRequest::setResponse(ApacheServerResponse* pResponse) ApacheServerRequest::~ApacheServerRequest()
{ {
_pResponse = pResponse; delete _pStream;
} }
bool ApacheServerRequest::expectContinue() const const Poco::Net::HTTPServerParams& ApacheServerRequest::serverParams() const
{ {
return false; throw Poco::NotImplementedException("No HTTPServerParams available in Apache modules.");
} }
Poco::Net::HTTPServerResponse& ApacheServerRequest::response() const
{
return *_pResponse;
}
void ApacheServerRequest::setResponse(ApacheServerResponse* pResponse)
{
_pResponse = pResponse;
}
bool ApacheServerRequest::expectContinue() const
{
return false;
}

View File

@@ -1,133 +1,151 @@
// //
// ApacheServerResponse.cpp // ApacheServerResponse.cpp
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheServerResponse.cpp#8 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheServerResponse.cpp#3 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheServerResponse.h" //
#include "ApacheServerRequest.h" // The copyright notices in the Software and this entire statement, including
#include "ApacheStream.h" // the above license grant, this restriction and the following disclaimer,
#include "ApacheConnector.h" // must be included in all copies of the Software, in whole or in part, and
#include "Poco/Net/HTTPCookie.h" // all derivative works of the Software, unless such copies or derivative
#include "Poco/File.h" // works are solely in the form of machine-executable object code generated by
#include "Poco/Exception.h" // a source language processor.
#include <fstream> //
#include <vector> // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
using Poco::File; // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
using Poco::OpenFileException; // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
using Poco::Net::HTTPCookie; // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
ApacheServerResponse::ApacheServerResponse(ApacheServerRequest* pRequest):
_pStream(0),
_pApacheRequest(pRequest->_pApacheRequest) #include "ApacheServerResponse.h"
{ #include "ApacheServerRequest.h"
setVersion(pRequest->getVersion()); #include "ApacheStream.h"
setKeepAlive(pRequest->getKeepAlive()); #include "ApacheConnector.h"
#include "Poco/Net/HTTPCookie.h"
pRequest->setResponse(this); #include "Poco/File.h"
} #include "Poco/Exception.h"
#include <fstream>
#include <vector>
ApacheServerResponse::~ApacheServerResponse()
{
delete _pStream; using Poco::File;
} using Poco::OpenFileException;
using Poco::Net::HTTPCookie;
void ApacheServerResponse::initApacheOutputStream()
{ ApacheServerResponse::ApacheServerResponse(ApacheServerRequest* pRequest):
poco_assert (!_pStream); _pStream(0),
_pApacheRequest(pRequest->_pApacheRequest)
_pApacheRequest->setContentType(getContentType()); {
setVersion(pRequest->getVersion());
std::vector<HTTPCookie> cookies; setKeepAlive(pRequest->getKeepAlive());
getCookies(cookies);
pRequest->setResponse(this);
std::size_t cnt = cookies.size(); }
for (int c = 0; c < cnt; c++)
{
_pApacheRequest->addHeader("Set-Cookie", cookies[c].toString()); ApacheServerResponse::~ApacheServerResponse()
} {
delete _pStream;
_pStream = new ApacheOutputStream(_pApacheRequest); }
}
void ApacheServerResponse::initApacheOutputStream()
void ApacheServerResponse::sendContinue() {
{ poco_assert (!_pStream);
// should be handled by Apache
} _pApacheRequest->setContentType(getContentType());
std::vector<HTTPCookie> cookies;
std::ostream& ApacheServerResponse::send() getCookies(cookies);
{
poco_assert (!_pStream); std::size_t cnt = cookies.size();
for (int c = 0; c < cnt; c++)
initApacheOutputStream(); {
_pApacheRequest->addHeader("Set-Cookie", cookies[c].toString());
return *_pStream; }
}
_pStream = new ApacheOutputStream(_pApacheRequest);
}
void ApacheServerResponse::sendFile(const std::string& path, const std::string& mediaType)
{
poco_assert (!_pStream); void ApacheServerResponse::sendContinue()
{
initApacheOutputStream(); // should be handled by Apache
}
File f(path);
if (_pApacheRequest->sendFile(path, static_cast<unsigned int>(f.getSize()), mediaType) != 0)
throw OpenFileException(path); std::ostream& ApacheServerResponse::send()
} {
poco_assert (!_pStream);
void ApacheServerResponse::sendBuffer(const void* pBuffer, std::size_t length) initApacheOutputStream();
{
poco_assert (!_pStream); return *_pStream;
}
initApacheOutputStream();
_pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length)); void ApacheServerResponse::sendFile(const std::string& path, const std::string& mediaType)
} {
poco_assert (!_pStream);
void ApacheServerResponse::redirect(const std::string& uri) initApacheOutputStream();
{
poco_assert (!_pStream); File f(path);
if (_pApacheRequest->sendFile(path, static_cast<unsigned int>(f.getSize()), mediaType) != 0)
initApacheOutputStream(); throw OpenFileException(path);
}
try
{
_pApacheRequest->redirect(uri); void ApacheServerResponse::sendBuffer(const void* pBuffer, std::size_t length)
} {
catch (Poco::Exception&) poco_assert (!_pStream);
{
ApacheConnector::log(__FILE__, __LINE__, 7 , 0, "caught exception in ApacheServerResponse::redirect - ignoring\n"); initApacheOutputStream();
}
} _pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length));
}
void ApacheServerResponse::sendErrorResponse(int status)
{ void ApacheServerResponse::redirect(const std::string& uri, HTTPStatus status)
initApacheOutputStream(); {
poco_assert (!_pStream);
_pApacheRequest->sendErrorResponse(status);
} initApacheOutputStream();
try
void ApacheServerResponse::requireAuthentication(const std::string& realm) {
{ _pApacheRequest->redirect(uri, status);
// should be handled by Apache }
} catch (Poco::Exception&)
{
ApacheConnector::log(__FILE__, __LINE__, 7 , 0, "caught exception in ApacheServerResponse::redirect - ignoring\n");
}
}
void ApacheServerResponse::sendErrorResponse(int status)
{
initApacheOutputStream();
_pApacheRequest->sendErrorResponse(status);
}
void ApacheServerResponse::requireAuthentication(const std::string& realm)
{
// should be handled by Apache
}

View File

@@ -1,124 +1,142 @@
// //
// ApacheStream.h // ApacheStream.h
// //
// $Id: //poco/Main/ApacheConnector/src/ApacheStream.cpp#9 $ // $Id: //poco/1.4/ApacheConnector/src/ApacheStream.cpp#2 $
// //
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// All rights reserved. // and Contributors.
// //
// This is unpublished proprietary source code of Applied Informatics. // Permission is hereby granted, free of charge, to any person or organization
// The contents of this file may not be disclosed to third parties, // obtaining a copy of the software and accompanying documentation covered by
// copied or duplicated in any form, in whole or in part. // this license (the "Software") to use, reproduce, display, distribute,
// // execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
#include "ApacheStream.h" //
#include "ApacheConnector.h" // The copyright notices in the Software and this entire statement, including
#include "Poco/Exception.h" // the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
using Poco::BufferedStreamBuf; // works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// ApacheStreamBuf // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData): // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out), // DEALINGS IN THE SOFTWARE.
_pApacheRequest(pApacheRequest), //
_haveData(haveData)
{
} #include "ApacheStream.h"
#include "ApacheConnector.h"
#include "Poco/Exception.h"
ApacheStreamBuf::~ApacheStreamBuf()
{
} using Poco::BufferedStreamBuf;
int ApacheStreamBuf::readFromDevice(char* buffer, std::streamsize len) //
{ // ApacheStreamBuf
if (_haveData) //
return _pApacheRequest->readRequest(buffer, static_cast<int>(len));
else
return 0; ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData):
} BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out),
_pApacheRequest(pApacheRequest),
_haveData(haveData)
int ApacheStreamBuf::writeToDevice(const char* buffer, std::streamsize length) {
{ }
_pApacheRequest->writeResponse(buffer, length);
return length;
} ApacheStreamBuf::~ApacheStreamBuf()
{
}
//
// ApacheIOS
// int ApacheStreamBuf::readFromDevice(char* buffer, std::streamsize len)
{
if (_haveData)
ApacheIOS::ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData): return _pApacheRequest->readRequest(buffer, static_cast<int>(len));
_buf(pApacheRequest, haveData) else
{ return 0;
poco_ios_init(&_buf); }
}
int ApacheStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
ApacheIOS::~ApacheIOS() {
{ _pApacheRequest->writeResponse(buffer, length);
try return length;
{ }
_buf.sync();
}
catch (...) //
{ // ApacheIOS
} //
}
ApacheIOS::ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData):
ApacheStreamBuf* ApacheIOS::rdbuf() _buf(pApacheRequest, haveData)
{ {
return &_buf; poco_ios_init(&_buf);
} }
void ApacheIOS::close() ApacheIOS::~ApacheIOS()
{ {
_buf.sync(); try
} {
_buf.sync();
}
// catch (...)
// ApacheOutputStream {
// }
}
ApacheOutputStream::ApacheOutputStream(ApacheRequestRec* pApacheRequest):
ApacheIOS(pApacheRequest), ApacheStreamBuf* ApacheIOS::rdbuf()
std::ostream(&_buf) {
{ return &_buf;
} }
ApacheOutputStream::~ApacheOutputStream() void ApacheIOS::close()
{ {
} _buf.sync();
}
//
// ApacheInputStream //
// // ApacheOutputStream
//
ApacheInputStream::ApacheInputStream(ApacheRequestRec* pApacheRequest):
ApacheIOS(pApacheRequest, pApacheRequest->haveRequestBody()), ApacheOutputStream::ApacheOutputStream(ApacheRequestRec* pApacheRequest):
std::istream(&_buf) ApacheIOS(pApacheRequest),
{ std::ostream(&_buf)
} {
}
ApacheInputStream::~ApacheInputStream()
{ ApacheOutputStream::~ApacheOutputStream()
} {
}
//
// ApacheInputStream
//
ApacheInputStream::ApacheInputStream(ApacheRequestRec* pApacheRequest):
ApacheIOS(pApacheRequest, pApacheRequest->haveRequestBody()),
std::istream(&_buf)
{
}
ApacheInputStream::~ApacheInputStream()
{
}

View File

@@ -17,7 +17,7 @@ SET(PROJECT_VERSION ${COMPLETE_VERSION})
if(NOT MSVC_IDE) if(NOT MSVC_IDE)
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release" FORCE) "Choose the type of build, options are: None Debug Release" FORCE)
endif() endif()
message(STATUS "Setting Poco build type - ${CMAKE_BUILD_TYPE}") message(STATUS "Setting Poco build type - ${CMAKE_BUILD_TYPE}")

View File

@@ -41,7 +41,7 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/err.h> #include <openssl/err.h>
#if SSLEAY_VERSION_NUMBER >= 0x0907000L #if OPENSSL_VERSION_NUMBER >= 0x0907000L
#include <openssl/conf.h> #include <openssl/conf.h>
#endif #endif
@@ -61,7 +61,7 @@ int OpenSSLInitializer::_rc(0);
OpenSSLInitializer::OpenSSLInitializer() OpenSSLInitializer::OpenSSLInitializer()
{ {
initialize(); initialize();
} }

View File

@@ -16,7 +16,7 @@ objects = Binder Extractor SessionImpl Connector \
MySQLStatementImpl ResultMetadata MySQLException \ MySQLStatementImpl ResultMetadata MySQLException \
SessionHandle StatementExecutor SessionHandle StatementExecutor
target = PocoMySQL target = PocoDataMySQL
target_version = $(LIBVERSION) target_version = $(LIBVERSION)
target_libs = PocoData PocoFoundation target_libs = PocoData PocoFoundation

View File

@@ -44,7 +44,7 @@ objects = Binder ConnectionHandle Connector EnvironmentHandle \
Extractor ODBCMetaColumn ODBCException ODBCStatementImpl \ Extractor ODBCMetaColumn ODBCException ODBCStatementImpl \
Parameter Preparator SessionImpl TypeInfo Unicode Utility Parameter Preparator SessionImpl TypeInfo Unicode Utility
target = PocoODBC target = PocoDataODBC
target_version = $(LIBVERSION) target_version = $(LIBVERSION)
target_libs = PocoData PocoFoundation target_libs = PocoData PocoFoundation

View File

@@ -17,7 +17,7 @@ objects = Binder Extractor SessionImpl Connector \
SQLiteException SQLiteStatementImpl Utility \ SQLiteException SQLiteStatementImpl Utility \
sqlite3 sqlite3
target = PocoSQLite target = PocoDataSQLite
target_version = $(LIBVERSION) target_version = $(LIBVERSION)
target_libs = PocoData PocoFoundation target_libs = PocoData PocoFoundation

View File

@@ -60,6 +60,10 @@
// #define POCO_NO_SHAREDMEMORY // #define POCO_NO_SHAREDMEMORY
// Define if no <locale> header is available (such as on WinCE)
// #define POCO_NO_LOCALE
// Define to desired default thread stack size // Define to desired default thread stack size
// Zero means OS default // Zero means OS default
#ifndef POCO_THREAD_STACK_SIZE #ifndef POCO_THREAD_STACK_SIZE

View File

@@ -52,12 +52,13 @@ public:
typedef UInt8 NodeId[6]; /// Ethernet address. typedef UInt8 NodeId[6]; /// Ethernet address.
static std::string getImpl(const std::string& name); static std::string getImpl(const std::string& name);
static bool hasImpl(const std::string& name); static bool hasImpl(const std::string& name);
static void setImpl(const std::string& name, const std::string& value); static void setImpl(const std::string& name, const std::string& value);
static std::string osNameImpl(); static std::string osNameImpl();
static std::string osVersionImpl(); static std::string osDisplayNameImpl();
static std::string osArchitectureImpl(); static std::string osVersionImpl();
static std::string nodeNameImpl(); static std::string osArchitectureImpl();
static std::string nodeNameImpl();
static void nodeIdImpl(NodeId& id); static void nodeIdImpl(NodeId& id);
static unsigned processorCountImpl(); static unsigned processorCountImpl();

View File

@@ -59,20 +59,20 @@ std::string Foundation_API format(const std::string& fmt, const Any& value);
/// ///
/// The format string can consist of any sequence of characters; certain /// The format string can consist of any sequence of characters; certain
/// characters have a special meaning. Characters without a special meaning /// characters have a special meaning. Characters without a special meaning
/// are copied verbatim to the result. A percent sign (%) marks the beginning /// are copied verbatim to the result. A percent sign (%) marks the beginning
/// of a format specification. Format specifications have the following syntax: /// of a format specification. Format specifications have the following syntax:
/// ///
/// %[<index>][<flags>][<width>][.<precision>][<modifier>]<type> /// %[<index>][<flags>][<width>][.<precision>][<modifier>]<type>
/// ///
/// Index, flags, width, precision and prefix are optional. The only required part of /// Index, flags, width, precision and prefix are optional. The only required part of
/// the format specification, apart from the percent sign, is the type. /// the format specification, apart from the percent sign, is the type.
/// ///
/// The optional index argument has the format "[<n>]" and allows to /// The optional index argument has the format "[<n>]" and allows to
/// address an argument by its zero-based position (see the example below). /// address an argument by its zero-based position (see the example below).
/// ///
/// Following are valid type specifications and their meaning: /// Following are valid type specifications and their meaning:
/// ///
/// * b boolean (true = 1, false = 0) /// * b boolean (true = 1, false = 0)
/// * c character /// * c character
/// * d signed decimal integer /// * d signed decimal integer
/// * i signed decimal integer /// * i signed decimal integer
@@ -86,13 +86,13 @@ std::string Foundation_API format(const std::string& fmt, const Any& value);
/// * s std::string /// * s std::string
/// * z std::size_t /// * z std::size_t
/// ///
/// The following flags are supported: /// The following flags are supported:
/// ///
/// * - left align the result within the given field width /// * - left align the result within the given field width
/// * + prefix the output value with a sign (+ or -) if the output value is of a signed type /// * + prefix the output value with a sign (+ or -) if the output value is of a signed type
/// * 0 if width is prefixed with 0, zeros are added until the minimum width is reached /// * 0 if width is prefixed with 0, zeros are added until the minimum width is reached
/// * # For o, x, X, the # flag prefixes any nonzero output value with 0, 0x, or 0X, respectively; /// * # For o, x, X, the # flag prefixes any nonzero output value with 0, 0x, or 0X, respectively;
/// for e, E, f, the # flag forces the output value to contain a decimal point in all cases. /// for e, E, f, the # flag forces the output value to contain a decimal point in all cases.
/// ///
/// The following modifiers are supported: /// The following modifiers are supported:
/// ///
@@ -106,20 +106,23 @@ std::string Foundation_API format(const std::string& fmt, const Any& value);
/// If the number of characters in the output value is less than the specified width, blanks or /// If the number of characters in the output value is less than the specified width, blanks or
/// leading zeros are added, according to the specified flags (-, +, 0). /// leading zeros are added, according to the specified flags (-, +, 0).
/// ///
/// Precision is a nonnegative decimal integer, preceded by a period (.), which specifies the number of characters /// Precision is a nonnegative decimal integer, preceded by a period (.), which specifies the number of characters
/// to be printed, the number of decimal places, or the number of significant digits. /// to be printed, the number of decimal places, or the number of significant digits.
/// ///
/// Throws a BadCastException if an argument does not correspond to the type of its format specification.
/// Throws an InvalidArgumentException if an argument index is out of range. /// Throws an InvalidArgumentException if an argument index is out of range.
///
/// Starting with release 1.4.3, an argument that does not match the format
/// specifier no longer results in a BadCastException. The string [ERRFMT] is
/// written to the result string instead.
/// ///
/// If there are more format specifiers than values, the format specifiers without a corresponding value /// If there are more format specifiers than values, the format specifiers without a corresponding value
/// are copied verbatim to output. /// are copied verbatim to output.
/// ///
/// If there are more values than format specifiers, the superfluous values are ignored. /// If there are more values than format specifiers, the superfluous values are ignored.
/// ///
/// Usage Examples: /// Usage Examples:
/// std::string s1 = format("The answer to life, the universe, and everything is %d", 42); /// std::string s1 = format("The answer to life, the universe, and everything is %d", 42);
/// std::string s2 = format("second: %[1]d, first: %[0]d", 1, 2); /// std::string s2 = format("second: %[1]d, first: %[0]d", 1, 2);
std::string Foundation_API format(const std::string& fmt, const Any& value1, const Any& value2); std::string Foundation_API format(const std::string& fmt, const Any& value1, const Any& value2);
std::string Foundation_API format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3); std::string Foundation_API format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3);

View File

@@ -337,16 +337,16 @@ public:
static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3); static std::string format(const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2, const std::string& arg3);
/// Replaces all occurences of $<n> in fmt with the string given in arg<n> and /// Replaces all occurences of $<n> in fmt with the string given in arg<n> and
/// returns the result. To include a dollar sign in the result string, /// returns the result. To include a dollar sign in the result string,
/// specify two dollar signs ($$) in the format string. /// specify two dollar signs ($$) in the format string.
static void formatDump(std::string& message, const void* buffer, std::size_t length); static void formatDump(std::string& message, const void* buffer, std::size_t length);
/// Creates a hex-dump of the given buffer and appends it to the /// Creates a hex-dump of the given buffer and appends it to the
/// given message string. /// given message string.
static void setLevel(const std::string& name, int level); static void setLevel(const std::string& name, int level);
/// Sets the given log level on all loggers that are /// Sets the given log level on all loggers that are
/// descendants of the Logger with the given name. /// descendants of the Logger with the given name.
static void setChannel(const std::string& name, Channel* pChannel); static void setChannel(const std::string& name, Channel* pChannel);
/// Attaches the given Channel to all loggers that are /// Attaches the given Channel to all loggers that are
@@ -396,11 +396,28 @@ public:
/// Loggers. /// Loggers.
static void names(std::vector<std::string>& names); static void names(std::vector<std::string>& names);
/// Fills the given vector with the names /// Fills the given vector with the names
/// of all currently defined loggers. /// of all currently defined loggers.
static const std::string ROOT; /// The name of the root logger (""). static int parseLevel(const std::string& level);
/// Parses a symbolic log level from a string and
/// returns the resulting numeric level.
///
/// Valid symbolic levels are:
/// - none (turns off logging)
/// - fatal
/// - critical
/// - error
/// - warning
/// - notice
/// - information
/// - debug
/// - trace
///
/// The level is not case sensitive.
static const std::string ROOT; /// The name of the root logger ("").
protected: protected:
typedef std::map<std::string, Logger*> LoggerMap; typedef std::map<std::string, Logger*> LoggerMap;
@@ -408,12 +425,12 @@ protected:
~Logger(); ~Logger();
void log(const std::string& text, Message::Priority prio); void log(const std::string& text, Message::Priority prio);
void log(const std::string& text, Message::Priority prio, const char* file, int line); void log(const std::string& text, Message::Priority prio, const char* file, int line);
static std::string format(const std::string& fmt, int argc, std::string argv[]); static std::string format(const std::string& fmt, int argc, std::string argv[]);
static Logger& parent(const std::string& name); static Logger& parent(const std::string& name);
static void add(Logger* pLogger); static void add(Logger* pLogger);
static Logger* find(const std::string& name); static Logger* find(const std::string& name);
private: private:
Logger(); Logger();

View File

@@ -151,12 +151,18 @@ public:
/// int rc = ph.wait(); /// int rc = ph.wait();
static int wait(const ProcessHandle& handle); static int wait(const ProcessHandle& handle);
/// Waits for the process specified by handle to terminate /// Waits for the process specified by handle to terminate
/// and returns the exit code of the process. /// and returns the exit code of the process.
static void kill(PID pid); static void kill(const ProcessHandle& handle);
/// Kills the process with the given pid. /// Kills the process specified by handle.
///
/// This is preferable on Windows where process IDs
/// may be reused.
static void kill(PID pid);
/// Kills the process with the given pid.
static void requestTermination(PID pid); static void requestTermination(PID pid);
/// Requests termination of the process with the give PID. /// Requests termination of the process with the give PID.
/// ///

View File

@@ -72,11 +72,12 @@ public:
typedef pid_t PIDImpl; typedef pid_t PIDImpl;
typedef std::vector<std::string> ArgsImpl; typedef std::vector<std::string> ArgsImpl;
static PIDImpl idImpl(); static PIDImpl idImpl();
static void timesImpl(long& userTime, long& kernelTime); static void timesImpl(long& userTime, long& kernelTime);
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe); static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
static void killImpl(PIDImpl pid); static void killImpl(const ProcessHandleImpl& handle);
static void requestTerminationImpl(PIDImpl pid); static void killImpl(PIDImpl pid);
static void requestTerminationImpl(PIDImpl pid);
}; };

View File

@@ -74,11 +74,12 @@ public:
typedef int PIDImpl; typedef int PIDImpl;
typedef std::vector<std::string> ArgsImpl; typedef std::vector<std::string> ArgsImpl;
static PIDImpl idImpl(); static PIDImpl idImpl();
static void timesImpl(long& userTime, long& kernelTime); static void timesImpl(long& userTime, long& kernelTime);
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe); static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
static void killImpl(PIDImpl pid); static void killImpl(const ProcessHandleImpl& handle);
static void requestTerminationImpl(PIDImpl pid); static void killImpl(PIDImpl pid);
static void requestTerminationImpl(PIDImpl pid);
}; };

View File

@@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
{ {
public: public:
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
~ProcessHandleImpl(); ~ProcessHandleImpl();
UInt32 id() const; UInt32 id() const;
int wait() const; HANDLE process() const;
int wait() const;
private: private:
HANDLE _hProcess; HANDLE _hProcess;
UInt32 _pid; UInt32 _pid;
@@ -76,12 +77,13 @@ public:
typedef UInt32 PIDImpl; typedef UInt32 PIDImpl;
typedef std::vector<std::string> ArgsImpl; typedef std::vector<std::string> ArgsImpl;
static PIDImpl idImpl(); static PIDImpl idImpl();
static void timesImpl(long& userTime, long& kernelTime); static void timesImpl(long& userTime, long& kernelTime);
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe); static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
static void killImpl(PIDImpl pid); static void killImpl(const ProcessHandleImpl& handle);
static void requestTerminationImpl(PIDImpl pid); static void killImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid); static void requestTerminationImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid);
}; };

View File

@@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
{ {
public: public:
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
~ProcessHandleImpl(); ~ProcessHandleImpl();
UInt32 id() const; UInt32 id() const;
int wait() const; HANDLE process() const;
int wait() const;
private: private:
HANDLE _hProcess; HANDLE _hProcess;
UInt32 _pid; UInt32 _pid;
@@ -76,12 +77,13 @@ public:
typedef UInt32 PIDImpl; typedef UInt32 PIDImpl;
typedef std::vector<std::string> ArgsImpl; typedef std::vector<std::string> ArgsImpl;
static PIDImpl idImpl(); static PIDImpl idImpl();
static void timesImpl(long& userTime, long& kernelTime); static void timesImpl(long& userTime, long& kernelTime);
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe); static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
static void killImpl(PIDImpl pid); static void killImpl(const ProcessHandleImpl& handle);
static void requestTerminationImpl(PIDImpl pid); static void killImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid); static void requestTerminationImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid);
}; };

View File

@@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
{ {
public: public:
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
~ProcessHandleImpl(); ~ProcessHandleImpl();
UInt32 id() const; UInt32 id() const;
int wait() const; HANDLE process() const;
int wait() const;
private: private:
HANDLE _hProcess; HANDLE _hProcess;
UInt32 _pid; UInt32 _pid;
@@ -76,12 +77,13 @@ public:
typedef UInt32 PIDImpl; typedef UInt32 PIDImpl;
typedef std::vector<std::string> ArgsImpl; typedef std::vector<std::string> ArgsImpl;
static PIDImpl idImpl(); static PIDImpl idImpl();
static void timesImpl(long& userTime, long& kernelTime); static void timesImpl(long& userTime, long& kernelTime);
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe); static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
static void killImpl(PIDImpl pid); static void killImpl(const ProcessHandleImpl& handle);
static void requestTerminationImpl(PIDImpl pid); static void killImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid); static void requestTerminationImpl(PIDImpl pid);
static std::string terminationEventName(PIDImpl pid);
}; };

View File

@@ -48,20 +48,27 @@ namespace Poco {
template <class M> template <class M>
class ScopedLock class ScopedLock
/// A class that simplifies thread synchronization /// A class that simplifies thread synchronization
/// with a mutex. /// with a mutex.
/// The constructor accepts a Mutex and locks it. /// The constructor accepts a Mutex (and optionally
/// The destructor unlocks the mutex. /// a timeout value in milliseconds) and locks it.
/// The destructor unlocks the mutex.
{ {
public: public:
inline ScopedLock(M& mutex): _mutex(mutex) explicit ScopedLock(M& mutex): _mutex(mutex)
{ {
_mutex.lock(); _mutex.lock();
} }
inline ~ScopedLock()
{ ScopedLock(M& mutex, long milliseconds): _mutex(mutex)
_mutex.unlock(); {
} _mutex.lock(milliseconds);
}
~ScopedLock()
{
_mutex.unlock();
}
private: private:
M& _mutex; M& _mutex;
@@ -74,22 +81,28 @@ private:
template <class M> template <class M>
class ScopedLockWithUnlock class ScopedLockWithUnlock
/// A class that simplifies thread synchronization /// A class that simplifies thread synchronization
/// with a mutex. /// with a mutex.
/// The constructor accepts a Mutex and locks it. /// The constructor accepts a Mutex (and optionally
/// The destructor unlocks the mutex. /// a timeout value in milliseconds) and locks it.
/// The unlock() member function allows for manual /// The destructor unlocks the mutex.
/// unlocking of the mutex. /// The unlock() member function allows for manual
/// unlocking of the mutex.
{ {
public: public:
ScopedLockWithUnlock(M& mutex): _pMutex(&mutex) explicit ScopedLockWithUnlock(M& mutex): _pMutex(&mutex)
{ {
_pMutex->lock(); _pMutex->lock();
} }
~ScopedLockWithUnlock() ScopedLockWithUnlock(M& mutex, long milliseconds): _pMutex(&mutex)
{ {
unlock(); _pMutex->lock(milliseconds);
}
~ScopedLockWithUnlock()
{
unlock();
} }
void unlock() void unlock()

View File

@@ -360,9 +360,11 @@ typedef uLong FAR uLongf;
# define Z_HAVE_UNISTD_H # define Z_HAVE_UNISTD_H
#endif #endif
#ifndef _WIN32_WCE
#ifdef STDC #ifdef STDC
# include <sys/types.h> /* for off_t */ # include <sys/types.h> /* for off_t */
#endif #endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even

View File

@@ -38,7 +38,9 @@
#include "Poco/Exception.h" #include "Poco/Exception.h"
#include "Poco/Ascii.h" #include "Poco/Ascii.h"
#include <sstream> #include <sstream>
#if !defined(POCO_NO_LOCALE)
#include <locale> #include <locale>
#endif
#include <cstddef> #include <cstddef>
@@ -167,72 +169,81 @@ namespace
void formatOne(std::string& result, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal) void formatOne(std::string& result, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
{ {
std::ostringstream str; std::ostringstream str;
#if !defined(POCO_NO_LOCALE)
str.imbue(std::locale::classic()); str.imbue(std::locale::classic());
parseFlags(str, itFmt, endFmt); #endif
parseWidth(str, itFmt, endFmt); try
parsePrec(str, itFmt, endFmt); {
char mod = parseMod(itFmt, endFmt); parseFlags(str, itFmt, endFmt);
if (itFmt != endFmt) parseWidth(str, itFmt, endFmt);
{ parsePrec(str, itFmt, endFmt);
char type = *itFmt++; char mod = parseMod(itFmt, endFmt);
prepareFormat(str, type); if (itFmt != endFmt)
switch (type)
{ {
case 'b': char type = *itFmt++;
str << AnyCast<bool>(*itVal++); prepareFormat(str, type);
break; switch (type)
case 'c':
str << AnyCast<char>(*itVal++);
break;
case 'd':
case 'i':
switch (mod)
{ {
case 'l': str << AnyCast<long>(*itVal++); break; case 'b':
case 'L': str << AnyCast<Int64>(*itVal++); break; str << AnyCast<bool>(*itVal++);
case 'h': str << AnyCast<short>(*itVal++); break; break;
case '?': writeAnyInt(str, *itVal++); break; case 'c':
default: str << AnyCast<int>(*itVal++); break; str << AnyCast<char>(*itVal++);
} break;
break; case 'd':
case 'o': case 'i':
case 'u': switch (mod)
case 'x': {
case 'X': case 'l': str << AnyCast<long>(*itVal++); break;
switch (mod) case 'L': str << AnyCast<Int64>(*itVal++); break;
{ case 'h': str << AnyCast<short>(*itVal++); break;
case 'l': str << AnyCast<unsigned long>(*itVal++); break; case '?': writeAnyInt(str, *itVal++); break;
case 'L': str << AnyCast<UInt64>(*itVal++); break; default: str << AnyCast<int>(*itVal++); break;
case 'h': str << AnyCast<unsigned short>(*itVal++); break; }
case '?': writeAnyInt(str, *itVal++); break; break;
default: str << AnyCast<unsigned>(*itVal++); break; case 'o':
} case 'u':
break; case 'x':
case 'e': case 'X':
case 'E': switch (mod)
case 'f': {
switch (mod) case 'l': str << AnyCast<unsigned long>(*itVal++); break;
{ case 'L': str << AnyCast<UInt64>(*itVal++); break;
case 'l': str << AnyCast<long double>(*itVal++); break; case 'h': str << AnyCast<unsigned short>(*itVal++); break;
case 'L': str << AnyCast<long double>(*itVal++); break; case '?': writeAnyInt(str, *itVal++); break;
case 'h': str << AnyCast<float>(*itVal++); break; default: str << AnyCast<unsigned>(*itVal++); break;
default: str << AnyCast<double>(*itVal++); break; }
} break;
break; case 'e':
case 's': case 'E':
str << RefAnyCast<std::string>(*itVal++); case 'f':
break; switch (mod)
case 'z': {
str << AnyCast<std::size_t>(*itVal++); case 'l': str << AnyCast<long double>(*itVal++); break;
break; case 'L': str << AnyCast<long double>(*itVal++); break;
case 'I': case 'h': str << AnyCast<float>(*itVal++); break;
case 'D': default: str << AnyCast<double>(*itVal++); break;
default: }
str << type; break;
} case 's':
} str << RefAnyCast<std::string>(*itVal++);
result.append(str.str()); break;
} case 'z':
str << AnyCast<std::size_t>(*itVal++);
break;
case 'I':
case 'D':
default:
str << type;
}
}
}
catch (Poco::BadCastException&)
{
str << "[ERRFMT]";
}
result.append(str.str());
}
} }

View File

@@ -39,6 +39,7 @@
#include "Poco/LoggingRegistry.h" #include "Poco/LoggingRegistry.h"
#include "Poco/Exception.h" #include "Poco/Exception.h"
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
#include "Poco/String.h"
namespace Poco { namespace Poco {
@@ -83,26 +84,7 @@ void Logger::setLevel(int level)
void Logger::setLevel(const std::string& level) void Logger::setLevel(const std::string& level)
{ {
if (level == "none") setLevel(parseLevel(level));
setLevel(0);
else if (level == "fatal")
setLevel(Message::PRIO_FATAL);
else if (level == "critical")
setLevel(Message::PRIO_CRITICAL);
else if (level == "error")
setLevel(Message::PRIO_ERROR);
else if (level == "warning")
setLevel(Message::PRIO_WARNING);
else if (level == "notice")
setLevel(Message::PRIO_NOTICE);
else if (level == "information")
setLevel(Message::PRIO_INFORMATION);
else if (level == "debug")
setLevel(Message::PRIO_DEBUG);
else if (level == "trace")
setLevel(Message::PRIO_TRACE);
else
throw InvalidArgumentException("Not a valid log level", level);
} }
@@ -449,6 +431,31 @@ Logger& Logger::parent(const std::string& name)
} }
int Logger::parseLevel(const std::string& level)
{
if (icompare(level, "none") == 0)
return 0;
else if (icompare(level, "fatal") == 0)
return Message::PRIO_FATAL;
else if (icompare(level, "critical") == 0)
return Message::PRIO_CRITICAL;
else if (icompare(level, "error") == 0)
return Message::PRIO_ERROR;
else if (icompare(level, "warning") == 0)
return Message::PRIO_WARNING;
else if (icompare(level, "notice") == 0)
return Message::PRIO_NOTICE;
else if (icompare(level, "information") == 0)
return Message::PRIO_INFORMATION;
else if (icompare(level, "debug") == 0)
return Message::PRIO_DEBUG;
else if (icompare(level, "trace") == 0)
return Message::PRIO_TRACE;
else
throw InvalidArgumentException("Not a valid log level", level);
}
class AutoLoggerShutdown class AutoLoggerShutdown
{ {
public: public:

View File

@@ -37,7 +37,9 @@
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
#include "Poco/MemoryStream.h" #include "Poco/MemoryStream.h"
#include <iomanip> #include <iomanip>
#if !defined(POCO_NO_LOCALE)
#include <locale> #include <locale>
#endif
#include <cstdio> #include <cstdio>
#include <cctype> #include <cctype>
@@ -361,9 +363,11 @@ void NumberFormatter::append(std::string& str, float value)
{ {
char buffer[64]; char buffer[64];
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer)); Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
#if !defined(POCO_NO_LOCALE)
ostr.imbue(std::locale::classic()); ostr.imbue(std::locale::classic());
#endif
ostr << std::setprecision(8) << value; ostr << std::setprecision(8) << value;
str.append(buffer, ostr.charsWritten()); str.append(buffer, static_cast<std::string::size_type>(ostr.charsWritten()));
} }
@@ -371,33 +375,39 @@ void NumberFormatter::append(std::string& str, double value)
{ {
char buffer[64]; char buffer[64];
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer)); Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
#if !defined(POCO_NO_LOCALE)
ostr.imbue(std::locale::classic()); ostr.imbue(std::locale::classic());
#endif
ostr << std::setprecision(16) << value; ostr << std::setprecision(16) << value;
str.append(buffer, ostr.charsWritten()); str.append(buffer, static_cast<std::string::size_type>(ostr.charsWritten()));
} }
void NumberFormatter::append(std::string& str, double value, int precision) void NumberFormatter::append(std::string& str, double value, int precision)
{ {
poco_assert (precision >= 0 && precision < 32); poco_assert (precision >= 0 && precision < 32);
char buffer[64]; char buffer[64];
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer)); Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
#if !defined(POCO_NO_LOCALE)
ostr.imbue(std::locale::classic()); ostr.imbue(std::locale::classic());
#endif
ostr << std::fixed << std::showpoint << std::setprecision(precision) << value; ostr << std::fixed << std::showpoint << std::setprecision(precision) << value;
str.append(buffer, ostr.charsWritten()); str.append(buffer, static_cast<std::string::size_type>(ostr.charsWritten()));
} }
void NumberFormatter::append(std::string& str, double value, int width, int precision) void NumberFormatter::append(std::string& str, double value, int width, int precision)
{ {
poco_assert (width > 0 && width < 64 && precision >= 0 && precision < width); poco_assert (width > 0 && width < 64 && precision >= 0 && precision < width);
char buffer[64]; char buffer[64];
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer)); Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
#if !defined(POCO_NO_LOCALE)
ostr.imbue(std::locale::classic()); ostr.imbue(std::locale::classic());
#endif
ostr << std::fixed << std::showpoint << std::setw(width) << std::setprecision(precision) << value; ostr << std::fixed << std::showpoint << std::setw(width) << std::setprecision(precision) << value;
str.append(buffer, ostr.charsWritten()); str.append(buffer, static_cast<std::string::size_type>(ostr.charsWritten()));
} }

View File

@@ -1,7 +1,7 @@
// //
// NumberParser.cpp // NumberParser.cpp
// //
// $Id: //poco/svn/Foundation/src/NumberParser.cpp#2 $ // $Id: //poco/1.4/Foundation/src/NumberParser.cpp#4 $
// //
// Library: Foundation // Library: Foundation
// Package: Core // Package: Core
@@ -38,15 +38,19 @@
#include "Poco/Exception.h" #include "Poco/Exception.h"
#include "Poco/MemoryStream.h" #include "Poco/MemoryStream.h"
#include "Poco/String.h" #include "Poco/String.h"
#ifdef POCO_LOCALE
#include <locale> #include <locale>
#endif
#include <cstdio> #include <cstdio>
#include <cctype> #include <cctype>
#if defined(_MSC_VER) #if defined(POCO_LONG_IS_64_BIT)
#define I64_FMT "I64" #define I64_FMT "l"
#elif defined(_MSC_VER)
#define I64_FMT "I64"
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define I64_FMT "q" #define I64_FMT "q"
#else #else
#define I64_FMT "ll" #define I64_FMT "ll"
#endif #endif
@@ -175,10 +179,12 @@ double NumberParser::parseFloat(const std::string& s)
bool NumberParser::tryParseFloat(const std::string& s, double& value) bool NumberParser::tryParseFloat(const std::string& s, double& value)
{ {
Poco::MemoryInputStream istr(s.data(), s.size()); Poco::MemoryInputStream istr(s.data(), s.size());
istr.imbue(std::locale::classic()); #if !defined(POCO_NO_LOCALE)
istr >> value; istr.imbue(std::locale::classic());
return istr.eof() && !istr.fail(); #endif
istr >> value;
return istr.eof() && !istr.fail();
} }

View File

@@ -127,9 +127,15 @@ int Process::wait(const ProcessHandle& handle)
} }
void Process::kill(const ProcessHandle& handle)
{
killImpl(*handle._pImpl);
}
void Process::kill(PID pid) void Process::kill(PID pid)
{ {
killImpl(pid); killImpl(pid);
} }

View File

@@ -169,9 +169,15 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
} }
void ProcessImpl::killImpl(const ProcessHandleImpl& handle)
{
killImpl(handle.id());
}
void ProcessImpl::killImpl(PIDImpl pid) void ProcessImpl::killImpl(PIDImpl pid)
{ {
if (kill(pid, SIGKILL) != 0) if (kill(pid, SIGKILL) != 0)
{ {
switch (errno) switch (errno)
{ {

View File

@@ -125,9 +125,15 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
} }
void ProcessImpl::killImpl(const ProcessHandleImpl& handle)
{
killImpl(handle.id());
}
void ProcessImpl::killImpl(PIDImpl pid) void ProcessImpl::killImpl(PIDImpl pid)
{ {
if (kill(pid, SIGKILL) != 0) if (kill(pid, SIGKILL) != 0)
{ {
switch (errno) switch (errno)
{ {

View File

@@ -89,9 +89,15 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
} }
void ProcessImpl::killImpl(const ProcessHandleImpl& handle)
{
throw Poco::NotImplementedException("Process::kill()");
}
void ProcessImpl::killImpl(PIDImpl pid) void ProcessImpl::killImpl(PIDImpl pid)
{ {
throw Poco::NotImplementedException("Process::kill()"); throw Poco::NotImplementedException("Process::kill()");
} }

View File

@@ -66,9 +66,15 @@ UInt32 ProcessHandleImpl::id() const
} }
HANDLE ProcessHandleImpl::process() const
{
return _hProcess;
}
int ProcessHandleImpl::wait() const int ProcessHandleImpl::wait() const
{ {
DWORD rc = WaitForSingleObject(_hProcess, INFINITE); DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
if (rc != WAIT_OBJECT_0) if (rc != WAIT_OBJECT_0)
throw SystemException("Wait failed for process", NumberFormatter::format(_pid)); throw SystemException("Wait failed for process", NumberFormatter::format(_pid));
@@ -176,9 +182,20 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
} }
void ProcessImpl::killImpl(const ProcessHandleImpl& handle)
{
if (TerminateProcess(handle.process(), 0) == 0)
{
CloseHandle(handle.process());
throw SystemException("cannot kill process");
}
CloseHandle(handle.process());
}
void ProcessImpl::killImpl(PIDImpl pid) void ProcessImpl::killImpl(PIDImpl pid)
{ {
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid); HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProc) if (hProc)
{ {
if (TerminateProcess(hProc, 0) == 0) if (TerminateProcess(hProc, 0) == 0)

View File

@@ -67,9 +67,15 @@ UInt32 ProcessHandleImpl::id() const
} }
HANDLE ProcessHandleImpl::process() const
{
return _hProcess;
}
int ProcessHandleImpl::wait() const int ProcessHandleImpl::wait() const
{ {
DWORD rc = WaitForSingleObject(_hProcess, INFINITE); DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
if (rc != WAIT_OBJECT_0) if (rc != WAIT_OBJECT_0)
throw SystemException("Wait failed for process", NumberFormatter::format(_pid)); throw SystemException("Wait failed for process", NumberFormatter::format(_pid));
@@ -180,9 +186,20 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
} }
void ProcessImpl::killImpl(const ProcessHandleImpl& handle)
{
if (TerminateProcess(handle.process(), 0) == 0)
{
CloseHandle(handle.process());
throw SystemException("cannot kill process");
}
CloseHandle(handle.process());
}
void ProcessImpl::killImpl(PIDImpl pid) void ProcessImpl::killImpl(PIDImpl pid)
{ {
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid); HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProc) if (hProc)
{ {
if (TerminateProcess(hProc, 0) == 0) if (TerminateProcess(hProc, 0) == 0)

View File

@@ -360,9 +360,11 @@ typedef uLong FAR uLongf;
# define Z_HAVE_UNISTD_H # define Z_HAVE_UNISTD_H
#endif #endif
#ifndef _WIN32_WCE
#ifdef STDC #ifdef STDC
# include <sys/types.h> /* for off_t */ # include <sys/types.h> /* for off_t */
#endif #endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even

View File

@@ -20,7 +20,8 @@ objects = \
HTTPFixedLengthStream HTTPServerRequest HTTPServerRequestImpl MultipartWriter StreamSocketImpl \ HTTPFixedLengthStream HTTPServerRequest HTTPServerRequestImpl MultipartWriter StreamSocketImpl \
HTTPHeaderStream HTTPServerResponse HTTPServerResponseImpl NameValueCollection TCPServer \ HTTPHeaderStream HTTPServerResponse HTTPServerResponseImpl NameValueCollection TCPServer \
HTTPMessage HTTPServerSession NetException TCPServerConnection HTTPBufferAllocator \ HTTPMessage HTTPServerSession NetException TCPServerConnection HTTPBufferAllocator \
HTTPRequest HTTPSession HTTPSessionInstantiator HTTPSessionFactory NetworkInterface TCPServerConnectionFactory \ HTTPCredentials HTTPDigestCredentials HTTPAuthenticationParams TCPServerConnectionFactory \
HTTPRequest HTTPSession HTTPSessionInstantiator HTTPSessionFactory NetworkInterface \
HTTPRequestHandler HTTPStream HTTPIOStream ServerSocket TCPServerDispatcher \ HTTPRequestHandler HTTPStream HTTPIOStream ServerSocket TCPServerDispatcher \
HTTPRequestHandlerFactory HTTPStreamFactory ServerSocketImpl TCPServerParams \ HTTPRequestHandlerFactory HTTPStreamFactory ServerSocketImpl TCPServerParams \
QuotedPrintableEncoder QuotedPrintableDecoder StringPartSource \ QuotedPrintableEncoder QuotedPrintableDecoder StringPartSource \
@@ -29,7 +30,8 @@ objects = \
MailRecipient MailMessage MailStream SMTPClientSession POP3ClientSession \ MailRecipient MailMessage MailStream SMTPClientSession POP3ClientSession \
RawSocket RawSocketImpl ICMPClient ICMPEventArgs ICMPPacket ICMPPacketImpl \ RawSocket RawSocketImpl ICMPClient ICMPEventArgs ICMPPacket ICMPPacketImpl \
ICMPSocket ICMPSocketImpl ICMPv4PacketImpl \ ICMPSocket ICMPSocketImpl ICMPv4PacketImpl \
RemoteSyslogChannel RemoteSyslogListener SMTPChannel RemoteSyslogChannel RemoteSyslogListener SMTPChannel \
WebSocket WebSocketImpl
target = PocoNet target = PocoNet
target_version = $(LIBVERSION) target_version = $(LIBVERSION)

View File

@@ -269,12 +269,20 @@ protected:
/// proxy username and password have been set. /// proxy username and password have been set.
void proxyAuthenticateImpl(HTTPRequest& request); void proxyAuthenticateImpl(HTTPRequest& request);
/// Sets the proxy credentials (Proxy-Authorization header), if /// Sets the proxy credentials (Proxy-Authorization header), if
/// proxy username and password have been set. /// proxy username and password have been set.
StreamSocket proxyConnect();
/// Sends a CONNECT request to the proxy server and returns
/// a StreamSocket for the resulting connection.
void proxyTunnel();
/// Calls proxyConnect() and attaches the resulting StreamSocket
/// to the HTTPClientSession.
private: private:
std::string _host; std::string _host;
Poco::UInt16 _port; Poco::UInt16 _port;
std::string _proxyHost; std::string _proxyHost;
Poco::UInt16 _proxyPort; Poco::UInt16 _proxyPort;
std::string _proxyUsername; std::string _proxyUsername;
@@ -286,9 +294,11 @@ private:
bool _expectResponseBody; bool _expectResponseBody;
std::ostream* _pRequestStream; std::ostream* _pRequestStream;
std::istream* _pResponseStream; std::istream* _pResponseStream;
HTTPClientSession(const HTTPClientSession&); HTTPClientSession(const HTTPClientSession&);
HTTPClientSession& operator = (const HTTPClientSession&); HTTPClientSession& operator = (const HTTPClientSession&);
friend class WebSocket;
}; };

View File

@@ -5,7 +5,7 @@
// //
// Library: Net // Library: Net
// Package: HTTP // Package: HTTP
// Module: HTTPCredentials // Module: HTTPCredentials
// //
// Definition of the HTTPCredentials class. // Definition of the HTTPCredentials class.
// //
@@ -58,91 +58,107 @@ class HTTPResponse;
class Net_API HTTPCredentials class Net_API HTTPCredentials
/// This is a utility class for working with HTTP /// This is a utility class for working with HTTP
/// authentication (basic or digest) in HTTPRequest objects. /// authentication (basic or digest) in HTTPRequest objects.
/// ///
/// Usage is as follows: /// Usage is as follows:
/// First, create a HTTPCredentials object containing /// First, create a HTTPCredentials object containing
/// the username and password. /// the username and password.
/// Poco::Net::HTTPCredentials creds("user", "s3cr3t"); /// Poco::Net::HTTPCredentials creds("user", "s3cr3t");
/// ///
/// Second, send the HTTP request with Poco::Net::HTTPClientSession. /// Second, send the HTTP request with Poco::Net::HTTPClientSession.
/// Poco::Net::HTTPClientSession session("pocoproject.org"); /// Poco::Net::HTTPClientSession session("pocoproject.org");
/// Poco::Net::HTTPRequest request(HTTPRequest::HTTP_GET, "/index.html", HTTPMessage::HTTP_1_1); /// Poco::Net::HTTPRequest request(HTTPRequest::HTTP_GET, "/index.html", HTTPMessage::HTTP_1_1);
/// session.sendRequest(request); /// session.sendRequest(request);
/// Poco::Net::HTTPResponse; /// Poco::Net::HTTPResponse;
/// std::istream& istr = session.receiveResponse(response); /// std::istream& istr = session.receiveResponse(response);
/// ///
/// If the server responds with a 401 status, authenticate the /// If the server responds with a 401 status, authenticate the
/// request and resend it: /// request and resend it:
/// if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED) /// if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
/// { /// {
/// creds.authenticate(request, response); /// creds.authenticate(request, response);
/// session.sendRequest(request); /// session.sendRequest(request);
/// ... /// ...
/// } /// }
/// ///
/// To perform multiple authenticated requests, call updateAuthInfo() /// To perform multiple authenticated requests, call updateAuthInfo()
/// instead of authenticate() on subsequent requests. /// instead of authenticate() on subsequent requests.
/// creds.updateAuthInfo(request); /// creds.updateAuthInfo(request);
/// session.sendRequest(request); /// session.sendRequest(request);
/// ... /// ...
/// ///
/// Note: Do not forget to read the entire response stream from the 401 response /// Note: Do not forget to read the entire response stream from the 401 response
/// before sending the authenticated request, otherwise there may be /// before sending the authenticated request, otherwise there may be
/// problems if a persistent connection is used. /// problems if a persistent connection is used.
{ {
public: public:
HTTPCredentials(); HTTPCredentials();
/// Creates an empty HTTPCredentials object. /// Creates an empty HTTPCredentials object.
HTTPCredentials(const std::string& username, const std::string& password); HTTPCredentials(const std::string& username, const std::string& password);
/// Creates an HTTPCredentials object with the given username and password. /// Creates an HTTPCredentials object with the given username and password.
~HTTPCredentials(); ~HTTPCredentials();
/// Destroys the HTTPCredentials. /// Destroys the HTTPCredentials.
void fromUserInfo(const std::string& userInfo);
/// Parses username:password string and sets username and password of
/// the credentials object.
/// Throws SyntaxException on invalid user information.
void fromURI(const URI& uri);
/// Extracts username and password from the given URI and sets username
/// and password of the credentials object.
/// Does nothing if URI has no user info part.
void setUsername(const std::string& username); void setUsername(const std::string& username);
/// Sets the username. /// Sets the username.
const std::string& getUsername() const; const std::string& getUsername() const;
/// Returns the username. /// Returns the username.
void setPassword(const std::string& password); void setPassword(const std::string& password);
/// Sets the password. /// Sets the password.
const std::string& getPassword() const; const std::string& getPassword() const;
/// Returns the password. /// Returns the password.
void authenticate(HTTPRequest& request, const HTTPResponse& response); void authenticate(HTTPRequest& request, const HTTPResponse& response);
/// Inspects authenticate header of the response, initializes /// Inspects authenticate header of the response, initializes
/// the internal state (in case of digest authentication) and /// the internal state (in case of digest authentication) and
/// adds required information to the given HTTPRequest. /// adds required information to the given HTTPRequest.
/// ///
/// Does nothing if there is no authentication header in the /// Does nothing if there is no authentication header in the
/// HTTPResponse. /// HTTPResponse.
void updateAuthInfo(HTTPRequest& request); void updateAuthInfo(HTTPRequest& request);
/// Updates internal state (in case of digest authentication) and /// Updates internal state (in case of digest authentication) and
/// replaces authentication information in the request accordingly. /// replaces authentication information in the request accordingly.
static bool isBasicCredentials(const std::string& header); static bool isBasicCredentials(const std::string& header);
/// Returns true if authentication header is for Basic authentication. /// Returns true if authentication header is for Basic authentication.
static bool isDigestCredentials(const std::string& header); static bool isDigestCredentials(const std::string& header);
/// Returns true if authentication header is for Digest authentication. /// Returns true if authentication header is for Digest authentication.
static bool hasBasicCredentials(const HTTPRequest& request);
/// Returns true if Authorization with Basic credentials header is present in the request.
static bool hasDigestCredentials(const HTTPRequest& request);
/// Returns true if Authorization with Digest credentials header is present in the request.
static void extractCredentials(const std::string& userInfo, std::string& username, std::string& password); static void extractCredentials(const std::string& userInfo, std::string& username, std::string& password);
/// Extracts username and password from user:password information string. /// Extracts username and password from user:password information string.
static void extractCredentials(const Poco::URI& uri, std::string& username, std::string& password); static void extractCredentials(const Poco::URI& uri, std::string& username, std::string& password);
/// Extracts username and password from the given URI (e.g.: "http://user:pass@sample.com/secret"). /// Extracts username and password from the given URI (e.g.: "http://user:pass@sample.com/secret").
private: private:
HTTPCredentials(const HTTPCredentials&); HTTPCredentials(const HTTPCredentials&);
HTTPCredentials& operator = (const HTTPCredentials&); HTTPCredentials& operator = (const HTTPCredentials&);
HTTPDigestCredentials _digest; HTTPDigestCredentials _digest;
}; };
@@ -151,25 +167,25 @@ private:
// //
inline void HTTPCredentials::setUsername(const std::string& username) inline void HTTPCredentials::setUsername(const std::string& username)
{ {
_digest.setUsername(username); _digest.setUsername(username);
} }
inline const std::string& HTTPCredentials::getUsername() const inline const std::string& HTTPCredentials::getUsername() const
{ {
return _digest.getUsername(); return _digest.getUsername();
} }
inline void HTTPCredentials::setPassword(const std::string& password) inline void HTTPCredentials::setPassword(const std::string& password)
{ {
_digest.setPassword(password); _digest.setPassword(password);
} }
inline const std::string& HTTPCredentials::getPassword() const inline const std::string& HTTPCredentials::getPassword() const
{ {
return _digest.getPassword(); return _digest.getPassword();
} }

View File

@@ -70,6 +70,7 @@ POCO_DECLARE_EXCEPTION(Net_API, SMTPException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, POP3Exception, NetException) POCO_DECLARE_EXCEPTION(Net_API, POP3Exception, NetException)
POCO_DECLARE_EXCEPTION(Net_API, ICMPException, NetException) POCO_DECLARE_EXCEPTION(Net_API, ICMPException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, HTMLFormException, NetException) POCO_DECLARE_EXCEPTION(Net_API, HTMLFormException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, WebSocketException, NetException)
} } // namespace Poco::Net } } // namespace Poco::Net

View File

@@ -415,4 +415,30 @@ void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request)
} }
StreamSocket HTTPClientSession::proxyConnect()
{
HTTPClientSession proxySession(getProxyHost(), getProxyPort());
proxySession.setTimeout(getTimeout());
SocketAddress targetAddress(getHost(), getPort());
HTTPRequest proxyRequest(HTTPRequest::HTTP_CONNECT, targetAddress.toString(), HTTPMessage::HTTP_1_1);
HTTPResponse proxyResponse;
proxyRequest.set("Proxy-Connection", "keep-alive");
proxyRequest.set("Host", getHost());
proxyAuthenticateImpl(proxyRequest);
proxySession.setKeepAlive(true);
proxySession.sendRequest(proxyRequest);
proxySession.receiveResponse(proxyResponse);
if (proxyResponse.getStatus() != HTTPResponse::HTTP_OK)
throw HTTPException("Cannot establish proxy connection", proxyResponse.getReason());
return proxySession.detachSocket();
}
void HTTPClientSession::proxyTunnel()
{
StreamSocket ss = proxyConnect();
attachSocket(ss);
}
} } // namespace Poco::Net } } // namespace Poco::Net

View File

@@ -5,7 +5,7 @@
// //
// Library: Net // Library: Net
// Package: HTTP // Package: HTTP
// Module: HTTPCredentials // Module: HTTPCredentials
// //
// Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru). // Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru).
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
@@ -42,6 +42,7 @@
#include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/NetException.h" #include "Poco/Net/NetException.h"
#include "Poco/String.h" #include "Poco/String.h"
#include "Poco/Ascii.h"
#include "Poco/URI.h" #include "Poco/URI.h"
@@ -58,7 +59,7 @@ HTTPCredentials::HTTPCredentials()
HTTPCredentials::HTTPCredentials(const std::string& username, const std::string& password): HTTPCredentials::HTTPCredentials(const std::string& username, const std::string& password):
_digest(username, password) _digest(username, password)
{ {
} }
@@ -68,77 +69,113 @@ HTTPCredentials::~HTTPCredentials()
} }
void HTTPCredentials::fromUserInfo(const std::string& userInfo)
{
std::string username;
std::string password;
extractCredentials(userInfo, username, password);
setUsername(username);
setPassword(password);
// TODO: Reset digest state?
}
void HTTPCredentials::fromURI(const URI& uri)
{
std::string username;
std::string password;
extractCredentials(uri, username, password);
setUsername(username);
setPassword(password);
// TODO: Reset digest state?
}
void HTTPCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response) void HTTPCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response)
{ {
for (HTTPResponse::ConstIterator iter = response.find("WWW-Authenticate"); iter != response.end(); ++iter) for (HTTPResponse::ConstIterator iter = response.find("WWW-Authenticate"); iter != response.end(); ++iter)
{ {
if (isBasicCredentials(iter->second)) if (isBasicCredentials(iter->second))
{ {
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request); HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
return; return;
} }
else if (isDigestCredentials(iter->second)) else if (isDigestCredentials(iter->second))
{ {
_digest.authenticate(request, HTTPAuthenticationParams(iter->second.substr(7))); _digest.authenticate(request, HTTPAuthenticationParams(iter->second.substr(7)));
return; return;
} }
} }
} }
void HTTPCredentials::updateAuthInfo(HTTPRequest& request) void HTTPCredentials::updateAuthInfo(HTTPRequest& request)
{ {
if (request.has("Authorization")) if (request.has(HTTPRequest::AUTHORIZATION))
{ {
const std::string& authorization = request.get("Authorization"); const std::string& authorization = request.get(HTTPRequest::AUTHORIZATION);
if (isBasicCredentials(authorization)) if (isBasicCredentials(authorization))
{ {
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request); HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
} }
else if (isDigestCredentials(authorization)) else if (isDigestCredentials(authorization))
{ {
_digest.updateAuthInfo(request); _digest.updateAuthInfo(request);
} }
} }
} }
bool HTTPCredentials::isBasicCredentials(const std::string& header) bool HTTPCredentials::isBasicCredentials(const std::string& header)
{ {
return icompare(header, 0, 6, "Basic ") == 0; return icompare(header, 0, 5, "Basic") == 0 && (header.size() > 5 ? Poco::Ascii::isSpace(header[5]) : true);
} }
bool HTTPCredentials::isDigestCredentials(const std::string& header) bool HTTPCredentials::isDigestCredentials(const std::string& header)
{ {
return icompare(header, 0, 7, "Digest ") == 0; return icompare(header, 0, 6, "Digest") == 0 && (header.size() > 6 ? Poco::Ascii::isSpace(header[6]) : true);
}
bool HTTPCredentials::hasBasicCredentials(const HTTPRequest& request)
{
return request.has(HTTPRequest::AUTHORIZATION) && isBasicCredentials(request.get(HTTPRequest::AUTHORIZATION));
}
bool HTTPCredentials::hasDigestCredentials(const HTTPRequest& request)
{
return request.has(HTTPRequest::AUTHORIZATION) && isDigestCredentials(request.get(HTTPRequest::AUTHORIZATION));
} }
void HTTPCredentials::extractCredentials(const std::string& userInfo, std::string& username, std::string& password) void HTTPCredentials::extractCredentials(const std::string& userInfo, std::string& username, std::string& password)
{ {
const std::string::size_type p = userInfo.find(':'); const std::string::size_type p = userInfo.find(':');
if (p != std::string::npos) if (p != std::string::npos)
{ {
username.assign(userInfo, 0, p); username.assign(userInfo, 0, p);
password.assign(userInfo, p + 1, std::string::npos); password.assign(userInfo, p + 1, std::string::npos);
} }
else else
{ {
username.assign(userInfo); username.assign(userInfo);
password.clear(); password.clear();
} }
} }
void HTTPCredentials::extractCredentials(const Poco::URI& uri, std::string& username, std::string& password) void HTTPCredentials::extractCredentials(const Poco::URI& uri, std::string& username, std::string& password)
{ {
if (!uri.getUserInfo().empty()) if (!uri.getUserInfo().empty())
{ {
extractCredentials(uri.getUserInfo(), username, password); extractCredentials(uri.getUserInfo(), username, password);
} }
} }

View File

@@ -5,7 +5,7 @@
// //
// Library: Net // Library: Net
// Package: HTTP // Package: HTTP
// Module: HTTPDigestCredentials // Module: HTTPDigestCredentials
// //
// Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru). // Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru).
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
@@ -49,39 +49,39 @@
namespace namespace
{ {
std::string digest(Poco::DigestEngine& engine, std::string digest(Poco::DigestEngine& engine,
const std::string& a, const std::string& a,
const std::string& b, const std::string& b,
const std::string& c = std::string(), const std::string& c = std::string(),
const std::string& d = std::string(), const std::string& d = std::string(),
const std::string& e = std::string(), const std::string& e = std::string(),
const std::string& f = std::string()) const std::string& f = std::string())
{ {
engine.reset(); engine.reset();
engine.update(a); engine.update(a);
engine.update(':'); engine.update(':');
engine.update(b); engine.update(b);
if (!c.empty()) if (!c.empty())
{ {
engine.update(':'); engine.update(':');
engine.update(c); engine.update(c);
if (!d.empty()) if (!d.empty())
{ {
engine.update(':'); engine.update(':');
engine.update(d); engine.update(d);
engine.update(':'); engine.update(':');
engine.update(e); engine.update(e);
engine.update(':'); engine.update(':');
engine.update(f); engine.update(f);
} }
} }
return Poco::DigestEngine::digestToHex(engine.digest()); return Poco::DigestEngine::digestToHex(engine.digest());
} }
std::string formatNonceCounter(int counter) std::string formatNonceCounter(int counter)
{ {
return Poco::NumberFormatter::formatHex(counter, 8); return Poco::NumberFormatter::formatHex(counter, 8);
} }
} }
@@ -111,10 +111,10 @@ HTTPDigestCredentials::HTTPDigestCredentials()
{ {
} }
HTTPDigestCredentials::HTTPDigestCredentials(const std::string& username, const std::string& password): HTTPDigestCredentials::HTTPDigestCredentials(const std::string& username, const std::string& password):
_username(username), _username(username),
_password(password) _password(password)
{ {
} }
@@ -126,67 +126,67 @@ HTTPDigestCredentials::~HTTPDigestCredentials()
void HTTPDigestCredentials::setUsername(const std::string& username) void HTTPDigestCredentials::setUsername(const std::string& username)
{ {
_username = username; _username = username;
} }
void HTTPDigestCredentials::setPassword(const std::string& password) void HTTPDigestCredentials::setPassword(const std::string& password)
{ {
_password = password; _password = password;
} }
void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response) void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response)
{ {
authenticate(request, HTTPAuthenticationParams(response)); authenticate(request, HTTPAuthenticationParams(response));
} }
void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPAuthenticationParams& responseAuthParams) void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPAuthenticationParams& responseAuthParams)
{ {
createAuthParams(request, responseAuthParams); createAuthParams(request, responseAuthParams);
request.setCredentials(SCHEME, _requestAuthParams.toString()); request.setCredentials(SCHEME, _requestAuthParams.toString());
} }
void HTTPDigestCredentials::updateAuthInfo(HTTPRequest& request) void HTTPDigestCredentials::updateAuthInfo(HTTPRequest& request)
{ {
updateAuthParams(request); updateAuthParams(request);
request.setCredentials(SCHEME, _requestAuthParams.toString()); request.setCredentials(SCHEME, _requestAuthParams.toString());
} }
std::string HTTPDigestCredentials::createNonce() std::string HTTPDigestCredentials::createNonce()
{ {
Poco::FastMutex::ScopedLock lock(_nonceMutex); Poco::FastMutex::ScopedLock lock(_nonceMutex);
MD5Engine md5; MD5Engine md5;
Timestamp::TimeVal now = Timestamp().epochMicroseconds(); Timestamp::TimeVal now = Timestamp().epochMicroseconds();
md5.update(&_nonceCounter, sizeof(_nonceCounter)); md5.update(&_nonceCounter, sizeof(_nonceCounter));
md5.update(&now, sizeof(now)); md5.update(&now, sizeof(now));
++_nonceCounter; ++_nonceCounter;
return DigestEngine::digestToHex(md5.digest()); return DigestEngine::digestToHex(md5.digest());
} }
void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const HTTPAuthenticationParams& responseAuthParams) void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const HTTPAuthenticationParams& responseAuthParams)
{ {
// Not implemented: "domain" auth parameter and integrity protection. // Not implemented: "domain" auth parameter and integrity protection.
if (!responseAuthParams.has(NONCE_PARAM) || !responseAuthParams.has(REALM_PARAM)) if (!responseAuthParams.has(NONCE_PARAM) || !responseAuthParams.has(REALM_PARAM))
throw InvalidArgumentException("Invalid HTTP authentication parameters"); throw InvalidArgumentException("Invalid HTTP authentication parameters");
const std::string& algorithm = responseAuthParams.get(ALGORITHM_PARAM, DEFAULT_ALGORITHM); const std::string& algorithm = responseAuthParams.get(ALGORITHM_PARAM, DEFAULT_ALGORITHM);
if (icompare(algorithm, DEFAULT_ALGORITHM) != 0) if (icompare(algorithm, DEFAULT_ALGORITHM) != 0)
throw NotImplementedException("Unsupported digest algorithm", algorithm); throw NotImplementedException("Unsupported digest algorithm", algorithm);
const std::string& nonce = responseAuthParams.get(NONCE_PARAM); const std::string& nonce = responseAuthParams.get(NONCE_PARAM);
const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP); const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP);
const std::string& realm = responseAuthParams.getRealm(); const std::string& realm = responseAuthParams.getRealm();
_requestAuthParams.clear(); _requestAuthParams.clear();
_requestAuthParams.set(USERNAME_PARAM, _username); _requestAuthParams.set(USERNAME_PARAM, _username);
@@ -194,104 +194,108 @@ void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const H
_requestAuthParams.set(NONCE_PARAM, nonce); _requestAuthParams.set(NONCE_PARAM, nonce);
_requestAuthParams.setRealm(realm); _requestAuthParams.setRealm(realm);
if (responseAuthParams.has(OPAQUE_PARAM)) if (responseAuthParams.has(OPAQUE_PARAM))
{ {
_requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM)); _requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM));
} }
if (qop.empty()) if (qop.empty())
{ {
MD5Engine engine; updateAuthParams(request);
const std::string ha1 = digest(engine, _username, realm, _password);
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, ha2));
} }
else else
{ {
Poco::StringTokenizer tok(qop, ",", Poco::StringTokenizer::TOK_TRIM); Poco::StringTokenizer tok(qop, ",", Poco::StringTokenizer::TOK_TRIM);
bool qopSupported = false; bool qopSupported = false;
for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it)
{ {
if (icompare(*it, AUTH_PARAM) == 0) if (icompare(*it, AUTH_PARAM) == 0)
{ {
qopSupported = true; qopSupported = true;
_requestAuthParams.set(CNONCE_PARAM, createNonce()); _requestAuthParams.set(CNONCE_PARAM, createNonce());
_requestAuthParams.set(QOP_PARAM, *it); _requestAuthParams.set(QOP_PARAM, *it);
updateAuthParams(request); updateAuthParams(request);
break; break;
} }
} }
if (!qopSupported) if (!qopSupported)
NotImplementedException("Unsupported QoP requested", qop); throw NotImplementedException("Unsupported QoP requested", qop);
} }
} }
void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request) void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
{ {
MD5Engine engine;
const std::string& qop = _requestAuthParams.get(QOP_PARAM, DEFAULT_QOP); const std::string& qop = _requestAuthParams.get(QOP_PARAM, DEFAULT_QOP);
if (icompare(qop, AUTH_PARAM) == 0) const std::string& realm = _requestAuthParams.getRealm();
{ const std::string& nonce = _requestAuthParams.get(NONCE_PARAM);
MD5Engine engine;
const std::string& nonce = _requestAuthParams.get(NONCE_PARAM); _requestAuthParams.set(URI_PARAM, request.getURI());
const std::string& realm = _requestAuthParams.getRealm();
if (qop.empty())
{
const std::string ha1 = digest(engine, _username, realm, _password);
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, ha2));
}
else if (icompare(qop, AUTH_PARAM) == 0)
{
const std::string& cnonce = _requestAuthParams.get(CNONCE_PARAM); const std::string& cnonce = _requestAuthParams.get(CNONCE_PARAM);
const std::string ha1 = digest(engine, _username, realm, _password); const std::string ha1 = digest(engine, _username, realm, _password);
const std::string ha2 = digest(engine, request.getMethod(), request.getURI()); const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
const std::string nc = formatNonceCounter(updateNonceCounter(nonce)); const std::string nc = formatNonceCounter(updateNonceCounter(nonce));
_requestAuthParams.set(NC_PARAM, nc); _requestAuthParams.set(NC_PARAM, nc);
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2)); _requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2));
} }
} }
bool HTTPDigestCredentials::verifyAuthInfo(const HTTPRequest& request) const bool HTTPDigestCredentials::verifyAuthInfo(const HTTPRequest& request) const
{ {
HTTPAuthenticationParams params(request); HTTPAuthenticationParams params(request);
return verifyAuthParams(request, params); return verifyAuthParams(request, params);
} }
bool HTTPDigestCredentials::verifyAuthParams(const HTTPRequest& request, const HTTPAuthenticationParams& params) const bool HTTPDigestCredentials::verifyAuthParams(const HTTPRequest& request, const HTTPAuthenticationParams& params) const
{ {
const std::string& nonce = params.get(NONCE_PARAM); const std::string& nonce = params.get(NONCE_PARAM);
const std::string& realm = params.getRealm(); const std::string& realm = params.getRealm();
const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP); const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP);
std::string response; std::string response;
MD5Engine engine; MD5Engine engine;
if (qop.empty()) if (qop.empty())
{ {
const std::string ha1 = digest(engine, _username, realm, _password); const std::string ha1 = digest(engine, _username, realm, _password);
const std::string ha2 = digest(engine, request.getMethod(), request.getURI()); const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
response = digest(engine, ha1, nonce, ha2); response = digest(engine, ha1, nonce, ha2);
} }
else if (icompare(qop, AUTH_PARAM) == 0) else if (icompare(qop, AUTH_PARAM) == 0)
{ {
const std::string& cnonce = params.get(CNONCE_PARAM); const std::string& cnonce = params.get(CNONCE_PARAM);
const std::string& nc = params.get(NC_PARAM); const std::string& nc = params.get(NC_PARAM);
const std::string ha1 = digest(engine, _username, realm, _password); const std::string ha1 = digest(engine, _username, realm, _password);
const std::string ha2 = digest(engine, request.getMethod(), request.getURI()); const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2); response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2);
} }
return response == params.get(RESPONSE_PARAM); return response == params.get(RESPONSE_PARAM);
} }
int HTTPDigestCredentials::updateNonceCounter(const std::string& nonce) int HTTPDigestCredentials::updateNonceCounter(const std::string& nonce)
{ {
NonceCounterMap::iterator iter = _nc.find(nonce); NonceCounterMap::iterator iter = _nc.find(nonce);
if (iter == _nc.end()) if (iter == _nc.end())
{ {
iter = _nc.insert(NonceCounterMap::value_type(nonce, 0)).first; iter = _nc.insert(NonceCounterMap::value_type(nonce, 0)).first;
} }
iter->second++; iter->second++;
return iter->second; return iter->second;
} }

View File

@@ -67,6 +67,7 @@ POCO_IMPLEMENT_EXCEPTION(SMTPException, NetException, "SMTP Exception")
POCO_IMPLEMENT_EXCEPTION(POP3Exception, NetException, "POP3 Exception") POCO_IMPLEMENT_EXCEPTION(POP3Exception, NetException, "POP3 Exception")
POCO_IMPLEMENT_EXCEPTION(ICMPException, NetException, "ICMP Exception") POCO_IMPLEMENT_EXCEPTION(ICMPException, NetException, "ICMP Exception")
POCO_IMPLEMENT_EXCEPTION(HTMLFormException, NetException, "HTML Form Exception") POCO_IMPLEMENT_EXCEPTION(HTMLFormException, NetException, "HTML Form Exception")
POCO_IMPLEMENT_EXCEPTION(WebSocketException, NetException, "WebSocket Exception")
} } // namespace Poco::Net } } // namespace Poco::Net

View File

@@ -299,14 +299,16 @@ void Application::stopOptionsProcessing()
int Application::run() int Application::run()
{ {
int rc = EXIT_SOFTWARE; int rc = EXIT_CONFIG;
initialize(*this); try
try {
{ initialize(*this);
rc = main(_args); rc = EXIT_SOFTWARE;
} rc = main(_args);
catch (Poco::Exception& exc) uninitialize();
{ }
catch (Poco::Exception& exc)
{
logger().log(exc); logger().log(exc);
} }
catch (std::exception& exc) catch (std::exception& exc)
@@ -314,11 +316,10 @@ int Application::run()
logger().error(exc.what()); logger().error(exc.what());
} }
catch (...) catch (...)
{ {
logger().fatal("system exception"); logger().fatal("system exception");
} }
uninitialize(); return rc;
return rc;
} }
@@ -368,13 +369,13 @@ void Application::processOptions()
while (it != _args.end() && !_stopOptionsProcessing) while (it != _args.end() && !_stopOptionsProcessing)
{ {
std::string name; std::string name;
std::string value; std::string value;
if (processor.process(*it, name, value)) if (processor.process(*it, name, value))
{ {
if (!name.empty()) // "--" option to end options processing or deferred argument if (!name.empty()) // "--" option to end options processing or deferred argument
{ {
handleOption(name, value); handleOption(name, value);
} }
it = _args.erase(it); it = _args.erase(it);
} }
else ++it; else ++it;

View File

@@ -388,12 +388,12 @@ void ServerApplication::registerService()
else else
service.registerService(path, _displayName); service.registerService(path, _displayName);
if (_startup == "auto") if (_startup == "auto")
service.setStartup(WinService::SVC_AUTO_START); service.setStartup(WinService::SVC_AUTO_START);
else if (_startup == "manual") else if (_startup == "manual")
service.setStartup(WinService::SVC_MANUAL_START); service.setStartup(WinService::SVC_MANUAL_START);
if (!_description.empty()) if (!_description.empty())
service.setDescription(_description); service.setDescription(_description);
logger().information("The application has been successfully registered as a service."); logger().information("The application has been successfully registered as a service.");
} }
@@ -428,19 +428,19 @@ void ServerApplication::defineOptions(OptionSet& options)
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("name") .argument("name")
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDisplayName))); .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDisplayName)));
options.addOption( options.addOption(
Option("description", "", "Specify a description for the service (only with /registerService).") Option("description", "", "Specify a description for the service (only with /registerService).")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("text") .argument("text")
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDescription))); .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDescription)));
options.addOption( options.addOption(
Option("startup", "", "Specify the startup mode for the service (only with /registerService).") Option("startup", "", "Specify the startup mode for the service (only with /registerService).")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("automatic|manual") .argument("automatic|manual")
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleStartup))); .callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleStartup)));
} }
@@ -466,13 +466,13 @@ void ServerApplication::handleDisplayName(const std::string& name, const std::st
void ServerApplication::handleDescription(const std::string& name, const std::string& value) void ServerApplication::handleDescription(const std::string& name, const std::string& value)
{ {
_description = value; _description = value;
} }
void ServerApplication::handleStartup(const std::string& name, const std::string& value) void ServerApplication::handleStartup(const std::string& name, const std::string& value)
{ {
if (Poco::icompare(value, 4, std::string("auto")) == 0) if (Poco::icompare(value, 4, std::string("auto")) == 0)
_startup = "auto"; _startup = "auto";
else if (Poco::icompare(value, std::string("manual")) == 0) else if (Poco::icompare(value, std::string("manual")) == 0)
_startup = "manual"; _startup = "manual";
@@ -496,20 +496,10 @@ int ServerApplication::run(int argc, char** argv)
} }
catch (Exception& exc) catch (Exception& exc)
{ {
logger().log(exc); logger().log(exc);
return EXIT_CONFIG; return EXIT_CONFIG;
} }
int rc = run(); return run();
try
{
uninitialize();
}
catch (Exception& exc)
{
logger().log(exc);
rc = EXIT_CONFIG;
}
return rc;
} }
@@ -521,20 +511,10 @@ int ServerApplication::run(const std::vector<std::string>& args)
} }
catch (Exception& exc) catch (Exception& exc)
{ {
logger().log(exc); logger().log(exc);
return EXIT_CONFIG; return EXIT_CONFIG;
} }
int rc = run(); return run();
try
{
uninitialize();
}
catch (Exception& exc)
{
logger().log(exc);
rc = EXIT_CONFIG;
}
return rc;
} }
@@ -547,20 +527,10 @@ int ServerApplication::run(int argc, wchar_t** argv)
} }
catch (Exception& exc) catch (Exception& exc)
{ {
logger().log(exc); logger().log(exc);
return EXIT_CONFIG; return EXIT_CONFIG;
} }
int rc = run(); return run();
try
{
uninitialize();
}
catch (Exception& exc)
{
logger().log(exc);
rc = EXIT_CONFIG;
}
return rc;
} }
#endif #endif

View File

@@ -53,9 +53,35 @@ namespace Poco {
namespace Util { namespace Util {
namespace
{
class AutoHandle
{
public:
AutoHandle(HMODULE h):
_h(h)
{
}
~AutoHandle()
{
FreeLibrary(_h);
}
HMODULE handle()
{
return _h;
}
private:
HMODULE _h;
};
}
WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly, REGSAM extraSam): WinRegistryKey::WinRegistryKey(const std::string& key, bool readOnly, REGSAM extraSam):
_hKey(0), _hKey(0),
_readOnly(readOnly), _readOnly(readOnly),
_extraSam(extraSam) _extraSam(extraSam)
{ {
std::string::size_type pos = key.find('\\'); std::string::size_type pos = key.find('\\');
@@ -266,17 +292,53 @@ void WinRegistryKey::deleteKey()
std::string subKey(_subKey); std::string subKey(_subKey);
subKey += "\\"; subKey += "\\";
subKey += *it; subKey += *it;
WinRegistryKey subRegKey(_hRootKey, subKey); WinRegistryKey subRegKey(_hRootKey, subKey);
subRegKey.deleteKey(); subRegKey.deleteKey();
} }
// NOTE: RegDeleteKeyEx is only available on Windows XP 64-bit SP3, Windows Vista or later.
// We cannot call it directly as this would prevent the code running on Windows XP 32-bit.
// Therefore, if we need to call RegDeleteKeyEx (_extraSam != 0) we need to check for
// its existence in ADVAPI32.DLL and call it indirectly.
#if defined(POCO_WIN32_UTF8) #if defined(POCO_WIN32_UTF8)
std::wstring usubKey; std::wstring usubKey;
Poco::UnicodeConverter::toUTF16(_subKey, usubKey); Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
throw NotFoundException(key()); typedef LONG (WINAPI *RegDeleteKeyExWFunc)(HKEY hKey, const wchar_t* lpSubKey, REGSAM samDesired, DWORD Reserved);
if (_extraSam != 0)
{
AutoHandle advAPI32(LoadLibraryW(L"ADVAPI32.DLL"));
if (advAPI32.handle())
{
RegDeleteKeyExWFunc pRegDeleteKeyExW = reinterpret_cast<RegDeleteKeyExWFunc>(GetProcAddress(advAPI32.handle() , "RegDeleteKeyExW"));
if (pRegDeleteKeyExW)
{
if ((*pRegDeleteKeyExW)(_hRootKey, usubKey.c_str(), _extraSam, 0) != ERROR_SUCCESS)
throw NotFoundException(key());
return;
}
}
}
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
throw NotFoundException(key());
#else #else
if (RegDeleteKey(_hRootKey, _subKey.c_str()) != ERROR_SUCCESS) typedef LONG (WINAPI *RegDeleteKeyExAFunc)(HKEY hKey, const char* lpSubKey, REGSAM samDesired, DWORD Reserved);
throw NotFoundException(key()); if (_extraSam != 0)
{
AutoHandle advAPI32(LoadLibraryA("ADVAPI32.DLL"));
if (advAPI32.handle())
{
RegDeleteKeyExAFunc pRegDeleteKeyExA = reinterpret_cast<RegDeleteKeyExAFunc>(GetProcAddress(advAPI32.handle() , "RegDeleteKeyExA"));
if (pRegDeleteKeyExA)
{
if ((*pRegDeleteKeyExA)(_hRootKey, _subKey.c_str(), _extraSam, 0) != ERROR_SUCCESS)
throw NotFoundException(key());
return;
}
}
}
if (RegDeleteKey(_hRootKey, _subKey.c_str()) != ERROR_SUCCESS)
throw NotFoundException(key());
#endif #endif
} }