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;
  }