1.2 Handling Requests

When you registered your service method in the previous section (Section 1.1, Registering Your Service), you specified demoMethod as your connection request method. This is the method that is called when a request comes in for your service.

In order to handle these requests, demoMethod needs to do more than just return a response; demoMethod needs to perform the following:

  1. Check initialization and deinitialization.

  2. Get the request (and ensure that it is valid).

  3. Check the type of the request (and ensure that the request type is one handled by our service).

  4. Get the path (and ensure that it is valid).

  5. Process the path and return a response.

The following demoMethod is modeled after the pServiceMethod callback defined with RegisterServiceMethodEx. For the complete sample code, see Section 1.2.1, Demo Method. Parameter descriptions are included with RegisterServiceMethodEx:

    UINT32 demoMethod(HINTERNET hndl, void *info, UINT32 infoLen, UNIT32 InfoBits)
    

The following code illustrates how to perform each of the tasks outlined above. You can then combine these snippets together and use it as a model for your own connection request method.

Variables

    int err = 0;  //stores returned error value
    int len = 0;  //determine if request is valid length
    char *bp;     //stores path portion of URL
    char* cnv;    //un-escaped path buffer
    UINT32 urlcount = 0;    //
    UINT32 methodType = 0;   //stores request type
    

Initialization

    //check to see if the process needs to be initialized
    //or deinitialized
    
    if (InfoBits & CONTROL_INITIALIZATION_BIT) return(0);  
    	if	(InfoBits & CONTROL_DEINITIALIZATION_BIT) return(0);
    
    

Get the Request

    //get the numerical value of the request method
    
    if (HttpReturnRequestMethod(hndl, &methodType) != TRUE)	
    {
    //hndl is invalid, return error
    		HttpSendErrorResponse(hndl, HTTP_INTERNAL_SERVER_ERROR);
    		return(HTTP_INTERNAL_SERVER_ERROR);	
    }
    

Check the Request Type

    //determine if the request is a get
    //we will only handle get requests
    
    if (methodType != HTTP_REQUEST_METHOD_GET)
    	{
    //request is not a get, return error
    		HttpSendErrorResponse(hndl, HTTP_STATUS_NOT_SUPPORTED);		return(HTTP_STATUS_NOT_SUPPORTED);	
    }
    

Get the Requested Path

    //get the requested path, remove our service name
    //and make sure that the request is valid
    
    err = HttpReturnPathBuffers(hndl, NULL, &bp, &cnv);
    	if (err)	
    {
    //hndl is invalid, return error
    		HttpSendErrorResponse(hndl, HTTP_INTERNAL_SERVER_ERROR);		return(HTTP_INTERNAL_SERVER_ERROR);
    	}
    

Process the Request and Return a Response

    //convert the component path to a usable form
     
    if (*bp != 0)
    {
       //bp++;
       urlCount = ConvertToComponentPath(bp);
    }
     
    //switch statement to determine the response
    //will display demo pages 2, 3, 4 or entry
     
    err = 0;
    switch (urlCount)
    {
    case 1:	// Display demo pages 2, 3, or 4
    if(ICmpB(bp, pzDemoPage2, (*bp) + 1) == -1)
    {
    HttpSendSuccessfulResponse(hndl, HttpReturnString(HTTP_CONTENT_TYPE_HTML));
    
       HttpSendDataSprintf(hndl,"<HTML><HEAD><TITLE>DEMO Page 2</TITLE>
       %s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 2.</BODY>",
       PORTAL_STYLE_SHEET);
       break;
    }
    if(ICmpB(bp, pzDemoPage3, (*bp) + 1) == -1)
    {
       HttpSendSuccessfulResponse(hndl,
       HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 3
       <TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 3.</BODY>",
       PORTAL_STYLE_SHEET);
       break;
    }
    if(ICmpB(bp, pzDemoPage4, (*bp) + 1) == -1)
    {
       HttpSendSuccessfulResponse(hndl, HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 4
       <TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 4.
       </BODY>", PORTAL_STYLE_SHEET);
       break;
    }
     
    err = HTTP_STATUS_BAD_REQUEST;
    break;
     
       case 0:	// display server page
       HttpSendSuccessfulResponse(hndl,
       HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 1
       </TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H1>This is demo page 1.</H1>",
       PORTAL_STYLE_SHEET);
     
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 2
       </A>\n", pzDemoService, pzDemoPage2+1);
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 
       </A>\n", pzDemoService, pzDemoPage3+1);
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 4
       </A>\n", pzDemoService, pzDemoPage4+1);
       HttpSendDataSprintf(hndl, "</BODY>");
       break;
    
       default:	// URL passed was bad - bail out
       err = HTTP_STATUS_BAD_REQUEST;
       break;
    }
    if(err)
       HttpSendErrorResponse(hndl, err);
    else
       HttpEndDataResponse(hndl); 
     
    return(err);
    }	
    

demoMethod will now return simple HTML reply to requests to our service.

1.2.1 Demo Method

