Programmer's Heaven - For C C++ Pascal Delphi Visual Basic Assembler C# .Net java JSP ASP ASP.NET Javascript developers!

Members
Username:

Password:

Auto-login

Register
Why register?
Forgot Password?
Blogs new Blog section
Jobs
Webtools
Message Boards
FAQ
CodePedia
Free Magazines
User search
What's New
Top lists
RSS Feeds RSS Feed

Submit content
Contact Us
Link To Us
Help



Advanced Search
Newsletter
E-mail:


More information
Current area: HOME -> Discover ISAPI. Working with GET-POST data

Sample Image

Introduction

This article presents a way to retrieve the GET-POST data from a form in an ISAPI extension. Two helpful collections class of parameters are also provided. Because a non MFC ISAPI extension is more reliable regarding the speed and the simultaneous number of connections, a non MFC version is included.

Functionality

Both MFC and Non MFC versions use Vector, Map and String STL based classes, with non MFC code inside. In the MFC version the string collection are based on _bstr_t type. In Non MFC version the string collection are based on STL String type. So, the MFC version is using the ISAPI MFC based macros to retrieve the server variables and parameters data while the non MFC version uses the WriteClient and ServerSupportFunction HTTP functions.

The default method writes to the browser  a complex form with check boxes, edit boxes, radio buttons, text area - even a file type edit box. The idea is to receive all the POST parameters into the same DLL extension. The form is loaded from a HTML string resource using the LoadLongResource helper function. This reduces the time needed to build the page because the string is loaded into memory on the first call of the extension. How to use the HTML string resources in your Visual Studio project it is show in my ADO Data access from ISAPI article.

The GET data is received very easy since that type of data is sent from the browser to the server using the URL. The POST data variables are transparent to the user and it is possible to transfer large amount of data. For more information about GET/POST data see my HTTP GET-POST utility article.

MFC version

The C++ classes used to store parameters from the data collection are Twin and TwinVector. The Default method of the ISAPI MFC version writes to the client browser the IDR_HTML_FORM resource. FormRequest is the method that receives the control after you click on the "Submit Query" button.
void CPostDataExtension::FormRequest(CHttpServerContext* pCtxt, 
                                     void* pVoid, DWORD dwBytes)
{                                
    //build the STL collection from server variables and POST data 
    TwinVector    vecServerCtx(pCtxt, (LPTSTR)pVoid);    

    //write on browser stream the server context variables
    WriteServerData(pCtxt);            

    //write on browser stream the STL collection of 
    //server context variables and POST data
    WriteServerVar(pCtxt, vecServerCtx);    
}                       

A little problem is to get the control from the DLL entry point to FormRequest method. Under the MFC, that is done very easy, using the macros:

DEFAULT_PARSE_COMMAND(FormRequest,    CPostDataExtension)
ON_PARSE_COMMAND(FormRequest,        CPostDataExtension, ITS_RAW)
To correctly know what method will receive the POST data, the MFC wrapper must receive from the HTML form one hidden parameter, which must be in the first place after the FORM HTML tag:
<form action="PostData.dll?" method=post>
<input TYPE=hidden NAME="MfcISAPICommand" VALUE="FormRequest">
In the WriteServerVar helper function, the server context variables collection is written on the HTTP stream. It's possible to directly obtain the value of a needed parameter: 
bstrValue = vecServerCtx.Find(L"Filename").
for (itVec = vecServerCtx.begin(); itVec != vecServerCtx.end(); itVec++)
    *pCtxt    <<    GetName()    << " = " <<    GetValue()    << "br";
Sample Image

   
In the same WriteServerVar helper function, the POST data collection is written to the HTTP stream in this way.

bstrToken    = L"DATA";
index        = vecServerCtx.Find(bstrToken);
if (index > -1)
{    
    map = vecServerCtx[index].GetValueAsMap();
    if (!map.empty())  //we have values
    for (itMap = map.begin(); itMap != map.end(); itMap++) 
        *pCtxt    <<    (*itMap).first    << " = " 
                  <<    (*itMap).second    << "br";
}
Sample Image     

It's possible to directly obtain the value of a needed parameter: 

*pCtxt << "Filename = " << map[L"Filename"] << "br".

