Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

Hi..
Anyone can suggest solution to following problem:

Calling IWEB_GetResponse() with some URL and WEBOPT_METHOD as POST results into same page i.e URL specified while function call instead of sending the action or result page

Thanks in advance

regds,
Nilesh

Did you encode the URL? See the documentation for IWEBUTIL_UrlEncode().

Did you encode the URL? See the documentation for IWEBUTIL_UrlEncode().

Hi,
Thanks for the reply.
I have already encoded the parameters using IWEBUTIL interface. I am attachin here code from Webber example(shippled iith BREW SDK 1.1) that i have modified.
Please sugguest if there are any problems with the code
regds,
Nilesh

Hi,
Thanks for the reply.
I have already encoded the parameters using IWEBUTIL interface. I am attachin here code from Webber example(shippled iith BREW SDK 1.1) that i have modified.
Please sugguest if there are any problems with the code
regds,
Nilesh

Posting same issue in multiple forum does not help anyone. Following certain basic netiquettes helps to build healthy environment for discussion.
When you post any data using IWEB follow the following steps:
1. URL encode your data buffer.
2. Create IPEEK/ISOURCE from the URL encoded data.
3. Call IWeb_GetResponse with appropriate WEB_OPT parameter. Make sure you refer SDK doc about WEB_OPT gotchas.
Your code does not seem to do step 2 correctly.
ruben

Posting same issue in multiple forum does not help anyone. Following certain basic netiquettes helps to build healthy environment for discussion.
When you post any data using IWEB follow the following steps:
1. URL encode your data buffer.
2. Create IPEEK/ISOURCE from the URL encoded data.
3. Call IWeb_GetResponse with appropriate WEB_OPT parameter. Make sure you refer SDK doc about WEB_OPT gotchas.
Your code does not seem to do step 2 correctly.
ruben

Thanx Ruben...
I have already followed step 2, here is the code
/* if there's post data, construct a stream for IWeb to consume */
if ((char *)0 != me->pszPostData)
{
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_SOURCEUTIL, (void **)&pisu))
{
ISOURCEUTIL_PeekFromMemory(pisu, me->pszPostData,STRLEN(me->pszPostData), 0, 0,
&me->pipPostData);
ISOURCEUTIL_Release(pisu);
}
}
Can u plz clarify in what format the parameter & value should be sent?
Whether it should be in "Param1: Value1\r\nParam2: Value2\r\n"
OR
"Param1 = Value1\r\nParam2 = Value2\r\n"
OR
any other format?
regds,
Nilesh

Thanx Ruben...
I have already followed step 2, here is the code
/* if there's post data, construct a stream for IWeb to consume */
if ((char *)0 != me->pszPostData)
{
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_SOURCEUTIL, (void **)&pisu))
{
ISOURCEUTIL_PeekFromMemory(pisu, me->pszPostData,STRLEN(me->pszPostData), 0, 0,
&me->pipPostData);
ISOURCEUTIL_Release(pisu);
}
}
Can u plz clarify in what format the parameter & value should be sent?
Whether it should be in "Param1: Value1\r\nParam2: Value2\r\n"
OR
"Param1 = Value1\r\nParam2 = Value2\r\n"
OR
any other format?
regds,
Nilesh

Quote:
Can u plz clarify in what format the parameter & value should be sent?
This issue is nothing specific to BREW, it applies to any http programming. It depends what your server is expecting. For example, you can specify content length in the http header, and post data is name-value pair seperated by space like
"var1=xxx var2=yyy" and it is url encoded. In this case it will be "var1=xxx&var2=yyy". If your server uses content length specifed in the http header then you don't need any termination, other wise based on server requirement it could be \r\n.
ruben

