1. Kiran Patel
  2. PowerBuilder
  3. Friday, 11 December 2020 13:35 PM UTC

When call  lnv_HttpClient.SendRequest("GET", lsurl, lsboby)

On some PC it show "Bad Request - Invalid Verb" this error

but it works on postman.

Develop on Appeon PowerBuilder 2019 R2 Build 2353

Deploy on Windows 10 64Bit

 

My Code

Integer li_rc
String ls_string, lsboby
HttpClient lnv_HttpClient
lnv_HttpClient = Create HttpClient
lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")

string lsurl, lsid, lssql
lsurl = "http://mydomain/myapp/api/sysfunction/sql"
lsid = "test"
lssql = "select item_code, item_name from item_master where item_code = 'CH'"
lsboby = '"{ '
lsboby = lsboby + ' \"corporateid' + '\": \"' + lsid + '\", ~r~n'
lsboby = lsboby + ' \"sql\": \"' + lssql + '\"'
lsboby = lsboby + ' }"'

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsboby)

lnv_HttpClient.GetResponseBody(ls_string)
mle_1.text = ls_string

 

Error:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>

 

Thank you

Kiran Patel

 

Accepted Answer
Roland Smith Accepted Answer Pending Moderation
  1. Wednesday, 16 December 2020 13:47 PM UTC
  2. PowerBuilder
  3. # Permalink

I had the same issue once. I came to the conclusion that the HttpClient object will only send data when the method is POST. You are sending data (the third argument) with GET.

The usual way is to use GET to return data from the server and POST to send data to the server. It appears that HttpClient is enforcing this.

Technically IIS will allow any value for method, it is up to the web application to determine what the client wants it to do.

Comment
  1. David Peace (Powersoft)
  2. Wednesday, 16 December 2020 14:36 PM UTC
That makes sense, I was uncertain as I have never tries to send data on a GET! Seems illogical.
  1. Helpful
  1. Daryl Foster
  2. Wednesday, 16 December 2020 22:28 PM UTC
While it is unusual and not at all recommended to send a body with a GET request, I don't think the latest HTTP specification actually prohibits it "A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.".



Adding a body to a GET request is not something I would use, but interestingly earlier versions of Postman wouldn't let you send a body with a GET request, but the latest versions do, so there must be some demand for it.



I tested the HttpClient in Powerbuilder 2019 R2 (Build 2328) earlier this week and it does send the body with a GET request. It even sets the Content-Length header which I didn't think it would. If you send a body with a GET request, it's really up to the Server to accept it, and then up to the specific API to handle it. Kiran has said that it works from his PC and logs it on the server so presumably the API handles it ok. Requests from the client don't work, but he does say that requests from the client aren't logged on the server, which is weird. I wonder whether the request from the client is intercepted by an upstream proxy and rejected before it reaches the server. Or whether the URL on the client resolves to a different IP Address than on his PC.



It is unclear whether Kiran has written the API or has access to the source code. If so the easiest thing would be to change it all to use POST, but if it is someone else's API he may be stuck with it as it is.
  1. Helpful
  1. David Peace (Powersoft)
  2. Thursday, 17 December 2020 14:18 PM UTC
The alternative is to build the data as parameters to the URL and post that as a get without the data payload... just a thought.

  1. Helpful
There are no comments made yet.
Kiran Patel Accepted Answer Pending Moderation
  1. Thursday, 17 December 2020 13:27 PM UTC
  2. PowerBuilder
  3. # 1

Thank you soo much Devid, Raand and Bruce

For your support, I will change my code to POST instead of GET. and it will solve my issue

But one query remain,
If my GET code is working on my pc and some of my client pc then it should work on other pcs also.
If this is HTTP Limitation then it should not work on any PC.

I am new student in DotNet core and Restful API,
so I don't know to not use body in GET. I want to retrieve data from server and i use GET + Body and it was working on my developer pc so i use GET.
But when deploy on client PC then to was working on some pc and not working on other pc.

