Search code examples
vbscriptasp-classichttp-post

Unable to get raw POST data when using Classic ASP 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.


Solution

  • 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
    
    %>