Quote:
Can u plz clarify in what format the parameter & value should be sent?
This issue is nothing specific to BREW, it applies to any http programming. It depends what your server is expecting. For example, you can specify content length in the http header, and post data is name-value pair seperated by space like
"var1=xxx var2=yyy" and it is url encoded. In this case it will be "var1=xxx&var2=yyy". If your server uses content length specifed in the http header then you don't need any termination, other wise based on server requirement it could be \r\n.
ruben

Thanx Ruben,
When I am passing the parameter(in format: var1=val1&var2=val2) alongwith URL for GET method, its returning me correct page, but putting parameters in same format in WEBOPT_BODY option and requesting POST method doesnt returns correct page.
Whether we need to specify Content-length in WEBOPT_HEADER if we are already specifying it in WEBOPT_CONTENTLENGTH.
Also i have tried with sending WEBOPT_HEADER in two following ways
1> "X-Method: POST\r\n"
2> "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-length: 40\r\n"
But still no success!!!Any idea abt why its not working properly?
regds,
Nilesh

Thanx Ruben,
When I am passing the parameter(in format: var1=val1&var2=val2) alongwith URL for GET method, its returning me correct page, but putting parameters in same format in WEBOPT_BODY option and requesting POST method doesnt returns correct page.
Whether we need to specify Content-length in WEBOPT_HEADER if we are already specifying it in WEBOPT_CONTENTLENGTH.
Also i have tried with sending WEBOPT_HEADER in two following ways
1> "X-Method: POST\r\n"
2> "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-length: 40\r\n"
But still no success!!!Any idea abt why its not working properly?
regds,
Nilesh

Use a packet sniffer to see what kind of packet you are sending. Are you receiving correct data on the server side?
Content length should be specified in WEBOPT_CONTENTLENGHT.
Post your code snippet, forum members may be able to give you more feedback.

Use a packet sniffer to see what kind of packet you are sending. Are you receiving correct data on the server side?
Content length should be specified in WEBOPT_CONTENTLENGHT.
Post your code snippet, forum members may be able to give you more feedback.

Here is the function that starts the web transaction
<<<<<<<<<<<<<<<<<<
static void WebAction_Start(WebAction *me, char *pszUrl)
{
ISourceUtil *pisu = NULL;
char* pszData = NULL;
char * pcOut = NULL;
int nInLen = 0;
int nOutLen = 0;
IWebUtil* p_IWebUtil = NULL;
int rv = 0;
/* Encode the parameters that have to be sent to server*/
pszData = (char *) MALLOC(70);
if(NULL == pszData)
return;
STRCPY(pszData ,"firstname=nilesh&lastname=bhanderi\r\n");
//STRCPY(pszData ,"firstname=nilesh\r\nlastname=bhanderi\r\n");
nInLen = 70;
pcOut = (char *) MALLOC(100);
if(NULL == pcOut)
return;
nOutLen = 100;
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_WEBUTIL, (void **)&p_IWebUtil ))
{
me->pszPostData = IWEBUTIL_UrlEncode(p_IWebUtil, pszData, &nInLen, pcOut, &nOutLen);
IWEBUTIL_Release(p_IWebUtil);
p_IWebUtil = NULL;
}
/* if there's post data, construct a stream for IWeb to consume */
if ((char *)0 != me->pszPostData)
{
me->pipPostData = NULL;
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_SOURCEUTIL, (void **)&pisu))
{
ISOURCEUTIL_PeekFromMemory(pisu, me->pszPostData,STRLEN(me->pszPostData), 0, 0,
&me->pipPostData);
ISOURCEUTIL_Release(pisu);
}
}
/* initialize the callback, where I'll be called when the request
completes */
CALLBACK_Init(&me->cb, WebAction_GotResp, me);
me->uStart = GETUPTIMEMS();
/* start transaction, pass callbacks for web status, web headers
the extra WEBOPT_HEADER is used to help test what's sent
(snoop.sh above shows all the headers) */
{
IWEB_GetResponse(me->pwbr->piWeb,
(me->pwbr->piWeb, &me->piWResp, &me->cb, pszUrl,
WEBOPT_HANDLERDATA, me,
WEBOPT_METHOD, "POST",
WEBOPT_HEADER, "X-Method: POST\r\n",
WEBOPT_BODY, me->pipPostData,
WEBOPT_CONTENTLENGTH, STRLEN(me->pszPostData),
WEBOPT_HEADERHANDLER, WebAction_Header,
WEBOPT_STATUSHANDLER, WebAction_Status,
WEBOPT_END));
}
//Release local buffers
if(pszData)
{
FREE(pszData);
pszData = NULL;
}
if(pcOut)
{
FREE(pcOut);
pcOut = NULL;
}
}
Instead of POST method, if i using GET method with url as "http://myserver/param.jsp?firstname=nilesh&lastname=bhanderi then its working fine ..
Also, my web server receives parametes correctly when i send it thru web browser.
So i think there is no problem from server side..
I m using Tomcat webserver, so any idea abt what shud be format for parameters?
regds,
Nilesh

