Reputation: 6525
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.
Upvotes: 3
Views: 11788
Reputation: 16671
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;
Content-Type
header on the xhr so we can call Request.Form
(actually works with Request.Body
, new one on me).data=value
encoded values.Upvotes: 0
Reputation: 1461
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
%>
Upvotes: 6