/*************************************************************************
 *
 *  $RCSfile: inethttp.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: mhu $ $Date: 2001/03/19 12:12:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Matthias Huetsch <matthias.huetsch@sun.com>
 *
 *
 ************************************************************************/

#ifndef _INETHTTP_HXX
#define _INETHTTP_HXX "$Revision: 1.2 $"

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _VOS_OBJECT_HXX_
#include <vos/object.hxx>
#endif
#ifndef _VOS_REF_HXX_
#include <vos/ref.hxx>
#endif

#ifndef _TOOLS_INETMSG_HXX
#include <tools/inetmsg.hxx>
#endif

#ifndef _INET_MACROS_HXX
#include <inet/macros.hxx>
#endif
#ifndef _INET_CLIENT_HXX
#include <inet/client.hxx>
#endif

#ifdef _USE_NAMESPACE
namespace inet {
#endif

/*=======================================================================
 *
 * INetHTTP interface.
 *
 * References:
 *   RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0 (Informational)
 *   RFC 2068 - Hypertext Transfer Protocol -- HTTP/1.1 (Proposed)
 *   RFC 2500 - Internet Official Protocol Standards    (STD 1)
 *
 *=====================================================================*/
class  INetHTTPRequest;
struct INetHTTPRequestContext;

/** INetHTTPRequestCallback function.
 *  Passed to each request.
 *
 *  @param  pRequest [in]
 *  @param  nReplyCode [in]
 *  @param  pReplyText [in]
 *  @param  pData [in] opaque callback data.
 *  @return ignored.
 */
typedef sal_Bool INetHTTPRequestCallback (
	INetHTTPRequest *pRequest,
	sal_Int32        nReplyCode,
	const sal_Char  *pReplyText,
	void            *pData);

/*=======================================================================
 *
 * INetHTTPConnection interface.
 *
 *=====================================================================*/
class INetHTTPConnection :
	public NAMESPACE_INET(INetClientConnection_Impl)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPConnection, inet));

public:
	static sal_Bool createInstance (
		NAMESPACE_VOS(ORef)<INetHTTPConnection> &rxConnection);

	virtual sal_Bool startRequest (
		INetHTTPRequestContext *pCtx) = 0;

	virtual sal_Bool abortRequest (
		INetHTTPRequestContext *pCtx) = 0;

protected:
	INetHTTPConnection (void);
	virtual ~INetHTTPConnection (void);

private:
	/** Not implemented.
	 */
	INetHTTPConnection (const INetHTTPConnection&);
	INetHTTPConnection& operator= (const INetHTTPConnection&);
};

/*=======================================================================
 *
 * INetHTTPRequest interface.
 *
 *=====================================================================*/
class INetHTTPRequest :
	public NAMESPACE_VOS(OReference),
	public NAMESPACE_VOS(OObject)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPRequest, inet));