Here is the function that starts the web transaction
<<<<<<<<<<<<<<<<<<
static void WebAction_Start(WebAction *me, char *pszUrl)
{
ISourceUtil *pisu = NULL;
char* pszData = NULL;
char * pcOut = NULL;
int nInLen = 0;
int nOutLen = 0;
IWebUtil* p_IWebUtil = NULL;
int rv = 0;
/* Encode the parameters that have to be sent to server*/
pszData = (char *) MALLOC(70);
if(NULL == pszData)
return;
STRCPY(pszData ,"firstname=nilesh&lastname=bhanderi\r\n");
//STRCPY(pszData ,"firstname=nilesh\r\nlastname=bhanderi\r\n");
nInLen = 70;
pcOut = (char *) MALLOC(100);
if(NULL == pcOut)
return;
nOutLen = 100;
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_WEBUTIL, (void **)&p_IWebUtil ))
{
me->pszPostData = IWEBUTIL_UrlEncode(p_IWebUtil, pszData, &nInLen, pcOut, &nOutLen);
IWEBUTIL_Release(p_IWebUtil);
p_IWebUtil = NULL;
}
/* if there's post data, construct a stream for IWeb to consume */
if ((char *)0 != me->pszPostData)
{
me->pipPostData = NULL;
if (SUCCESS == ISHELL_CreateInstance(me->pwbr->piShell,AEECLSID_SOURCEUTIL, (void **)&pisu))
{
ISOURCEUTIL_PeekFromMemory(pisu, me->pszPostData,STRLEN(me->pszPostData), 0, 0,
&me->pipPostData);
ISOURCEUTIL_Release(pisu);
}
}
/* initialize the callback, where I'll be called when the request
completes */
CALLBACK_Init(&me->cb, WebAction_GotResp, me);
me->uStart = GETUPTIMEMS();
/* start transaction, pass callbacks for web status, web headers
the extra WEBOPT_HEADER is used to help test what's sent
(snoop.sh above shows all the headers) */
{
IWEB_GetResponse(me->pwbr->piWeb,
(me->pwbr->piWeb, &me->piWResp, &me->cb, pszUrl,
WEBOPT_HANDLERDATA, me,
WEBOPT_METHOD, "POST",
WEBOPT_HEADER, "X-Method: POST\r\n",
WEBOPT_BODY, me->pipPostData,
WEBOPT_CONTENTLENGTH, STRLEN(me->pszPostData),
WEBOPT_HEADERHANDLER, WebAction_Header,
WEBOPT_STATUSHANDLER, WebAction_Status,
WEBOPT_END));
}
//Release local buffers
if(pszData)
{
FREE(pszData);
pszData = NULL;
}
if(pcOut)
{
FREE(pcOut);
pcOut = NULL;
}
}
Instead of POST method, if i using GET method with url as "http://myserver/param.jsp?firstname=nilesh&lastname=bhanderi then its working fine ..
Also, my web server receives parametes correctly when i send it thru web browser.
So i think there is no problem from server side..
I m using Tomcat webserver, so any idea abt what shud be format for parameters?
regds,
Nilesh

