Is it possible to change the classic ASP response once you've written to it? - asp-classic

If I have a classic ASP response in the format:
someJsFunctionName({"0":{"field1":0,"field2":"","field3":0,"field4":2,"field5":1,"field6":1}});
that is built with
response.write "someFunctionName("
someMethod(param1, param2).Flush
response.write ");"
If I want to insert a new field to the response
someJsFunctionName({"0":{"field1":0,"field2":"","field3":0,"field4":2,"field5":1,"field6":1, "field7":2}});
Would I be able to call a method similar to
response.replace("}});", "\"field7\":2}});")
?
Or would I have to clear the entire response to write a new string into it?
Would I have to keep track of the result of someMethod(param1, param2).Flush, modify that string before writing it to the response?

I can't see any need for you to output directly to the Response buffer, to be clear you can only manipulate the Response buffer up to the point you Call Response.Flush() as this clears the buffer and writes the headers. Up to that point you can still Call Response.Clear() to empty the buffer without writing it then fill the buffer again with Call Response.Write("yourstring").
The reason I can't see a need for this is because you could get the same effect by simply assigning your string to a variable building it up (manipulating it with Replace() if you want to) then Call Response.Write(yourstringvariable) to output it.
Dim myfunc
myfunc = "someFunctionName("
'someMethod should return a string
myfunc = myfunc & someMethod(param1, param2)
myfunc = myfunc & ");"
Call Response.Write(myfunc)

Related

Exploding a string ASP

I have the following which is returned from an api call:
<WORST>0</WORST>
<AVERAGE>93</AVERAGE>
<START>1</START>
I need to parse this to just give me the <AVERAGE></AVERAGE> number, 93.
Here's what I'm trying but get error detected:
res = AjaxGet(url)
myArray = split(res,"AVERAGE>")
myArray2 = split(myArray[1],"</AVERAGE>")
response.write myArray2[0]
I'm brand new to ASP, normally code in PHP
VBScript doesn't recognise square brackets [] when accessing Array elements and will produce a Syntax Error in the VBScript Engine.
Try making the following changes to the code snippet to fix this problem;
res = AjaxGet(url)
myArray = split(res,"AVERAGE>")
myArray2 = split(myArray(1),"</AVERAGE>")
response.write myArray2(0)
On a side Note:
Parsing XML data in this way is really inefficient if the AjaxGet() function returns an XML response you could use the XML DOM / XPath to locate the Node and access the value.

Issuing a POST request with a large amount of data fails in VB6

I have a pretty standard function to post some XML string data to a remote WCF service and extract the result. It works fine, but fails to scale to a "large" amount of data (138KB in this case.)
' performs a HTTP POST and returns the resulting message content
Function HttpPost(sUrl As String, sSOAPAction As String, sContent As String) As String
Dim oHttp As Object
'Set oHttp = CreateObject("Microsoft.XMLHTTP")
Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")
oHttp.open "POST", sUrl, False
oHttp.setRequestHeader "SOAPAction", """http://conducive.com.au/IXpacManagement/" & sSOAPAction & """"
oHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
oHttp.setRequestHeader "Content-Length", Len(sContent)
oHttp.send Str(sContent)
If oHttp.status = 200 Then
HttpPost = oHttp.responseText
Else
MsgBox "An error (" & LTrim(Str(oHttp.status)) & ") has occurred connecting to the server."
HttpPost = ""
End If
Set oHttp = Nothing
End Function
When I use Microsoft.XMLHTTP I get error 7 out of memory.
When I use MSXML2.XMLHTTP.6.0 I get object doesn't support this property or method.
In either case sending a small string of under a thousand characters works perfectly.
Here's what I get when I try different ways of sending the string:
Using oHttp.send(sContent): Even small POSTs fail with Invalid procedure call or argument Runtime error 5.
Using oHttp.send sContent: Even small POSTs fail with Invalid procedure call or argument Runtime error 5.
In the end oHttp.send CStr(sContent) worked. Thank you all for the suggestions because I was lost.
Try taking out the Str() around sContent and just using parentheses to pass it by value, e.g.
oHttp.send (sContent)
or failing that at least use CStr() - Str() is supposed to convert numbers to strings.

Simple encrypt/decrypt functions in Classic ASP