The following is a complete version of the demoMethod sample, including methods to convert the URL path.

    //include statements
     
    #include "httpexp.h"
     
    char *pzDemoService = "DEMO";  //the registered service name
    char *pzDemoPage2 = "\x3pg2";
    char *pzDemoPage3 = "\x3pg3";
    char *pzDemoPage4 = "\x3pg4";
     
    //utility functions to parse the URL 
     
    #define ConvertSlashToNull(bp, cnt) {cnt = 0; while (bp[cnt])
    {if (bp[cnt] == ’/’) {bp[cnt] = 0;}cnt++;}}
    #define	CountToSlash(bp, cnt) {cnt = 0; while (*bp && (*bp == ’/’)){cnt++;}}
     
    //HTML tag to use Portal style sheets
     
    char * PORTAL_STYLE_SHEET = "<LINK REL=stylesheet TYPE=""text/css"" HREF=/SYS/LOGIN/portal.css>";
     
    //method to process the requested path
     
    int ConvertToComponentPath(char *dst)
    {
     int cnt;
     char *pcnt;
     char c;
    
    	 for (cnt=0, c=*dst; ((c != 0) && (c != ’?’) && (c !=’=’) && (c !=’#’));)
    	  {
    		    pcnt = dst++;
    		    *pcnt = 0;
    		    c=*dst;
    		    if (c)
    		  			   {
    			       for (; ((c != 0) && (c != ’/’) && (c != ’?’) && (c !=’=’) && (c !=’#’));)
    			        {
    				          dst++;
    				          c = *dst;
    				          (*pcnt)++;
    			         }
    			cnt++;
    		     }
    	  }	
    	return(cnt);
    }
    
    
    
    //process the get request using our connection request method, demo method.
     
    int err = 0;  //stores returned error value
    int len = 0;  //determine if request is valid length
    char *bp;     //stores path portion of URL
    char* cnv;    //un-escaped path buffer
     
    UINT32 urlcount = 0;     //
    UINT32 methodType = 0;   //stores request type
     
    //check to see if the process needs to be initialized
    //or deinitialized
     
    if (InfoBits & CONTROL_INITIALIZATION_BIT) return(0);  
    if (InfoBits & CONTROL_DEINITIALIZATION_BIT) return(0);
     
    //get the numerical value of the request method
     
    if (HttpReturnRequestMethod(hndl, &methodType) != TRUE)
    {
       //hndl is invalid, return error
       HttpSendErrorResponse(hndl, HTTP_INTERNAL_SERVER_ERROR);
       return(HTTP_INTERNAL_SERVER_ERROR);
    }
    //determine if the request is a get
    //we will only handle get requests
     
    if (methodType != HTTP_REQUEST_METHOD_GET)
    {
       //request is not a get, return error
       HttpSendErrorResponse(hndl, HTTP_STATUS_NOT_SUPPORTED);
       return(HTTP_STATUS_NOT_SUPPORTED);
    }
     
    //get the requested path, remove our service name
    //and make sure that the request is valid
     
    err = HttpReturnPathBuffers(hndl, NULL, &bp, &cnv);
    if (err)
    {
    //hndl is invalid, return error
     
       HttpSendErrorResponse(hndl, HTTP_INTERNAL_SERVER_ERROR);
       Return(HTTP_INTERNAL_SERVER_ERROR);
    }
     
    //convert the component path to a usable form
     
    if (*bp != 0)
    {
       //bp++;
       urlCount = ConvertToComponentPath(bp);
    }
     
    //switch statement to determine the response
    //will display demo pages 2, 3, 4 or entry
     
    err = 0;
    switch (urlCount)
    {
    case 1:	// Display demo pages 2, 3, or 4
    if(ICmpB(bp, pzDemoPage2, (*bp) + 1) == -1)
    {
    HttpSendSuccessfulResponse(hndl, HttpReturnString(HTTP_CONTENT_TYPE_HTML));
    
       HttpSendDataSprintf(hndl,"<HTML><HEAD><TITLE>DEMO Page 2</TITLE>
       %s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 2.</BODY>",
       PORTAL_STYLE_SHEET);
       break;
    }
    if(ICmpB(bp, pzDemoPage3, (*bp) + 1) == -1)
    {
       HttpSendSuccessfulResponse(hndl,
       HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 3
       <TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 3.</BODY>",
       PORTAL_STYLE_SHEET);
       break;
    }
    if(ICmpB(bp, pzDemoPage4, (*bp) + 1) == -1)
    {
       HttpSendSuccessfulResponse(hndl, HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 4
       <TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H2>This is demo page 4.
       </BODY>", PORTAL_STYLE_SHEET);
       break;
    }
     
    err = HTTP_STATUS_BAD_REQUEST;
    break;
     
       case 0:	// display server page
       HttpSendSuccessfulResponse(hndl,
       HttpReturnString(HTTP_CONTENT_TYPE_HTML));
       HttpSendDataSprintf(hndl, "<HTML><HEAD><TITLE>DEMO Page 1
       </TITLE>%s</HEAD><BODY>", PORTAL_STYLE_SHEET);
       HttpSendDataSprintf(hndl, "<H1>This is demo page 1.</H1>",
       PORTAL_STYLE_SHEET);
     
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 2
       </A>\n", pzDemoService, pzDemoPage2+1);
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 
       </A>\n", pzDemoService, pzDemoPage3+1);
       HttpSendDataSprintf(hndl, "<B><A HREF=/%s/%s>Demo Page 4
       </A>\n", pzDemoService, pzDemoPage4+1);
       HttpSendDataSprintf(hndl, "</BODY>");
       break;
    
       default:	// URL passed was bad - bail out
       err = HTTP_STATUS_BAD_REQUEST;
       break;
    }
    if(err)
       HttpSendErrorResponse(hndl, err);
    else
       HttpEndDataResponse(hndl); 
     
    return(err);
    }