You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by bl...@apache.org on 2004/04/20 14:28:29 UTC
cvs commit: xml-security/c/src/utils/unixutils XSECSOAPRequestorSimpleUnix.cpp
blautenb 2004/04/20 05:28:29
Modified: c/src/tools/xklient xklient.cpp
c/src/utils XSECSOAPRequestor.hpp
Added: c/src/utils XSECSOAPRequestorSimple.cpp
XSECSOAPRequestorSimple.hpp
c/src/utils/unixutils XSECSOAPRequestorSimpleUnix.cpp
Log:
Basic requests under UNIX
Revision Changes Path
1.3 +8 -14 xml-security/c/src/tools/xklient/xklient.cpp
Index: xklient.cpp
===================================================================
RCS file: /home/cvs/xml-security/c/src/tools/xklient/xklient.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- xklient.cpp 19 Apr 2004 10:55:37 -0000 1.2
+++ xklient.cpp 20 Apr 2004 12:28:29 -0000 1.3
@@ -39,9 +39,7 @@
#include <xsec/xkms/XKMSLocateRequest.hpp>
#include <xsec/xkms/XKMSQueryKeyBinding.hpp>
-#if defined(_WIN32)
-# include <xsec/utils/winutils/XSECSOAPRequestorSimpleWin32.hpp>
-#endif
+#include <xsec/utils/XSECSOAPRequestorSimple.hpp>
// General
@@ -79,6 +77,11 @@
#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
+XALAN_USING_XALAN(XPathEvaluator)
+XALAN_USING_XALAN(XalanTransformer)
+
+#endif
+
#if defined (HAVE_OPENSSL)
// OpenSSL
@@ -86,11 +89,6 @@
#endif
-XALAN_USING_XALAN(XPathEvaluator)
-XALAN_USING_XALAN(XalanTransformer)
-
-#endif
-
// --------------------------------------------------------------------------------
// Global definitions
// --------------------------------------------------------------------------------
@@ -268,7 +266,6 @@
int doRequest(char * msgType) {
XSECProvider prov;
- XKMSMessageFactory * factory = prov.getXKMSMessageFactory();
// Create a new message
XKMSMessageAbstractType * msg;
@@ -283,10 +280,8 @@
}
-#if defined(_WIN32)
- XSECSOAPRequestorSimpleWin32 req(MAKE_UNICODE_STRING(g_serviceURI));
+ XSECSOAPRequestorSimple req(MAKE_UNICODE_STRING(g_serviceURI));
req.doRequest(doc);
-#endif
delete msg;
doc->release();
@@ -302,7 +297,6 @@
int doMessageCreate(char * msgType) {
XSECProvider prov;
- XKMSMessageFactory * factory = prov.getXKMSMessageFactory();
// Create a new message
XKMSMessageAbstractType * msg;
1.2 +2 -2 xml-security/c/src/utils/XSECSOAPRequestor.hpp
Index: XSECSOAPRequestor.hpp
===================================================================
RCS file: /home/cvs/xml-security/c/src/utils/XSECSOAPRequestor.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XSECSOAPRequestor.hpp 16 Apr 2004 12:07:23 -0000 1.1
+++ XSECSOAPRequestor.hpp 20 Apr 2004 12:28:29 -0000 1.2
@@ -67,7 +67,7 @@
//@{
XSECSOAPRequestor() {}
- ~XSECSOAPRequestor() {}
+ virtual ~XSECSOAPRequestor() {}
//@}
1.1 xml-security/c/src/utils/XSECSOAPRequestorSimple.cpp
Index: XSECSOAPRequestorSimple.cpp
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* imitations under the License.
*/
/*
* XSEC
*
* XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
* HTTP wrapper for testing the client code.
*
*
* $Id: XSECSOAPRequestorSimple.cpp,v 1.1 2004/04/20 12:28:29 blautenb Exp $
*
*/
#include "XSECSOAPRequestorSimple.hpp"
#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECSafeBuffer.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/xkms/XKMSConstants.hpp>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
// --------------------------------------------------------------------------------
// Strings for constructing SOAP envelopes
// --------------------------------------------------------------------------------
static XMLCh s_prefix[] = {
chLatin_e,
chLatin_n,
chLatin_v,
chNull
};
static XMLCh s_Envelope[] = {
chLatin_E,
chLatin_n,
chLatin_v,
chLatin_e,
chLatin_l,
chLatin_o,
chLatin_p,
chLatin_e,
chNull
};
static XMLCh s_Body[] = {
chLatin_B,
chLatin_o,
chLatin_d,
chLatin_y,
chNull
};
// --------------------------------------------------------------------------------
// Constructors and Destructors
// --------------------------------------------------------------------------------
/* NOTE: This is initialised via the platform specific code */
XSECSOAPRequestorSimple::~XSECSOAPRequestorSimple() {
}
// --------------------------------------------------------------------------------
// Wrap and serialise the request message
// --------------------------------------------------------------------------------
char * XSECSOAPRequestorSimple::wrapAndSerialise(DOMDocument * request) {
// Create a new document to wrap the request in
XMLCh tempStr[100];
XMLString::transcode("Core", tempStr, 99);
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
safeBuffer str;
makeQName(str, s_prefix, s_Envelope);
DOMDocument *doc = impl->createDocument(
XKMSConstants::s_unicodeStrURISOAP11,
str.rawXMLChBuffer(),
NULL);// DOMDocumentType()); // document type object (DTD).
DOMElement *rootElem = doc->getDocumentElement();
makeQName(str, s_prefix, s_Body);
DOMElement *body = doc->createElementNS(
XKMSConstants::s_unicodeStrURISOAP11,
str.rawXMLChBuffer());
rootElem->appendChild(body);
// Now replicate the request into the document
DOMElement * reqElement = (DOMElement *) doc->importNode(request->getDocumentElement(), true);
body->appendChild(reqElement);
// OK - Now we have the SOAP request as a document, we serialise to a string buffer
// and return
DOMWriter *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);
MemBufFormatTarget *formatTarget = new MemBufFormatTarget;
theSerializer->writeNode(formatTarget, *doc);
// Now replicate the buffer
char * ret = XMLString::replicate((const char *) formatTarget->getRawBuffer());
delete theSerializer;
delete formatTarget;
doc->release();
return ret;
}
1.1 xml-security/c/src/utils/XSECSOAPRequestorSimple.hpp
Index: XSECSOAPRequestorSimple.hpp
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* imitations under the License.
*/
/*
* XSEC
*
* XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
* HTTP wrapper for testing the client code.
*
*
* $Id: XSECSOAPRequestorSimple.hpp,v 1.1 2004/04/20 12:28:29 blautenb Exp $
*
*/
#ifndef XSECSOAPREQUESTORSIMPLE_INCLUDE
#define XSECSOAPREQUESTORSIMPLE_INCLUDE
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/utils/XSECSOAPRequestor.hpp>
#include <xercesc/util/XMLUri.hpp>
XSEC_DECLARE_XERCES_CLASS(DOMDocument);
/**
* @ingroup xkms
*/
/*\@{*/
/**
* @brief Basic HTTP implementation for SOAP Requests
*
* The XKMS client code needs to be able to call on a SOAP requestor
* implementation that will handle wrapping the request in a SOAP msg
* and transporting it to the SOAP server. This class provides a very
* naieve implementation that wraps the message and does a basic
* HTTP POST to get the message to the end server.
*
*/
class DSIG_EXPORT XSECSOAPRequestorSimple : public XSECSOAPRequestor {
public :
/** @name Constructors and Destructors */
//@{
/**
* \brief Constructor
*
* Create a SOAP requestor that can be used to access a specific
* server
*
* @param uri The URI of the server that will be accessed.
* @note The URI must be http://...
*/
XSECSOAPRequestorSimple(const XMLCh * uri);
virtual ~XSECSOAPRequestorSimple();
//@}
/** @name Interface methods */
/**
* \brief Do a SOAP request
*
* Performs a request based on the passed in DOM document and
* the indicated URI. The function is returns a pointer
* to the parsed result message (with the SOAP envelope removed)
*
* @param request The DOM document containing the message to be
* wrapped and sent.
* @returns The DOM document representing the result, with all
* SOAP headers removed
*/
virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *
doRequest(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * request);
private:
char * wrapAndSerialise(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * request);
XERCES_CPP_NAMESPACE_QUALIFIER XMLUri
m_uri;
};
#endif /* XSECSOAPREQUESTORSIMPLE_INCLUDE */
1.1 xml-security/c/src/utils/unixutils/XSECSOAPRequestorSimpleUnix.cpp
Index: XSECSOAPRequestorSimpleUnix.cpp
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* imitations under the License.
*/
/*
* XSEC
*
* XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
* HTTP wrapper for testing the client code.
*
*
* $Id: XSECSOAPRequestorSimpleUnix.cpp,v 1.1 2004/04/20 12:28:29 blautenb Exp $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <xsec/utils/XSECSOAPRequestorSimple.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
// --------------------------------------------------------------------------------
// Platform specific constructor
// --------------------------------------------------------------------------------
XSECSOAPRequestorSimple::XSECSOAPRequestorSimple(const XMLCh * uri) : m_uri(uri) {
}
// --------------------------------------------------------------------------------
// Interface
// --------------------------------------------------------------------------------
DOMDocument * XSECSOAPRequestorSimple::doRequest(DOMDocument * request) {
char * content = wrapAndSerialise(request);
// First we need to serialise
char fBuffer[4000];
char * fBufferEnd;
char * fBufferPos;
//
// Pull all of the parts of the URL out of th m_uri object, and transcode them
// and transcode them back to ASCII.
//
const XMLCh* hostName = m_uri.getHost();
char* hostNameAsCharStar = XMLString::transcode(hostName);
ArrayJanitor<char> janBuf1(hostNameAsCharStar);
const XMLCh* path = m_uri.getPath();
char* pathAsCharStar = XMLString::transcode(path);
ArrayJanitor<char> janBuf2(pathAsCharStar);
const XMLCh* fragment = m_uri.getFragment();
char* fragmentAsCharStar = 0;
if (fragment)
fragmentAsCharStar = XMLString::transcode(fragment);
ArrayJanitor<char> janBuf3(fragmentAsCharStar);
const XMLCh* query = m_uri.getQueryString();
char* queryAsCharStar = 0;
if (query)
queryAsCharStar = XMLString::transcode(query);
ArrayJanitor<char> janBuf4(queryAsCharStar);
unsigned short portNumber = (unsigned short) m_uri.getPort();
// If no number is set, go with port 80
if (portNumber == USHRT_MAX)
portNumber = 80;
//
// Set up a socket.
//
struct hostent* hostEntPtr = 0;
struct sockaddr_in sa;
if ((hostEntPtr = gethostbyname(hostNameAsCharStar)) == NULL)
{
unsigned long numAddress = inet_addr(hostNameAsCharStar);
if (numAddress == 0)
{
ThrowXML(NetAccessorException,
XMLExcepts::NetAcc_TargetResolution);
}
if ((hostEntPtr =
gethostbyaddr((char *) &numAddress,
sizeof(unsigned long), AF_INET)) == NULL)
{
ThrowXML(NetAccessorException,
XMLExcepts::NetAcc_TargetResolution);
}
}
memcpy((void *) &sa.sin_addr,
(const void *) hostEntPtr->h_addr, hostEntPtr->h_length);
sa.sin_family = hostEntPtr->h_addrtype;
sa.sin_port = htons(portNumber);
int s = socket(hostEntPtr->h_addrtype, SOCK_STREAM, 0);
if (s < 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error creating socket");
}
if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error connecting to end server");
}
// The port is open and ready to go.
// Build up the http GET command to send to the server.
// To do: We should really support http 1.1. This implementation
// is weak.
memset(fBuffer, 0, sizeof(fBuffer));
strcpy(fBuffer, "POST ");
strcat(fBuffer, pathAsCharStar);
if (queryAsCharStar != 0)
{
// Tack on a ? before the fragment
strcat(fBuffer,"?");
strcat(fBuffer, queryAsCharStar);
}
if (fragmentAsCharStar != 0)
{
strcat(fBuffer, fragmentAsCharStar);
}
strcat(fBuffer, " HTTP/1.0\r\n");
strcat(fBuffer, "Content-Type: text/xml; charset=utf-8\r\n");
strcat(fBuffer, "Host: ");
strcat(fBuffer, hostNameAsCharStar);
if (portNumber != 80)
{
int i = strlen(fBuffer);
sprintf(fBuffer+i, ":%d", portNumber);
}
strcat(fBuffer, "\r\n");
strcat(fBuffer, "Content-Length: ");
int i = (int) strlen(fBuffer);
sprintf(fBuffer+i, "%d", strlen(content));
strcat(fBuffer, "\r\n");
strcat(fBuffer, "SOAPAction: \"\"\r\n");
/* strcat(fBuffer, "Connection: Close\r\n");
strcat(fBuffer, "Cache-Control: no-cache\r\n");*/
strcat(fBuffer, "\r\n");
// Now the content
strcat(fBuffer, content);
// Send the http request
int lent = strlen(fBuffer);
int aLent = 0;
if ((aLent = write(s, (void *) fBuffer, lent)) != lent)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error writing to socket");
}
//
// get the response, check the http header for errors from the server.
//
aLent = read(s, (void *)fBuffer, sizeof(fBuffer)-1);
/***/
fBuffer[aLent] = '\0';
printf(fBuffer);
/***/
if (aLent <= 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error reported reading socket");
}
fBufferEnd = fBuffer+aLent;
*fBufferEnd = 0;
// Find the break between the returned http header and any data.
// (Delimited by a blank line)
// Hang on to any data for use by the first read from this BinHTTPURLInputStream.
//
fBufferPos = strstr(fBuffer, "\r\n\r\n");
if (fBufferPos != 0)
{
fBufferPos += 4;
*(fBufferPos-2) = 0;
}
else
{
fBufferPos = strstr(fBuffer, "\n\n");
if (fBufferPos != 0)
{
fBufferPos += 2;
*(fBufferPos-1) = 0;
}
else
fBufferPos = fBufferEnd;
}
// Make sure the header includes an HTTP 200 OK response.
//
char *p = strstr(fBuffer, "HTTP");
if (p == 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error reported reading socket");
}
p = strchr(p, ' ');
if (p == 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error reported reading socket");
}
int httpResponse = atoi(p);
if (httpResponse == 302 || httpResponse == 301) {
//Once grows, should use a switch
char redirectBuf[256];
int q;
// Find the "Location:" string
p = strstr(p, "Location:");
if (p == 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error reported reading socket");
}
p = strchr(p, ' ');
if (p == 0)
{
throw XSECException(XSECException::HTTPURIInputStreamError,
"Error reported reading socket");
}
// Now read
p++;
for (q=0; q < 255 && p[q] != '\r' && p[q] !='\n'; ++q)
redirectBuf[q] = p[q];
redirectBuf[q] = '\0';
// Try to find this location
m_uri = XMLUri(XMLString::transcode(redirectBuf));
return doRequest(request);
}
else if (httpResponse != 200)
{
// Most likely a 404 Not Found error.
// Should recognize and handle the forwarding responses.
//
throw XSECException(XSECException::HTTPURIInputStreamError,
"Unknown HTTP Response");
}
while (aLent != 0) {
aLent = read(s, (void *)fBuffer, sizeof(fBuffer)-1);
/***/
fBuffer[aLent] = '\0';
printf(fBuffer);
/***/
}
return NULL;
}