Are there any simple encrypt/decrypt functions in Classic ASP?
The data that needs to be encrypted and decrypted is not super sensitive. So simple functions would do.
4guysfromrolla.com: RC4 Encryption Using ASP & VBScript
See the attachments at the end of the page.
The page layout looks a bit broken to me, but all the info is there. I made it readable it by deleting the code block from the DOM via bowser development tools.
Try this:
' Encrypt and decrypt functions for classic ASP (by TFI)
'********* set a random string with random length ***********
cryptkey = "GNQ?4i0-*\CldnU+[vrF1j1PcWeJfVv4QGBurFK6}*l[H1S:oY\v#U?i,oD]f/n8oFk6NesH--^PJeCLdp+(t8SVe:ewY(wR9p-CzG<,Q/(U*.pXDiz/KvnXP`BXnkgfeycb)1A4XKAa-2G}74Z8CqZ*A0P8E[S`6RfLwW+Pc}13U}_y0bfscJ<vkA[JC;0mEEuY4Q,([U*XRR}lYTE7A(O8KiF8>W/m1D*YoAlkBK#`3A)trZsO5xv#5#MRRFkt\"
'**************************** ENCRYPT FUNCTION ******************************
'*** Note: bytes 255 and 0 are converted into the same character, in order to
'*** avoid a char 0 which would terminate the string
function encrypt(inputstr)
Dim i,x
outputstr=""
cc=0
for i=1 to len(inputstr)
x=asc(mid(inputstr,i,1))
x=x-48
if x<0 then x=x+255
x=x+asc(mid(cryptkey,cc+1,1))
if x>255 then x=x-255
outputstr=outputstr&chr(x)
cc=(cc+1) mod len(cryptkey)
next
encrypt=server.urlencode(replace(outputstr,"%","%25"))
end function
'**************************** DECRYPT FUNCTION ******************************
function decrypt(byval inputstr)
Dim i,x
inputstr=urldecode(inputstr)
outputstr=""
cc=0
for i=1 to len(inputstr)
x=asc(mid(inputstr,i,1))
x=x-asc(mid(cryptkey,cc+1,1))
if x<0 then x=x+255
x=x+48
if x>255 then x=x-255
outputstr=outputstr&chr(x)
cc=(cc+1) mod len(cryptkey)
next
decrypt=outputstr
end function
'****************************************************************************
Function URLDecode(sConvert)
Dim aSplit
Dim sOutput
Dim I
If IsNull(sConvert) Then
URLDecode = ""
Exit Function
End If
'sOutput = REPLACE(sConvert, "+", " ") ' convert all pluses to spaces
sOutput=sConvert
aSplit = Split(sOutput, "%") ' next convert %hexdigits to the character
If IsArray(aSplit) Then
sOutput = aSplit(0)
For I = 0 to UBound(aSplit) - 1
sOutput = sOutput & Chr("&H" & Left(aSplit(i + 1), 2)) & Right(aSplit(i + 1), Len(aSplit(i + 1)) - 2)
Next
End If
URLDecode = sOutput
End Function
I know is a bit late for BrokenLink, but for the record and others like me who were looking for the same.
I found this https://www.example-code.com/vbscript/crypt_aes_encrypt_file.asp.
It needs to install a chilkat ActiveX component on WindowsServer. But this inconvenient becomes convenient when looking resources and processing time.
Its very easy to use, and the given example is pretty clear. To make it your own, just change the "keyHex" variable value and voilá.

How do you call a method from a variable in ASP Classic?

