IXMLHTTPRequest problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AlirezaShokoienia
    New Member
    • Sep 2008
    • 8

    IXMLHTTPRequest problem

    Hi all,

    I have developed an application and in them i want save some files in a remote
    server. usually before save the file, i read the directory tree in remote server and user can select the right destination directory and often everything is OK and the application works fine.Except unfortunately when the destination directory(or actually the full path) is too long, the "send" method does not return and readyState remain 2, but on other hand file is correctly saved in remote server.
    In this way i have tried to use a network monitoring application(Eth ereal) und i observed that a "PUT" request is sent to remote server and then "200" response
    is received form the server and according to this observation the file was saved correctly. I think that i have problem with my client (MSXML4.DLL) or any internet setting.

    Everybody can give me any recommendations .
    Thanks in advance

    Alireza
  • acoder
    Recognized Expert MVP
    • Nov 2006
    • 16032

    #2
    Can you post the code you're using. It may help debug the problem.

    Comment

    • AlirezaShokoienia
      New Member
      • Sep 2008
      • 8

      #3
      Originally posted by acoder
      Can you post the code you're using. It may help debug the problem.
      Hi acoder, and thank you for your reply.

      Here is the code of two functions that I'm using. I've omitted some codes those are not important such as reporting errors to make shorter message :


      Code:
      void CWebDAVOperation::GetWebDAVDirTree()
      {
      	// Variables.
          HRESULT hr; 
      	IXMLHTTPRequestPtr pRequest = NULL;
      
      	long lStatus = 0;
      	BSTR bstrResp;
      	BSTR bstrResponseText;
      	CString strQuery;
      	CString strDir = skillInfo.m_strAgentDirURI + _T("/") + m_strCallLogDir;
      
      	// Create an instance of the request object.
      	hr=pRequest.CreateInstance("Msxml2.XMLHTTP.6.0");
      	SUCCEEDED(hr) ? 0 : throw hr;
      
      	try
      	{
      		// Open the XMLHTTPRequest object with the SEARCH method and
      		// specify that it will be sent asynchronously.
      		hr=pRequest->open("SEARCH", _bstr_t(strDir), false, _bstr_t(skillInfo.m_strAgentUserName) , _bstr_t(skillInfo.m_strAgentPassword));
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		// Set the Content-Type header.
      		hr=pRequest->setRequestHeader((bstr_t)"Content-Type", (bstr_t)"text/xml");
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		// Build the query for a hierarchical search.
      		strQuery = _T("<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >");
      		strQuery += _T("<D:sql>SELECT \"DAV:href\" FROM scope('deep traversal of \"");
      		strQuery += strDir;
      		strQuery += _T("\"')");
      		strQuery += _T("WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\" = True");
      		strQuery += _T("</D:sql></D:searchrequest>");
      
      		// Send the SEARCH method request.
      		hr=pRequest->send(_bstr_t(strQuery));
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		// Get the response status.
      		pRequest->get_status(&lStatus);
      
      		// An error occurred on the server.
      		if(lStatus >= 500)
      		{
      			// report the error...
      		}
      
      		// The method request was successful.
      		else if (lStatus == 207)
      		{
      			// Variables.
      			MSXML2::IXMLDOMDocumentPtr pDOMDoc = NULL;
      			MSXML2::IXMLDOMNodeListPtr pDOMNodeList = NULL;
      			MSXML2::IXMLDOMNodePtr pDOMNode = NULL;
      			BSTR bstrRespText;
      
      			// Create an instance of the DOM Document.
      			HRESULT hr = pDOMDoc.CreateInstance(__uuidof(MSXML2::DOMDocument));
      
      			// Check the status of pointer creation.
      			if(FAILED(hr))
      			{
      				// report the error...
      			}
      
      			// Get the method response XML text.
      			pRequest->get_responseText(&bstrRespText);
      
      			// Load the XML document with the response text.
      			pDOMDoc->loadXML(bstrRespText);
      
      			// Build a list of the DAV:href XML nodes, corresponding to the folders
      			// returned in the search request. The DAV: namespace is typically
      			// assigned the a: prefix in the XML response body.
      			pDOMNodeList = pDOMDoc->getElementsByTagName((bstr_t)"a:prop");
      			//pDOMNodeList = pDOMDoc->getElementsByTagName((bstr_t)"a:href");
      
      			// Display the number of folders found.
      			long lLen, lShowLen;
      			pDOMNodeList->get_length(&lLen);
      
      			::SysFreeString(bstrRespText);
      
      			lShowLen = lLen;
      			// List the folders found.
      			for(int i=0; i<lLen;i++)
      			{
      				pDOMNode = pDOMNodeList->nextNode();
      				if(pDOMNode != NULL)
      				{
      					BSTR bstrText;
      					pDOMNode->get_text(&bstrText);
      					CString strText(bstrText);
      
      					// i save the folder name
      					// ...
      
      					::SysFreeString(bstrText);
      				}
      			}
      		}
      		else
      		{
      			// report the lStatus
      		}
      
      		pRequest = NULL;
      	}
      	catch(_com_error& e)
      	{
      
      		// report the error message
      		
      		pRequest = NULL;
      
      	}
      }
      
      bool CWebDAVOperation::SaveStream(IStream* pIStream, CString strPath, CString strUserName, CString strPassword)
      {
      	HRESULT hr;
      	int WebDavStep = 0;
      	BSTR bstrString = NULL;
      	IXMLHTTPRequestPtr pIXMLHTTPRequest = NULL;
      	try
      	{
      		WebDavStep ++;
      		hr=pIXMLHTTPRequest.CreateInstance("Msxml2.XMLHTTP.6.0");
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		bstrString =  _bstr_t(strPath);
      
      		WebDavStep ++;
      		hr=pIXMLHTTPRequest->open("PUT", bstrString, false, _bstr_t(strUserName) , _bstr_t(strPassword));
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		WebDavStep ++;
      		// Set the Content-Type header.
      		hr=pIXMLHTTPRequest ->setRequestHeader((bstr_t)"Content-Type", (bstr_t)"audio/mpeg3");
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		WebDavStep ++;
      		// Set the Translate header to False.
      		hr=pIXMLHTTPRequest ->setRequestHeader((bstr_t)"Translate", (bstr_t)"f");
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		WebDavStep ++;
      		hr=pIXMLHTTPRequest->send(pIStream);
      		SUCCEEDED(hr) ? 0 : throw hr;
      
      		BSTR bstrValue = NULL;
      		WebDavStep ++;
      		hr=pIXMLHTTPRequest->get_responseText(&bstrValue);
      		CString Str1, Str2;
      		CString strResp(bstrValue);
      
      		// report resonseText
      		//...
      
      		::SysFreeString(bstrValue);
      		bstrValue = NULL;
      
      		pIXMLHTTPRequest = NULL;
      
      		if(bstrString)
      		{
      			 ::SysFreeString(bstrString);
      			 bstrString = NULL;
      		}
      
      		return true;
      	}
      	catch(_com_error& e)
      	{
           
      		// report the error message
      		
      		pIXMLHTTPRequest = NULL;
      
      	}
      
      	return false;
      }
      thanks a lot.
      Alireza
      Last edited by gits; Sep 15 '08, 08:36 AM. Reason: added code tags

      Comment

      • AlirezaShokoienia
        New Member
        • Sep 2008
        • 8

        #4
        Hi acoder,

        I must be tell that the previous code was my first try in synchronous form, but I've tried to send the request in asynchronous mode.
        Here is the code:

        Code:
        bool CWebDAVOperation::SaveStream(IStream* pIStream, CString strPath, CString strUserName, CString strPassword)
        {
        
        //...
        		HANDLE completedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        
        		// ...
        
        		WebDavStep ++;
        		hr=pIXMLHTTPRequest->open("PUT", bstrString, true, _bstr_t(strUserName) , _bstr_t(strPassword));
        		SUCCEEDED(hr) ? 0 : throw hr;
        
        		// ...
        
        		// Hook up the onreadystatechange event handler
        		IDispatch *sink = new XMLHttpEventSink(pIXMLHTTPRequest, completedEvent, &m_lstate);
        		hr=pIXMLHTTPRequest->put_onreadystatechange(sink);
        
        		WebDavStep ++;
        		hr=pIXMLHTTPRequest->send(pIStream);
        		SUCCEEDED(hr) ? 0 : throw hr;
        
        		// Since this is a console app the process would end if we just continued from here.
        		// So we wait until the async request is done (in real life, this means we didn't
        		// need an async request in the first place, but this is a sample, not real life).
        
        		do
        		{
        			DWORD dwRetp = WaitForSingleObject(completedEvent, 1000);
        
        			// report the m_lState (readyState)
        
        			if(dwRetp == WAIT_OBJECT_0)
        				break;
        		}while(true);
        
        		sink->Release();
        
        		CloseHandle(completedEvent);
        
        		// ...
        
        }
        
        
        STDMETHODIMP XMLHttpEventSink::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
        {
            // Since this class isn't used for anything else, Invoke will get called only for onreadystatechange, and
            // dispIdMember will always be 0.
        
            long state;
            // Retrieve the state
            _request->get_readyState(&state);
        	*m_plState = state;
            //std::wcout << L"State: " << state << std::endl;
        
            if( state == 4 )
            {
                // The request has completed.
                // Get the request status.
        
                //long status;
                //_request->get_status(&status);
        
               // std::wcout << L"Status: " << status << std::endl;
        
                // Signal the main thread we're done.
                SetEvent(_completedEvent);
            }
            return S_OK;
        }
        thanks again.
        Alireza
        Last edited by gits; Sep 15 '08, 08:37 AM. Reason: added code tags

        Comment

        • acoder
          Recognized Expert MVP
          • Nov 2006
          • 16032

          #5
          OK, this is not JavaScript. It seems like you're using Web DAV. I have no experience of it, so can't be much help, but if you decide to use JavaScript, I can help. Maybe someone else who has used WebDAV will be able to assist you here.

          Comment

          • AlirezaShokoienia
            New Member
            • Sep 2008
            • 8

            #6
            Originally posted by acoder
            OK, this is not JavaScript. It seems like you're using Web DAV. I have no experience of it, so can't be much help, but if you decide to use JavaScript, I can help. Maybe someone else who has used WebDAV will be able to assist you here.
            Thanks for your reply. Really I'm new in "bytes". Can you recommend me, in which
            forum may i become any tips to resolve my problem.

            thank a lot.
            Alireza

            Comment

            • acoder
              Recognized Expert MVP
              • Nov 2006
              • 16032

              #7
              Correct me if I'm wrong, but this seems like C++ code. If so, you can post in the C/C++ forum.

              Comment

              • AlirezaShokoienia
                New Member
                • Sep 2008
                • 8

                #8
                Originally posted by acoder
                Correct me if I'm wrong, but this seems like C++ code. If so, you can post in the C/C++ forum.
                Yes, it is and thanks for your effort. I do so.

                Alieza

                Comment

                • acoder
                  Recognized Expert MVP
                  • Nov 2006
                  • 16032

                  #9
                  OK, good luck in solving your problem.

                  Comment

                  • rnd me
                    Recognized Expert Contributor
                    • Jun 2007
                    • 427

                    #10
                    msxml4 is kinda crappy if i remember correctly.

                    ok, checked and i was right.

                    try using 6 or 3 instead.

                    check out the rundown on this page

                    Comment

                    Working...