After so many trial and error i post my query on community.

Thank you every one to support me.

Regards...

Kiran Patel :)

Comment
There are no comments made yet.
Bruce Armstrong Accepted Answer Pending Moderation
  1. Wednesday, 16 December 2020 17:39 PM UTC
  2. PowerBuilder
  3. # 2

Perhaps somebody address this already (I didn't read every response in the thread), but you can't send data in a GET request.  That's not a PowerBuilder limitation, it's part of the HTTP protocol.

Comment
There are no comments made yet.
Kiran Patel Accepted Answer Pending Moderation
  1. Tuesday, 15 December 2020 06:49 AM UTC
  2. PowerBuilder
  3. # 3

Hi Darly,

As your suggestion I have do changes in Header but same result

I change Get to GET,  my HTTP method is http and is not https

when I call this API from my pc then on server its generate log, but on client pc its not generate log on server.

In Postman there there is 3 header is <calculate when request is sent>

Send my code again after your suggestion

Integer li_rc
String ls_string, lsbody
lsbody = '{"corporateid": "test","sql": "select item_name from item_master where item_code = ~'CH~'" }'
HttpClient lnv_HttpClient
lnv_HttpClient = Create HttpClient
lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")
lnv_HttpClient.SetRequestHeader("Content-Length", string(len(lsbody)))
lnv_HttpClient.SetRequestHeader("Host", "my ip")
lnv_HttpClient.SetRequestHeader("User-Agent","PostmanRuntime/7.26.8")
lnv_HttpClient.SetRequestHeader("Accept", "*/*")
lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")
lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")


string lsurl
lsurl = "http://my ip/my app/api/sysfunction/sql_josan"
lsid = "test"
mle_2.text = lsbody
li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsbody)
lnv_HttpClient.GetResponseBody(ls_string)
mle_1.text = "Return Code :" + string(li_rc) + "~r~n" + ls_string

send you postman image also

Regards...Kiran

 

Comment
  1. Daryl Foster
  2. Tuesday, 15 December 2020 07:01 AM UTC
Hi Kiran, that is very strange that the client pc doesn't produce a log on the server but it does from your own PC. If it was me, to troubleshoot I would just implement a simple echoing web server and point the url on your PC and on the client PC to it to see exactly what the server is getting from each of the clients. Is your web service on a public IP Address, or is it running on your LAN?
  1. Helpful
  1. Kiran Patel
  2. Tuesday, 15 December 2020 08:44 AM UTC
Hi Darly,

its on Public IP not local LAN

  1. Helpful
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Monday, 14 December 2020 22:25 PM UTC
  2. PowerBuilder
  3. # 4

Hi Kiran,

I tested it and it looks like the Content-Length does get set correctly for a GET request, so my answer below may not be that helpful.  The other thing that you should check is that the GET argument is uppercase.  Depending on the server, the HTTP method may be case sensitive.  Some of your sample code shows you using GET and another shows you using Get

Try and change this:

li_rc = lnv_HttpClient.SendRequest("Get", lsurl, lsboby)

to this:

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsboby)

 

Also, is the url definitely http and not https?

Your Postman headers image shows 8 headers being set but it only shows 6 in the image.  I'm assuming the seventh is the "Connection:keep-alive" header.  What is the 8th header in Postman?

Did you write the API that is being called?  Do you have access to any of the logs from the server to try and troubleshoot?

Comment
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Monday, 14 December 2020 19:50 PM UTC
  2. PowerBuilder
  3. # 5

Hi Kiran, based on your postman screenshot you may need to set a Content-Length header, which you work out from the length of your final json string.  The API will be receiving your request but not know about the body without it.

I think it might be set automatically for POST requests, but I'm not sure about GET requests, because it's unusual to send a body with a GET request.

Comment
  1. Kiran Patel
  2. Tuesday, 15 December 2020 06:34 AM UTC
Hi Daryl,

