mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
trunk: sync from 1.4.3
make & cmake fixes
This commit is contained in:
parent
0afd04898b
commit
8b70c37260
@ -1,60 +1,78 @@
|
||||
//
|
||||
// ApacheApplication.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheApplication.h#2 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheApplication_INCLUDED
|
||||
#define ApacheConnector_ApacheApplication_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Mutex.h"
|
||||
|
||||
|
||||
class ApacheApplication: public Poco::Util::Application
|
||||
{
|
||||
public:
|
||||
ApacheApplication();
|
||||
/// Creates the ApacheApplication and sets the
|
||||
/// ApacheChannel as the root logger channel.
|
||||
|
||||
~ApacheApplication();
|
||||
/// Destroys the ApacheApplication.
|
||||
|
||||
void setup();
|
||||
/// Initializes the application if called for the first
|
||||
/// time; does nothing in later calls.
|
||||
|
||||
ApacheRequestHandlerFactory& factory();
|
||||
/// Returns the ApacheRequestHandlerFactory.
|
||||
|
||||
static ApacheApplication& instance();
|
||||
/// Returns the application instance.
|
||||
|
||||
private:
|
||||
bool _ready;
|
||||
ApacheRequestHandlerFactory _factory;
|
||||
Poco::FastMutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline ApacheRequestHandlerFactory& ApacheApplication::factory()
|
||||
{
|
||||
return _factory;
|
||||
}
|
||||
|
||||
|
||||
#endif // ApacheConnector_ApacheApplication_INCLUDED
|
||||
//
|
||||
// ApacheApplication.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheApplication.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheApplication_INCLUDED
|
||||
#define ApacheConnector_ApacheApplication_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Mutex.h"
|
||||
|
||||
|
||||
class ApacheApplication: public Poco::Util::Application
|
||||
{
|
||||
public:
|
||||
ApacheApplication();
|
||||
/// Creates the ApacheApplication and sets the
|
||||
/// ApacheChannel as the root logger channel.
|
||||
|
||||
~ApacheApplication();
|
||||
/// Destroys the ApacheApplication.
|
||||
|
||||
void setup();
|
||||
/// Initializes the application if called for the first
|
||||
/// time; does nothing in later calls.
|
||||
|
||||
ApacheRequestHandlerFactory& factory();
|
||||
/// Returns the ApacheRequestHandlerFactory.
|
||||
|
||||
static ApacheApplication& instance();
|
||||
/// Returns the application instance.
|
||||
|
||||
private:
|
||||
bool _ready;
|
||||
ApacheRequestHandlerFactory _factory;
|
||||
Poco::FastMutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline ApacheRequestHandlerFactory& ApacheApplication::factory()
|
||||
{
|
||||
return _factory;
|
||||
}
|
||||
|
||||
|
||||
#endif // ApacheConnector_ApacheApplication_INCLUDED
|
||||
|
@ -1,34 +1,52 @@
|
||||
//
|
||||
// ApacheChannel.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheChannel.h#1 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef 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
|
||||
//
|
||||
// ApacheChannel.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheChannel.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef 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
|
||||
|
@ -1,90 +1,108 @@
|
||||
//
|
||||
// ApacheConnector.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheConnector.h#3 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheConnector_INCLUDED
|
||||
#define ApacheConnector_ApacheConnector_INCLUDED
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
struct request_rec;
|
||||
class ApacheServerRequest;
|
||||
|
||||
|
||||
class ApacheRequestRec
|
||||
/// This class wraps an Apache request_rec.
|
||||
{
|
||||
public:
|
||||
ApacheRequestRec(request_rec* _pRec);
|
||||
/// Creates the ApacheRequestRec;
|
||||
|
||||
bool haveRequestBody();
|
||||
/// Returns true if the request contains a body.
|
||||
|
||||
int readRequest(char* buffer, int length);
|
||||
/// Read up to length bytes from request body into buffer.
|
||||
/// Returns the number of bytes read, 0 if eof or -1 if an error occured.
|
||||
|
||||
void writeResponse(const char* buffer, int length);
|
||||
/// Writes the given characters as response to the given request_rec.
|
||||
|
||||
void addHeader(const std::string& key, const std::string& value);
|
||||
/// Adds the given key / value pair to the outgoing headers of the
|
||||
/// http response.
|
||||
|
||||
void setContentType(const std::string& mediaType);
|
||||
/// Sets the response content type.
|
||||
|
||||
void redirect(const std::string& uri);
|
||||
/// Redirects the response to the given uri.
|
||||
|
||||
void sendErrorResponse(int status);
|
||||
/// Sends an error response with the given HTTP status code.
|
||||
|
||||
int sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType);
|
||||
/// Sends the file given by fileName as response.
|
||||
|
||||
void copyHeaders(ApacheServerRequest& request);
|
||||
/// Copies the request uri and header fields from the Apache request
|
||||
/// to the ApacheServerRequest.
|
||||
|
||||
private:
|
||||
request_rec* _pRec;
|
||||
};
|
||||
|
||||
|
||||
class ApacheConnector
|
||||
/// This class provides static methods wrapping the
|
||||
/// Apache API.
|
||||
{
|
||||
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
|
||||
//
|
||||
// ApacheConnector.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheConnector.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheConnector_INCLUDED
|
||||
#define ApacheConnector_ApacheConnector_INCLUDED
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
struct request_rec;
|
||||
class ApacheServerRequest;
|
||||
|
||||
|
||||
class ApacheRequestRec
|
||||
/// This class wraps an Apache request_rec.
|
||||
{
|
||||
public:
|
||||
ApacheRequestRec(request_rec* _pRec);
|
||||
/// Creates the ApacheRequestRec;
|
||||
|
||||
bool haveRequestBody();
|
||||
/// Returns true if the request contains a body.
|
||||
|
||||
int readRequest(char* buffer, int length);
|
||||
/// Read up to length bytes from request body into buffer.
|
||||
/// Returns the number of bytes read, 0 if eof or -1 if an error occured.
|
||||
|
||||
void writeResponse(const char* buffer, int length);
|
||||
/// Writes the given characters as response to the given request_rec.
|
||||
|
||||
void addHeader(const std::string& key, const std::string& value);
|
||||
/// Adds the given key / value pair to the outgoing headers of the
|
||||
/// http response.
|
||||
|
||||
void setContentType(const std::string& mediaType);
|
||||
/// Sets the response content type.
|
||||
|
||||
void redirect(const std::string& uri, int status);
|
||||
/// Redirects the response to the given uri.
|
||||
|
||||
void sendErrorResponse(int status);
|
||||
/// Sends an error response with the given HTTP status code.
|
||||
|
||||
int sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType);
|
||||
/// Sends the file given by fileName as response.
|
||||
|
||||
void copyHeaders(ApacheServerRequest& request);
|
||||
/// Copies the request uri and header fields from the Apache request
|
||||
/// to the ApacheServerRequest.
|
||||
|
||||
private:
|
||||
request_rec* _pRec;
|
||||
};
|
||||
|
||||
|
||||
class ApacheConnector
|
||||
/// This class provides static methods wrapping the
|
||||
/// Apache API.
|
||||
{
|
||||
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
|
||||
|
@ -1,59 +1,77 @@
|
||||
//
|
||||
// ApacheRequestHandlerFactory.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheRequestHandlerFactory.h#5 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
|
||||
#define ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/ClassLoader.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
class ApacheRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||
{
|
||||
public:
|
||||
ApacheRequestHandlerFactory();
|
||||
/// Constructs the ApacheRequestHandlerFactory
|
||||
|
||||
~ApacheRequestHandlerFactory();
|
||||
/// Destructor of the ApacheRequestHandlerFactory
|
||||
|
||||
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
|
||||
/// Creates a new request handler for the given HTTP request.
|
||||
|
||||
bool mustHandle(const std::string& uri);
|
||||
/// Returns 1 if the given uri must be handled by the
|
||||
/// poco_mapper module, 0 otherwise.
|
||||
|
||||
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
|
||||
//
|
||||
// ApacheRequestHandlerFactory.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheRequestHandlerFactory.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
|
||||
#define ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/ClassLoader.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
class ApacheRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||
{
|
||||
public:
|
||||
ApacheRequestHandlerFactory();
|
||||
/// Constructs the ApacheRequestHandlerFactory
|
||||
|
||||
~ApacheRequestHandlerFactory();
|
||||
/// Destructor of the ApacheRequestHandlerFactory
|
||||
|
||||
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
|
||||
/// Creates a new request handler for the given HTTP request.
|
||||
|
||||
bool mustHandle(const std::string& uri);
|
||||
/// Returns 1 if the given uri must be handled by the
|
||||
/// poco_mapper module, 0 otherwise.
|
||||
|
||||
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
|
||||
|
@ -1,102 +1,120 @@
|
||||
//
|
||||
// ApacheServerRequest.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheServerRequest.h#6 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheServerRequest_INCLUDED
|
||||
#define ApacheConnector_ApacheServerRequest_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
class ApacheServerResponse;
|
||||
|
||||
|
||||
class ApacheServerRequest: public Poco::Net::HTTPServerRequest
|
||||
{
|
||||
public:
|
||||
ApacheServerRequest(
|
||||
ApacheRequestRec* pApacheRequest,
|
||||
const char* serverName,
|
||||
int serverPort,
|
||||
const char* clientName,
|
||||
int clientPort);
|
||||
/// Creates a new ApacheServerRequest.
|
||||
|
||||
~ApacheServerRequest();
|
||||
/// Destroys the ApacheServerRequest.
|
||||
|
||||
std::istream& stream();
|
||||
/// Returns the input stream for reading
|
||||
/// the request body.
|
||||
///
|
||||
/// The stream is valid until the HTTPServerRequest
|
||||
/// object is destroyed.
|
||||
|
||||
bool expectContinue() const;
|
||||
/// Returns true if the client expects a
|
||||
/// 100 Continue response.
|
||||
|
||||
const Poco::Net::SocketAddress& clientAddress() const;
|
||||
/// Returns the client's address.
|
||||
|
||||
const Poco::Net::SocketAddress& serverAddress() const;
|
||||
/// Returns the server's address.
|
||||
|
||||
const Poco::Net::HTTPServerParams& serverParams() const;
|
||||
/// Returns a reference to the server parameters.
|
||||
|
||||
Poco::Net::HTTPServerResponse& response() const;
|
||||
/// Returns a reference to the associated response
|
||||
|
||||
protected:
|
||||
void setResponse(ApacheServerResponse* pResponse);
|
||||
|
||||
private:
|
||||
ApacheRequestRec* _pApacheRequest;
|
||||
ApacheServerResponse* _pResponse;
|
||||
ApacheInputStream* _pStream;
|
||||
Poco::Net::SocketAddress _serverAddress;
|
||||
Poco::Net::SocketAddress _clientAddress;
|
||||
|
||||
friend class ApacheServerResponse;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline std::istream& ApacheServerRequest::stream()
|
||||
{
|
||||
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
|
||||
//
|
||||
// ApacheServerRequest.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheServerRequest.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheServerRequest_INCLUDED
|
||||
#define ApacheConnector_ApacheServerRequest_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
class ApacheServerResponse;
|
||||
|
||||
|
||||
class ApacheServerRequest: public Poco::Net::HTTPServerRequest
|
||||
{
|
||||
public:
|
||||
ApacheServerRequest(
|
||||
ApacheRequestRec* pApacheRequest,
|
||||
const char* serverName,
|
||||
int serverPort,
|
||||
const char* clientName,
|
||||
int clientPort);
|
||||
/// Creates a new ApacheServerRequest.
|
||||
|
||||
~ApacheServerRequest();
|
||||
/// Destroys the ApacheServerRequest.
|
||||
|
||||
std::istream& stream();
|
||||
/// Returns the input stream for reading
|
||||
/// the request body.
|
||||
///
|
||||
/// The stream is valid until the HTTPServerRequest
|
||||
/// object is destroyed.
|
||||
|
||||
bool expectContinue() const;
|
||||
/// Returns true if the client expects a
|
||||
/// 100 Continue response.
|
||||
|
||||
const Poco::Net::SocketAddress& clientAddress() const;
|
||||
/// Returns the client's address.
|
||||
|
||||
const Poco::Net::SocketAddress& serverAddress() const;
|
||||
/// Returns the server's address.
|
||||
|
||||
const Poco::Net::HTTPServerParams& serverParams() const;
|
||||
/// Returns a reference to the server parameters.
|
||||
|
||||
Poco::Net::HTTPServerResponse& response() const;
|
||||
/// Returns a reference to the associated response
|
||||
|
||||
protected:
|
||||
void setResponse(ApacheServerResponse* pResponse);
|
||||
|
||||
private:
|
||||
ApacheRequestRec* _pApacheRequest;
|
||||
ApacheServerResponse* _pResponse;
|
||||
ApacheInputStream* _pStream;
|
||||
Poco::Net::SocketAddress _serverAddress;
|
||||
Poco::Net::SocketAddress _clientAddress;
|
||||
|
||||
friend class ApacheServerResponse;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline std::istream& ApacheServerRequest::stream()
|
||||
{
|
||||
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
|
||||
|
@ -1,124 +1,144 @@
|
||||
//
|
||||
// ApacheServerResponse.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheServerResponse.h#6 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheServerResponse_INCLUDED
|
||||
#define ApacheConnector_ApacheServerResponse_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
|
||||
class ApacheServerRequest;
|
||||
|
||||
|
||||
class ApacheServerResponse: public Poco::Net::HTTPServerResponse
|
||||
/// This subclass of HTTPResponse is used for
|
||||
/// representing server-side HTTP responses for apache.
|
||||
///
|
||||
/// A ApacheServerResponse is passed to the
|
||||
/// handleRequest() method of HTTPRequestHandler.
|
||||
///
|
||||
/// handleRequest() must set a status code
|
||||
/// and optional reason phrase, set headers
|
||||
/// as necessary, and provide a message body.
|
||||
{
|
||||
public:
|
||||
ApacheServerResponse(ApacheServerRequest* pRequest);
|
||||
/// Creates the ApacheServerResponse.
|
||||
|
||||
~ApacheServerResponse();
|
||||
/// Destroys the ApacheServerResponse.
|
||||
|
||||
void sendContinue();
|
||||
/// Sends a 100 Continue response to the
|
||||
/// client.
|
||||
|
||||
void sendErrorResponse(int status);
|
||||
/// Sends an error response with the given
|
||||
/// status back to the client.
|
||||
|
||||
std::ostream& send();
|
||||
/// Sends the response header to the client and
|
||||
/// returns an output stream for sending the
|
||||
/// response body.
|
||||
///
|
||||
/// The returned stream is valid until the response
|
||||
/// object is destroyed.
|
||||
///
|
||||
/// Must not be called after sendFile(), sendBuffer()
|
||||
/// or redirect() has been called.
|
||||
|
||||
void sendFile(const std::string& path, const std::string& mediaType);
|
||||
/// Sends the response header to the client, followed
|
||||
/// by the content of the given file.
|
||||
///
|
||||
/// Must not be called after send(), sendBuffer()
|
||||
/// or redirect() has been called.
|
||||
///
|
||||
/// Throws a FileNotFoundException if the file
|
||||
/// cannot be found, or an OpenFileException if
|
||||
/// the file cannot be opened.
|
||||
|
||||
void sendBuffer(const void* pBuffer, std::size_t length);
|
||||
/// Sends the response header to the client, followed
|
||||
/// by the contents of the given buffer.
|
||||
///
|
||||
/// The Content-Length header of the response is set
|
||||
/// to length and chunked transfer encoding is disabled.
|
||||
///
|
||||
/// If both the HTTP message header and body (from the
|
||||
/// given buffer) fit into one single network packet, the
|
||||
/// complete response can be sent in one network packet.
|
||||
///
|
||||
/// Must not be called after send(), sendFile()
|
||||
/// or redirect() has been called.
|
||||
|
||||
void redirect(const std::string& uri);
|
||||
/// Sets the status code to 302 (Found)
|
||||
/// and sets the "Location" header field
|
||||
/// to the given URI, which according to
|
||||
/// the HTTP specification, must be absolute.
|
||||
///
|
||||
/// Must not be called after send() has been called.
|
||||
|
||||
void requireAuthentication(const std::string& realm);
|
||||
/// Sets the status code to 401 (Unauthorized)
|
||||
/// and sets the "WWW-Authenticate" header field
|
||||
/// according to the given realm.
|
||||
|
||||
bool sent() const;
|
||||
/// 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
|
||||
//
|
||||
// ApacheServerResponse.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheServerResponse.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheServerResponse_INCLUDED
|
||||
#define ApacheConnector_ApacheServerResponse_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "Poco/Net/Net.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
|
||||
class ApacheServerRequest;
|
||||
|
||||
|
||||
class ApacheServerResponse: public Poco::Net::HTTPServerResponse
|
||||
/// This subclass of HTTPResponse is used for
|
||||
/// representing server-side HTTP responses for apache.
|
||||
///
|
||||
/// A ApacheServerResponse is passed to the
|
||||
/// handleRequest() method of HTTPRequestHandler.
|
||||
///
|
||||
/// handleRequest() must set a status code
|
||||
/// and optional reason phrase, set headers
|
||||
/// as necessary, and provide a message body.
|
||||
{
|
||||
public:
|
||||
ApacheServerResponse(ApacheServerRequest* pRequest);
|
||||
/// Creates the ApacheServerResponse.
|
||||
|
||||
~ApacheServerResponse();
|
||||
/// Destroys the ApacheServerResponse.
|
||||
|
||||
void sendContinue();
|
||||
/// Sends a 100 Continue response to the
|
||||
/// client.
|
||||
|
||||
void sendErrorResponse(int status);
|
||||
/// Sends an error response with the given
|
||||
/// status back to the client.
|
||||
|
||||
std::ostream& send();
|
||||
/// Sends the response header to the client and
|
||||
/// returns an output stream for sending the
|
||||
/// response body.
|
||||
///
|
||||
/// The returned stream is valid until the response
|
||||
/// object is destroyed.
|
||||
///
|
||||
/// Must not be called after sendFile(), sendBuffer()
|
||||
/// or redirect() has been called.
|
||||
|
||||
void sendFile(const std::string& path, const std::string& mediaType);
|
||||
/// Sends the response header to the client, followed
|
||||
/// by the content of the given file.
|
||||
///
|
||||
/// Must not be called after send(), sendBuffer()
|
||||
/// or redirect() has been called.
|
||||
///
|
||||
/// Throws a FileNotFoundException if the file
|
||||
/// cannot be found, or an OpenFileException if
|
||||
/// the file cannot be opened.
|
||||
|
||||
void sendBuffer(const void* pBuffer, std::size_t length);
|
||||
/// Sends the response header to the client, followed
|
||||
/// by the contents of the given buffer.
|
||||
///
|
||||
/// The Content-Length header of the response is set
|
||||
/// to length and chunked transfer encoding is disabled.
|
||||
///
|
||||
/// If both the HTTP message header and body (from the
|
||||
/// given buffer) fit into one single network packet, the
|
||||
/// complete response can be sent in one network packet.
|
||||
///
|
||||
/// Must not be called after send(), sendFile()
|
||||
/// or redirect() has been called.
|
||||
|
||||
void redirect(const std::string& uri, Poco::Net::HTTPResponse::HTTPStatus status);
|
||||
/// Sets the status code, which must be one of
|
||||
/// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302),
|
||||
/// or HTTP_SEE_OTHER (303),
|
||||
/// and sets the "Location" header field
|
||||
/// to the given URI, which according to
|
||||
/// the HTTP specification, must be absolute.
|
||||
///
|
||||
/// Must not be called after send() has been called.
|
||||
|
||||
void requireAuthentication(const std::string& realm);
|
||||
/// Sets the status code to 401 (Unauthorized)
|
||||
/// and sets the "WWW-Authenticate" header field
|
||||
/// according to the given realm.
|
||||
|
||||
bool sent() const;
|
||||
/// 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
|
||||
|
@ -1,107 +1,125 @@
|
||||
//
|
||||
// ApacheStream.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/include/ApacheStream.h#5 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheStream_INCLUDED
|
||||
#define ApacheConnector_ApacheStream_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/BufferedStreamBuf.h"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
class ApacheStreamBuf: public Poco::BufferedStreamBuf
|
||||
/// This is the streambuf class used for reading from and writing to a socket.
|
||||
{
|
||||
public:
|
||||
ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData = false);
|
||||
/// Creates a ApacheStreamBuf with the given socket.
|
||||
|
||||
~ApacheStreamBuf();
|
||||
/// Destroys the SocketStreamBuf.
|
||||
|
||||
protected:
|
||||
int readFromDevice(char* buffer, std::streamsize length);
|
||||
int writeToDevice(const char* buffer, std::streamsize length);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
STREAM_BUFFER_SIZE = 1024
|
||||
};
|
||||
|
||||
ApacheRequestRec* _pApacheRequest;
|
||||
bool _haveData;
|
||||
};
|
||||
|
||||
|
||||
class ApacheIOS: public virtual std::ios
|
||||
/// The base class for ApacheStream, ApacheInputStream and
|
||||
/// ApacheOutputStream.
|
||||
///
|
||||
/// This class is needed to ensure the correct initialization
|
||||
/// order of the stream buffer and base classes.
|
||||
{
|
||||
public:
|
||||
ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData = false);
|
||||
/// Creates the ApacheIOS with the given socket.
|
||||
|
||||
~ApacheIOS();
|
||||
/// Destroys the ApacheIOS.
|
||||
///
|
||||
/// Flushes the buffer, but does not close the socket.
|
||||
|
||||
ApacheStreamBuf* rdbuf();
|
||||
/// Returns a pointer to the internal ApacheStreamBuf.
|
||||
|
||||
void close();
|
||||
/// Flushes the stream.
|
||||
|
||||
protected:
|
||||
ApacheStreamBuf _buf;
|
||||
};
|
||||
|
||||
|
||||
class ApacheOutputStream: public ApacheIOS, public std::ostream
|
||||
/// An output stream for writing to an Apache response.
|
||||
{
|
||||
public:
|
||||
ApacheOutputStream(ApacheRequestRec* pApacheRequest);
|
||||
/// Creates the ApacheOutputStream with the given socket.
|
||||
|
||||
~ApacheOutputStream();
|
||||
/// Destroys the ApacheOutputStream.
|
||||
///
|
||||
/// Flushes the buffer.
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
//
|
||||
// ApacheStream.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/include/ApacheStream.h#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ApacheConnector_ApacheStream_INCLUDED
|
||||
#define ApacheConnector_ApacheStream_INCLUDED
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/BufferedStreamBuf.h"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
class ApacheStreamBuf: public Poco::BufferedStreamBuf
|
||||
/// This is the streambuf class used for reading from and writing to a socket.
|
||||
{
|
||||
public:
|
||||
ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData = false);
|
||||
/// Creates a ApacheStreamBuf with the given socket.
|
||||
|
||||
~ApacheStreamBuf();
|
||||
/// Destroys the SocketStreamBuf.
|
||||
|
||||
protected:
|
||||
int readFromDevice(char* buffer, std::streamsize length);
|
||||
int writeToDevice(const char* buffer, std::streamsize length);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
STREAM_BUFFER_SIZE = 1024
|
||||
};
|
||||
|
||||
ApacheRequestRec* _pApacheRequest;
|
||||
bool _haveData;
|
||||
};
|
||||
|
||||
|
||||
class ApacheIOS: public virtual std::ios
|
||||
/// The base class for ApacheStream, ApacheInputStream and
|
||||
/// ApacheOutputStream.
|
||||
///
|
||||
/// This class is needed to ensure the correct initialization
|
||||
/// order of the stream buffer and base classes.
|
||||
{
|
||||
public:
|
||||
ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData = false);
|
||||
/// Creates the ApacheIOS with the given socket.
|
||||
|
||||
~ApacheIOS();
|
||||
/// Destroys the ApacheIOS.
|
||||
///
|
||||
/// Flushes the buffer, but does not close the socket.
|
||||
|
||||
ApacheStreamBuf* rdbuf();
|
||||
/// Returns a pointer to the internal ApacheStreamBuf.
|
||||
|
||||
void close();
|
||||
/// Flushes the stream.
|
||||
|
||||
protected:
|
||||
ApacheStreamBuf _buf;
|
||||
};
|
||||
|
||||
|
||||
class ApacheOutputStream: public ApacheIOS, public std::ostream
|
||||
/// An output stream for writing to an Apache response.
|
||||
{
|
||||
public:
|
||||
ApacheOutputStream(ApacheRequestRec* pApacheRequest);
|
||||
/// Creates the ApacheOutputStream with the given socket.
|
||||
|
||||
~ApacheOutputStream();
|
||||
/// Destroys the ApacheOutputStream.
|
||||
///
|
||||
/// Flushes the buffer.
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
|
@ -1,188 +1,206 @@
|
||||
//
|
||||
// FormServer.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/samples/FormServer/src/FormServer.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Net/HTMLForm.h"
|
||||
#include "Poco/Net/PartHandler.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/NullStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/ClassLibrary.h"
|
||||
|
||||
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPRequestHandlerFactory;
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Net::MessageHeader;
|
||||
using Poco::Net::HTMLForm;
|
||||
using Poco::Net::NameValueCollection;
|
||||
using Poco::CountingInputStream;
|
||||
using Poco::NullOutputStream;
|
||||
using Poco::StreamCopier;
|
||||
|
||||
|
||||
class MyPartHandler: public Poco::Net::PartHandler
|
||||
{
|
||||
public:
|
||||
MyPartHandler():
|
||||
_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
void handlePart(const MessageHeader& header, std::istream& stream)
|
||||
{
|
||||
_type = header.get("Content-Type", "(unspecified)");
|
||||
if (header.has("Content-Disposition"))
|
||||
{
|
||||
std::string disp;
|
||||
NameValueCollection params;
|
||||
MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
|
||||
_name = params.get("name", "(unnamed)");
|
||||
_fileName = params.get("filename", "(unnamed)");
|
||||
}
|
||||
|
||||
CountingInputStream istr(stream);
|
||||
NullOutputStream ostr;
|
||||
StreamCopier::copyStream(istr, ostr);
|
||||
_length = istr.chars();
|
||||
}
|
||||
|
||||
int length() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
const std::string& name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
const std::string& fileName() const
|
||||
{
|
||||
return _fileName;
|
||||
}
|
||||
|
||||
const std::string& contentType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
private:
|
||||
int _length;
|
||||
std::string _type;
|
||||
std::string _name;
|
||||
std::string _fileName;
|
||||
};
|
||||
|
||||
|
||||
class FormRequestHandler: public HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
{
|
||||
public:
|
||||
FormRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
MyPartHandler partHandler;
|
||||
HTMLForm form(request, request.stream(), partHandler);
|
||||
|
||||
response.setChunkedTransferEncoding(true);
|
||||
response.setContentType("text/html");
|
||||
|
||||
std::ostream& ostr = response.send();
|
||||
|
||||
ostr <<
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>POCO Form Server Sample</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<h1>POCO Form Server Sample</h1>\n"
|
||||
"<h2>GET Form</h2>\n"
|
||||
"<form method=\"GET\" action=\"/form\">\n"
|
||||
"<input type=\"text\" name=\"text\" size=\"31\">\n"
|
||||
"<input type=\"submit\" value=\"GET\">\n"
|
||||
"</form>\n"
|
||||
"<h2>POST Form</h2>\n"
|
||||
"<form method=\"POST\" action=\"/form\">\n"
|
||||
"<input type=\"text\" name=\"text\" size=\"31\">\n"
|
||||
"<input type=\"submit\" value=\"POST\">\n"
|
||||
"</form>\n"
|
||||
"<h2>File Upload</h2>\n"
|
||||
"<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n"
|
||||
"<input type=\"file\" name=\"file\" size=\"31\"> \n"
|
||||
"<input type=\"submit\" value=\"Upload\">\n"
|
||||
"</form>\n";
|
||||
|
||||
ostr << "<h2>Request</h2><p>\n";
|
||||
ostr << "Method: " << request.getMethod() << "<br>\n";
|
||||
ostr << "URI: " << request.getURI() << "<br>\n";
|
||||
NameValueCollection::ConstIterator it = request.begin();
|
||||
NameValueCollection::ConstIterator end = request.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ostr << it->first << ": " << it->second << "<br>\n";
|
||||
}
|
||||
ostr << "</p>";
|
||||
|
||||
if (!form.empty())
|
||||
{
|
||||
ostr << "<h2>Form</h2><p>\n";
|
||||
it = form.begin();
|
||||
end = form.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ostr << it->first << ": " << it->second << "<br>\n";
|
||||
}
|
||||
ostr << "</p>";
|
||||
}
|
||||
|
||||
if (!partHandler.name().empty())
|
||||
{
|
||||
ostr << "<h2>Upload</h2><p>\n";
|
||||
ostr << "Name: " << partHandler.name() << "<br>\n";
|
||||
ostr << "File Name: " << partHandler.fileName() << "<br>\n";
|
||||
ostr << "Type: " << partHandler.contentType() << "<br>\n";
|
||||
ostr << "Size: " << partHandler.length() << "<br>\n";
|
||||
ostr << "</p>";
|
||||
}
|
||||
ostr << "</body>\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
//
|
||||
// FormServer.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/samples/FormServer/src/FormServer.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Net/HTMLForm.h"
|
||||
#include "Poco/Net/PartHandler.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/NullStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/ClassLibrary.h"
|
||||
|
||||
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPRequestHandlerFactory;
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Net::MessageHeader;
|
||||
using Poco::Net::HTMLForm;
|
||||
using Poco::Net::NameValueCollection;
|
||||
using Poco::CountingInputStream;
|
||||
using Poco::NullOutputStream;
|
||||
using Poco::StreamCopier;
|
||||
|
||||
|
||||
class MyPartHandler: public Poco::Net::PartHandler
|
||||
{
|
||||
public:
|
||||
MyPartHandler():
|
||||
_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
void handlePart(const MessageHeader& header, std::istream& stream)
|
||||
{
|
||||
_type = header.get("Content-Type", "(unspecified)");
|
||||
if (header.has("Content-Disposition"))
|
||||
{
|
||||
std::string disp;
|
||||
NameValueCollection params;
|
||||
MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
|
||||
_name = params.get("name", "(unnamed)");
|
||||
_fileName = params.get("filename", "(unnamed)");
|
||||
}
|
||||
|
||||
CountingInputStream istr(stream);
|
||||
NullOutputStream ostr;
|
||||
StreamCopier::copyStream(istr, ostr);
|
||||
_length = istr.chars();
|
||||
}
|
||||
|
||||
int length() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
const std::string& name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
const std::string& fileName() const
|
||||
{
|
||||
return _fileName;
|
||||
}
|
||||
|
||||
const std::string& contentType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
private:
|
||||
int _length;
|
||||
std::string _type;
|
||||
std::string _name;
|
||||
std::string _fileName;
|
||||
};
|
||||
|
||||
|
||||
class FormRequestHandler: public HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
{
|
||||
public:
|
||||
FormRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
MyPartHandler partHandler;
|
||||
HTMLForm form(request, request.stream(), partHandler);
|
||||
|
||||
response.setChunkedTransferEncoding(true);
|
||||
response.setContentType("text/html");
|
||||
|
||||
std::ostream& ostr = response.send();
|
||||
|
||||
ostr <<
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>POCO Form Server Sample</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<h1>POCO Form Server Sample</h1>\n"
|
||||
"<h2>GET Form</h2>\n"
|
||||
"<form method=\"GET\" action=\"/form\">\n"
|
||||
"<input type=\"text\" name=\"text\" size=\"31\">\n"
|
||||
"<input type=\"submit\" value=\"GET\">\n"
|
||||
"</form>\n"
|
||||
"<h2>POST Form</h2>\n"
|
||||
"<form method=\"POST\" action=\"/form\">\n"
|
||||
"<input type=\"text\" name=\"text\" size=\"31\">\n"
|
||||
"<input type=\"submit\" value=\"POST\">\n"
|
||||
"</form>\n"
|
||||
"<h2>File Upload</h2>\n"
|
||||
"<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n"
|
||||
"<input type=\"file\" name=\"file\" size=\"31\"> \n"
|
||||
"<input type=\"submit\" value=\"Upload\">\n"
|
||||
"</form>\n";
|
||||
|
||||
ostr << "<h2>Request</h2><p>\n";
|
||||
ostr << "Method: " << request.getMethod() << "<br>\n";
|
||||
ostr << "URI: " << request.getURI() << "<br>\n";
|
||||
NameValueCollection::ConstIterator it = request.begin();
|
||||
NameValueCollection::ConstIterator end = request.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ostr << it->first << ": " << it->second << "<br>\n";
|
||||
}
|
||||
ostr << "</p>";
|
||||
|
||||
if (!form.empty())
|
||||
{
|
||||
ostr << "<h2>Form</h2><p>\n";
|
||||
it = form.begin();
|
||||
end = form.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ostr << it->first << ": " << it->second << "<br>\n";
|
||||
}
|
||||
ostr << "</p>";
|
||||
}
|
||||
|
||||
if (!partHandler.name().empty())
|
||||
{
|
||||
ostr << "<h2>Upload</h2><p>\n";
|
||||
ostr << "Name: " << partHandler.name() << "<br>\n";
|
||||
ostr << "File Name: " << partHandler.fileName() << "<br>\n";
|
||||
ostr << "Type: " << partHandler.contentType() << "<br>\n";
|
||||
ostr << "Size: " << partHandler.length() << "<br>\n";
|
||||
ostr << "</p>";
|
||||
}
|
||||
ostr << "</body>\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
|
@ -1,77 +1,95 @@
|
||||
//
|
||||
// TimeServer.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/samples/TimeServer/src/TimeServer.cpp#1 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/ClassLibrary.h"
|
||||
|
||||
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPRequestHandlerFactory;
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Timestamp;
|
||||
using Poco::DateTimeFormatter;
|
||||
using Poco::DateTimeFormat;
|
||||
|
||||
|
||||
class TimeRequestHandler: public HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
{
|
||||
public:
|
||||
TimeRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
Timestamp now;
|
||||
std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
|
||||
|
||||
response.setChunkedTransferEncoding(true);
|
||||
response.setContentType("text/html");
|
||||
|
||||
std::ostream& ostr = response.send();
|
||||
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>";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
//
|
||||
// TimeServer.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/samples/TimeServer/src/TimeServer.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
#include "Poco/ClassLibrary.h"
|
||||
|
||||
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPRequestHandlerFactory;
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Timestamp;
|
||||
using Poco::DateTimeFormatter;
|
||||
using Poco::DateTimeFormat;
|
||||
|
||||
|
||||
class TimeRequestHandler: public HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
{
|
||||
public:
|
||||
TimeRequestHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
Timestamp now;
|
||||
std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
|
||||
|
||||
response.setChunkedTransferEncoding(true);
|
||||
response.setContentType("text/html");
|
||||
|
||||
std::ostream& ostr = response.send();
|
||||
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>";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
|
@ -1,57 +1,75 @@
|
||||
//
|
||||
// ApacheApplication.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheApplication.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheApplication.h"
|
||||
#include "ApacheChannel.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::Logger;
|
||||
using Poco::FastMutex;
|
||||
|
||||
|
||||
ApacheApplication::ApacheApplication():
|
||||
_ready(false)
|
||||
{
|
||||
Logger::root().setChannel(new ApacheChannel);
|
||||
}
|
||||
|
||||
|
||||
ApacheApplication::~ApacheApplication()
|
||||
{
|
||||
Logger::shutdown();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
//
|
||||
// ApacheApplication.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheApplication.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheApplication.h"
|
||||
#include "ApacheChannel.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::Logger;
|
||||
using Poco::FastMutex;
|
||||
|
||||
|
||||
ApacheApplication::ApacheApplication():
|
||||
_ready(false)
|
||||
{
|
||||
Logger::root().setChannel(new ApacheChannel);
|
||||
}
|
||||
|
||||
|
||||
ApacheApplication::~ApacheApplication()
|
||||
{
|
||||
Logger::shutdown();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -1,33 +1,51 @@
|
||||
//
|
||||
// ApacheApplication.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheChannel.cpp#1 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#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());
|
||||
}
|
||||
//
|
||||
// ApacheApplication.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheChannel.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#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());
|
||||
}
|
||||
|
@ -1,291 +1,309 @@
|
||||
//
|
||||
// ApacheConnector.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheConnector.cpp#6 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheApplication.h"
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "httpd.h"
|
||||
#include "http_connection.h"
|
||||
#include "http_config.h"
|
||||
#include "http_core.h"
|
||||
#include "http_protocol.h"
|
||||
#include "http_log.h"
|
||||
#include "apr.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_buckets.h"
|
||||
#include "apr_file_info.h"
|
||||
#include "apr_hash.h"
|
||||
#define APR_WANT_STRFUNC
|
||||
#include "apr_want.h"
|
||||
#include "http_request.h"
|
||||
#include "util_filter.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPResponse;
|
||||
|
||||
|
||||
extern "C" module AP_MODULE_DECLARE_DATA poco_module;
|
||||
|
||||
|
||||
ApacheRequestRec::ApacheRequestRec(request_rec* pRec):
|
||||
_pRec(pRec)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ApacheRequestRec::haveRequestBody()
|
||||
{
|
||||
return ap_should_client_block(_pRec) != 0;
|
||||
}
|
||||
|
||||
|
||||
int ApacheRequestRec::readRequest(char* buffer, int length)
|
||||
{
|
||||
return ap_get_client_block(_pRec, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::writeResponse(const char* buffer, int length)
|
||||
{
|
||||
ap_rwrite(buffer, length, _pRec);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::redirect(const std::string& uri)
|
||||
{
|
||||
apr_table_set(_pRec->headers_out, "Location", uri.c_str());
|
||||
_pRec->connection->keepalive = AP_CONN_CLOSE;
|
||||
_pRec->status = 302;
|
||||
ap_set_keepalive(_pRec);
|
||||
ap_send_error_response(_pRec, 0);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::sendErrorResponse(int status)
|
||||
{
|
||||
_pRec->connection->keepalive = AP_CONN_CLOSE;
|
||||
_pRec->status = status;
|
||||
ap_set_keepalive(_pRec);
|
||||
|
||||
ap_send_error_response(_pRec, 0);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::addHeader(const std::string& key, const std::string& value)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::setContentType(const std::string& mediaType)
|
||||
{
|
||||
ap_set_content_type(_pRec, mediaType.c_str());
|
||||
}
|
||||
|
||||
|
||||
int ApacheRequestRec::sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType)
|
||||
{
|
||||
apr_file_t *thefile = 0;
|
||||
apr_finfo_t finfo;
|
||||
apr_size_t nBytes;
|
||||
|
||||
// setting content-type
|
||||
ap_set_content_type(_pRec, mediaType.c_str());
|
||||
|
||||
// opening file
|
||||
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);
|
||||
|
||||
// setting last-updated & co
|
||||
ap_update_mtime(_pRec, finfo.mtime);
|
||||
ap_set_last_modified(_pRec);
|
||||
ap_set_content_length(_pRec, fileSize);
|
||||
|
||||
// sending file
|
||||
ap_send_fd(thefile, _pRec, 0, fileSize, &nBytes);
|
||||
|
||||
// well done
|
||||
return 0;
|
||||
}
|
||||
|
||||
// file not opened successfully -> produce an exception in C++ code
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
request.setMethod(_pRec->method);
|
||||
request.setURI(_pRec->unparsed_uri);
|
||||
|
||||
// iterating over raw-headers and printing them
|
||||
for (int i = 0; i < arr->nelts; i++)
|
||||
{
|
||||
request.add(elts[i].key, elts[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApacheConnector::log(const char* file, int line, int level, int status, const char *text)
|
||||
{
|
||||
ap_log_error(file, line, level, 0, NULL, text);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int ApacheConnector_handler(request_rec *r)
|
||||
{
|
||||
ApacheRequestRec rec(r);
|
||||
ApacheApplication& app(ApacheApplication::instance());
|
||||
|
||||
try
|
||||
{
|
||||
// ensure application is ready
|
||||
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))
|
||||
return DECLINED;
|
||||
|
||||
apr_status_t rv;
|
||||
if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
|
||||
return rv;
|
||||
|
||||
std::auto_ptr<ApacheServerRequest> pRequest(new ApacheServerRequest(
|
||||
&rec,
|
||||
r->connection->local_ip,
|
||||
r->connection->local_addr->port,
|
||||
r->connection->remote_ip,
|
||||
r->connection->remote_addr->port));
|
||||
|
||||
std::auto_ptr<ApacheServerResponse> pResponse(new ApacheServerResponse(pRequest.get()));
|
||||
|
||||
// add header information to request
|
||||
rec.copyHeaders(*pRequest);
|
||||
|
||||
try
|
||||
{
|
||||
std::auto_ptr<HTTPRequestHandler> pHandler(app.factory().createRequestHandler(*pRequest));
|
||||
|
||||
if (pHandler.get())
|
||||
{
|
||||
pHandler->handleRequest(*pRequest, *pResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
pResponse->sendErrorResponse(HTTP_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pResponse->sendErrorResponse(HTTP_INTERNAL_SERVER_ERROR);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ApacheConnector_register_hooks(apr_pool_t *p)
|
||||
{
|
||||
ap_hook_handler(ApacheConnector_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char* ApacheConnector_uris(cmd_parms *cmd, void *in_dconf, const char *in_str)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApacheApplication::instance().factory().handleURIs(in_str);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char* ApacheConnector_config(cmd_parms *cmd, void *in_dconf, const char *in_str)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApacheApplication::instance().loadConfiguration(in_str);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const command_rec ApacheConnector_cmds[] =
|
||||
{
|
||||
AP_INIT_RAW_ARGS(
|
||||
"AddPocoRequestHandler",
|
||||
reinterpret_cast<cmd_func>(ApacheConnector_uris),
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
"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(
|
||||
"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
|
||||
};
|
||||
//
|
||||
// ApacheConnector.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheConnector.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheConnector.h"
|
||||
#include "ApacheApplication.h"
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include <memory>
|
||||
#include "httpd.h"
|
||||
#include "http_connection.h"
|
||||
#include "http_config.h"
|
||||
#include "http_core.h"
|
||||
#include "http_protocol.h"
|
||||
#include "http_log.h"
|
||||
#include "apr.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_buckets.h"
|
||||
#include "apr_file_info.h"
|
||||
#include "apr_hash.h"
|
||||
#define APR_WANT_STRFUNC
|
||||
#include "apr_want.h"
|
||||
#include "http_request.h"
|
||||
#include "util_filter.h"
|
||||
|
||||
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPResponse;
|
||||
|
||||
|
||||
extern "C" module AP_MODULE_DECLARE_DATA poco_module;
|
||||
|
||||
|
||||
ApacheRequestRec::ApacheRequestRec(request_rec* pRec):
|
||||
_pRec(pRec)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ApacheRequestRec::haveRequestBody()
|
||||
{
|
||||
return ap_should_client_block(_pRec) != 0;
|
||||
}
|
||||
|
||||
|
||||
int ApacheRequestRec::readRequest(char* buffer, int length)
|
||||
{
|
||||
return ap_get_client_block(_pRec, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::writeResponse(const char* buffer, int length)
|
||||
{
|
||||
ap_rwrite(buffer, length, _pRec);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::redirect(const std::string& uri, int status)
|
||||
{
|
||||
apr_table_set(_pRec->headers_out, "Location", uri.c_str());
|
||||
_pRec->connection->keepalive = AP_CONN_CLOSE;
|
||||
_pRec->status = status;
|
||||
ap_set_keepalive(_pRec);
|
||||
ap_send_error_response(_pRec, 0);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::sendErrorResponse(int status)
|
||||
{
|
||||
_pRec->connection->keepalive = AP_CONN_CLOSE;
|
||||
_pRec->status = status;
|
||||
ap_set_keepalive(_pRec);
|
||||
|
||||
ap_send_error_response(_pRec, 0);
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::addHeader(const std::string& key, const std::string& value)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestRec::setContentType(const std::string& mediaType)
|
||||
{
|
||||
ap_set_content_type(_pRec, mediaType.c_str());
|
||||
}
|
||||
|
||||
|
||||
int ApacheRequestRec::sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType)
|
||||
{
|
||||
apr_file_t *thefile = 0;
|
||||
apr_finfo_t finfo;
|
||||
apr_size_t nBytes;
|
||||
|
||||
// setting content-type
|
||||
ap_set_content_type(_pRec, mediaType.c_str());
|
||||
|
||||
// opening file
|
||||
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);
|
||||
|
||||
// setting last-updated & co
|
||||
ap_update_mtime(_pRec, finfo.mtime);
|
||||
ap_set_last_modified(_pRec);
|
||||
ap_set_content_length(_pRec, fileSize);
|
||||
|
||||
// sending file
|
||||
ap_send_fd(thefile, _pRec, 0, fileSize, &nBytes);
|
||||
|
||||
// well done
|
||||
return 0;
|
||||
}
|
||||
|
||||
// file not opened successfully -> produce an exception in C++ code
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
request.setMethod(_pRec->method);
|
||||
request.setURI(_pRec->unparsed_uri);
|
||||
|
||||
// iterating over raw-headers and printing them
|
||||
for (int i = 0; i < arr->nelts; i++)
|
||||
{
|
||||
request.add(elts[i].key, elts[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApacheConnector::log(const char* file, int line, int level, int status, const char *text)
|
||||
{
|
||||
ap_log_error(file, line, level, 0, NULL, "%s", text);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int ApacheConnector_handler(request_rec *r)
|
||||
{
|
||||
ApacheRequestRec rec(r);
|
||||
ApacheApplication& app(ApacheApplication::instance());
|
||||
|
||||
try
|
||||
{
|
||||
// ensure application is ready
|
||||
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))
|
||||
return DECLINED;
|
||||
|
||||
apr_status_t rv;
|
||||
if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
|
||||
return rv;
|
||||
|
||||
std::auto_ptr<ApacheServerRequest> pRequest(new ApacheServerRequest(
|
||||
&rec,
|
||||
r->connection->local_ip,
|
||||
r->connection->local_addr->port,
|
||||
r->connection->remote_ip,
|
||||
r->connection->remote_addr->port));
|
||||
|
||||
std::auto_ptr<ApacheServerResponse> pResponse(new ApacheServerResponse(pRequest.get()));
|
||||
|
||||
// add header information to request
|
||||
rec.copyHeaders(*pRequest);
|
||||
|
||||
try
|
||||
{
|
||||
std::auto_ptr<HTTPRequestHandler> pHandler(app.factory().createRequestHandler(*pRequest));
|
||||
|
||||
if (pHandler.get())
|
||||
{
|
||||
pHandler->handleRequest(*pRequest, *pResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
pResponse->sendErrorResponse(HTTP_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pResponse->sendErrorResponse(HTTP_INTERNAL_SERVER_ERROR);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ApacheConnector_register_hooks(apr_pool_t *p)
|
||||
{
|
||||
ap_hook_handler(ApacheConnector_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char* ApacheConnector_uris(cmd_parms *cmd, void *in_dconf, const char *in_str)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApacheApplication::instance().factory().handleURIs(in_str);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char* ApacheConnector_config(cmd_parms *cmd, void *in_dconf, const char *in_str)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApacheApplication::instance().loadConfiguration(in_str);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, "Unknown exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const command_rec ApacheConnector_cmds[] =
|
||||
{
|
||||
AP_INIT_RAW_ARGS(
|
||||
"AddPocoRequestHandler",
|
||||
reinterpret_cast<cmd_func>(ApacheConnector_uris),
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
"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(
|
||||
"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
|
||||
};
|
||||
|
@ -1,118 +1,136 @@
|
||||
//
|
||||
// ApacheRequestHandlerFactory.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheRequestHandlerFactory.cpp#8 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Manifest.h"
|
||||
#include "Poco/File.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::StringTokenizer;
|
||||
using Poco::FastMutex;
|
||||
|
||||
|
||||
ApacheRequestHandlerFactory::ApacheRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheRequestHandlerFactory::~ApacheRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Poco::Net::HTTPRequestHandler* ApacheRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
// only if the given uri is found in _uris we are
|
||||
// handling this request.
|
||||
RequestHandlerFactories::iterator it = _requestHandlers.begin();
|
||||
RequestHandlerFactories::iterator itEnd = _requestHandlers.end();
|
||||
std::string uri = request.getURI();
|
||||
|
||||
// if any uri in our map is found at the beginning of the given
|
||||
// uri -> then we handle it!!
|
||||
for (; it != itEnd; it++)
|
||||
{
|
||||
if (uri.find(it->first) == 0 || it->first.find(uri) == 0)
|
||||
{
|
||||
return it->second->createRequestHandler(request);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestHandlerFactory::handleURIs(const std::string& uris)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
StringTokenizer st(uris, " ", StringTokenizer::TOK_TRIM);
|
||||
StringTokenizer::Iterator it = st.begin();
|
||||
StringTokenizer::Iterator itEnd = st.end();
|
||||
std::string factoryName = (*it);
|
||||
it++;
|
||||
std::string dllName = (*it);
|
||||
it++;
|
||||
|
||||
for (; it != itEnd; it++)
|
||||
{
|
||||
addRequestHandlerFactory(dllName, factoryName, *it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestHandlerFactory::addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri)
|
||||
{
|
||||
try
|
||||
{
|
||||
_loader.loadLibrary(dllPath);
|
||||
Poco::Net::HTTPRequestHandlerFactory* pFactory = _loader.classFor(factoryName).create();
|
||||
_requestHandlers.insert(std::make_pair(uri, pFactory));
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ApacheRequestHandlerFactory::mustHandle(const std::string& uri)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
// 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;
|
||||
}
|
||||
//
|
||||
// ApacheRequestHandlerFactory.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheRequestHandlerFactory.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Manifest.h"
|
||||
#include "Poco/File.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::StringTokenizer;
|
||||
using Poco::FastMutex;
|
||||
|
||||
|
||||
ApacheRequestHandlerFactory::ApacheRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheRequestHandlerFactory::~ApacheRequestHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Poco::Net::HTTPRequestHandler* ApacheRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
// only if the given uri is found in _uris we are
|
||||
// handling this request.
|
||||
RequestHandlerFactories::iterator it = _requestHandlers.begin();
|
||||
RequestHandlerFactories::iterator itEnd = _requestHandlers.end();
|
||||
std::string uri = request.getURI();
|
||||
|
||||
// if any uri in our map is found at the beginning of the given
|
||||
// uri -> then we handle it!!
|
||||
for (; it != itEnd; it++)
|
||||
{
|
||||
if (uri.find(it->first) == 0 || it->first.find(uri) == 0)
|
||||
{
|
||||
return it->second->createRequestHandler(request);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestHandlerFactory::handleURIs(const std::string& uris)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
StringTokenizer st(uris, " ", StringTokenizer::TOK_TRIM);
|
||||
StringTokenizer::Iterator it = st.begin();
|
||||
StringTokenizer::Iterator itEnd = st.end();
|
||||
std::string factoryName = (*it);
|
||||
it++;
|
||||
std::string dllName = (*it);
|
||||
it++;
|
||||
|
||||
for (; it != itEnd; it++)
|
||||
{
|
||||
addRequestHandlerFactory(dllName, factoryName, *it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApacheRequestHandlerFactory::addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri)
|
||||
{
|
||||
try
|
||||
{
|
||||
_loader.loadLibrary(dllPath);
|
||||
Poco::Net::HTTPRequestHandlerFactory* pFactory = _loader.classFor(factoryName).create();
|
||||
_requestHandlers.insert(std::make_pair(uri, pFactory));
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
ApacheConnector::log(__FILE__, __LINE__, ApacheConnector::PRIO_ERROR, 0, exc.displayText().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ApacheRequestHandlerFactory::mustHandle(const std::string& uri)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -1,64 +1,82 @@
|
||||
//
|
||||
// ApacheServerRequest.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheServerRequest.cpp#9 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
ApacheServerRequest::ApacheServerRequest(
|
||||
ApacheRequestRec* pApacheRequest,
|
||||
const char* serverName,
|
||||
int serverPort,
|
||||
const char* clientName,
|
||||
int clientPort):
|
||||
_pApacheRequest(pApacheRequest),
|
||||
_pResponse(0),
|
||||
_pStream(new ApacheInputStream(_pApacheRequest)),
|
||||
_serverAddress(serverName, serverPort),
|
||||
_clientAddress(clientName, clientPort)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheServerRequest::~ApacheServerRequest()
|
||||
{
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
const Poco::Net::HTTPServerParams& ApacheServerRequest::serverParams() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
//
|
||||
// ApacheServerRequest.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheServerRequest.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheRequestHandlerFactory.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
ApacheServerRequest::ApacheServerRequest(
|
||||
ApacheRequestRec* pApacheRequest,
|
||||
const char* serverName,
|
||||
int serverPort,
|
||||
const char* clientName,
|
||||
int clientPort):
|
||||
_pApacheRequest(pApacheRequest),
|
||||
_pResponse(0),
|
||||
_pStream(new ApacheInputStream(_pApacheRequest)),
|
||||
_serverAddress(serverName, serverPort),
|
||||
_clientAddress(clientName, clientPort)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheServerRequest::~ApacheServerRequest()
|
||||
{
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
const Poco::Net::HTTPServerParams& ApacheServerRequest::serverParams() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -1,133 +1,151 @@
|
||||
//
|
||||
// ApacheServerResponse.cpp
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheServerResponse.cpp#8 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Net/HTTPCookie.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::File;
|
||||
using Poco::OpenFileException;
|
||||
using Poco::Net::HTTPCookie;
|
||||
|
||||
|
||||
ApacheServerResponse::ApacheServerResponse(ApacheServerRequest* pRequest):
|
||||
_pStream(0),
|
||||
_pApacheRequest(pRequest->_pApacheRequest)
|
||||
{
|
||||
setVersion(pRequest->getVersion());
|
||||
setKeepAlive(pRequest->getKeepAlive());
|
||||
|
||||
pRequest->setResponse(this);
|
||||
}
|
||||
|
||||
|
||||
ApacheServerResponse::~ApacheServerResponse()
|
||||
{
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::initApacheOutputStream()
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
_pApacheRequest->setContentType(getContentType());
|
||||
|
||||
std::vector<HTTPCookie> cookies;
|
||||
getCookies(cookies);
|
||||
|
||||
std::size_t cnt = cookies.size();
|
||||
for (int c = 0; c < cnt; c++)
|
||||
{
|
||||
_pApacheRequest->addHeader("Set-Cookie", cookies[c].toString());
|
||||
}
|
||||
|
||||
_pStream = new ApacheOutputStream(_pApacheRequest);
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendContinue()
|
||||
{
|
||||
// should be handled by Apache
|
||||
}
|
||||
|
||||
|
||||
std::ostream& ApacheServerResponse::send()
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
return *_pStream;
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendFile(const std::string& path, const std::string& mediaType)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
File f(path);
|
||||
if (_pApacheRequest->sendFile(path, static_cast<unsigned int>(f.getSize()), mediaType) != 0)
|
||||
throw OpenFileException(path);
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendBuffer(const void* pBuffer, std::size_t length)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
_pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length));
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::redirect(const std::string& uri)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
try
|
||||
{
|
||||
_pApacheRequest->redirect(uri);
|
||||
}
|
||||
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
|
||||
}
|
||||
//
|
||||
// ApacheServerResponse.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheServerResponse.cpp#3 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheServerResponse.h"
|
||||
#include "ApacheServerRequest.h"
|
||||
#include "ApacheStream.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Net/HTTPCookie.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
using Poco::File;
|
||||
using Poco::OpenFileException;
|
||||
using Poco::Net::HTTPCookie;
|
||||
|
||||
|
||||
ApacheServerResponse::ApacheServerResponse(ApacheServerRequest* pRequest):
|
||||
_pStream(0),
|
||||
_pApacheRequest(pRequest->_pApacheRequest)
|
||||
{
|
||||
setVersion(pRequest->getVersion());
|
||||
setKeepAlive(pRequest->getKeepAlive());
|
||||
|
||||
pRequest->setResponse(this);
|
||||
}
|
||||
|
||||
|
||||
ApacheServerResponse::~ApacheServerResponse()
|
||||
{
|
||||
delete _pStream;
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::initApacheOutputStream()
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
_pApacheRequest->setContentType(getContentType());
|
||||
|
||||
std::vector<HTTPCookie> cookies;
|
||||
getCookies(cookies);
|
||||
|
||||
std::size_t cnt = cookies.size();
|
||||
for (int c = 0; c < cnt; c++)
|
||||
{
|
||||
_pApacheRequest->addHeader("Set-Cookie", cookies[c].toString());
|
||||
}
|
||||
|
||||
_pStream = new ApacheOutputStream(_pApacheRequest);
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendContinue()
|
||||
{
|
||||
// should be handled by Apache
|
||||
}
|
||||
|
||||
|
||||
std::ostream& ApacheServerResponse::send()
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
return *_pStream;
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendFile(const std::string& path, const std::string& mediaType)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
File f(path);
|
||||
if (_pApacheRequest->sendFile(path, static_cast<unsigned int>(f.getSize()), mediaType) != 0)
|
||||
throw OpenFileException(path);
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::sendBuffer(const void* pBuffer, std::size_t length)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
_pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length));
|
||||
}
|
||||
|
||||
|
||||
void ApacheServerResponse::redirect(const std::string& uri, HTTPStatus status)
|
||||
{
|
||||
poco_assert (!_pStream);
|
||||
|
||||
initApacheOutputStream();
|
||||
|
||||
try
|
||||
{
|
||||
_pApacheRequest->redirect(uri, status);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -1,124 +1,142 @@
|
||||
//
|
||||
// ApacheStream.h
|
||||
//
|
||||
// $Id: //poco/Main/ApacheConnector/src/ApacheStream.cpp#9 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheStream.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
using Poco::BufferedStreamBuf;
|
||||
|
||||
|
||||
//
|
||||
// ApacheStreamBuf
|
||||
//
|
||||
|
||||
|
||||
ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out),
|
||||
_pApacheRequest(pApacheRequest),
|
||||
_haveData(haveData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheStreamBuf::~ApacheStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int ApacheStreamBuf::readFromDevice(char* buffer, std::streamsize len)
|
||||
{
|
||||
if (_haveData)
|
||||
return _pApacheRequest->readRequest(buffer, static_cast<int>(len));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ApacheStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
_pApacheRequest->writeResponse(buffer, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheIOS
|
||||
//
|
||||
|
||||
|
||||
ApacheIOS::ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData):
|
||||
_buf(pApacheRequest, haveData)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
ApacheIOS::~ApacheIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ApacheStreamBuf* ApacheIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
void ApacheIOS::close()
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheOutputStream
|
||||
//
|
||||
|
||||
|
||||
ApacheOutputStream::ApacheOutputStream(ApacheRequestRec* pApacheRequest):
|
||||
ApacheIOS(pApacheRequest),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheOutputStream::~ApacheOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheInputStream
|
||||
//
|
||||
|
||||
|
||||
ApacheInputStream::ApacheInputStream(ApacheRequestRec* pApacheRequest):
|
||||
ApacheIOS(pApacheRequest, pApacheRequest->haveRequestBody()),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheInputStream::~ApacheInputStream()
|
||||
{
|
||||
}
|
||||
//
|
||||
// ApacheStream.h
|
||||
//
|
||||
// $Id: //poco/1.4/ApacheConnector/src/ApacheStream.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// 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:
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#include "ApacheStream.h"
|
||||
#include "ApacheConnector.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
using Poco::BufferedStreamBuf;
|
||||
|
||||
|
||||
//
|
||||
// ApacheStreamBuf
|
||||
//
|
||||
|
||||
|
||||
ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData):
|
||||
BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out),
|
||||
_pApacheRequest(pApacheRequest),
|
||||
_haveData(haveData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheStreamBuf::~ApacheStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int ApacheStreamBuf::readFromDevice(char* buffer, std::streamsize len)
|
||||
{
|
||||
if (_haveData)
|
||||
return _pApacheRequest->readRequest(buffer, static_cast<int>(len));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ApacheStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
|
||||
{
|
||||
_pApacheRequest->writeResponse(buffer, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheIOS
|
||||
//
|
||||
|
||||
|
||||
ApacheIOS::ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData):
|
||||
_buf(pApacheRequest, haveData)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
|
||||
ApacheIOS::~ApacheIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ApacheStreamBuf* ApacheIOS::rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
|
||||
void ApacheIOS::close()
|
||||
{
|
||||
_buf.sync();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheOutputStream
|
||||
//
|
||||
|
||||
|
||||
ApacheOutputStream::ApacheOutputStream(ApacheRequestRec* pApacheRequest):
|
||||
ApacheIOS(pApacheRequest),
|
||||
std::ostream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheOutputStream::~ApacheOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ApacheInputStream
|
||||
//
|
||||
|
||||
|
||||
ApacheInputStream::ApacheInputStream(ApacheRequestRec* pApacheRequest):
|
||||
ApacheIOS(pApacheRequest, pApacheRequest->haveRequestBody()),
|
||||
std::istream(&_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheInputStream::~ApacheInputStream()
|
||||
{
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ SET(PROJECT_VERSION ${COMPLETE_VERSION})
|
||||
|
||||
if(NOT MSVC_IDE)
|
||||
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)
|
||||
endif()
|
||||
message(STATUS "Setting Poco build type - ${CMAKE_BUILD_TYPE}")
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#if SSLEAY_VERSION_NUMBER >= 0x0907000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0907000L
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
@ -61,7 +61,7 @@ int OpenSSLInitializer::_rc(0);
|
||||
|
||||
OpenSSLInitializer::OpenSSLInitializer()
|
||||
{
|
||||
initialize();
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ objects = Binder Extractor SessionImpl Connector \
|
||||
MySQLStatementImpl ResultMetadata MySQLException \
|
||||
SessionHandle StatementExecutor
|
||||
|
||||
target = PocoMySQL
|
||||
target = PocoDataMySQL
|
||||
target_version = $(LIBVERSION)
|
||||
target_libs = PocoData PocoFoundation
|
||||
|
||||
|
@ -44,7 +44,7 @@ objects = Binder ConnectionHandle Connector EnvironmentHandle \
|
||||
Extractor ODBCMetaColumn ODBCException ODBCStatementImpl \
|
||||
Parameter Preparator SessionImpl TypeInfo Unicode Utility
|
||||
|
||||
target = PocoODBC
|
||||
target = PocoDataODBC
|
||||
target_version = $(LIBVERSION)
|
||||
target_libs = PocoData PocoFoundation
|
||||
|
||||
|
@ -17,7 +17,7 @@ objects = Binder Extractor SessionImpl Connector \
|
||||
SQLiteException SQLiteStatementImpl Utility \
|
||||
sqlite3
|
||||
|
||||
target = PocoSQLite
|
||||
target = PocoDataSQLite
|
||||
target_version = $(LIBVERSION)
|
||||
target_libs = PocoData PocoFoundation
|
||||
|
||||
|
@ -60,6 +60,10 @@
|
||||
// #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
|
||||
// Zero means OS default
|
||||
#ifndef POCO_THREAD_STACK_SIZE
|
||||
|
@ -52,12 +52,13 @@ public:
|
||||
typedef UInt8 NodeId[6]; /// Ethernet address.
|
||||
|
||||
static std::string getImpl(const std::string& name);
|
||||
static bool hasImpl(const std::string& name);
|
||||
static void setImpl(const std::string& name, const std::string& value);
|
||||
static std::string osNameImpl();
|
||||
static std::string osVersionImpl();
|
||||
static std::string osArchitectureImpl();
|
||||
static std::string nodeNameImpl();
|
||||
static bool hasImpl(const std::string& name);
|
||||
static void setImpl(const std::string& name, const std::string& value);
|
||||
static std::string osNameImpl();
|
||||
static std::string osDisplayNameImpl();
|
||||
static std::string osVersionImpl();
|
||||
static std::string osArchitectureImpl();
|
||||
static std::string nodeNameImpl();
|
||||
static void nodeIdImpl(NodeId& id);
|
||||
static unsigned processorCountImpl();
|
||||
|
||||
|
@ -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
|
||||
/// characters have a special meaning. Characters without a special meaning
|
||||
/// are copied verbatim to the result. A percent sign (%) marks the beginning
|
||||
/// of a format specification. Format specifications have the following syntax:
|
||||
///
|
||||
/// %[<index>][<flags>][<width>][.<precision>][<modifier>]<type>
|
||||
///
|
||||
/// 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 optional index argument has the format "[<n>]" and allows to
|
||||
/// address an argument by its zero-based position (see the example below).
|
||||
///
|
||||
/// Following are valid type specifications and their meaning:
|
||||
///
|
||||
/// * b boolean (true = 1, false = 0)
|
||||
/// are copied verbatim to the result. A percent sign (%) marks the beginning
|
||||
/// of a format specification. Format specifications have the following syntax:
|
||||
///
|
||||
/// %[<index>][<flags>][<width>][.<precision>][<modifier>]<type>
|
||||
///
|
||||
/// 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 optional index argument has the format "[<n>]" and allows to
|
||||
/// address an argument by its zero-based position (see the example below).
|
||||
///
|
||||
/// Following are valid type specifications and their meaning:
|
||||
///
|
||||
/// * b boolean (true = 1, false = 0)
|
||||
/// * c character
|
||||
/// * d 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
|
||||
/// * z std::size_t
|
||||
///
|
||||
/// The following flags are supported:
|
||||
///
|
||||
/// * - 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
|
||||
/// * 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 e, E, f, the # flag forces the output value to contain a decimal point in all cases.
|
||||
/// The following flags are supported:
|
||||
///
|
||||
/// * - 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
|
||||
/// * 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 e, E, f, the # flag forces the output value to contain a decimal point in all cases.
|
||||
///
|
||||
/// 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
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// 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
|
||||
/// are copied verbatim to output.
|
||||
///
|
||||
/// If there are more values than format specifiers, the superfluous values are ignored.
|
||||
///
|
||||
/// Usage Examples:
|
||||
/// 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);
|
||||
/// If there are more values than format specifiers, the superfluous values are ignored.
|
||||
///
|
||||
/// Usage Examples:
|
||||
/// 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 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);
|
||||
|
@ -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);
|
||||
/// 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,
|
||||
/// specify two dollar signs ($$) in the format string.
|
||||
/// returns the result. To include a dollar sign in the result string,
|
||||
/// specify two dollar signs ($$) in the format string.
|
||||
|
||||
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
|
||||
/// given message string.
|
||||
|
||||
static void setLevel(const std::string& name, int level);
|
||||
/// Sets the given log level on all loggers that are
|
||||
/// descendants of the Logger with the given name.
|
||||
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
|
||||
/// given message string.
|
||||
|
||||
static void setLevel(const std::string& name, int level);
|
||||
/// Sets the given log level on all loggers that are
|
||||
/// descendants of the Logger with the given name.
|
||||
|
||||
static void setChannel(const std::string& name, Channel* pChannel);
|
||||
/// Attaches the given Channel to all loggers that are
|
||||
@ -396,11 +396,28 @@ public:
|
||||
/// Loggers.
|
||||
|
||||
static void names(std::vector<std::string>& names);
|
||||
/// Fills the given vector with the names
|
||||
/// of all currently defined loggers.
|
||||
|
||||
static const std::string ROOT; /// The name of the root logger ("").
|
||||
|
||||
/// Fills the given vector with the names
|
||||
/// of all currently defined loggers.
|
||||
|
||||
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:
|
||||
typedef std::map<std::string, Logger*> LoggerMap;
|
||||
|
||||
@ -408,12 +425,12 @@ protected:
|
||||
~Logger();
|
||||
|
||||
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 Logger& parent(const std::string& name);
|
||||
static void add(Logger* pLogger);
|
||||
static Logger* find(const std::string& name);
|
||||
static std::string format(const std::string& fmt, int argc, std::string argv[]);
|
||||
static Logger& parent(const std::string& name);
|
||||
static void add(Logger* pLogger);
|
||||
static Logger* find(const std::string& name);
|
||||
|
||||
private:
|
||||
Logger();
|
||||
|
@ -151,12 +151,18 @@ public:
|
||||
/// int rc = ph.wait();
|
||||
|
||||
static int wait(const ProcessHandle& handle);
|
||||
/// Waits for the process specified by handle to terminate
|
||||
/// and returns the exit code of the process.
|
||||
|
||||
static void kill(PID pid);
|
||||
/// Kills the process with the given pid.
|
||||
|
||||
/// Waits for the process specified by handle to terminate
|
||||
/// and returns the exit code of the process.
|
||||
|
||||
static void kill(const ProcessHandle& handle);
|
||||
/// 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);
|
||||
/// Requests termination of the process with the give PID.
|
||||
///
|
||||
|
@ -72,11 +72,12 @@ public:
|
||||
typedef pid_t PIDImpl;
|
||||
typedef std::vector<std::string> ArgsImpl;
|
||||
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(const ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,11 +74,12 @@ public:
|
||||
typedef int PIDImpl;
|
||||
typedef std::vector<std::string> ArgsImpl;
|
||||
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(const ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
|
||||
{
|
||||
public:
|
||||
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
int wait() const;
|
||||
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
HANDLE process() const;
|
||||
int wait() const;
|
||||
|
||||
private:
|
||||
HANDLE _hProcess;
|
||||
UInt32 _pid;
|
||||
@ -76,12 +77,13 @@ public:
|
||||
typedef UInt32 PIDImpl;
|
||||
typedef std::vector<std::string> ArgsImpl;
|
||||
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(const ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
|
||||
{
|
||||
public:
|
||||
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
int wait() const;
|
||||
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
HANDLE process() const;
|
||||
int wait() const;
|
||||
|
||||
private:
|
||||
HANDLE _hProcess;
|
||||
UInt32 _pid;
|
||||
@ -76,12 +77,13 @@ public:
|
||||
typedef UInt32 PIDImpl;
|
||||
typedef std::vector<std::string> ArgsImpl;
|
||||
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(const ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,11 +56,12 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject
|
||||
{
|
||||
public:
|
||||
ProcessHandleImpl(HANDLE _hProcess, UInt32 pid);
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
int wait() const;
|
||||
|
||||
~ProcessHandleImpl();
|
||||
|
||||
UInt32 id() const;
|
||||
HANDLE process() const;
|
||||
int wait() const;
|
||||
|
||||
private:
|
||||
HANDLE _hProcess;
|
||||
UInt32 _pid;
|
||||
@ -76,12 +77,13 @@ public:
|
||||
typedef UInt32 PIDImpl;
|
||||
typedef std::vector<std::string> ArgsImpl;
|
||||
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
static PIDImpl idImpl();
|
||||
static void timesImpl(long& userTime, long& kernelTime);
|
||||
static ProcessHandleImpl* launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe);
|
||||
static void killImpl(const ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static void requestTerminationImpl(PIDImpl pid);
|
||||
static std::string terminationEventName(PIDImpl pid);
|
||||
};
|
||||
|
||||
|
||||
|
@ -48,20 +48,27 @@ namespace Poco {
|
||||
|
||||
template <class M>
|
||||
class ScopedLock
|
||||
/// A class that simplifies thread synchronization
|
||||
/// with a mutex.
|
||||
/// The constructor accepts a Mutex and locks it.
|
||||
/// The destructor unlocks the mutex.
|
||||
/// A class that simplifies thread synchronization
|
||||
/// with a mutex.
|
||||
/// The constructor accepts a Mutex (and optionally
|
||||
/// a timeout value in milliseconds) and locks it.
|
||||
/// The destructor unlocks the mutex.
|
||||
{
|
||||
public:
|
||||
inline ScopedLock(M& mutex): _mutex(mutex)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
inline ~ScopedLock()
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
explicit ScopedLock(M& mutex): _mutex(mutex)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
ScopedLock(M& mutex, long milliseconds): _mutex(mutex)
|
||||
{
|
||||
_mutex.lock(milliseconds);
|
||||
}
|
||||
|
||||
~ScopedLock()
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
M& _mutex;
|
||||
@ -74,22 +81,28 @@ private:
|
||||
|
||||
template <class M>
|
||||
class ScopedLockWithUnlock
|
||||
/// A class that simplifies thread synchronization
|
||||
/// with a mutex.
|
||||
/// The constructor accepts a Mutex and locks it.
|
||||
/// The destructor unlocks the mutex.
|
||||
/// The unlock() member function allows for manual
|
||||
/// unlocking of the mutex.
|
||||
/// A class that simplifies thread synchronization
|
||||
/// with a mutex.
|
||||
/// The constructor accepts a Mutex (and optionally
|
||||
/// a timeout value in milliseconds) and locks it.
|
||||
/// The destructor unlocks the mutex.
|
||||
/// The unlock() member function allows for manual
|
||||
/// unlocking of the mutex.
|
||||
{
|
||||
public:
|
||||
ScopedLockWithUnlock(M& mutex): _pMutex(&mutex)
|
||||
{
|
||||
_pMutex->lock();
|
||||
}
|
||||
|
||||
~ScopedLockWithUnlock()
|
||||
{
|
||||
unlock();
|
||||
explicit ScopedLockWithUnlock(M& mutex): _pMutex(&mutex)
|
||||
{
|
||||
_pMutex->lock();
|
||||
}
|
||||
|
||||
ScopedLockWithUnlock(M& mutex, long milliseconds): _pMutex(&mutex)
|
||||
{
|
||||
_pMutex->lock(milliseconds);
|
||||
}
|
||||
|
||||
~ScopedLockWithUnlock()
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
|
@ -360,9 +360,11 @@ typedef uLong FAR uLongf;
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
|
@ -38,7 +38,9 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Ascii.h"
|
||||
#include <sstream>
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
#include <locale>
|
||||
#endif
|
||||
#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)
|
||||
{
|
||||
std::ostringstream str;
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
str.imbue(std::locale::classic());
|
||||
parseFlags(str, itFmt, endFmt);
|
||||
parseWidth(str, itFmt, endFmt);
|
||||
parsePrec(str, itFmt, endFmt);
|
||||
char mod = parseMod(itFmt, endFmt);
|
||||
if (itFmt != endFmt)
|
||||
{
|
||||
char type = *itFmt++;
|
||||
prepareFormat(str, type);
|
||||
switch (type)
|
||||
#endif
|
||||
try
|
||||
{
|
||||
parseFlags(str, itFmt, endFmt);
|
||||
parseWidth(str, itFmt, endFmt);
|
||||
parsePrec(str, itFmt, endFmt);
|
||||
char mod = parseMod(itFmt, endFmt);
|
||||
if (itFmt != endFmt)
|
||||
{
|
||||
case 'b':
|
||||
str << AnyCast<bool>(*itVal++);
|
||||
break;
|
||||
case 'c':
|
||||
str << AnyCast<char>(*itVal++);
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
switch (mod)
|
||||
char type = *itFmt++;
|
||||
prepareFormat(str, type);
|
||||
switch (type)
|
||||
{
|
||||
case 'l': str << AnyCast<long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<Int64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<int>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<unsigned long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<UInt64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<unsigned short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<unsigned>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'L': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'h': str << AnyCast<float>(*itVal++); break;
|
||||
default: str << AnyCast<double>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
str << RefAnyCast<std::string>(*itVal++);
|
||||
break;
|
||||
case 'z':
|
||||
str << AnyCast<std::size_t>(*itVal++);
|
||||
break;
|
||||
case 'I':
|
||||
case 'D':
|
||||
default:
|
||||
str << type;
|
||||
}
|
||||
}
|
||||
result.append(str.str());
|
||||
}
|
||||
case 'b':
|
||||
str << AnyCast<bool>(*itVal++);
|
||||
break;
|
||||
case 'c':
|
||||
str << AnyCast<char>(*itVal++);
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<Int64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<int>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<unsigned long>(*itVal++); break;
|
||||
case 'L': str << AnyCast<UInt64>(*itVal++); break;
|
||||
case 'h': str << AnyCast<unsigned short>(*itVal++); break;
|
||||
case '?': writeAnyInt(str, *itVal++); break;
|
||||
default: str << AnyCast<unsigned>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
switch (mod)
|
||||
{
|
||||
case 'l': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'L': str << AnyCast<long double>(*itVal++); break;
|
||||
case 'h': str << AnyCast<float>(*itVal++); break;
|
||||
default: str << AnyCast<double>(*itVal++); break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
str << RefAnyCast<std::string>(*itVal++);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "Poco/LoggingRegistry.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -83,26 +84,7 @@ void Logger::setLevel(int level)
|
||||
|
||||
void Logger::setLevel(const std::string& level)
|
||||
{
|
||||
if (level == "none")
|
||||
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);
|
||||
setLevel(parseLevel(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
|
||||
{
|
||||
public:
|
||||
|
@ -37,7 +37,9 @@
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include <iomanip>
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
#include <locale>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
|
||||
@ -361,9 +363,11 @@ void NumberFormatter::append(std::string& str, float value)
|
||||
{
|
||||
char buffer[64];
|
||||
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
ostr.imbue(std::locale::classic());
|
||||
#endif
|
||||
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];
|
||||
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
ostr.imbue(std::locale::classic());
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
poco_assert (precision >= 0 && precision < 32);
|
||||
poco_assert (precision >= 0 && precision < 32);
|
||||
|
||||
char buffer[64];
|
||||
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
ostr.imbue(std::locale::classic());
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
poco_assert (width > 0 && width < 64 && precision >= 0 && precision < width);
|
||||
poco_assert (width > 0 && width < 64 && precision >= 0 && precision < width);
|
||||
|
||||
char buffer[64];
|
||||
Poco::MemoryOutputStream ostr(buffer, sizeof(buffer));
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
ostr.imbue(std::locale::classic());
|
||||
#endif
|
||||
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()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// NumberParser.cpp
|
||||
//
|
||||
// $Id: //poco/svn/Foundation/src/NumberParser.cpp#2 $
|
||||
// $Id: //poco/1.4/Foundation/src/NumberParser.cpp#4 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
@ -38,15 +38,19 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/String.h"
|
||||
#ifdef POCO_LOCALE
|
||||
#include <locale>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define I64_FMT "I64"
|
||||
#if defined(POCO_LONG_IS_64_BIT)
|
||||
#define I64_FMT "l"
|
||||
#elif defined(_MSC_VER)
|
||||
#define I64_FMT "I64"
|
||||
#elif defined(__APPLE__)
|
||||
#define I64_FMT "q"
|
||||
#define I64_FMT "q"
|
||||
#else
|
||||
#define I64_FMT "ll"
|
||||
#endif
|
||||
@ -175,10 +179,12 @@ double NumberParser::parseFloat(const std::string& s)
|
||||
|
||||
bool NumberParser::tryParseFloat(const std::string& s, double& value)
|
||||
{
|
||||
Poco::MemoryInputStream istr(s.data(), s.size());
|
||||
istr.imbue(std::locale::classic());
|
||||
istr >> value;
|
||||
return istr.eof() && !istr.fail();
|
||||
Poco::MemoryInputStream istr(s.data(), s.size());
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
istr.imbue(std::locale::classic());
|
||||
#endif
|
||||
istr >> value;
|
||||
return istr.eof() && !istr.fail();
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,9 +127,15 @@ int Process::wait(const ProcessHandle& handle)
|
||||
}
|
||||
|
||||
|
||||
void Process::kill(const ProcessHandle& handle)
|
||||
{
|
||||
killImpl(*handle._pImpl);
|
||||
}
|
||||
|
||||
|
||||
void Process::kill(PID pid)
|
||||
{
|
||||
killImpl(pid);
|
||||
killImpl(pid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
if (kill(pid, SIGKILL) != 0)
|
||||
if (kill(pid, SIGKILL) != 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
if (kill(pid, SIGKILL) != 0)
|
||||
if (kill(pid, SIGKILL) != 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
throw Poco::NotImplementedException("Process::kill()");
|
||||
throw Poco::NotImplementedException("Process::kill()");
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,9 +66,15 @@ UInt32 ProcessHandleImpl::id() const
|
||||
}
|
||||
|
||||
|
||||
HANDLE ProcessHandleImpl::process() const
|
||||
{
|
||||
return _hProcess;
|
||||
}
|
||||
|
||||
|
||||
int ProcessHandleImpl::wait() const
|
||||
{
|
||||
DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
|
||||
DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
|
||||
if (rc != WAIT_OBJECT_0)
|
||||
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)
|
||||
{
|
||||
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
if (hProc)
|
||||
{
|
||||
if (TerminateProcess(hProc, 0) == 0)
|
||||
|
@ -67,9 +67,15 @@ UInt32 ProcessHandleImpl::id() const
|
||||
}
|
||||
|
||||
|
||||
HANDLE ProcessHandleImpl::process() const
|
||||
{
|
||||
return _hProcess;
|
||||
}
|
||||
|
||||
|
||||
int ProcessHandleImpl::wait() const
|
||||
{
|
||||
DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
|
||||
DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
|
||||
if (rc != WAIT_OBJECT_0)
|
||||
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)
|
||||
{
|
||||
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
if (hProc)
|
||||
{
|
||||
if (TerminateProcess(hProc, 0) == 0)
|
||||
|
@ -360,9 +360,11 @@ typedef uLong FAR uLongf;
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#ifdef STDC
|
||||
# include <sys/types.h> /* for off_t */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
|
@ -20,7 +20,8 @@ objects = \
|
||||
HTTPFixedLengthStream HTTPServerRequest HTTPServerRequestImpl MultipartWriter StreamSocketImpl \
|
||||
HTTPHeaderStream HTTPServerResponse HTTPServerResponseImpl NameValueCollection TCPServer \
|
||||
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 \
|
||||
HTTPRequestHandlerFactory HTTPStreamFactory ServerSocketImpl TCPServerParams \
|
||||
QuotedPrintableEncoder QuotedPrintableDecoder StringPartSource \
|
||||
@ -29,7 +30,8 @@ objects = \
|
||||
MailRecipient MailMessage MailStream SMTPClientSession POP3ClientSession \
|
||||
RawSocket RawSocketImpl ICMPClient ICMPEventArgs ICMPPacket ICMPPacketImpl \
|
||||
ICMPSocket ICMPSocketImpl ICMPv4PacketImpl \
|
||||
RemoteSyslogChannel RemoteSyslogListener SMTPChannel
|
||||
RemoteSyslogChannel RemoteSyslogListener SMTPChannel \
|
||||
WebSocket WebSocketImpl
|
||||
|
||||
target = PocoNet
|
||||
target_version = $(LIBVERSION)
|
||||
|
@ -269,12 +269,20 @@ protected:
|
||||
/// proxy username and password have been set.
|
||||
|
||||
void proxyAuthenticateImpl(HTTPRequest& request);
|
||||
/// Sets the proxy credentials (Proxy-Authorization header), if
|
||||
/// proxy username and password have been set.
|
||||
/// Sets the proxy credentials (Proxy-Authorization header), if
|
||||
/// 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:
|
||||
std::string _host;
|
||||
Poco::UInt16 _port;
|
||||
std::string _host;
|
||||
Poco::UInt16 _port;
|
||||
std::string _proxyHost;
|
||||
Poco::UInt16 _proxyPort;
|
||||
std::string _proxyUsername;
|
||||
@ -286,9 +294,11 @@ private:
|
||||
bool _expectResponseBody;
|
||||
std::ostream* _pRequestStream;
|
||||
std::istream* _pResponseStream;
|
||||
|
||||
HTTPClientSession(const HTTPClientSession&);
|
||||
HTTPClientSession& operator = (const HTTPClientSession&);
|
||||
|
||||
HTTPClientSession(const HTTPClientSession&);
|
||||
HTTPClientSession& operator = (const HTTPClientSession&);
|
||||
|
||||
friend class WebSocket;
|
||||
};
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPCredentials
|
||||
// Module: HTTPCredentials
|
||||
//
|
||||
// Definition of the HTTPCredentials class.
|
||||
//
|
||||
@ -58,91 +58,107 @@ class HTTPResponse;
|
||||
|
||||
|
||||
class Net_API HTTPCredentials
|
||||
/// This is a utility class for working with HTTP
|
||||
/// authentication (basic or digest) in HTTPRequest objects.
|
||||
///
|
||||
/// Usage is as follows:
|
||||
/// First, create a HTTPCredentials object containing
|
||||
/// the username and password.
|
||||
/// Poco::Net::HTTPCredentials creds("user", "s3cr3t");
|
||||
///
|
||||
/// Second, send the HTTP request with Poco::Net::HTTPClientSession.
|
||||
/// Poco::Net::HTTPClientSession session("pocoproject.org");
|
||||
/// Poco::Net::HTTPRequest request(HTTPRequest::HTTP_GET, "/index.html", HTTPMessage::HTTP_1_1);
|
||||
/// session.sendRequest(request);
|
||||
/// Poco::Net::HTTPResponse;
|
||||
/// std::istream& istr = session.receiveResponse(response);
|
||||
///
|
||||
/// If the server responds with a 401 status, authenticate the
|
||||
/// request and resend it:
|
||||
/// if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
|
||||
/// {
|
||||
/// creds.authenticate(request, response);
|
||||
/// session.sendRequest(request);
|
||||
/// ...
|
||||
/// }
|
||||
///
|
||||
/// To perform multiple authenticated requests, call updateAuthInfo()
|
||||
/// instead of authenticate() on subsequent requests.
|
||||
/// creds.updateAuthInfo(request);
|
||||
/// session.sendRequest(request);
|
||||
/// ...
|
||||
///
|
||||
/// Note: Do not forget to read the entire response stream from the 401 response
|
||||
/// before sending the authenticated request, otherwise there may be
|
||||
/// problems if a persistent connection is used.
|
||||
/// This is a utility class for working with HTTP
|
||||
/// authentication (basic or digest) in HTTPRequest objects.
|
||||
///
|
||||
/// Usage is as follows:
|
||||
/// First, create a HTTPCredentials object containing
|
||||
/// the username and password.
|
||||
/// Poco::Net::HTTPCredentials creds("user", "s3cr3t");
|
||||
///
|
||||
/// Second, send the HTTP request with Poco::Net::HTTPClientSession.
|
||||
/// Poco::Net::HTTPClientSession session("pocoproject.org");
|
||||
/// Poco::Net::HTTPRequest request(HTTPRequest::HTTP_GET, "/index.html", HTTPMessage::HTTP_1_1);
|
||||
/// session.sendRequest(request);
|
||||
/// Poco::Net::HTTPResponse;
|
||||
/// std::istream& istr = session.receiveResponse(response);
|
||||
///
|
||||
/// If the server responds with a 401 status, authenticate the
|
||||
/// request and resend it:
|
||||
/// if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
|
||||
/// {
|
||||
/// creds.authenticate(request, response);
|
||||
/// session.sendRequest(request);
|
||||
/// ...
|
||||
/// }
|
||||
///
|
||||
/// To perform multiple authenticated requests, call updateAuthInfo()
|
||||
/// instead of authenticate() on subsequent requests.
|
||||
/// creds.updateAuthInfo(request);
|
||||
/// session.sendRequest(request);
|
||||
/// ...
|
||||
///
|
||||
/// Note: Do not forget to read the entire response stream from the 401 response
|
||||
/// before sending the authenticated request, otherwise there may be
|
||||
/// problems if a persistent connection is used.
|
||||
{
|
||||
public:
|
||||
HTTPCredentials();
|
||||
/// Creates an empty HTTPCredentials object.
|
||||
HTTPCredentials();
|
||||
/// Creates an empty HTTPCredentials object.
|
||||
|
||||
HTTPCredentials(const std::string& username, const std::string& password);
|
||||
/// Creates an HTTPCredentials object with the given username and password.
|
||||
HTTPCredentials(const std::string& username, const std::string& password);
|
||||
/// Creates an HTTPCredentials object with the given username and password.
|
||||
|
||||
~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);
|
||||
/// Sets the username.
|
||||
|
||||
const std::string& getUsername() const;
|
||||
/// Returns the username.
|
||||
const std::string& getUsername() const;
|
||||
/// Returns the username.
|
||||
|
||||
void setPassword(const std::string& password);
|
||||
/// Sets the password.
|
||||
void setPassword(const std::string& password);
|
||||
/// Sets the password.
|
||||
|
||||
const std::string& getPassword() const;
|
||||
/// Returns the password.
|
||||
const std::string& getPassword() const;
|
||||
/// Returns the password.
|
||||
|
||||
void authenticate(HTTPRequest& request, const HTTPResponse& response);
|
||||
/// Inspects authenticate header of the response, initializes
|
||||
/// the internal state (in case of digest authentication) and
|
||||
/// adds required information to the given HTTPRequest.
|
||||
///
|
||||
/// Does nothing if there is no authentication header in the
|
||||
/// HTTPResponse.
|
||||
void authenticate(HTTPRequest& request, const HTTPResponse& response);
|
||||
/// Inspects authenticate header of the response, initializes
|
||||
/// the internal state (in case of digest authentication) and
|
||||
/// adds required information to the given HTTPRequest.
|
||||
///
|
||||
/// Does nothing if there is no authentication header in the
|
||||
/// HTTPResponse.
|
||||
|
||||
void updateAuthInfo(HTTPRequest& request);
|
||||
/// Updates internal state (in case of digest authentication) and
|
||||
/// replaces authentication information in the request accordingly.
|
||||
void updateAuthInfo(HTTPRequest& request);
|
||||
/// Updates internal state (in case of digest authentication) and
|
||||
/// replaces authentication information in the request accordingly.
|
||||
|
||||
static bool isBasicCredentials(const std::string& header);
|
||||
/// Returns true if authentication header is for Basic authentication.
|
||||
static bool isBasicCredentials(const std::string& header);
|
||||
/// Returns true if authentication header is for Basic authentication.
|
||||
|
||||
static bool isDigestCredentials(const std::string& header);
|
||||
/// 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);
|
||||
/// Extracts username and password from user:password information string.
|
||||
|
||||
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").
|
||||
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").
|
||||
|
||||
private:
|
||||
HTTPCredentials(const HTTPCredentials&);
|
||||
HTTPCredentials& operator = (const HTTPCredentials&);
|
||||
HTTPCredentials(const HTTPCredentials&);
|
||||
HTTPCredentials& operator = (const HTTPCredentials&);
|
||||
|
||||
HTTPDigestCredentials _digest;
|
||||
HTTPDigestCredentials _digest;
|
||||
};
|
||||
|
||||
|
||||
@ -151,25 +167,25 @@ private:
|
||||
//
|
||||
inline void HTTPCredentials::setUsername(const std::string& username)
|
||||
{
|
||||
_digest.setUsername(username);
|
||||
_digest.setUsername(username);
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& HTTPCredentials::getUsername() const
|
||||
{
|
||||
return _digest.getUsername();
|
||||
return _digest.getUsername();
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void HTTPCredentials::setPassword(const std::string& password)
|
||||
{
|
||||
_digest.setPassword(password);
|
||||
_digest.setPassword(password);
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& HTTPCredentials::getPassword() const
|
||||
{
|
||||
return _digest.getPassword();
|
||||
return _digest.getPassword();
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,6 +70,7 @@ POCO_DECLARE_EXCEPTION(Net_API, SMTPException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, POP3Exception, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, ICMPException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, HTMLFormException, NetException)
|
||||
POCO_DECLARE_EXCEPTION(Net_API, WebSocketException, NetException)
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -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
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPCredentials
|
||||
// Module: HTTPCredentials
|
||||
//
|
||||
// Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru).
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
@ -42,6 +42,7 @@
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Ascii.h"
|
||||
#include "Poco/URI.h"
|
||||
|
||||
|
||||
@ -58,7 +59,7 @@ HTTPCredentials::HTTPCredentials()
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
for (HTTPResponse::ConstIterator iter = response.find("WWW-Authenticate"); iter != response.end(); ++iter)
|
||||
{
|
||||
if (isBasicCredentials(iter->second))
|
||||
{
|
||||
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
|
||||
return;
|
||||
}
|
||||
else if (isDigestCredentials(iter->second))
|
||||
{
|
||||
_digest.authenticate(request, HTTPAuthenticationParams(iter->second.substr(7)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (isBasicCredentials(iter->second))
|
||||
{
|
||||
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
|
||||
return;
|
||||
}
|
||||
else if (isDigestCredentials(iter->second))
|
||||
{
|
||||
_digest.authenticate(request, HTTPAuthenticationParams(iter->second.substr(7)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
{
|
||||
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
|
||||
}
|
||||
else if (isDigestCredentials(authorization))
|
||||
{
|
||||
_digest.updateAuthInfo(request);
|
||||
}
|
||||
}
|
||||
HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
|
||||
}
|
||||
else if (isDigestCredentials(authorization))
|
||||
{
|
||||
_digest.updateAuthInfo(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const std::string::size_type p = userInfo.find(':');
|
||||
const std::string::size_type p = userInfo.find(':');
|
||||
|
||||
if (p != std::string::npos)
|
||||
{
|
||||
username.assign(userInfo, 0, p);
|
||||
password.assign(userInfo, p + 1, std::string::npos);
|
||||
}
|
||||
else
|
||||
{
|
||||
username.assign(userInfo);
|
||||
password.clear();
|
||||
}
|
||||
if (p != std::string::npos)
|
||||
{
|
||||
username.assign(userInfo, 0, p);
|
||||
password.assign(userInfo, p + 1, std::string::npos);
|
||||
}
|
||||
else
|
||||
{
|
||||
username.assign(userInfo);
|
||||
password.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPCredentials::extractCredentials(const Poco::URI& uri, std::string& username, std::string& password)
|
||||
{
|
||||
if (!uri.getUserInfo().empty())
|
||||
{
|
||||
extractCredentials(uri.getUserInfo(), username, password);
|
||||
}
|
||||
if (!uri.getUserInfo().empty())
|
||||
{
|
||||
extractCredentials(uri.getUserInfo(), username, password);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// Library: Net
|
||||
// Package: HTTP
|
||||
// Module: HTTPDigestCredentials
|
||||
// Module: HTTPDigestCredentials
|
||||
//
|
||||
// Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru).
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
@ -49,39 +49,39 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string digest(Poco::DigestEngine& engine,
|
||||
const std::string& a,
|
||||
const std::string& b,
|
||||
const std::string& c = std::string(),
|
||||
const std::string& d = std::string(),
|
||||
const std::string& e = std::string(),
|
||||
const std::string& f = std::string())
|
||||
{
|
||||
engine.reset();
|
||||
engine.update(a);
|
||||
engine.update(':');
|
||||
engine.update(b);
|
||||
if (!c.empty())
|
||||
{
|
||||
engine.update(':');
|
||||
engine.update(c);
|
||||
if (!d.empty())
|
||||
{
|
||||
engine.update(':');
|
||||
engine.update(d);
|
||||
engine.update(':');
|
||||
engine.update(e);
|
||||
engine.update(':');
|
||||
engine.update(f);
|
||||
}
|
||||
}
|
||||
return Poco::DigestEngine::digestToHex(engine.digest());
|
||||
}
|
||||
|
||||
std::string formatNonceCounter(int counter)
|
||||
{
|
||||
return Poco::NumberFormatter::formatHex(counter, 8);
|
||||
}
|
||||
std::string digest(Poco::DigestEngine& engine,
|
||||
const std::string& a,
|
||||
const std::string& b,
|
||||
const std::string& c = std::string(),
|
||||
const std::string& d = std::string(),
|
||||
const std::string& e = std::string(),
|
||||
const std::string& f = std::string())
|
||||
{
|
||||
engine.reset();
|
||||
engine.update(a);
|
||||
engine.update(':');
|
||||
engine.update(b);
|
||||
if (!c.empty())
|
||||
{
|
||||
engine.update(':');
|
||||
engine.update(c);
|
||||
if (!d.empty())
|
||||
{
|
||||
engine.update(':');
|
||||
engine.update(d);
|
||||
engine.update(':');
|
||||
engine.update(e);
|
||||
engine.update(':');
|
||||
engine.update(f);
|
||||
}
|
||||
}
|
||||
return Poco::DigestEngine::digestToHex(engine.digest());
|
||||
}
|
||||
|
||||
std::string formatNonceCounter(int counter)
|
||||
{
|
||||
return Poco::NumberFormatter::formatHex(counter, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,10 +111,10 @@ HTTPDigestCredentials::HTTPDigestCredentials()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
HTTPDigestCredentials::HTTPDigestCredentials(const std::string& username, const std::string& password):
|
||||
_username(username),
|
||||
_password(password)
|
||||
_username(username),
|
||||
_password(password)
|
||||
{
|
||||
}
|
||||
|
||||
@ -126,67 +126,67 @@ HTTPDigestCredentials::~HTTPDigestCredentials()
|
||||
|
||||
void HTTPDigestCredentials::setUsername(const std::string& username)
|
||||
{
|
||||
_username = username;
|
||||
_username = username;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HTTPDigestCredentials::setPassword(const std::string& password)
|
||||
{
|
||||
_password = password;
|
||||
_password = password;
|
||||
}
|
||||
|
||||
|
||||
void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response)
|
||||
{
|
||||
authenticate(request, HTTPAuthenticationParams(response));
|
||||
authenticate(request, HTTPAuthenticationParams(response));
|
||||
}
|
||||
|
||||
|
||||
void HTTPDigestCredentials::authenticate(HTTPRequest& request, const HTTPAuthenticationParams& responseAuthParams)
|
||||
{
|
||||
createAuthParams(request, responseAuthParams);
|
||||
request.setCredentials(SCHEME, _requestAuthParams.toString());
|
||||
createAuthParams(request, responseAuthParams);
|
||||
request.setCredentials(SCHEME, _requestAuthParams.toString());
|
||||
}
|
||||
|
||||
|
||||
void HTTPDigestCredentials::updateAuthInfo(HTTPRequest& request)
|
||||
{
|
||||
updateAuthParams(request);
|
||||
request.setCredentials(SCHEME, _requestAuthParams.toString());
|
||||
updateAuthParams(request);
|
||||
request.setCredentials(SCHEME, _requestAuthParams.toString());
|
||||
}
|
||||
|
||||
|
||||
std::string HTTPDigestCredentials::createNonce()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_nonceMutex);
|
||||
Poco::FastMutex::ScopedLock lock(_nonceMutex);
|
||||
|
||||
MD5Engine md5;
|
||||
Timestamp::TimeVal now = Timestamp().epochMicroseconds();
|
||||
MD5Engine md5;
|
||||
Timestamp::TimeVal now = Timestamp().epochMicroseconds();
|
||||
|
||||
md5.update(&_nonceCounter, sizeof(_nonceCounter));
|
||||
md5.update(&now, sizeof(now));
|
||||
md5.update(&_nonceCounter, sizeof(_nonceCounter));
|
||||
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)
|
||||
{
|
||||
// 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))
|
||||
throw InvalidArgumentException("Invalid HTTP authentication parameters");
|
||||
if (!responseAuthParams.has(NONCE_PARAM) || !responseAuthParams.has(REALM_PARAM))
|
||||
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)
|
||||
throw NotImplementedException("Unsupported digest algorithm", algorithm);
|
||||
if (icompare(algorithm, DEFAULT_ALGORITHM) != 0)
|
||||
throw NotImplementedException("Unsupported digest algorithm", algorithm);
|
||||
|
||||
const std::string& nonce = responseAuthParams.get(NONCE_PARAM);
|
||||
const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
||||
const std::string& realm = responseAuthParams.getRealm();
|
||||
const std::string& nonce = responseAuthParams.get(NONCE_PARAM);
|
||||
const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
||||
const std::string& realm = responseAuthParams.getRealm();
|
||||
|
||||
_requestAuthParams.clear();
|
||||
_requestAuthParams.set(USERNAME_PARAM, _username);
|
||||
@ -194,104 +194,108 @@ void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const H
|
||||
_requestAuthParams.set(NONCE_PARAM, nonce);
|
||||
_requestAuthParams.setRealm(realm);
|
||||
if (responseAuthParams.has(OPAQUE_PARAM))
|
||||
{
|
||||
_requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM));
|
||||
}
|
||||
{
|
||||
_requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM));
|
||||
}
|
||||
|
||||
if (qop.empty())
|
||||
{
|
||||
MD5Engine engine;
|
||||
|
||||
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));
|
||||
updateAuthParams(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
Poco::StringTokenizer tok(qop, ",", Poco::StringTokenizer::TOK_TRIM);
|
||||
bool qopSupported = false;
|
||||
for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it)
|
||||
{
|
||||
if (icompare(*it, AUTH_PARAM) == 0)
|
||||
{
|
||||
qopSupported = true;
|
||||
_requestAuthParams.set(CNONCE_PARAM, createNonce());
|
||||
_requestAuthParams.set(QOP_PARAM, *it);
|
||||
updateAuthParams(request);
|
||||
break;
|
||||
Poco::StringTokenizer tok(qop, ",", Poco::StringTokenizer::TOK_TRIM);
|
||||
bool qopSupported = false;
|
||||
for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it)
|
||||
{
|
||||
if (icompare(*it, AUTH_PARAM) == 0)
|
||||
{
|
||||
qopSupported = true;
|
||||
_requestAuthParams.set(CNONCE_PARAM, createNonce());
|
||||
_requestAuthParams.set(QOP_PARAM, *it);
|
||||
updateAuthParams(request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!qopSupported)
|
||||
NotImplementedException("Unsupported QoP requested", qop);
|
||||
if (!qopSupported)
|
||||
throw NotImplementedException("Unsupported QoP requested", qop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
|
||||
{
|
||||
MD5Engine engine;
|
||||
const std::string& qop = _requestAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
||||
if (icompare(qop, AUTH_PARAM) == 0)
|
||||
{
|
||||
MD5Engine engine;
|
||||
const std::string& realm = _requestAuthParams.getRealm();
|
||||
const std::string& nonce = _requestAuthParams.get(NONCE_PARAM);
|
||||
|
||||
const std::string& nonce = _requestAuthParams.get(NONCE_PARAM);
|
||||
const std::string& realm = _requestAuthParams.getRealm();
|
||||
_requestAuthParams.set(URI_PARAM, request.getURI());
|
||||
|
||||
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 ha1 = digest(engine, _username, realm, _password);
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
const std::string nc = formatNonceCounter(updateNonceCounter(nonce));
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
const std::string nc = formatNonceCounter(updateNonceCounter(nonce));
|
||||
|
||||
_requestAuthParams.set(NC_PARAM, nc);
|
||||
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2));
|
||||
}
|
||||
_requestAuthParams.set(NC_PARAM, nc);
|
||||
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool HTTPDigestCredentials::verifyAuthInfo(const HTTPRequest& request) const
|
||||
{
|
||||
HTTPAuthenticationParams params(request);
|
||||
return verifyAuthParams(request, params);
|
||||
HTTPAuthenticationParams params(request);
|
||||
return verifyAuthParams(request, params);
|
||||
}
|
||||
|
||||
|
||||
bool HTTPDigestCredentials::verifyAuthParams(const HTTPRequest& request, const HTTPAuthenticationParams& params) const
|
||||
{
|
||||
const std::string& nonce = params.get(NONCE_PARAM);
|
||||
const std::string& realm = params.getRealm();
|
||||
const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP);
|
||||
std::string response;
|
||||
MD5Engine engine;
|
||||
if (qop.empty())
|
||||
{
|
||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
response = digest(engine, ha1, nonce, ha2);
|
||||
}
|
||||
else if (icompare(qop, AUTH_PARAM) == 0)
|
||||
{
|
||||
const std::string& cnonce = params.get(CNONCE_PARAM);
|
||||
const std::string& nc = params.get(NC_PARAM);
|
||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2);
|
||||
}
|
||||
return response == params.get(RESPONSE_PARAM);
|
||||
const std::string& nonce = params.get(NONCE_PARAM);
|
||||
const std::string& realm = params.getRealm();
|
||||
const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP);
|
||||
std::string response;
|
||||
MD5Engine engine;
|
||||
if (qop.empty())
|
||||
{
|
||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
response = digest(engine, ha1, nonce, ha2);
|
||||
}
|
||||
else if (icompare(qop, AUTH_PARAM) == 0)
|
||||
{
|
||||
const std::string& cnonce = params.get(CNONCE_PARAM);
|
||||
const std::string& nc = params.get(NC_PARAM);
|
||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||
response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2);
|
||||
}
|
||||
return response == params.get(RESPONSE_PARAM);
|
||||
}
|
||||
|
||||
|
||||
int HTTPDigestCredentials::updateNonceCounter(const std::string& nonce)
|
||||
{
|
||||
NonceCounterMap::iterator iter = _nc.find(nonce);
|
||||
NonceCounterMap::iterator iter = _nc.find(nonce);
|
||||
|
||||
if (iter == _nc.end())
|
||||
{
|
||||
iter = _nc.insert(NonceCounterMap::value_type(nonce, 0)).first;
|
||||
}
|
||||
iter->second++;
|
||||
if (iter == _nc.end())
|
||||
{
|
||||
iter = _nc.insert(NonceCounterMap::value_type(nonce, 0)).first;
|
||||
}
|
||||
iter->second++;
|
||||
|
||||
return iter->second;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,6 +67,7 @@ POCO_IMPLEMENT_EXCEPTION(SMTPException, NetException, "SMTP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(POP3Exception, NetException, "POP3 Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(ICMPException, NetException, "ICMP Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(HTMLFormException, NetException, "HTML Form Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(WebSocketException, NetException, "WebSocket Exception")
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
@ -299,14 +299,16 @@ void Application::stopOptionsProcessing()
|
||||
|
||||
int Application::run()
|
||||
{
|
||||
int rc = EXIT_SOFTWARE;
|
||||
initialize(*this);
|
||||
try
|
||||
{
|
||||
rc = main(_args);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
int rc = EXIT_CONFIG;
|
||||
try
|
||||
{
|
||||
initialize(*this);
|
||||
rc = EXIT_SOFTWARE;
|
||||
rc = main(_args);
|
||||
uninitialize();
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
@ -314,11 +316,10 @@ int Application::run()
|
||||
logger().error(exc.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
logger().fatal("system exception");
|
||||
}
|
||||
uninitialize();
|
||||
return rc;
|
||||
{
|
||||
logger().fatal("system exception");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -368,13 +369,13 @@ void Application::processOptions()
|
||||
while (it != _args.end() && !_stopOptionsProcessing)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
if (processor.process(*it, name, value))
|
||||
{
|
||||
if (!name.empty()) // "--" option to end options processing or deferred argument
|
||||
{
|
||||
handleOption(name, value);
|
||||
}
|
||||
std::string value;
|
||||
if (processor.process(*it, name, value))
|
||||
{
|
||||
if (!name.empty()) // "--" option to end options processing or deferred argument
|
||||
{
|
||||
handleOption(name, value);
|
||||
}
|
||||
it = _args.erase(it);
|
||||
}
|
||||
else ++it;
|
||||
|
@ -388,12 +388,12 @@ void ServerApplication::registerService()
|
||||
else
|
||||
service.registerService(path, _displayName);
|
||||
if (_startup == "auto")
|
||||
service.setStartup(WinService::SVC_AUTO_START);
|
||||
else if (_startup == "manual")
|
||||
service.setStartup(WinService::SVC_MANUAL_START);
|
||||
if (!_description.empty())
|
||||
service.setDescription(_description);
|
||||
logger().information("The application has been successfully registered as a service.");
|
||||
service.setStartup(WinService::SVC_AUTO_START);
|
||||
else if (_startup == "manual")
|
||||
service.setStartup(WinService::SVC_MANUAL_START);
|
||||
if (!_description.empty())
|
||||
service.setDescription(_description);
|
||||
logger().information("The application has been successfully registered as a service.");
|
||||
}
|
||||
|
||||
|
||||
@ -428,19 +428,19 @@ void ServerApplication::defineOptions(OptionSet& options)
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("name")
|
||||
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDisplayName)));
|
||||
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDisplayName)));
|
||||
|
||||
options.addOption(
|
||||
Option("description", "", "Specify a description for the service (only with /registerService).")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("text")
|
||||
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDescription)));
|
||||
options.addOption(
|
||||
Option("description", "", "Specify a description for the service (only with /registerService).")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("text")
|
||||
.callback(OptionCallback<ServerApplication>(this, &ServerApplication::handleDescription)));
|
||||
|
||||
options.addOption(
|
||||
Option("startup", "", "Specify the startup mode for the service (only with /registerService).")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
options.addOption(
|
||||
Option("startup", "", "Specify the startup mode for the service (only with /registerService).")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("automatic|manual")
|
||||
.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)
|
||||
{
|
||||
_description = value;
|
||||
_description = 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";
|
||||
else if (Poco::icompare(value, std::string("manual")) == 0)
|
||||
_startup = "manual";
|
||||
@ -496,20 +496,10 @@ int ServerApplication::run(int argc, char** argv)
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
int rc = run();
|
||||
try
|
||||
{
|
||||
uninitialize();
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
rc = EXIT_CONFIG;
|
||||
}
|
||||
return rc;
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
return run();
|
||||
}
|
||||
|
||||
|
||||
@ -521,20 +511,10 @@ int ServerApplication::run(const std::vector<std::string>& args)
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
int rc = run();
|
||||
try
|
||||
{
|
||||
uninitialize();
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
rc = EXIT_CONFIG;
|
||||
}
|
||||
return rc;
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
return run();
|
||||
}
|
||||
|
||||
|
||||
@ -547,20 +527,10 @@ int ServerApplication::run(int argc, wchar_t** argv)
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
int rc = run();
|
||||
try
|
||||
{
|
||||
uninitialize();
|
||||
}
|
||||
catch (Exception& exc)
|
||||
{
|
||||
logger().log(exc);
|
||||
rc = EXIT_CONFIG;
|
||||
}
|
||||
return rc;
|
||||
logger().log(exc);
|
||||
return EXIT_CONFIG;
|
||||
}
|
||||
return run();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -53,9 +53,35 @@ namespace Poco {
|
||||
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):
|
||||
_hKey(0),
|
||||
_readOnly(readOnly),
|
||||
_hKey(0),
|
||||
_readOnly(readOnly),
|
||||
_extraSam(extraSam)
|
||||
{
|
||||
std::string::size_type pos = key.find('\\');
|
||||
@ -266,17 +292,53 @@ void WinRegistryKey::deleteKey()
|
||||
std::string subKey(_subKey);
|
||||
subKey += "\\";
|
||||
subKey += *it;
|
||||
WinRegistryKey subRegKey(_hRootKey, subKey);
|
||||
subRegKey.deleteKey();
|
||||
}
|
||||
WinRegistryKey subRegKey(_hRootKey, subKey);
|
||||
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)
|
||||
std::wstring usubKey;
|
||||
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
||||
if (RegDeleteKeyW(_hRootKey, usubKey.c_str()) != ERROR_SUCCESS)
|
||||
throw NotFoundException(key());
|
||||
std::wstring usubKey;
|
||||
Poco::UnicodeConverter::toUTF16(_subKey, usubKey);
|
||||
|
||||
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
|
||||
if (RegDeleteKey(_hRootKey, _subKey.c_str()) != ERROR_SUCCESS)
|
||||
throw NotFoundException(key());
|
||||
typedef LONG (WINAPI *RegDeleteKeyExAFunc)(HKEY hKey, const char* lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||
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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user