Following is the output from TCP Viewer for my web transaction
<<<<<<<<<<<<<
POST /servlets-examples/servlet/RequestParamExample HTTP/1.0
Accept: */*
Host: 163.122.36.118:8080
User-Agent: BREW/1.1.0.18 (built Dec 17 2001)
Content-Length: 46
Connection: Keep-Alive
X-Method: POST
Content-Type: application/x-www-form-urlencoded
firstname%3Dnilesh%26lastname%3Dbhanderi%0D%0A
>>>>>>>>>>>>

Following is the output from TCP Viewer for my web transaction
<<<<<<<<<<<<<
POST /servlets-examples/servlet/RequestParamExample HTTP/1.0
Accept: */*
Host: 163.122.36.118:8080
User-Agent: BREW/1.1.0.18 (built Dec 17 2001)
Content-Length: 46
Connection: Keep-Alive
X-Method: POST
Content-Type: application/x-www-form-urlencoded
firstname%3Dnilesh%26lastname%3Dbhanderi%0D%0A
>>>>>>>>>>>>

You need set breakpoints in your code and see if everything is going allright as expected. For example do you have valid post data pointer. One of the important thing to note pszUrl lifetime. Don't put this on the stack of the calling function. By the way, URLEncode function will replace space with appropriate value. You should not be ,"firstname=nilesh&lastname=bhanderi\r\n" instead it should be ,"firstname=nilesh lastname=bhanderi\r\n".
Using packet sniffer on your server side check what is your server response.
ruben

You need set breakpoints in your code and see if everything is going allright as expected. For example do you have valid post data pointer. One of the important thing to note pszUrl lifetime. Don't put this on the stack of the calling function. By the way, URLEncode function will replace space with appropriate value. You should not be ,"firstname=nilesh&lastname=bhanderi\r\n" instead it should be ,"firstname=nilesh lastname=bhanderi\r\n".
Using packet sniffer on your server side check what is your server response.
ruben

Possibly following will help:
http://brewforums.qualcomm.com/showthread.php?s=&threadid=3803
--
(a) POST data is "param1=val1&m2=val2" (w-out "\r\n")
(b) data is _NOT_ encoded with IWEBUTIL_UrlEncode()
(c) WEBOPT_HEADER is "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\n"

Possibly following will help:
http://brewforums.qualcomm.com/showthread.php?s=&threadid=3803
--
(a) POST data is "param1=val1&m2=val2" (w-out "\r\n")
(b) data is _NOT_ encoded with IWEBUTIL_UrlEncode()
(c) WEBOPT_HEADER is "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\n"

Thanks dva..
Finally i successed in postin data to the server.
But in following guidelines that u suggested
a) POST data is "param1=val1&m2=val2" (w-out "\r\n")
(b) data is _NOT_ encoded with IWEBUTIL_UrlEncode()
(c) WEBOPT_HEADER is "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\n"
If data is not to be encoded then why "Content-Type" should be specified as "application/x-www-form-urlencoded"?
Thanks once again,
Nilesh

Thanks dva..
Finally i successed in postin data to the server.
But in following guidelines that u suggested
a) POST data is "param1=val1&m2=val2" (w-out "\r\n")
(b) data is _NOT_ encoded with IWEBUTIL_UrlEncode()
(c) WEBOPT_HEADER is "X-Method: POST\r\nContent-Type: application/x-www-form-urlencoded\r\n"
If data is not to be encoded then why "Content-Type" should be specified as "application/x-www-form-urlencoded"?
Thanks once again,
Nilesh

Yeah, it's not logical but it works ;)
Don't know how to explain :/

Yeah, it's not logical but it works ;)
Don't know how to explain :/