As your suggestion and others i do changes in header and also send body send in JSON format but there is no change in result.

I am using GET because, I want return data from this call, and send multiple sql in body, that is not possible to send parameters. and this is working fine on some pcs.(W7 and W10)

And why lnv_HttpClient.SendRequest("GET", lsurl, lsbody) is behave differently in different pcs, I don't understand.



my code

Integer li_rc

String ls_string, lsbody

lsbody = '{"corporateid": "test","sql": "select item_name from item_master where item_code = ~'CH~'" }'

HttpClient lnv_HttpClient

lnv_HttpClient = Create HttpClient

lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")

lnv_HttpClient.SetRequestHeader("Content-Length", string(len(lsbody)))

lnv_HttpClient.SetRequestHeader("Host", "my ip")

lnv_HttpClient.SetRequestHeader("User-Agent","PostmanRuntime/7.26.8")

lnv_HttpClient.SetRequestHeader("Accept", "*/*")

lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")

lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")





string lsurl, lsid, lssql

lsurl = "http://my ip/my app/api/sysfunction/sql_josan"

lsid = "test"

mle_2.text = lsbody

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsbody)

lnv_HttpClient.GetResponseBody(ls_string)

mle_1.text = "Return Code :" + string(li_rc) + "~r~n" + ls_string

  1. Helpful
  1. Daryl Foster
  2. Tuesday, 15 December 2020 06:47 AM UTC
Hi Kiran, did you write the web service that is being called? Do you have access to the logs from the web service to see why some clients fail and not others?
  1. Helpful
There are no comments made yet.
Kiran Patel Accepted Answer Pending Moderation
  1. Monday, 14 December 2020 12:40 PM UTC
  2. PowerBuilder
  3. # 6

Hi Mark,

As your suggestion change header

lnv_HttpClient = Create HttpClient
lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")
/*lnv_HttpClient.SetRequestHeader("Content-Type", "application/json/text/xml;charset=UTF-8")*/
lnv_HttpClient.SetRequestHeader("User-Agent","PostmanRuntime/7.26.8")
lnv_HttpClient.SetRequestHeader("Accept", "*/*")
lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")
lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")

but its show same error

PB Return Code :1

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>

Attach postman image api header and parameters setting

One more thing i notice, when i open feddler on client pc then run postman then it now error, but if close feddler then run postman api then its working.

on my pc there is no issue if i run both software feddler and postman.

 

Regards...Kiran

Attachments (2)
Comment
  1. Mark Lee @Appeon
  2. Tuesday, 15 December 2020 03:14 AM UTC
Hi Kiran,



I googled this error "400 Bad Request", and it must be caused by the wrong parameter you sent.

The executed link and transmitted JSON content in the screenshot you provide are different from the executed link and transmitted JSON content in the PB code you provided.

I can't tell you what is wrong at present. I think you only need to make sure that the content sent to the server using HttpClient in the PB code is the same as you did with Postman, then this request should be successful.



Regards,
  1. Helpful
  1. Kiran Patel
  2. Tuesday, 15 December 2020 06:25 AM UTC
Hi Mark,

As your suggestion and others i do changes in header and also send body send in JSON format but there is no change in result.



my code

Integer li_rc

String ls_string, lsbody

lsbody = '{"corporateid": "test","sql": "select item_name from item_master where item_code = ~'CH~'" }'

HttpClient lnv_HttpClient

lnv_HttpClient = Create HttpClient

lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")

lnv_HttpClient.SetRequestHeader("Content-Length", string(len(lsbody)))

lnv_HttpClient.SetRequestHeader("Host", "my ip")

lnv_HttpClient.SetRequestHeader("User-Agent","PostmanRuntime/7.26.8")

lnv_HttpClient.SetRequestHeader("Accept", "*/*")

lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")

lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")





string lsurl, lsid, lssql

lsurl = "http://my ip/my app/api/sysfunction/sql_josan"

lsid = "test"

mle_2.text = lsbody

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsbody)