The TwinVector class offer the VARIANT GetVariant() method and TwinVector(VARIANT varSafe) constructor, to easy transport the collection over network between COM+ components.

Non MFC version

The non MFC version is based on the MSDN article regarding at GET-POST data in ISAPI extensions.

The C++ extension receive the entry point in the DWORD WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK pECB ) method.

Here it launches the Run method of the CWriteFormExtension class - there isonly one running object in our ISAPI extension.

The C++ classes used to keep the parameters in the data collection are MultipartParser and MultipartEntry. The cParser variable of inherited Map STL type receive the entire collection of POST data. That is done in Initialize method. The GetParam is a helper method who return the value of a needed parameter.

String CWriteFormExtension::GetParam(MultipartParser& cParser, String sName)
{
    String           sValue; //the output string
    MultipartEntry*  pEntry  = cParser[sName.c_str()];

    if(pEntry != NULL)     //we have data
    {
        sValue = (LPCTSTR) pEntry->Data();    //get value from collection        
        int nLen = sValue.size();
        
        if(sValue[nLen - 1] == '\n' && sValue[nLen - 2] == '\r')
        sValue = sValue.substr(0, nLen - 2);
    }
    return sValue;
}

This is the result of the Run method:

Sample Image

The LoadLongResource private function is a little modified compared with the MFC version. The input/output str string parameter is of STL string type. In the szPath char variable we must put the name of the DLL file in order to load the correct resource library.
BOOL CWriteLayoutExtension::LoadLongResource(String &str, UINT nID)
{
    HRSRC               hRes;
    BOOL                bResult            = FALSE;
    CHAR                szPath[MAX_PATH];
    
    strcpy(szPath, "WriteForm.dll");
    HINSTANCE hInst = LoadLibrary(szPath);

    //if you want standard html type
    hRes = FindResource(hInst, MAKEINTRESOURCE(nID), RT_HTML);    
    if (hRes == NULL)
    {    
         //trace error
        str = "Error: Resource could not be found\r\n";
    }
    else
    {    
        DWORD dwSize = SizeofResource(hInst, hRes);
        if (dwSize == 0)
        {    
            str.empty();
            bResult = TRUE;
        }
        else
        {    
            HGLOBAL hGlob = LoadResource(hInst, hRes);
            if (hGlob != NULL)
            {    
                LPVOID lpData = LockResource(hGlob);
                if (lpData != NULL)
                {    
                    str            = (LPCTSTR)lpData;    
                    bResult        = TRUE;
                }
                FreeResource(hGlob);
            }    
        }
        if (!bResult)
        str = "Error: Resource could not be load\r\n";
    }
    return bResult;
}

About Adrian Bacaianu

I make programming for over 4 years and extensive experience in C++, ASP, Pascal, MFC, COM+, ATL, TCP/IP, HTTP protocols, XML, XSL, SOAP and SQL. For the last 2 years i working extensively at the background of financial sites (databases, n tier architecture).

I’m available for contracts and/or outsourcing. Contact adrian_bacaianu@yahoo.com.


  User Comments

This article has not been rated or commented on yet. Why not take a moment to
post your comments and rate this article?

      Rate and comment this article


Think you've can write or have written a good article? Want to get it hosted for free on a highly respected programming site? Get the attention you deserve! Click here to find our more

 

Sponsored Links 
Build IT Knowledge with Current & Trusted Content
Helps Employees Develop & Hone New Technical Programming Skills. Sign Up & Get Full Access.
Check Out IT Certification Preparation Materials
Sign Up With SkillSoft & Get Access to Training Materials for Over 50 Professional Certifications.
Localize software in three simple steps
Localize .Net, C/C++ & Delphi apps visually. HTML, HTML Help, XML & databases. Try Sisulizer now!
Delphi Localization Tool Sisulizer (WYSIWYG)
Create multilingual Delphi apps in three simple steps. Localize XML, HTML Help ... Try Sisulizer now
Web based bug tracking - AdminiTrack.com
AdminiTrack offers an effective web-based bug tracking system designed for professional software development teams.
Buy a link now

Newsletter Submit Content About Advertising Awards Contact Us Link to us    
© 1996-2008 Community Networks Ltd All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by .NET konsult - Synchron Data.