Here you are doing your own URL encoding by specifying & for space "param1=val1&m2=val2", that's why even without passing through IWEBUTIL_UrlEncode() you can post data successfully.

Here you are doing your own URL encoding by specifying & for space "param1=val1&m2=val2", that's why even without passing through IWEBUTIL_UrlEncode() you can post data successfully.

hi
dva,ruben
give me a example !
thanks!

hi
dva,ruben
give me a example !
thanks!

There are bunch of threads on post methods. It is exactly like "Get" except that you have post data which is URL encoded, for POST method. Your server can use either post data terminating character or post data length to determine post data.
ruben

There are bunch of threads on post methods. It is exactly like "Get" except that you have post data which is URL encoded, for POST method. Your server can use either post data terminating character or post data length to determine post data.
ruben

Hi Nilesh,
I have very silly question. You r using WEBOPt_headerhandle to to check the what u r postingin the header?? I think WebAction_header is the funciton u r passing to Webopt_Headerhandler? Can u say me how to check the the data being posted by the WEBOPT_HeaderHandler ? if u put some example it will be nice and describle it little better
Regards
Pramod

Hi Nilesh,
I have very silly question. You r using WEBOPt_headerhandle to to check the what u r postingin the header?? I think WebAction_header is the funciton u r passing to Webopt_Headerhandler? Can u say me how to check the the data being posted by the WEBOPT_HeaderHandler ? if u put some example it will be nice and describle it little better
Regards
Pramod

ruben wrote:You should not be ,"firstname=nilesh&lastname=bhanderi\r\n" instead it should be ,"firstname=nilesh lastname=bhanderi\r\n".
Using packet sniffer on your server side check what is your server response.
ruben
Hi Ruben,
I found the same description in thread
http://brewforums.qualcomm.com/showthread.php?t=3803&highlight=urlencode
Is it really correct to encode the whole query string as you said. My emulator gives
param1%3Dval1+m2%3Dval2
if I pass
param1=val1 param2=val2
as the cpcIn parameter for IWEBUTIL_UrlEncode(). Delimiters '=' and ' ' (SPACE) are also URL encoded so we cant get the correct query. What is expected here is
param1=val1&param2=val2
So the correct usage of IWEBUTIL_UrlEncode() is to apply it to each part (each parameter name and value) of the query, then concatenate them together with the correct delimiters('=' and '&')
There's one interesting side effect(BUG?) I found with IWEBUTIL_UrlEncode(). The encoded string is not terminated with zero in some case. In my environment, I see that it is zero-terminated only if the receiving buffer is initialized with a zero-terminated string.
For example,
char *inStr = "param1=val1 m2=val2";
int inLen = STRLEN(inStr);
char outStr[128];
int outLen = 128;
IWEBUTIL_UrlEncode(me->m_pWebUtil, inStr, &inLen, outStr, &outLen);
will give outStr unterminated. On the other hand,
char *inStr = "param1=val1 m2=val2";
int inLen = STRLEN(inStr);
char outStr[128] = ""; // terminated it before calling
int outLen = 128;
IWEBUTIL_UrlEncode(me->m_pWebUtil, inStr, &inLen, outStr, &outLen);
This is surely a source of subtle bugs! I would like the encoded string is zero-terminated in all cases.
TO BREW Support engineers: Can you confirm it in your side? I didnt found any information about the above in the SDK documents.

