Unable to get raw POST data when using Classic ASP VBScript - vbscript
I've been trying for two days to set up an endpoint that meets the requirements of a 3rd-party provider. They are going to send us updates about the status of a business object via a HTTPS POST and the contents of the request will be JSON. Unfortunately, it has to be written in VBScript for now.
At the moment, I'm unable to get the raw contents of the request they are sending me, so I cannot process it at all.
I have created a simple endpoint (raw-form.asp) and two test pages to demonstrate the issue. First, I set up a simple test HTML page (raw-form-test1.asp) using an HTML form, and it works correctly. The second test page (raw-form-test2.asp) sends the contents to the endpoint using a WinHttpRequest. When using this, the data isn't there. I'm attempting to get it via Request.Body.
raw-form-asp:
<%
Dim post : post = Request.Body
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
%>
raw-form-test1.asp:
<!DOCTYPE html>
<html>
<body>
<form action="raw-form.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
raw-form-test2.asp:
<%
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:8080/raw-form.asp"
http.Send data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
%>
<!DOCTYPE html>
<html>
<body>
<%= Server.HTMLEncode(resp) %>
<form action="raw-form-test2.asp" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
When filling in some random text and submitting the first test, the response body is as I'd expect:
Your POST data was: data=abc
When using the second test, the returned result in resp is:
200 | Your POST data was:
I've also tried to use Request.BinaryRead() without success (VBScript can get its length, but not the contents - probably just VB being terrible with types). I'm hoping there's an alternative way to get the data.
In raw-form.asp, you can Response.BinaryWrite the result of Request.BinaryRead, like this:
<%
If Request.TotalBytes > 0 Then
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: "
Response.BinaryWrite Request.BinaryRead(Request.TotalBytes)
End If
%>
Or you can use Request.BinaryRead and then write the bytes to an ADO stream object, which you can then read the text from. Here's an example from: https://stackoverflow.com/a/9777124/989516
<%
If Request.TotalBytes > 0 Then
Dim lngBytesCount, post
lngBytesCount = Request.TotalBytes
post = BytesToStr(Request.BinaryRead(lngBytesCount))
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End If
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "iso-8859-1"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
%>
Still trying to understand what the big issue is, assuming your endpoint returns JSON you could modify the below procedures in the example code I posted.
Sub http_post()
Dim data : data = Request.Body
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
'Interpret the response from the xhr as JSON.
Response.ContentType = "application/json"
Call Response.Write(http.ResponseText)
End Sub
Sub http_xhr()
Dim post : post = Request.Body
Response.ContentType = "application/json"
%>{
data: {
"SomeItem": "SomeData",
"SomeNumber": 1,
"PostedData": "<%= post %>"
}
}<%
End Sub
%>
I've just tested your code and restructured it a bit so I could test it using one file and it does the same thing.
<%
Dim data, method
Call init()
Sub init()
Dim action
method = UCase(Request.ServerVariables("REQUEST_METHOD") & "")
Select Case method
Case "GET"
Call http_get()
Case "POST"
action = Request.QueryString("action") & ""
If Len(action) > 0 And IsNumeric(action) Then action = CLng(action) Else action = 1
Select Case action
Case 1
Call http_post()
Case 2
Call http_xhr()
End Select
End Select
End Sub
Sub http_get()
%>
<!DOCTYPE html>
<html>
<body>
<form action="?action=1" method="post">
<p><textarea name="data"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>
<%
End Sub
Sub http_post()
Dim data : data = Request.Form("data")
Dim resp : resp = ""
If data <> "" Then
Dim http : Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
http.Open "post", "http://localhost:1337/test9.asp?action=2"
'We are mimicing a form post use x-ww-form-urlencoded.
Call http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
'Need to make sure we pass this as "data=value" so we can use `Request.Form("data") in the xhr call.
http.Send "data=" & data
http.WaitForResponse(10)
resp = http.Status & " | " & http.ResponseText
End If
Call Response.Write(resp)
End Sub
Sub http_xhr()
Dim post : post = Request.Form("data")
Response.ContentType = "text/plain"
Response.Write "Your " & Request.ServerVariables("REQUEST_METHOD") & " data was: " & post
End Sub
%>
In main differences that make it work are;
Setting the Content-Type header on the xhr so we can call Request.Form (actually works with Request.Body, new one on me).
Passing the data to the xhr as data=value encoded values.
Related
Got the error File type is not supported when uploading a file in ruby on rails
url = URI("https://api.podium.com/v4/messages/attachment") https = Net::HTTP.new(url.host, url.port) https.use_ssl = true request = Net::HTTP::Post.new(url) request["Content-Type"] = "multipart/form-data" request["Authorization"] = "Bearer #{access_token}" form_data = [["attachment",File.open('D:\proj\v5\ap\fl\Screenshot (1).png')],['data', "#{request_data}"]] request.set_form(form_data, 'multipart/form-data') response = https.request(request) response_body = JSON.parse(response.body) if response.code == '200' || response.code == '201' return response_body,'success' else return response_body,"#{response.message}" end rescue Exception => ex return ex,'Exception' end ** When i am sending the request i got the error like {"code"=>"invalid_request_values", "message"=>"File type is not supported.", "moreInfo"=>"https://docs.podium.com/docs/errors#invalid_request_values"} **
Here are a couple of things you could try: The podium documentation says that the images cannot be above 5mb in size. You can verify if this is the case. https://help.podium.com/hc/en-us/articles/360039896873-Sending-Messages#Attach%20media%20to%20a%20message I noticed the code snippet you've shared does set have this line as mentioned in their documentation here https://docs.podium.com/reference/messagesend_with_attachment request["accept"] = 'application/json' Maybe adding this header might fix it for you, as you are saying that it is working for you in Postman but not in Ruby. Try uploading the file from the API Doc reference page itself and check out the code sample they provide there. There are some differences in the code sample you've shared, and the one that podium shows in their doc.
Sending Request using NTLM Authentication in VBScript [duplicate]
I am using Classic ASP and trying to use the JustGiving API. I'd like to use it to display the total amount raised, and total donations received on my donation page, on my website. I can see that info is available via: https://api.justgiving.com/docs/resources/v1/Account/Retrieve <% vurl = "http://api.justgiving.com/---myIDhere---/v1/account" Set http = Server.CreateObject("msxml2.ServerXMLHTTP") http.Open "GET", vurl, False http.Send Set dom = Server.CreateObject("msxml2.DOMDocument") dom.loadXML http.responseText Set items = dom.getElementsByTagName("account") For Each item In items Set var_totalDonated = item.getElementsByTagName("totalDonated") If NOT (var_totalDonated IS Nothing) Then var_totalDonated = ap(totalDonated(0).Text) response.write var_totalDonated End If Next %> However, the page times out when I access it. I think it's because I need to provide some authentication information as detailed here: https://api.justgiving.com/docs/usage#protectedResources So I got that authentication info. But I have no idea how to "send" it to the API, so that it can authenticate me as a user and provide the info. It also mentions providing info on the header via the link above this one (I can't post the link as I don't have enough reputation), but replace #protectedResources at the end of the URL with #contentTypes. I'm sorry - am I also missing something on that side? I'm sorry if I'm asking silly questions, but the info on the API docs assumes some level of intelligence on the part of the user, and I don't have a lot of it! Any advice much appreciated. Thanks Thanks to John for your reply. Based on that, I changed the code to: <% vurl = "https://api.justgiving.com/API_KEY/v1/account" Set http = Server.CreateObject("msxml2.ServerXMLHTTP") http.Open "GET", vurl, False, "username", "pwd" http.setTimeouts 5000, 5000, 10000, 10000 ''ms - resolve, connect, send, receive http.setRequestHeader "Authorization", "Basic MY_AUTH_STRING" http.Send Set dom = Server.CreateObject("msxml2.DOMDocument") dom.loadXML http.responseText Set items = dom.getElementsByTagName("account") For Each item In items Set var_totalDonated = item.getElementsByTagName("totalDonated") If NOT (var_totalDonated IS Nothing) Then var_totalDonated = (var_totalDonated(0).Text) response.write var_totalDonated End If Next %> But unfortunately the page still times out. I'm checking also via: groups.google.com/forum/#!topic/justgiving-api/Xhz5Fkxuy1s But no answer so far. Thanks again Fixed Version <% Sub debug( varName ) Dim varValue varValue = Eval( varName ) response.write "<p style='margin:10px; border-bottom:2px solid #ccc;border-top:1px solid #eaeaea;background-color:white;padding:10px;color:red;text-align:left;'><strong>" & varName & "</strong>: " & varvalue & "</p>" & vbcrlf & vbcrlf End Sub vurl = "https://api.justgiving.com/AP_KEY/v1/account" Set http = Server.CreateObject("msxml2.ServerXMLHTTP") http.Open "GET", vurl, False, username, password http.setTimeouts 5000, 5000, 10000, 10000 'ms - resolve, connect, send, receive http.setRequestHeader "Authorization", "Basic AUTH_STRING" http.Send Response.ContentType = "application/xml" Set dom = Server.CreateObject("msxml2.DOMDocument") dom.loadXML http.responseText Set items = dom.getElementsByTagName("account") For Each item In items Set var_totalDonated = item.getElementsByTagName("totalDonated") If NOT (var_totalDonated IS Nothing) Then var_totalDonated = ap(var_totalDonated(0).Text) debug "var_totalDonated" End If Set var_totalRaised = item.getElementsByTagName("totalRaised") If NOT (var_totalRaised IS Nothing) Then var_totalRaised = ap(var_totalRaised(0).Text) debug "var_totalRaised" End If Set var_totalGiftAid = item.getElementsByTagName("totalGiftAid") If NOT (var_totalGiftAid IS Nothing) Then var_totalGiftAid = ap(var_totalGiftAid(0).Text) debug "var_totalGiftAid" End If Next %> Previously I was using: vurl = "https://api.justgiving.com/AP_KEY/v1/account" But when I changed it to https it worked. I thought I had tried that previously, but obviously not. Thanks again to John, I really appreciate your help!
Try http.Open "GET", vurl, False, "yourusername", "yourpassword" I don't know if this works on justgiving, but it does with the Bing API Also, this question may be relevant XmlHttp Request Basic Authentication Issue Edit - using Response.ContentType and Msxml2.ServerXMLHTTP.6.0 vurl = "https://api.justgiving.com/API_KEY/v1/account" Set http = Server.CreateObject("msxml2.ServerXMLHTTP.6.0") http.Open "GET", vurl, False, "username", "pwd" http.setTimeouts 5000, 5000, 10000, 10000 'ms - resolve, connect, send, receive' http.setRequestHeader "Authorization", "Basic MY_AUTH_STRING" http.Send Response.ContentType = "application/xml" Set items = http.responseXML.getElementsByTagName("account") etc
Apologies for adding to an old post. However this has consistently come up when Googling for help on MailChimp API V3.0 and VBA. This is the fix I used: ret = objhttp.Open("POST", sURL, False) objhttp.setRequestHeader "Content-Type", "application/json" objhttp.setRequestHeader "Accept", "application/json" 'V3 API uses HTTP Basic Authorisation inside an https: wrapper. 'The standard windows method does not seem to work however the 'following hack does. 'In summary the user name and APIkey are seperated with a Colon: and 'base 64 encoded and added to a Http RequestHeader objhttp.setRequestHeader "Authorization", "Basic " & Base64Encode(APIUser & ":" & ApiKey) objhttp.send (sJson) You will need to code the Base64Encode function. I grabbed some code from http://pastie.org/1192157 (Ex StackOverflow) and pasted it into a VBA Module. Hope it helps.
Using MSXML2.ServerXMLHTTP instead of XMLHTTP for POST requests from VB5 application for handling HTTPS
I've been using XMLHTTP for making HTTP POST requests (From a VB5 application) to a WCF (self hosted in a windows service) endpoint with the next code and everything was working as expected, Dim xmlhttp As MSXML2.XMLHTTP30 Dim blnSuccess As Boolean Dim resp, strTit, strRes As String Dim intPos1, intPos2, intPos3 As Integer Dim mType As VbMsgBoxStyle Set xmlhttp = New MSXML2.XMLHTTP30 xmlhttp.Open "POST", strURL, False xmlhttp.setRequestHeader "Man", "POST " & strURL & " HTTP/1.1" xmlhttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8" xmlhttp.setRequestHeader "SOAPAction", strSOAPAction Call xmlhttp.send(strSoap) However since I was requested to change from HTTP to HTTPS Had to change WCF to add and SSL certificate by binding the certificate to the port, and everything was working fine while doing requests from postman, but the problem was that when I tried to test it on my VB application It did not work and I was prompted with this error run time error -214669728 (800c0008) The download of the specified resource has failed. So while doing some research I change my code to use SeverXMLHTTP instead of XMLHTTP and setOption for bypassing certificate errors as is shown in the next code Dim xmlhttp As MSXML2.ServerXMLHTTP30 Dim blnSuccess As Boolean Dim resp, strTit, strRes As String Dim intPos1, intPos2, intPos3 As Integer Dim mType As VbMsgBoxStyle Set xmlhttp = New MSXML2.ServerXMLHTTP30 xmlhttp.Open "POST", strURL, False xmlhttp.setRequestHeader "Man", "POST " & strURL & " HTTP/1.1" xmlhttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8" xmlhttp.setRequestHeader "SOAPAction", strSOAPAction xmlhttp.setOption 2, 13056 blnSuccess = False Call xmlhttp.send(strSoap) The problem is that I been reading that as the name says, SeverXMLHTTP must be used for server application not client as my VB is acting in this context. I referred to this post I am concerned if this is the correct path to follow but while reading this article I think I will not have problems even this object points to use between server to server communication. Could anybody instruct me a little bit about this, what I observed in testing everything is good so far, but I not quite experienced using this object . Thanks
How to consume a asp.net web api in classic asp?
I have a sample web API want to consume it in asp file, please guide me with the steps to consume web API in classic asp.
Below is the asp code. <% Dim Id Id = Request.QueryString("Id") url = "http://localhost:50464/api/values/"+Id Dim oXMLHttp Set oXMLHttp=Server.Createobject("MSXML2.ServerXMLHTTP.6.0") oXMLHttp.open "GET", url,false oXMLHttp.setRequestHeader "Content-Type", "application/json" oXMLHttp.send response.write oXMLHttp.responseText Set oXMLHttp = Nothing %> API url: http://localhost:50464/api/values
POST Request using VBScript
Am trying to post a request and get a response through VBS. Dim response Set xHttp = CreateObject("Microsoft.XMLHTTP") xHttp.Open "POST", "https://idoc-api-int.platform-test.sample.com/interactiveDocumentOrchestrator", False, u1i, p1i xHttp.Send response = xHttp.responseText Msgbox response Basically, I'm using SOAP UI to send a request to the URL with a body content and I will be getting the response. I'm trying to achieve it through a VBScript. Kindly suggest if there is any way I am able to do this.