lnv_HttpClient.GetResponseBody(ls_string)

mle_1.text = "Return Code :" + string(li_rc) + "~r~n" + ls_string

  1. Helpful
  1. Mark Lee @Appeon
  2. Wednesday, 16 December 2020 01:20 AM UTC
Hi Kiran,



1. Please try commenting the code below and see if it works? (Since HttpClient doesn't support this encryption protocol.)

//lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")



2. If you confirmed that this code works fine on some PCs (W7 and W10), please check if you have enabled IE Proxy setup. It's suggested that you disable Proxy setup and see if it works.

https://community.appeon.com/index.php/qna/q-a/hrrpclient-sendrequest-is-very-slow-on-some-pc



3. Currently, I don't have other solutions. If the methods above do not help, we would need you to provide a reproducible case for us for further analysis.

  1. Helpful
There are no comments made yet.
Kiran Patel Accepted Answer Pending Moderation
  1. Monday, 14 December 2020 12:28 PM UTC
  2. PowerBuilder
  3. # 7

Hi Daryl Foster,

 

As you suggest in change my request body to json.

here is my code

Integer li_rc
String ls_string, lsboby
HttpClient lnv_HttpClient
lnv_HttpClient = Create HttpClient
lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")


//lnv_HttpClient.SetRequestHeader("Content-Type", "application/json/text/xml;charset=UTF-8")
//lnv_HttpClient.SetRequestHeader("User-Agent","PostmanRuntime/7.26.8")
//lnv_HttpClient.SetRequestHeader("Accept", "*/*")
//lnv_HttpClient.SetRequestHeader("Accept-Encoding", "deflate, br")
lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")


string lsurl, lsid, lssql
lsurl = "http://myip/myapp/api/sysfunction/sql_jsoan"
lsid = "test"
lssql = "select item_name from item_master where item_code = 'CH'"
lsboby = '{ '
lsboby = lsboby + ' "corporateid' + '": "' + lsid + '", ~r~n'
lsboby = lsboby + ' "sql": "' + lssql + '"'
lsboby = lsboby + ' }'
mle_2.text = lsboby

//{"corporateid": "test", "sql": "select item_name from item_master where item_code = 'CH'"}

li_rc = lnv_HttpClient.SendRequest("Get", lsurl, lsboby)
lnv_HttpClient.GetResponseBody(ls_string)
mle_1.text = "Return Code :" + string(li_rc) + "~r~n" + ls_string

 

But Same error

Return Code :1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>

Its Working on my pc and my office pc but give this error on client pc. (same app)

Its working on Postman on client PC

Regards...Kiran

 

Comment
There are no comments made yet.
Mark Lee @Appeon Accepted Answer Pending Moderation
  1. Monday, 14 December 2020 07:30 AM UTC
  2. PowerBuilder
  3. # 8

Hi Kiran,

1. Daryl Foster might be right. You can try referring to his reply.

2. In most cases, if it works on postman and doesn’t work in PB using HttpClient, it means the requests send from PB end and Postman are different. 
It is recommended that you use other tools, like Fiddler or HTTPAnalyzer, to monitor the Headers content Settings that you capture when you send an API request in the PCs with PB code or postman side. And then compare them to see if there's any difference. If yes, then add the corresponding SetRequestHeader method to your PB code to set the request header content and then test it again.

3. You can also refer to the link below for cases of sending requests using the SendRequest method:
https://docs.appeon.com/pb2019r2/application_techniques/ch18s02.html
https://docs.appeon.com/pb2019r2/application_techniques/ch18s02.html#d0e13942
https://docs.appeon.com/pb2019r2/powerscript_reference/ch10s684.html


4. BTW, if you can provide a screenshot of the parameters settings when sending the same API from Postman, we can help compare and see which of your PB code needs modifying.

 

Regards,

 

Comment
  1. David Peace (Powersoft)
  2. Tuesday, 15 December 2020 11:25 AM UTC
Clearly the message you are sending is not the same as postman, I would use Fiddler to compare the two.
  1. Helpful
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Sunday, 13 December 2020 23:44 PM UTC
  2. PowerBuilder
  3. # 9

Hi Kiran,

Are you sure it's a GET request and not a POST request?  You can technically send a body with a GET request (if the API is expecting it), but it's not generally done.  Data is generally passed to a GET request as URL arguments.

I'm assuming you are trying to send JSON to the API?  If so, the big issue I can see if that you are not creating valid JSON.  You don't need to escape those double quotes unless they are part of the value's data.  E.g if your sql statement used double quotes instead of single quotes.  You also don't need that carriage return newline there, but it doesn't do any harm.  You also don't want to wrap your JSON in double quotes, so the first character of the JSON should be { if it's an object, or [ if it's an array.

Your code produces the following invalid JSON

 

"{  \"corporateid\": \"test\",
 \"sql\": \"select item_code, item_name from item_master where item_code = 'CH'\" }"

 

If you remove all the escaping of double quotes

lsid = "test"
lssql = "select item_code, item_name from item_master where item_code = 'CH'"
lsboby = '{'
lsboby = lsboby + '"corporateid": "' + lsid + '",'
lsboby = lsboby + '"sql": "' + lssql + '"'
lsboby = lsboby + '}'

It should produce the following valid JSON:

{"corporateid": "test","sql": "select item_code, item_name from item_master where item_code = 'CH'"}

Comment
There are no comments made yet.
Kiran Patel Accepted Answer Pending Moderation
  1. Saturday, 12 December 2020 06:20 AM UTC
  2. PowerBuilder
  3. # 10

Hi Givinda

Now change code as you say

Integer li_rc
String ls_string, lsboby
HttpClient lnv_HttpClient
lnv_HttpClient = Create HttpClient
lnv_HttpClient.SetRequestHeader("Content-Type", "application/json")
lnv_HttpClient.SetRequestHeader("Accept", "*/*")
//lnv_HttpClient.SetRequestHeader("Accept-Encoding", "gzip")
lnv_HttpClient.SetRequestHeader("Accept-Language", "en")
lnv_HttpClient.SetRequestHeader("Connection", "keep-alive")
lnv_HttpClient.SetRequestHeader("User-Agent", "Chrome/60.0.3112.113")
lnv_HttpClient.SetRequestHeader("Cache-Control", "no-cache")

string lsurl, lsid, lssql
lsurl = "http://muip/myapp/api/sysfunction/sql"
lsid = "test"
lssql = "select item_code, item_name from item_master where item_code = 'CH'"
lsboby = '"{ '
lsboby = lsboby + ' \"corporateid' + '\": \"' + lsid + '\", ~r~n'
lsboby = lsboby + ' \"sql\": \"' + lssql + '\"'
lsboby = lsboby + ' }"'

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, lsboby)
lnv_HttpClient.GetResponseBody(ls_string)
mle_1.text = ls_string

also try with "["  and "]"

li_rc = lnv_HttpClient.SendRequest("GET", lsurl, '['+lsboby+']')

but error is same

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>

but this same api is working fine on postman on client pc

 

Regards...Kiran

Comment
There are no comments made yet.
Govinda Lopez @Appeon Accepted Answer Pending Moderation
  1. Friday, 11 December 2020 15:45 PM UTC
  2. PowerBuilder
  3. # 11

Hi Kiran,

 

You might want to check the encoding of your request. I see, by the response headers, that the Web API uses a certain encoding, perhaps you need to enforce it in certain machines and that's why you keep on getting this error message.

 

Try the PowerScript method SetRequestHeader() to set the corresponding encoding (https://docs.appeon.com/pb2019r2/powerscript_reference/ch10s749.html).

 

Another thing you might want to look for is if your Web API is expecting a JSON string or a JSON object. Try adding the "[" and "]" and the beginning and end of your JSON. See if that makes any difference.

 

 

Regards,

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.