public:
	/** Method.
	 */
	enum Method
	{
		METHOD_GET,
		METHOD_HEAD,
		METHOD_POST,
		METHOD_PUT,
		METHOD_DELETE
	};

	/** Scheme.
	 */
	enum Scheme
	{
		SCHEME_FTP,
		SCHEME_HTTP,
		SCHEME_HTTPS,
		SCHEME_OTHER
	};

	/** Reply.
	 */
	enum Reply
	{
		// Implementation defined Reply (-x)
		REPLY_CONNECTION_TERMINATED = -18,

		REPLY_RESPONSE_DONE         = -16,
		REPLY_RESPONSE_ERROR        = -15,
		REPLY_RESPONSE_WAIT         = -14,

		REPLY_REQUEST_DONE          = -12,
		REPLY_REQUEST_ERROR         = -11,
		REPLY_REQUEST_WAIT          = -10,

		REPLY_CONNECT_DONE          =  -8,
		REPLY_CONNECT_ERROR         =  -7,
		REPLY_CONNECT_WAIT          =  -6,

		REPLY_RESOLVER_DONE         =  -4,
		REPLY_RESOLVER_ERROR        =  -3,
		REPLY_RESOLVER_WAIT         =  -2,

		REPLY_NETWORK_ERROR         =  -1,

		// HTTP/0.9 (None)
		REPLY_09                    =   0,

		// Succesful (2xx)
		REPLY_OK                    = 200,
		REPLY_CREATED               = 201,
		REPLY_ACCEPTED              = 202,
		REPLY_NO_CONTENT            = 204,

		// Redirection (3xx)
		REPLY_MULTIPLE_CHOICE       = 300,
		REPLY_MOVED_PERMANENT       = 301,
		REPLY_MOVED_TEMPORARY       = 302,
		REPLY_NOT_MODIFIED          = 304,

		// Client Error (4xx)
		REPLY_BAD_REQUEST           = 400,
		REPLY_UNAUTHORIZED          = 401,
		REPLY_FORBIDDEN             = 403,
		REPLY_NOT_FOUND             = 404,
		REPLY_PROXY_UNAUTHORIZED    = 407,

		// Server Error (5xx)
		REPLY_INTERNAL_ERROR        = 500,
		REPLY_NOT_IMPLEMENTED       = 501,
		REPLY_BAD_GATEWAY           = 502,
		REPLY_SERVICE_UNAVAIL       = 503
	};

	/** start.
	 */
	virtual sal_Bool start (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

	/** abort.
	 */
	virtual void abort (void);

	/** Query connection endpoint.
	 */
	virtual sal_Bool getEndpoint (
		rtl::OUString &rHost, sal_uInt16 &rPort) const;

	/** Query status code.
	 */
	virtual sal_Int32  getStatusCode (void) const;

	/** Query header state.
	 */
	virtual sal_Bool   isRequestHeaderGenerated  (void) const;
	virtual sal_Bool   isResponseHeaderParsed    (void) const;

	/** Query document length.
	 */
	virtual sal_uInt32 getRequestDocumentLength  (void) const;
	virtual sal_uInt32 getResponseDocumentLength (void) const;

protected:
	INetHTTPRequest (Method eMethod);
	virtual ~INetHTTPRequest (void);

private:
	/** Representation.
	 */
	NAMESPACE_VOS(ORef)<INetHTTPConnection>  m_xConnection;
	INetHTTPRequestContext                  *m_pContext;

	/** Not implemented.
	 */
	INetHTTPRequest (const INetHTTPRequest&);
	INetHTTPRequest& operator= (const INetHTTPRequest&);
};

/*=======================================================================
 *
 * INetHTTPGetRequest interface.
 *
 *=====================================================================*/
class INetHTTPGetRequest : public NAMESPACE_INET(INetHTTPRequest)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPGetRequest, inet));