ruben wrote:You should not be ,"firstname=nilesh&lastname=bhanderi\r\n" instead it should be ,"firstname=nilesh lastname=bhanderi\r\n".
Using packet sniffer on your server side check what is your server response.
ruben
Hi Ruben,
I found the same description in thread
http://brewforums.qualcomm.com/showthread.php?t=3803&highlight=urlencode
Is it really correct to encode the whole query string as you said. My emulator gives
param1%3Dval1+m2%3Dval2
if I pass
param1=val1 param2=val2
as the cpcIn parameter for IWEBUTIL_UrlEncode(). Delimiters '=' and ' ' (SPACE) are also URL encoded so we cant get the correct query. What is expected here is
param1=val1&param2=val2
So the correct usage of IWEBUTIL_UrlEncode() is to apply it to each part (each parameter name and value) of the query, then concatenate them together with the correct delimiters('=' and '&')
There's one interesting side effect(BUG?) I found with IWEBUTIL_UrlEncode(). The encoded string is not terminated with zero in some case. In my environment, I see that it is zero-terminated only if the receiving buffer is initialized with a zero-terminated string.
For example,
char *inStr = "param1=val1 m2=val2";
int inLen = STRLEN(inStr);
char outStr[128];
int outLen = 128;
IWEBUTIL_UrlEncode(me->m_pWebUtil, inStr, &inLen, outStr, &outLen);
will give outStr unterminated. On the other hand,
char *inStr = "param1=val1 m2=val2";
int inLen = STRLEN(inStr);
char outStr[128] = ""; // terminated it before calling
int outLen = 128;
IWEBUTIL_UrlEncode(me->m_pWebUtil, inStr, &inLen, outStr, &outLen);
This is surely a source of subtle bugs! I would like the encoded string is zero-terminated in all cases.
TO BREW Support engineers: Can you confirm it in your side? I didnt found any information about the above in the SDK documents.

Dick,
Most likely what you want to do is only encode the values of your parameters and "assemble" the rest of the url with &s and =s .
for example, if you want "param1" to have the value of "1=2", and "param2" to have the value "3&4", your eventual url encoded string would look like this:
param1=1%3d2&param2=3%3d4
and you would do something like:
//semi-pseudocode
str = STRCAT(str, "param1=");
str = STRCAT(str, UrlEncode("1=2"));
str = STRCAT(str, "&param2=");
str = STRCAT(str, UrlEncode("3&4"));
obviously you need to add more error checking for the string length and such, but thats the basic idea..
i can also depend on what your server is running and/or how it parses the data on its side (ASP, PHP, Perl, JSP, etc)
you can also "assemble" a get url the same way..
-Tyndal

Dick,
Most likely what you want to do is only encode the values of your parameters and "assemble" the rest of the url with &s and =s .
for example, if you want "param1" to have the value of "1=2", and "param2" to have the value "3&4", your eventual url encoded string would look like this:
param1=1%3d2&param2=3%3d4
and you would do something like:
//semi-pseudocode
str = STRCAT(str, "param1=");
str = STRCAT(str, UrlEncode("1=2"));
str = STRCAT(str, "&param2=");
str = STRCAT(str, UrlEncode("3&4"));
obviously you need to add more error checking for the string length and such, but thats the basic idea..
i can also depend on what your server is running and/or how it parses the data on its side (ASP, PHP, Perl, JSP, etc)
you can also "assemble" a get url the same way..
-Tyndal

Hi Tyndal,
Yeah. Your pseudo code is what I think the correct way to use with most CGI scripts that read form data sent from a browser.
By the way, do you see the same problem with the encoded string not being NULL terminated in your environment?
I would like very much to be informed about this from you as well as other people.
Thank you.

Hi Tyndal,
Yeah. Your pseudo code is what I think the correct way to use with most CGI scripts that read form data sent from a browser.
By the way, do you see the same problem with the encoded string not being NULL terminated in your environment?
I would like very much to be informed about this from you as well as other people.
Thank you.

In order to avoid all sorts of problems, our large network centric application has its own URL encoding function. It is not that hard to write a URL encoding function.

In order to avoid all sorts of problems, our large network centric application has its own URL encoding function. It is not that hard to write a URL encoding function.

I always zero out buffers/strings etc before using them in brew.
-Tyndal

I always zero out buffers/strings etc before using them in brew.
-Tyndal