You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sa...@apache.org on 2004/09/21 05:52:24 UTC

cvs commit: ws-axis/c/src/transport/axis2 Axis2Transport.cpp Axis2Transport.h AxisTransportException.cpp AxisTransportException.h Channel.cpp Channel.h Makefile.am Platform.h URL.cpp URL.h

samisa      2004/09/20 20:52:24

  Added:       c/src/transport/axis2 Axis2Transport.cpp Axis2Transport.h
                        AxisTransportException.cpp AxisTransportException.h
                        Channel.cpp Channel.h Makefile.am Platform.h
                        URL.cpp URL.h
  Log:
  New trasport with cyclic referances to classes removed and
  lesser number of classes to help maintanace.
  There has been some logic changes to improve performance.
  
  Revision  Changes    Path
  1.1                  ws-axis/c/src/transport/axis2/Axis2Transport.cpp
  
  Index: Axis2Transport.cpp
  ===================================================================
  /*
  *   Copyright 2003-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
  *   limitations under the License.
  */
  
  /*
   * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
   *
   */
  
  
  #ifdef WIN32
  #pragma warning (disable : 4786)
  #pragma warning (disable : 4101)
  #endif
  
  #include "Axis2Transport.h"
  
  #include <stdio.h>
  #include <iostream>
  
  Axis2Transport::Axis2Transport()
          : m_bURIChanged( false ), 
          m_strHTTPProtocol("HTTP/1.1"), m_strHTTPMethod("POST"), 
          m_bChunked(false), m_bReadPastHTTPHeaders(false) ,m_strProxyHost( "" ), m_uiProxyPort( 0 ), m_bUseProxy( false )
  {
      m_pcEndpointUri = NULL;
      m_pReleaseBufferCallback = 0;
      m_strBytesToSend = "";
      m_iBytesLeft = 0;
      m_iContentLength = 0;
      m_pcReceived = 0;
  }
  
  Axis2Transport::~Axis2Transport()
  {
      if ( m_pcEndpointUri )
          free( m_pcEndpointUri );
  }
  
  void Axis2Transport::setEndpointUri( const char* pcEndpointUri )
  {
      if ( m_Channel.getURL() )
          if ( strcmp( m_Channel.getURL(), pcEndpointUri ) == 0 )
              return ; // no change to the current URI; hence do nothing
  
      // we have a new URI
      m_Channel.setURL( pcEndpointUri );
      m_bURIChanged = true;
  }
  
  int Axis2Transport::openConnection()
  {
      //Samisa: I wonder whether this should be a SOAPTransport API call.
      //It should not be the job of the upper layers to tell the trasport
      //to open and close connections. Rather the transport should determine
      //when to do that, when sendBytes is called.
  
      return AXIS_SUCCESS;
  
  }
  
  void Axis2Transport::closeConnection()
  {
          m_bReadPastHTTPHeaders = false; // get ready for a new message
          m_strReceived = "";    //clear the message buffer in preperation of the next read
          m_iContentLength = 0;
  }
  
  
  AXIS_TRANSPORT_STATUS Axis2Transport::flushOutput()
  {
      if ( m_bURIChanged )
          m_Channel.open();
  
      char buff[ 8 ];
      sprintf( buff, "%d", m_strBytesToSend.length() );
      this->setTransportProperty( "Content-Length" , buff );
  
      try
      {
          m_Channel << this->getHTTPHeaders();
          m_Channel << this->m_strBytesToSend.c_str();
      }
      catch(AxisTransportException& e)
      {
          throw;
      }
      catch(AxisException& e)
      {
          throw;
      }
      catch(...)
      {
          throw;
      }
  
      m_strBytesToSend = "";
      return TRANSPORT_FINISHED;
  }
  
  const char* Axis2Transport::getHTTPHeaders()
  {
      URL& url = m_Channel.getURLObject();
  
      std::string strHTTPHeaders = m_strHTTPMethod + " ";
      //strHTTPHeaders += std::string(url.getURL()) + " ";
      strHTTPHeaders += std::string(url.getResource()) + " ";
      strHTTPHeaders += m_strHTTPProtocol + "\r\n";
  
      strHTTPHeaders += std::string("Host: ") + url.getHostName();
  
      unsigned short port = url.getPort ();
      char buff[8];
      sprintf (buff, "%u", port);
      strHTTPHeaders += ":";
      strHTTPHeaders += buff;
      strHTTPHeaders += "\r\n";
  
      strHTTPHeaders += "Content-Type: text/xml; charset=UTF-8\r\n";
  
      // Set other HTTP headers
      for (unsigned int i = 0; i < m_vHTTPHeaders.size (); i++)
      {
  
          strHTTPHeaders += m_vHTTPHeaders[i].first;
          strHTTPHeaders += ": ";
          strHTTPHeaders += m_vHTTPHeaders[i].second;
          strHTTPHeaders += "\r\n";
      }
  
      strHTTPHeaders += "\r\n";
  
      return strHTTPHeaders.c_str();
  }
  
  const char* Axis2Transport::getHTTPMethod()
  {
      return m_strHTTPMethod.c_str();
  }
  
  void Axis2Transport::setHTTPMethod(const char* cpMethod)
  {
      m_strHTTPMethod = std::string(cpMethod);
  }
  
  AXIS_TRANSPORT_STATUS Axis2Transport::sendBytes( const char* pcSendBuffer,
          const void* pBufferId )
  {
      m_strBytesToSend += std::string( pcSendBuffer );
  
      return TRANSPORT_IN_PROGRESS;
  }
  
  
  AXIS_TRANSPORT_STATUS Axis2Transport::getBytes( char* pcBuffer, int* pSize )
  {
      if ( 0 <= m_iBytesLeft )
      {
          try
          {
              m_Channel >> m_strReceived;
              if (!m_bReadPastHTTPHeaders)
              {
                  do
                  {
                      if (m_strReceived.find ("\r\n\r\n") == std::string::npos)
                          m_Channel >> m_strReceived;    // Assume non blocking here
                  }
                  while (m_strReceived.find ("\r\n\r\n") == std::string::npos);
                  //now we have found the end of headers
                  m_bReadPastHTTPHeaders = true;
  
                  unsigned int pos = 0;
  
                  // Look for content lenght
                  if ((pos = m_strReceived.find ("Content-Length: ")) != std::string::npos)
                  {
                      m_iContentLength = atoi (m_strReceived.substr (pos + strlen ("Content-Length: "),
                                               m_strReceived.find("\n", pos) ).c_str ());
                  }
  
                  // Check if the message is chunked
                  if ((pos = m_strReceived.find ("Transfer-Encoding: chunked")) != std::string::npos)
                  {
                      m_bChunked = true;
                  }
                  else
                  {
                      m_bChunked = false;
                  }
  
                  // Skip headers and get payload
                  m_strReceived = m_strReceived.substr(m_strReceived.find ("\r\n\r\n") + 4 );
              }
  
              // Read past headers. Deal with payload
  
              // make sure we have a message with some content
              if (m_strReceived.length() == 0)
                  m_Channel >> m_strReceived;
  
              if (m_bChunked && m_iContentLength < 1 )
              {
                  /*
                   *Chunked data looks like ->
                   *      Chunked-Body   = *chunk
                   *                       "0" CRLF
                   *                       footer
                   *                       CRLF
                   *
                   *      chunk          = chunk-size [ chunk-ext ] CRLF
                   *                         chunk-data CRLF
                   *
                   *      hex-no-zero    = <HEX excluding "0">
                   *
                   *      chunk-size     = hex-no-zero *HEX
                   *      chunk-ext      = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
                   *      chunk-ext-name = token
                   *      chunk-ext-val  = token | quoted-string
                   *      chunk-data     = chunk-size(OCTET)
                   *
                   *      footer         = *entity-header
                   */
                  // firstly read in the chunk size line. 
                  //There might be chunk extensions in there too but we may not need them                
                  unsigned int endOfChunkData = m_strReceived.find ("\r\n");
                  
                  // make sure we have read at least some part of the message
                  if (endOfChunkData == std::string::npos)
                  {
                      do
                      {
                          m_Channel >> m_strReceived;
                          endOfChunkData = m_strReceived.find ("\r\n");
                      }while (endOfChunkData == std::string::npos);
                  }
                  
                  int endOfChunkSize = endOfChunkData;
  
                  // now get just the size of the chunk from the data
                  // look to see if there are any extensions - these are put in brackets so look for those
                  if (m_strReceived.substr (0, endOfChunkData).find ("(") != string::npos)
                  {
                      // there are extensions so just get the chunk dataSize
                      endOfChunkSize = m_strReceived.find ("(");
                  }
  
                  // convert the hex String into the length of the chunk
                  m_iContentLength = axtoi ((char *) m_strReceived.substr (0, endOfChunkSize).c_str ());
                  // if the chunk size is zero then we have reached the footer
                  // If we have reached the footer then we can throw it away because we don't need it
                  if (m_iContentLength > 0)
                  {
                      // now get the chunk without the CRLF
                      m_strReceived = m_strReceived.substr (endOfChunkData + 2);//, chunkSize);
                      // OK, now we have the chunk, we need to read in more chunks from the channel.
                      // we must have more chunks because we haven't reached the ")" which signifies the end of the
                      // now move the unparsed chunk along avoiding the 2 bytes of CRLF.
                      //unParsedChunks = unParsedChunks.substr (endOfChunkData + 2 + chunkSize + 2);
                      
                  }
                  else
                  {
                      m_strReceived = "";
                  }
              }
              else // Not chunked
              {
                  //nothing to do here
              }
  
              //printf( "cont len = %ld, read = %ld", m_iContentLength, m_strReceived.length());
  
              m_pcReceived = m_strReceived.c_str();
              if ( m_pcReceived )
                  m_iBytesLeft = strlen( m_pcReceived );
              else
                  throw AxisTransportException( SERVER_TRANSPORT_BUFFER_EMPTY, "Reveved null" );
  
              m_iContentLength -= m_iBytesLeft;
          }
          catch ( AxisTransportException & e )
          {
              throw;
          }
          catch ( AxisException & e )
          {
              throw;
          }
          catch ( ... )
          {
              throw;
          }
      }
      if ( m_pcReceived )
      {
          int iToCopy = ( *pSize < m_iBytesLeft ) ? *pSize : m_iBytesLeft;
          strncpy( pcBuffer, m_pcReceived, iToCopy );
          m_iBytesLeft -= iToCopy;
          m_pcReceived += iToCopy;
          *pSize = iToCopy;
          return TRANSPORT_IN_PROGRESS;
      }
      else
      {
          m_bReadPastHTTPHeaders = false; // get ready for a new message
          m_strReceived = "";    //clear the message buffer in preperation of the next read
          return TRANSPORT_FINISHED;
      }
  }
  
  
  void Axis2Transport::setTransportProperty
  ( AXIS_TRANSPORT_INFORMATION_TYPE type, const char* value )
  {
      const char * key = NULL;
      switch ( type )
      {
      case SOAPACTION_HEADER:
          key = "SOAPAction";
          break;
      case SERVICE_URI:   // need to set ?
          break;
      case OPERATION_NAME:   // need to set ?
          break;
      case SOAP_MESSAGE_LENGTH:
          key = "Content-Length"; // this Axis transport handles only HTTP
          break;
      default:
          ;
      }
      if ( !key )
          return ;
      setTransportProperty( key, value );
  }
  
  void Axis2Transport::setTransportProperty( const char* pcKey, const char* pcValue )
  {
      bool b_KeyFound = false;    
  
      if ( strcmp( pcKey, "SOAPAction" ) == 0 || strcmp( pcKey, "Content-Length" ) == 0 )
      {
          std::string strKeyToFind = std::string(pcKey);
          
          for ( unsigned int i = 0; i < m_vHTTPHeaders.size(); i++ )
          {
              if ( m_vHTTPHeaders[ i ].first == strKeyToFind )
              {
                  m_vHTTPHeaders[ i ].second = ( string ) pcValue;
                  b_KeyFound = true;                
                  break;
              }
          }
      }
  
      if ( !b_KeyFound )
      {
          m_vHTTPHeaders.push_back ( std::make_pair ((string) pcKey, (string) pcValue ) );
      }
  }
  
  const char* Axis2Transport::getTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE eType )
  {
      //TODO
      return 0;
  }
  
  const char* Axis2Transport::getServiceName()
  {
      //Assume SOAPAction header to contain service name
      for ( unsigned int i = 0; i < m_vHTTPHeaders.size(); i++ )
      {
          if ( m_vHTTPHeaders[ i ].first == "SOAPAction" )
          {
              return ((string) m_vHTTPHeaders[ i ].second ).c_str();
          }
      }
  
      return NULL;
  }
  
  AXIS_PROTOCOL_TYPE Axis2Transport::getProtocol()
  {
      return APTHTTP;
  }
  
  
  /**
   * This method is supposed to return whether it is http GET or POST
   */
  int Axis2Transport::getSubProtocol()
  {
      //TODO
      return 0;
  }
  
  void
  Axis2Transport::setProxy( const char* pcProxyHost, unsigned int uiProxyPort )
  {
      m_strProxyHost = pcProxyHost;
      m_uiProxyPort = uiProxyPort;
      m_bUseProxy = true;
  }
  
  void Axis2Transport::setTimeout( const long lSeconds )
  {
      m_Channel.setTimeout( lSeconds );
  }
  
  const char* Axis2Transport::getHTTPProtocol()
  {
      return m_strHTTPProtocol.c_str();
  }
  
  void Axis2Transport::setHTTPProtocol( int iVersion )
  {
      switch(iVersion)
      {
      case 0:
          m_strHTTPProtocol = "HTTP/1.0";
          break;
      case 1:
      default:
          m_strHTTPProtocol = "HTTP/1.1";
      }
  }
  
  
  extern "C"
  {
      STORAGE_CLASS_INFO
      int CreateInstance( SOAPTransport **inst )
      {
          *inst = new Axis2Transport();
          if ( *inst )
          {
              return AXIS_SUCCESS;
          }
          return AXIS_FAIL;
      }
      STORAGE_CLASS_INFO
      int DestroyInstance( SOAPTransport * inst )
      {
          if ( inst )
          {
              delete inst;
              return AXIS_SUCCESS;
          }
          return AXIS_FAIL;
      }
  }
  
  extern "C"
  {
      STORAGE_CLASS_INFO
      void initializeLibrary( void )
      {
          // Do init actions
      }
  }
  
  extern "C"
  {
      STORAGE_CLASS_INFO
      void uninitializeLibrary( void )
      {
          // Do uninit actions
      }
  }
  
  
   /*
    * This converts an ascii hex string to int converter.
    */
  int
  axtoi (char *hexStg)
  {
      int
  	n = 0;			// position in string
      int
  	m = 0;			// position in digit[] to shift
      int
  	count;			// loop index
      int
  	intValue = 0;		// integer value of hex string
      int
  	digit[32];		// hold values to convert
      while (n < 32)
      {
  	if (hexStg[n] == '\0')
  	    break;
  	if (hexStg[n] > 0x29 && hexStg[n] < 0x40)	//if 0 to 9
  	    digit[n] = hexStg[n] & 0x0f;	//convert to int
  	else if (hexStg[n] >= 'a' && hexStg[n] <= 'f')	//if a to f
  	    digit[n] = (hexStg[n] & 0x0f) + 9;	//convert to int
  	else if (hexStg[n] >= 'A' && hexStg[n] <= 'F')	//if A to F
  	    digit[n] = (hexStg[n] & 0x0f) + 9;	//convert to int
  	else
  	    break;
  	n++;
      }
      count = n;
      m = n - 1;
      n = 0;
      while (n < count)
      {
  	// digit[n] is value of hex digit at position n
  	// (m << 2) is the number of positions to shift
  	// OR the bits into return value
  	intValue = intValue | (digit[n] << (m << 2));
  	m--;			// adjust the position to set
  	n++;			// next digit to process
      }
      return (intValue);
  }
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/Axis2Transport.h
  
  Index: Axis2Transport.h
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
   */
  
  
  #if !defined(_AXIS_AXIS_TRANSPORT_HPP)
  #define _AXIS_AXIS_TRANSPORT_HPP
  
  #include "../SOAPTransport.h"
  #include "Channel.h"
  #include <string>
  #include <vector>
  
  AXIS_CPP_NAMESPACE_USE
  using namespace std;
  
  int axtoi (char *hexStg);
  
  class Axis2Transport : public SOAPTransport
  {
  public:
      Axis2Transport();
      virtual ~Axis2Transport();
      
    /**
      * Sets the endpoint URI. 
      * Keeps track of the changes made to the URI. (Because if the URI changes, 
      * we cannot reuse the opned socket)
      * @param pcEndPointURI End point URI of the service to connect to.
      *                       e.g. http://localhost:8080/axis/services/echo
      */ 
      void setEndpointUri(const char* pcEndpointUri);
      int openConnection();
      void closeConnection();
      AXIS_TRANSPORT_STATUS sendBytes(const char* pcSendBuffer, const void* pBufferId);
  	void registerReleaseBufferCallback(AXIS_ENGINE_CALLBACK_RELEASE_SEND_BUFFER pFunct)
  	{ m_pReleaseBufferCallback = pFunct; };
      AXIS_TRANSPORT_STATUS getBytes(char* pcBuffer, int* piSize);
      void setTransportProperty(AXIS_TRANSPORT_INFORMATION_TYPE eType, const char* pcValue);
      const char* getTransportProperty(AXIS_TRANSPORT_INFORMATION_TYPE eType);
      void setTransportProperty(const char* pcKey, const char* pcValue);
      const char* getTransportProperty(const char* pcKey){return "value";};
  	void setAttachment(const char* pcAttachmentId, const char* pcAttachment){};
  	const char* getAttachment(const char* pcAttachmentId){return "value";};
  	
  	
  	void setSessionId(const char* pcSessionId){};
  	const char* getSessionId(){return "some session id";};
  	const char* getServiceName();
  	AXIS_PROTOCOL_TYPE getProtocol();
  	int getSubProtocol();
  	AXIS_TRANSPORT_STATUS flushOutput();
  	
    /**
      * Set proxy server and port for transport.
      *
      * @param pcProxyHost Host name of proxy server
      * @param uiProxyPort Port of proxy server
      */
      void setProxy(const char* pcProxyHost, unsigned int uiProxyPort); 
  
    /**
      * Set transport timeout.
      *
      * @param lSeconds Timeout in seconds
      */
      void setTimeout(const long lSeconds);
      
    /**
      * @return HTTP protocol in use - HTTP/1.1 or HTTP/1.0
      */  
      const char* getHTTPProtocol();
      
    /**
      * Sets the HTTP protocol to be 1.1 or 1.0
      * @param iVersion Version to be used 
      *        If 0 HTTP/1.0 would be used, if 1 HTTP/1.1 would be used.
      *        Default is HTTP1.1
      */
      void setHTTPProtocol( int iVersion );
    
    /**
      * @return HTTP Method in use - POST, GET etc.
      */     
      const char* getHTTPMethod();
      
    /**
      * Set HTTP Method to use
      * @param cpMethod - Possible values POST, GET, etc. 
      *        Only POST is handled correctly at the moment
      */     
      void setHTTPMethod(const char* cpMethod);
      
      const char* getHTTPHeaders();
  
      
  
  private:
    /**
      * Keeps track of URI changes.
      * Set true by setEndpointUri.
      * Set false when a socket connection is established with the enpoint.
      */
      bool m_bURIChanged;
      
    /**
      * Channel used for comminication
      */
      Channel m_Channel;
      
    /**
      * Message string to be sent.
      */
      std::string m_strBytesToSend;
        
    /**
      * Vector to hold HTTP header key/value pairs
      */  
      std::vector< std::pair<std::string, std::string> > m_vHTTPHeaders;
      
    /**
      * HTTP protocol (1.1 or 1.0). Default is HTTP/1.1
      */   
      std::string m_strHTTPProtocol;
      
    /**
      * HTTP method (POST, GET etc.)  - Only support POST at the moment
      */
      std::string m_strHTTPMethod;
      
    /**
      * Bytes left in the payload buffer to be read
      */  
      int m_iBytesLeft;
      
    /**
      * Payload lenght
      */  
      int m_iContentLength;
      
    /**
      * Is the message chunked
      */  
      int m_bChunked;
          
    /**  
      * String holding what we received over the channel
      */
      std::string m_strReceived;
      
    /**
      * Have we read past HTTP headers?
      */
      bool m_bReadPastHTTPHeaders;
      
    /**
      * Payload buffer
      */  
  	const char* m_pcReceived;
       
    /**
      * Proxy server name.
      */
      std::string m_strProxyHost;
    /**
      * Proxy server port.
      */
      unsigned int m_uiProxyPort;
    /**
      * Use Proxy or not?
      */
      bool m_bUseProxy;
  
  };
  
  #endif
  
      
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/AxisTransportException.cpp
  
  Index: AxisTransportException.cpp
  ===================================================================
  /* -*- C++ -*- */
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   *
   * 
   * @author  Damitha Kumarage (damitha@opensource.lk, damitha@jkcsworld.com)
   *
   */
  
  #include "AxisTransportException.h"
  
  /**
   *    Default when no parameter passed. When thrown with no parameter
   *    more general SERVER_TRANSPORT_EXCEPTION is assumed.
  */
  AxisTransportException::AxisTransportException()
  {
      processException(SERVER_TRANSPORT_EXCEPTION);
  }
  
  AxisTransportException::AxisTransportException (const int iExceptionCode)
  {
      m_iExceptionCode = iExceptionCode;
      processException (iExceptionCode);
  }
  
  AxisTransportException::AxisTransportException(const int iExceptionCode, char* pcMessage)
  {
      m_iExceptionCode = iExceptionCode;
      processException(iExceptionCode, pcMessage);
  }
  
  AxisTransportException::AxisTransportException (const exception* e)
  {
      processException (e);
  }
  
  AxisTransportException::AxisTransportException (const exception* e, const int iExceptionCode)
  {
      processException (e, iExceptionCode);
  }
  
  AxisTransportException::~AxisTransportException() throw ()
  {
  
  }
  
  void AxisTransportException::processException (const exception* e, const int iExceptionCode)
  {
      m_sMessage = getMessage (iExceptionCode) + ":" + getMessage(e);
  }
  
  void AxisTransportException::processException (const exception* e, char* pcMessage)
  {
      m_sMessage += "AxisTransportException:" + string(pcMessage) + ":" + getMessage (e);
  }
  
  void AxisTransportException::processException (const exception* e)
  {
      m_sMessage += "AxisTransportException:" + getMessage (e);
  }
  
  void AxisTransportException::processException(const int iExceptionCode)
  {
      m_sMessage = getMessage (iExceptionCode);
  }
  
  void AxisTransportException::processException(const int iExceptionCode, char* pcMessage)
  {
      AxisString sMessage = pcMessage;
      m_sMessage = getMessage(iExceptionCode) + " " + sMessage;
      if(pcMessage)
          delete pcMessage;
  }
  const string& AxisTransportException::getMessage (const exception* objException)
  {
  	static string objExDetail = objException->what();
  
      return objExDetail;
  }
  
  const string& AxisTransportException::getMessage (const int iExceptionCode)
  {
      switch(iExceptionCode)
      {
         case SERVER_TRANSPORT_RECEPTION_EXCEPTION:
              m_sMessage = "AxisTransportException:Problem occured when" \
                  " receiving the stream";
              break;
          case SERVER_TRANSPORT_SENDING_EXCEPTION:
              m_sMessage = "AxisTransportException:Problem occured when sending" \
                  " the stream";
              break;
          case SERVER_TRANSPORT_HTTP_EXCEPTION:
              m_sMessage = "AxisTransportException:HTTP transport error";
              break;
          case SERVER_TRANSPORT_PROCESS_EXCEPTION:
              m_sMessage = "AxisTransportException:HTTP Error, cannot process" \
                  " response message";
              break;
          case SERVER_TRANSPORT_UNKNOWN_HTTP_RESPONSE:
              m_sMessage = "AxisTransportException:Unknow HTTP response," \
                  " cannot process response message";
              break;
          case SERVER_TRANSPORT_UNEXPECTED_STRING:
              m_sMessage = "AxisTransportException:Unexpected string " \
                  "received. Most probably server " \
                  "returned an empty stream";
              break;
          case SERVER_TRANSPORT_CHANNEL_INIT_ERROR:
              m_sMessage = "AxisTransportException:Cannot initialize a " \
                  "channel to the remote end";
              break;
          case SERVER_TRANSPORT_SOCKET_CREATE_ERROR:
              m_sMessage = "AxisTransportException:Sockets error Couldn't" \
                 " create socket";
              break;
          case SERVER_TRANSPORT_SOCKET_CONNECT_ERROR:
              m_sMessage = "AxisTransportException:Cannot open a channel to the" \
              " remote end, shutting down the channel";
              break;
          case SERVER_TRANSPORT_INVALID_SOCKET:
              m_sMessage = "AxisTransportException:Invalid socket. Socket may" \
                  " not be open";
              break;
          case SERVER_TRANSPORT_OUTPUT_STREAMING_ERROR:
              m_sMessage = "AxisTransportException:Output streaming error on" \
                  " Channel while writing data";
              break;
          case SERVER_TRANSPORT_INPUT_STREAMING_ERROR:
              m_sMessage = "AxisTransportException:Input streaming error while" \
                  " getting data";
              break;
          case SERVER_TRANSPORT_TIMEOUT_EXCEPTION:
              m_sMessage = "AxisTransportException:Channel error while waiting" \
                   " for timeout";
              break;
          case SERVER_TRANSPORT_TIMEOUT_EXPIRED:
              m_sMessage = "AxisTransportException:Channel error connection " \
                  "timeout before receving";
              break;
          case SERVER_TRANSPORT_BUFFER_EMPTY:
              m_sMessage = "AxisTransportException:Transport buffer is empty";
              break;
          default:
              m_sMessage = "AxisTransportException:Unknown Transport Exception"; 
      }
      return m_sMessage;
  }
  
  const char* AxisTransportException::what() throw ()
  {
      return m_sMessage.c_str ();
  }
  
  const int AxisTransportException::getExceptionCode()
  {
      return m_iExceptionCode;
  }
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/AxisTransportException.h
  
  Index: AxisTransportException.h
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   *
   *
   *   @author Damitha Kumarage (damitha@opensource.lk, damitha@jkcsworld.com)
   *
   */
   
  #ifndef __AXISTRANSPORTEXCEPTION_H_OF_AXIS_INCLUDED_
  #define __AXISTRANSPORTEXCEPTION_H_OF_AXIS_INCLUDED_
  
  #include <string>
  #include <axis/server/AxisException.h>
  using namespace std;
  
  AXIS_CPP_NAMESPACE_USE
  
  class STORAGE_CLASS_INFO AxisTransportException :public AxisException
  {
  
  public:
      AxisTransportException();
      AxisTransportException(const int iExceptionCode);
      AxisTransportException(const int iExceptionCode, char* pcMessage);
      AxisTransportException(const exception* e);
      AxisTransportException(const exception* e, const int iExceptionCode);
      virtual ~AxisTransportException() throw();
      const char* what() throw();
      const int getExceptionCode();
                                                                                                                               
  private:
      const string& getMessage(const exception* e);
      const string& getMessage(const int iExceptionCode);
      void processException(const exception* e);
      void processException(const exception* e, const int iExceptionCode);
  	void processException (const exception* e, char* pcMessage);
      void processException(const int iExceptionCode);
      void processException(const int iExceptionCode, char* pcMessage);                                                                                                                           
      string m_sMessage;
      int m_iExceptionCode;
  };
  
  #endif
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/Channel.cpp
  
  Index: Channel.cpp
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   * @author Lilantha Darshana (lilantha@virtusa.com)
   * @author Damitha Kumarage (damitha@jkcsworld.com, damitha@opensource.lk)
   * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
   */
  
  #include "Platform.h"
  #include "Channel.h"
  #include <iostream>
  #include <stdio.h>
  
  using namespace std;
  /**
   * Create a Channel & initialize
   * 
   */
  
  Channel::Channel ():m_Sock (INVALID_SOCKET)
  {
  
  }
  
  Channel::~Channel ()
  {
      closeChannel ();
  }
  
  void Channel::setURL(const char* cpURL)
  {
      m_URL.setURL(cpURL);
  }
      
  const char* Channel::getURL() 
  {
      return m_URL.getURL();
  }
  
  
  /**
   * This channel open INET channel for the time being using primitive sockets
   * Do we need any other type of channel; like shared memory, pipes etc. ????
   * 
   * @param    p_RemoteNode    End point address as hostname/IP
   * @param    p_RemoteEnd        Port #
   *
   * @return  true if successfuly open a soket to the endpoint. o/w exception is 
   * thrown
   */
  
  bool
  Channel::open () //std::string & p_RemoteNode, unsigned short p_RemoteEnd)
  throw (AxisTransportException)
  {
      if (!Init ())
  	throw AxisTransportException(SERVER_TRANSPORT_CHANNEL_INIT_ERROR);
  
      sockaddr_in clAddr, svAddr;
  
      if ((m_Sock = socket (PF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
      {
  	clAddr.sin_family = AF_INET;	/* AF_INET (address family Internet). */
  	clAddr.sin_port = 0;	/* No Specify Port required */
  	clAddr.sin_addr.s_addr = INADDR_ANY;
  
  	if (bind (m_Sock, (struct sockaddr *) &clAddr, sizeof (clAddr)) ==
  	    SOCKET_ERROR)
  	{
  	    /* Error - Binding. Cannot open a channel to the remote end, 
                 shutting down the channel
              */
  	    closeChannel ();
  	    throw AxisTransportException(SERVER_TRANSPORT_SOCKET_CONNECT_ERROR);
  	}
  
  	/* Although the above fragment makes use of the bind() API, it would be
  	 * just as effective to skip over this call as there are no specific
  	 * local port ID requirements for this client. The only advantage that
  	 * bind() offers is the accessibility of the port which the system 
  	 * chose via the .sin_port member of the cli_addr structure which will 
  	 * be set upon success of the bind() call.
  	 */
  
  	svAddr.sin_family = AF_INET;
  	svAddr.sin_port = htons (m_URL.getPort());
  
  	struct hostent *pHostEntry = NULL;
  
  	/* probably this is the host-name of the server we are connecting to */
  	if ((pHostEntry = gethostbyname (m_URL.getHostName())))
  	{
  	    svAddr.sin_addr.s_addr =
  		((struct in_addr *) pHostEntry->h_addr)->s_addr;
  	}
  	else
  	{
  	    /* no this is the IP address */
  	    svAddr.sin_addr.s_addr = inet_addr (m_URL.getHostName());
  	}
  
  	/* connect to the remote server. */
  	if (connect (m_Sock, (struct sockaddr *) &svAddr,
  		     sizeof (svAddr)) == SOCKET_ERROR)
  	{
  	    closeChannel ();
              /*Cannot open a channel to the remote end, shutting down the channel*/
  	    throw AxisTransportException(SERVER_TRANSPORT_SOCKET_CONNECT_ERROR);
  	}
      }
      else
      {
  	closeChannel ();
          /* Sockets error Couldn't create socket*/
  	throw AxisTransportException(SERVER_TRANSPORT_SOCKET_CREATE_ERROR);
      }
  
      return true;
  }
  
  /*
   * OS specific initialization should do here
   *
   * @return  true if successfuly initilaize OS specific stuffs. false o/w
   */
  
  bool
  Channel::Init ()
  {
  #ifdef WIN32
  
      WSADATA wsaData;		/* contains vendor-specific information, such as the
  				 * maximum number of sockets available and the maximum
  				 * datagram size.
  				 */
      if (WSAStartup (WS_VERSION_REQD, &wsaData))
  	/* Filled by Windows Sockets DLLs */
      {
  	m_LastErr = "WinSock DLL not responding.";
  	//Error ((char *) m_LastErr.c_str ());
  	return false;
      }
      else
      {
  	/* Query to see whether the available version matches what we need */
  	if ((LOBYTE (wsaData.wVersion) < WS_VERSION_MAJOR ()) ||
  	    (LOBYTE (wsaData.wVersion) == WS_VERSION_MAJOR () &&
  	     HIBYTE (wsaData.wVersion) < WS_VERSION_MINOR ()))
  	{
  	    char buf[100];
  	    sprintf (buf,
  		     "Windows Sockets version %d.%d not supported by winsock2.dll",
  		     LOBYTE (wsaData.wVersion), HIBYTE (wsaData.wVersion));
  	    Error (buf);
  	    closeChannel ();
  	    return false;
  	}
      }
  #else
      /* cout << "no need for linux" << endl; */
      /* other OS specific Intitialization goes here */
  #endif
  
      return true;
  }
  
  /*
   * Write/send a message to the remote server; sending blocks the app.
   * we may need to do this asynchronizely; preferably either non-blocking
   * send or pthread.
   *
   * @param    Message to be written to the open channel
   */
  const Channel &
  Channel::operator << (const char *msg)
  {
      if (INVALID_SOCKET == m_Sock)
      {
  	
  	/*Writing cannot be done without having a open socket to remote end*/
  	throw AxisTransportException(SERVER_TRANSPORT_INVALID_SOCKET);
      }
  
      int size = strlen (msg), nByteSent;
  
      if ((nByteSent = send (m_Sock, msg, size, MSG_DONTROUTE)) == SOCKET_ERROR)
      {
  	/*Output streaming error while writing data*/
  	closeChannel ();
  	throw AxisTransportException(SERVER_TRANSPORT_OUTPUT_STREAMING_ERROR);
      }
  
      return *this;
  }
  
  /*
   * Read/receive a message from the remote server; reading may be done in 
   * chunks.
   * @param    string to hold the read Message 
   */
  
  const Channel &
  Channel::operator >> (std::string & msg)
  {
      msg = "";
      if (INVALID_SOCKET == m_Sock)
      {
  	/* Reading cannot be done without having a open socket
             Input streaming error on undefined channel; please open the channel first
           */
  	throw AxisTransportException (SERVER_TRANSPORT_INVALID_SOCKET);
      }
  
      int nByteRecv = 0;
      const int BUF_SIZE = 1024;
      char buf[BUF_SIZE];
  
      //assume timeout not set; set default tatus to OK
      int iTimeoutStatus = 1;
  
      //check if timeout set
      if(m_lTimeoutSeconds)
          iTimeoutStatus = applyTimeout();
  
      //handle timeout outcome
      if(iTimeoutStatus < 0)//error
      {
          //select SOCKET_ERROR. Channel error while waiting for timeout
          throw AxisTransportException(SERVER_TRANSPORT_TIMEOUT_EXCEPTION, 
                                       "Channel error while waiting for timeout");        
          
      }
  
      if(iTimeoutStatus == 0)//timeout expired
      {
          /*"select timeout expired.
           *Channel error connection timeout before receving
          */
          throw AxisTransportException(SERVER_TRANSPORT_TIMEOUT_EXPIRED, 
                                       "Channel error: connection timed out before receving");
      }
  
      //either timeout was not set or data available before timeout; so read
  
      if ((nByteRecv = recv (m_Sock, (char *) &buf, BUF_SIZE - 1, 0))
  	== SOCKET_ERROR)
      {
  	/*recv SOCKET_ERROR, Channel error while getting data*/
  	/* closeChannel(); */
  	throw AxisTransportException(SERVER_TRANSPORT_INPUT_STREAMING_ERROR, 
                                       "Channel error while getting data");
  	/* throw AxisTransportException(SERVER_TRANSPORT_INPUT_STREAMING_ERROR); 
  	 */
      }
      if (nByteRecv)
      {
  	/* printf("nByteRecv:%d\n", nByteRecv); */
  	buf[nByteRecv] = '\0';
  	/* got a part of the message, so add " \        "to form */
  	msg = buf;
  	/* printf("buf:%s\n", buf); */
      }
      else
  	;//printf ("execution break\n");
      
      return *this;
  }
  
  const Channel &
  Channel::readNonBlocking( std::string & msg, bool bBlockingRequired)
  {
      msg = "";
      if (INVALID_SOCKET == m_Sock)
      {
  	/*Reading cannot be done without having a open socket*/
  	throw AxisTransportException(SERVER_TRANSPORT_INVALID_SOCKET);
      }
  
      int nByteRecv = 0;
      const int BUF_SIZE = 1024;
      char buf[BUF_SIZE];
  
      //Samisa: I want to set the socket to non blocking mode here
      //for Winsock there is no simple way to do this but for Linux I used MSG_DONTWAIT
      //there is no MSG_DONTWAIT defined in Winsock
      int flags = 0;
  
  #if defined WIN32
        // Set the socket I/O mode; iMode = 0 for blocking; iMode != 0 for non-blocking
        int iMode = 1;
   
   	if( bBlockingRequired)
   	{
   		iMode = 0;
   	}
   
       ioctlsocket( m_Sock, FIONBIO, (u_long FAR*) &iMode);
   
        flags = 0;
  #elif defined AIX
  	flags=MSG_WAITALL;
  	if (!bBlockingRequired)
  	{
          flags=MSG_NONBLOCK;
  	}
  #elif defined( __OS400__ )
     fcntl(m_Sock, F_SETFL, (int)O_NONBLOCK);
     flags = 0;
  #else
      //for linux
   	if( !bBlockingRequired)
   	{
   	    flags = MSG_DONTWAIT;
   	}
   
      //TODO: define flags (or other means) to enable non blocking for other operating systems
  #endif
  
      if ((nByteRecv = recv (m_Sock, (char *) &buf, BUF_SIZE - 1, flags))
  	== SOCKET_ERROR)
      {
  	/*Channel error while getting data*/
  	return *this;
      }
      if (nByteRecv)
      {
  	buf[nByteRecv] = '\0';
  	msg = buf;
      }
      else
  	Error( "Channel::readNonBlocking: execution break");
  
      return *this;
  }
  
  //samisa
  
  /*
   *    Close, and clean-up any OS specific stuff
   *
   */
  
  void
  Channel::closeChannel ()
  {
  #ifdef WIN32
      if (INVALID_SOCKET != m_Sock)
  	closesocket (m_Sock);
  
      /* Check for any possible error conditions from WSACleanup() and report
       * them before exiting, as this information might indicate a network
       * layer problem in the system.
       */
  
      WSACleanup ();
  #else
      if (INVALID_SOCKET != m_Sock)
  	::close (m_Sock);
  
  #endif
  }
  
  /*
   * Log any errors that cause on channel usage/initilaization
   *
   */
  
  void
  Channel::Error (const char *err)
  {
  #ifdef _DEBUG
      std::cerr << err << std::endl;
  #endif
  }
  
  void Channel::setTimeout(const long lSeconds)
  {
      m_lTimeoutSeconds = lSeconds;
  }
  
  int Channel::applyTimeout()
  {
      fd_set set;
      struct timeval timeout;
  
      /* Initialize the file descriptor set. */
      FD_ZERO(&set);
      FD_SET(m_Sock, &set);
  
      /* Initialize the timeout data structure. */
      timeout.tv_sec = m_lTimeoutSeconds;
      timeout.tv_usec = 0;
  
      /* select returns 0 if timeout, 1 if input available, -1 if error. */
      return select(FD_SETSIZE, &set, NULL, NULL, &timeout);
  }
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/Channel.h
  
  Index: Channel.h
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   * @author Lilantha Darshana (lilantha@virtusa.com)
   * @author Damitha Kumarage (damitha@jkcsworld.com, damitha@opensource.lk)
   * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
   */
  
  #if !defined(_AXIS_CHANNEL_HPP)
  #define _AXIS_CHANNEL_HPP
  
  #include <string>
  
  #include "AxisTransportException.h"
  #include "URL.h"
  
  /* platform specific stuff */
  
  #ifdef WIN32
  
  #include <winsock2.h>
  
  /* what version of WinSock is required */
  const int    WS_VERSION_REQD    = 0x0101;
  
  /* macros to get version major & minor */
  inline WS_VERSION_MAJOR() {return HIBYTE(WS_VERSION_REQD);}
  inline WS_VERSION_MINOR() {return LOBYTE(WS_VERSION_REQD);}
  
  
  #else
  
  #include    <unistd.h>
  #include    <sys/types.h>    /* basic system data types  */
  #include    <sys/socket.h>    /* basic socket definitions */
  #include    <fcntl.h>        /* for nonblocking if need  */
  #include  <sys/time.h>
  #include    <netdb.h>
  #include     <netinet/in.h>
  #include    <arpa/inet.h>    /* inet(3) functions */
  
  const unsigned int INVALID_SOCKET =  0;
  const int           SOCKET_ERROR   = -1;
  
  /* ther OS specific stuff goes here */
  
  
  
  #endif
  
  /*
   * 
   * Implements primitive socket connection for all platforms, for 
   * sending/receiving SOAP Envelops with given transport; This implementation
   * abstract the low-level communications.
   *    
   * @brief     The primitive socket implementation for SOAP Envelops passing.
   *
   */
  
  class Channel  
  {
  public:
      Channel();
      virtual ~Channel();
      
      void setURL(const char* cpURL);
      
      const char* getURL(); 
      
      URL& getURLObject() { return m_URL; };
  
      /* Open a socket to a given remote node/server address with remote port */
      virtual bool  open() throw (AxisTransportException);
  
      /* Close all open sockets and clean up */
      virtual void  close(){closeChannel();}
  
      /* Read from a open socket and store read message in msg */
      virtual const Channel& operator >> (std::string& msg);
      
      /* Read from socket in non bloking more in msg */
      virtual const Channel& readNonBlocking(std::string& msg, bool bBlockingRequired);
  
      /* Write a given message (msg) to the end-point using the open socket */
      virtual const Channel& operator << (const char* msg);
      
      /* Return last error (if any). */
      virtual const std::string& GetLastError(){return m_LastErr;}
  
    /**
      * Set transport timeout.
      *
      * @param lSeconds Timeout in seconds
      */
      void setTimeout(const long lSeconds);
  
  protected:
      /* OS specific initilization */
      virtual bool Init();
  
      /* Report error on read/write */
      virtual void Error(const char * err);
  
      /* Close & clean-up the open socket/system resources */
      virtual void closeChannel();
  
    /**
      * @return 0 if timeout, 1 if input available, -1 if error.
      */
      int applyTimeout();
  
      unsigned int   m_Sock;        /* Socket descriptor */
      URL m_URL;
      std::string    m_LastErr;     /* Last error as a string */
  
    /**
      * Timeout in seconds
      */
      long m_lTimeoutSeconds;
  
  };
  
  #endif
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  lib_LTLIBRARIES = libaxis2_transport.la
  AM_CPPFLAGS = $(CPPFLAGS)
  libaxis2_transport_la_SOURCES = Channel.cpp \
                                 URL.cpp \
                                 Axis2Transport.cpp \
                                 AxisTransportException.cpp
  
  libaxis2_transport_la_LIBADD = -lstdc++
  INCLUDES = -I../../../include
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/Platform.h
  
  Index: Platform.h
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   *
   * @author Lilantha Darshana (lilantha@erunway.com)
   *
   */
  
  
  #if !defined(_AXIS_STDAFX_H)
  #define _AXIS_STDAFX_H
  
  
  #ifdef WIN32
  
  #define WIN32_LEAN_AND_MEAN        
  /* Exclude rarely-used stuff from Windows headers */
  
  #pragma warning ( disable : 4786 )
  
  
  /* #include <afx.h> */
  /* #include <afxwin.h> */
  
  #ifdef AXIS_EXPORTS
  #define AXIS_API __declspec(dllexport)
  #else
  #define AXIS_API __declspec(dllimport)
  #endif
  
  
  #else /* WIN32 */
  
  #define AXIS_API
  #include <unistd.h>
  /* other OS specific stuff goes here */
  
  #endif
  
  #if defined(_DEBUG)
  #    include <iostream>
  #    define DebugMsg(x)    std::cout << x <<std::endl;
  #else
  #    define DebugMsg(x)
  #endif
  
  #endif
  
  
  
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/URL.cpp
  
  Index: URL.cpp
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   *
   *
   * @author Lilantha Darshana (lilantha@virtusa.com)
   *
   */
  
  
  #include "Platform.h"
  #include "URL.h"
  #include <ctype.h>
  #include <iostream>
  using namespace std;
  
  
  URL::URL()
      : m_Protocol(unknown), m_Port(0), m_URL("")
  {
     /* cout << "inside URL constructor" << endl;  */
  }
  
  URL::URL(std::string url)
  {
      m_URL = url;
      if(isascii((int)url.at(0)))
      {
          /* check this a valid URL */
          if((url.at(1) == (int)':') &&
              ((url.at(2) == (int)'/') || (url.at(2) == (int)'\\')))
              return;
          else /* assume valid URL hence, proceed with finding entries */
              ParseURL(url);
      }
  }
  
  URL::~URL()
  {
  
  }
  
  void URL::setProtocol(std::string prot)
  {
      m_Port = 0;
      if(prot == "http")
      {
          m_Protocol = http;
          m_Port = HTTP_PORT;
      }
      else if( prot == "file")
      {
          m_Protocol = file;
      }
      else if( prot == "ftp")
      {
          m_Protocol = ftp;
          m_Port = FTP_PORT;
      }
      else if( prot == "https")
      {
  
          m_Protocol = https;
          m_Port = HTTPS_PORT;
      }
      else
          m_Protocol = unknown;
  
  }
  
  void URL::setURL(const char* cpURL)
  {
      m_URL = std::string(cpURL);
      if(isascii((int)m_URL.at(0)))
      {
          /* check this a valid URL */
          if((m_URL.at(1) == (int)':') &&
              ((m_URL.at(2) == (int)'/') || (m_URL.at(2) == (int)'\\')))
              return;
          else /* assume valid URL hence, proceed with finding entries */
              ParseURL(m_URL);
      }
  }
  
  const char* URL::getURL()
  { 
      if (m_URL.length() > 0 )
          return m_URL.c_str();
      else
          return NULL;
  }
  
  void URL::ParseURL(std::string url)
  {
      std::string::size_type begpos, pos;
  
      /* try to find out the protocol */
      if((pos = url.find("://")) != std::string::npos)
      {
          setProtocol(url.substr(0, pos));
          /* find m_Host name */
          if(m_Protocol != unknown)
          {
              url = url.substr(pos + 3); /* rest of the URL string */
              begpos = pos = 0;
              std::string key(":/?");
              
              while((pos = url.find_first_of(key, begpos)))
              {
                  if(pos == std::string::npos) /* only host name found */
                  {
                      if(m_Host.empty())
                          m_Host = url;
                      if (key == "?") /* found path */
                          m_Path = url.substr(begpos - 1);
                      break;
                  }
                  else
                      if(pos == 0) break;
  
                  switch(url.at(pos))
                  {
                      case ':': 
                          if(m_Host.empty())
                              m_Host = url.substr(begpos, pos - begpos);
                          pos++;
                          begpos = pos;
                          key = "/?"; 
                          /* scan for the rest to get the path & query */
                          continue;
  
                      case '/':
                          if (key == "/?") /* found port number */
                          {
                              m_Port = atoi(url.substr(begpos, 
                                  pos - begpos + 1).c_str());
                              if(m_Host.empty())
                                  m_Host = url.substr(0, begpos - 1);
                          }
                          else
                              m_Host = url.substr(0, pos);
                          pos++;
                          begpos = pos;
                          /*
                          key = "?";
                          continue;
  
                        case '?':
                          //not correctly supported
                          m_Query = url.substr(pos);                        
                          */
                          /* no need to find other ? */
                          m_Path = url.substr(begpos - 1);
                          break;
                  }    
                  break;
              }                            
          }
      }
  }
  
  
  
   
                      
  
                      
  
  
  
  
  
  1.1                  ws-axis/c/src/transport/axis2/URL.h
  
  Index: URL.h
  ===================================================================
  /*
   *   Copyright 2003-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
   *   limitations under the License.
   */
  
  /*
   *
   *
   * @author Lilantha Darshana (lilantha@virtusa.com)
   *
   */
  
  
  #if !defined(_AXIS_URL_HPP)
  #define _AXIS_URL_HPP
  
  #include <string>
  
  /* Welknown ports */
  const unsigned short HTTP_PORT  = 80;
  const unsigned short HTTPS_PORT = 443;
  const unsigned short FTP_PORT   = 21;
  
  
  /*
   *    Implementation of URL to manupulate URLs.  
   *
   *    This implementation only supports subset of a URL
   *    note that # references, userinfo query string 
   *    processing are not supported for this version.
   *
   *    URLs are of the form:
   * 
   *    URL              = protocol "://" server "/" [path]["?" query]
   *    server        = [userinfo "@"] hostname-port
   *    hostname-port = hostname [ ":" port ]
   *    userinfo      = user[:password]
   *
   *
   *    @brief    Manupulate URLs
   */
  
  
  class URL  
  {
  public:
  
      enum Protocol { http, https, ftp, file, unknown}; 
      /* for our purpose currently we need http, https only. This is provided
       * To make extensible to support other transports for RPC but file????, 
       * yes we may require pipes; with web-service????
       */
  
  public:
      URL();
      URL(std::string url);
      ~URL();
  
      void setProtocol(std::string prot);
      void setProtocol(Protocol prot){m_Protocol = prot;}
      void setHostName(std::string host){m_Host= host;}
      void setResource(std::string path){m_Path = path;}
      void setPort(unsigned short port){m_Port = port;}
  
      Protocol    getProtocol(){return m_Protocol;}
      const char* getHostName(){return m_Host.c_str();}
      std::string getResource(){return m_Path;}
      void setURL(const char* cpURL);
      const char* getURL(); 
  
      unsigned short getPort(){return m_Port;}
  
      // other functions are not supported yet
  
  private:
  
      void ParseURL(std::string url);
      
      Protocol        m_Protocol;
      std::string     m_Host;
      unsigned short  m_Port;
      std::string     m_Path;
      std::string     m_Query;
  
      std::string m_Password;
      std::string m_User;
      std::string m_URL;
  };
  
  #endif