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:
Check initialization and deinitialization.
Get the request (and ensure that it is valid).
Check the type of the request (and ensure that the request type is one handled by our service).
Get the path (and ensure that it is valid).
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.
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);
}
demoMethod will now return simple HTML reply to requests to our service.
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);
}