public:
	inline INetHTTPGetRequest (void);

	inline sal_Bool loadDocument (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

	inline sal_Bool reloadDocument (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

protected:
	virtual ~INetHTTPGetRequest (void) {}

private:
	/** Not implemented.
	 */
	INetHTTPGetRequest (const INetHTTPGetRequest&);
	INetHTTPGetRequest& operator= (const INetHTTPGetRequest&);
};

inline INetHTTPGetRequest::INetHTTPGetRequest (void)
	: INetHTTPRequest (METHOD_GET)
{
}

inline sal_Bool INetHTTPGetRequest::loadDocument (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

inline sal_Bool INetHTTPGetRequest::reloadDocument (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	rReqMsg.SetPragma (rtl::OUString::createFromAscii ("no-cache"));
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

/*=======================================================================
 *
 * INetHTTPHeadRequest interface.
 *
 *=====================================================================*/
class INetHTTPHeadRequest : public NAMESPACE_INET(INetHTTPRequest)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPHeadRequest, inet));

public:
	inline INetHTTPHeadRequest (void);

	inline sal_Bool loadHeader (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

	inline sal_Bool reloadHeader (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

protected:
	virtual ~INetHTTPHeadRequest (void) {}

private:
	/** Not implemented.
	 */
	INetHTTPHeadRequest (const INetHTTPHeadRequest&);
	INetHTTPHeadRequest& operator= (const INetHTTPHeadRequest&);
};

inline INetHTTPHeadRequest::INetHTTPHeadRequest (void)
	: INetHTTPRequest (METHOD_HEAD)
{
}

inline sal_Bool INetHTTPHeadRequest::loadHeader (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

inline sal_Bool INetHTTPHeadRequest::reloadHeader (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	rReqMsg.SetPragma (rtl::OUString::createFromAscii ("no-cache"));
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

/*=======================================================================
 *
 * INetHTTPPostRequest interface.
 *
 *=====================================================================*/
class INetHTTPPostRequest : public NAMESPACE_INET(INetHTTPRequest)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPPostRequest, inet));

public:
	inline INetHTTPPostRequest (void);

	inline sal_Bool postDocument (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

protected:
	virtual ~INetHTTPPostRequest (void) {}

private:
	/** Not implemented.
	 */
	INetHTTPPostRequest (const INetHTTPPostRequest&);
	INetHTTPPostRequest& operator= (const INetHTTPPostRequest&);
};

inline INetHTTPPostRequest::INetHTTPPostRequest (void)
	: INetHTTPRequest (METHOD_POST)
{
}

inline sal_Bool INetHTTPPostRequest::postDocument (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

/*=======================================================================
 *
 * INetHTTPPutRequest interface (HTTP/1.1).
 *
 *=====================================================================*/
class INetHTTPPutRequest : public NAMESPACE_INET(INetHTTPRequest)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPPutRequest, inet));

public:
	inline INetHTTPPutRequest (void);

	inline sal_Bool storeDocument (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

protected:
	virtual ~INetHTTPPutRequest (void) {}

private:
	/** Not implemented.
	 */
	INetHTTPPutRequest (const INetHTTPPutRequest&);
	INetHTTPPutRequest& operator= (const INetHTTPPutRequest&);
};

inline INetHTTPPutRequest::INetHTTPPutRequest (void)
	: INetHTTPRequest (METHOD_PUT)
{
}

inline sal_Bool INetHTTPPutRequest::storeDocument (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

/*=======================================================================
 *
 * INetHTTPDeleteRequest interface (HTTP/1.1).
 *
 *=====================================================================*/
class INetHTTPDeleteRequest : public NAMESPACE_INET(INetHTTPRequest)
{
	VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (INetHTTPDeleteRequest, inet));

public:
	inline INetHTTPDeleteRequest (void);

	inline sal_Bool deleteDocument (
		const rtl::OUString     &rReqURI,
		INetHTTPMessage         &rReqMsg,
		INetHTTPMessage         &rResMsg,
		INetHTTPRequestCallback *pfnCB,
		void                    *pDataCB);

protected:
	virtual ~INetHTTPDeleteRequest (void) {}

private:
	/** Not implemented.
	 */
	INetHTTPDeleteRequest (const INetHTTPDeleteRequest&);
	INetHTTPDeleteRequest& operator= (const INetHTTPDeleteRequest&);
};

inline INetHTTPDeleteRequest::INetHTTPDeleteRequest (void)
	: INetHTTPRequest (METHOD_DELETE)
{
}

inline sal_Bool INetHTTPDeleteRequest::deleteDocument (
	const rtl::OUString     &rReqURI,
	INetHTTPMessage         &rReqMsg,
	INetHTTPMessage         &rResMsg,
	INetHTTPRequestCallback *pfnCB,
	void                    *pDataCB)
{
	return start (rReqURI, rReqMsg, rResMsg, pfnCB, pDataCB);
}

/*=======================================================================
 *
 * The End.
 *
 *=====================================================================*/
#ifdef _USE_NAMESPACE
}
#endif

#endif /* !_INETHTTP_HXX */