For example, how can I run me.test below?
myvar = 'test'
me.myvar
ASP looks for the method "myvar" and doesn't find it. In PHP I could simply say $me->$myvar but ASP's syntax doesn't distinguish between variables and methods. Suggestions?
Closely related to this, is there a method_exists function in ASP Classic?
Thanks in advance!
EDIT: I'm writing a validation class and would like to call a list of methods via a pipe delimited string.
So for example, to validate a name field, I'd call:
validate("required|min_length(3)|max_length(100)|alphanumeric")
I like the idea of having a single line that shows all the ways a given field is being validated. And each pipe delimited section of the string is the name of a method.
If you have suggestions for a better setup, I'm all ears!
You can achieve this in VBScript by using the GetRef function:-
Function Test(val)
Test = val & " has been tested"
End Function
Dim myvar : myvar = "Test"
Dim x : Set x = GetRef(myvar)
Response.Write x("Thing")
Will send "Thing has been tested" to the client.
So here is your validate requirement using GetRef:-
validate("Hello World", "min_length(3)|max_length(10)|alphanumeric")
Function required(val)
required = val <> Empty
End Function
Function min_length(val, params)
min_length = Len(val) >= CInt(params(0))
End Function
Function max_length(val, params)
max_length = Len(val) <= CInt(params(0))
End Function
Function alphanumeric(val)
Dim rgx : Set rgx = New RegExp
rgx.Pattern = "^[A-Za-z0-9]+$"
alphanumeric = rgx.Test(val)
End Function
Function validate(val, criterion)
Dim arrCriterion : arrCriterion = Split(criterion, "|")
Dim criteria
validate = True
For Each criteria in arrCriterion
Dim paramListPos : paramListPos = InStr(criteria, "(")
If paramListPos = 0 Then
validate = GetRef(criteria)(val)
Else
Dim paramList
paramList = Split(Mid(criteria, paramListPos + 1, Len(criteria) - paramListPos - 1), ",")
criteria = Left(criteria, paramListPos - 1)
validate = GetRef(criteria)(val, paramList)
End If
If Not validate Then Exit For
Next
End Function
Having provided this I have to say though that if you are familiar with PHP then JScript would be a better choice on the server. In Javascript you can call a method like this:-
function test(val) { return val + " has been tested"; )
var myvar = "test"
Response.Write(this[myvar]("Thing"))
If you are talking about VBScript, it doesn't have that kind of functionality. (at least not to my knowledge) I might attempt it like this :
Select myvar
case "test":
test
case "anotherSub":
anotherSub
else
defaultSub
end select
It's been a while since I wrote VBScript (thank god), so I'm not sure how good my syntax is.
EDIT-Another strategy
Personally, I would do the above, for security reasons. But if you absolutely do not like it, then you may want to try using different languages on your page. I have in the past used both Javascript AND VBScript on my Classic ASP pages (both server side), and was able to call functions declared in the other language from my current language. This came in especially handy when I wanted to do something with Regular Expressions, but was in VBScript.
You can try something like
<script language="vbscript" runat="server">
MyJavascriptEval myvar
</script>
<script language="javascript" runat="server">
function MyJavascriptEval( myExpression)
{
eval(myExpression);
}
/* OR
function MyJavascriptEval( myExpression)
{
var f = new Function(myExpression);
f();
}
*/
</script>
I didn't test this in a classic ASP page, but I think it's close enough that it will work with minor tweaks.
Use the "Execute" statement in ASP/VBScript.
Execute "Response.Write ""hello world"""
PHP's ability to dynamically call or create functions are hacks that lead to poor programming practices. You need to explain what you're trying to accomplish (not how) and learn the correct way to code.
Just because you can do something, doesn't make it right or a good idea.
ASP does not support late binding in this manner. What are you trying to do, in a larger sense? Explain that, and someone can show you how to accomplish it in asp.
Additionally, you might consider "objectifying" the validation functionality. Making classes is possible (though not widely used) in VB Script.
<%
Class User
' declare private class variable
Private m_userName
' declare the property
Public Property Get UserName
UserName = m_userName
End Property
Public Property Let UserName (strUserName)
m_userName = strUserName
End Property
' declare and define the method
Sub DisplayUserName
Response.Write UserName
End Sub
End Class
%>

How do I traverse a collection in classic ASP?

I want to be able to do:
For Each thing In things
End For
CLASSIC ASP - NOT .NET!
Something like this?
dim cars(2),x
cars(0)="Volvo"
cars(1)="Saab"
cars(2)="BMW"
For Each x in cars
response.write(x & "<br />")
Next
See www.w3schools.com.
If you want to associate keys and values use a dictionary object instead:
Dim objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.Add "Name", "Scott"
objDictionary.Add "Age", "20"
if objDictionary.Exists("Name") then
' Do something
else
' Do something else
end if
Whatever your [things] are need to be written outside of VBScript.
In VB6, you can write a Custom Collection class, then you'll need to compile to an ActiveX DLL and register it on your webserver to access it.
The closest you are going to get is using a Dictionary (as mentioned by Pacifika)
Dim objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.CompareMode = vbTextCompare 'makes the keys case insensitive'
objDictionary.Add "Name", "Scott"
objDictionary.Add "Age", "20"
But I loop through my dictionaries like a collection
For Each Entry In objDictionary
Response.write objDictionary(Entry) & "<br />"
Next
You can loop through the entire dictionary this way writing out the values which would look like this:
Scott
20
You can also do this
For Each Entry In objDictionary
Response.write Entry & ": " & objDictionary(Entry) & "<br />"
Next
Which would produce
Name: Scott
Age: 20
One approach I've used before is to use a property of the collection that returns an array, which can be iterated over.
Class MyCollection
Public Property Get Items
Items = ReturnItemsAsAnArray()
End Property
...
End Class
Iterate like:
Set things = New MyCollection
For Each thing in things.Items
...
Next
As Brett said, its better to use a vb component to create collections. Dictionary objects are not very commonly used in ASP unless for specific need based applications.
Be VERY carefully on using VB Script Dictionary Object!
Just discover this "autovivication" thing, native on this object: http://en.wikipedia.org/wiki/Autovivification
So, when you need to compare values, NEVER use a boolen comparison like:
If objDic.Item("varName") <> "" Then...
This will automatically add the key "varName" to the dictionary (if it doesn't exist, with an empty value) , in order to carry on evaluating the boolean expression.
If needed, use instead If objDic.Exists("varName").
Just spend a few days knocking walls, with this Microsoft "feature"...
vbscript-dictionary-object-creating-a-key-which-never-existed-but-present-in-another-object

Resources