3

This is classic ASP, running on IIS 8.5.

I need to run some VBScript that should be common to all my *.asp pages at the beginning of every Http request to those *.asp files.

Currently I am using a #include tag at the top of each and every *.asp file. I reference a file that contains the code that I want to run.

It does the trick, but it's ugly and dangerous: if one of the *.asp files happens to miss the #include tag, the code will not run.

Is there a way to make some code run for every *.asp request, without having to write code inside every *.asp file?

In ASP.NET we have the HttpApplication.BeginRequest event. What I'm looking for is something equivalent to that, but in Classic ASP. I need to run some VBScript that is able to access the Classic ASP objects at the beginning of every *.asp request.

Edit: as per @Kul-Tigin request, this is the reason that I want to do it: My *.asp files are encoded in ANSI. But the URL requests comes encoded in UTF-8, which generate problems.

If I do nothing, the ASP engine decodes the url (and query strings) as if they were in ANSI. For instance: a query string ?value=ç will be sent by the browser as ?value=%C3%A7. C3A7 are the bytes for 'ç' encoded in UTF-8. But the ASP engine reads the 2 bytes as 2 separate ANSI chars. So, if I do nothing, the Request.QueryString("value") will be a string with length 2, with the content "ç".

To fix this, I created the following workaround, which WORKS:

Sub Workaround()
    Response.CodePage = 65001 ' Temporarally set the Response CodePage to UTF-8. Originally it was 1252 (ANSI).
    Dim foo
    foo = Request.QueryString("foo") 'ASP engine uses the Response.CodePage to decode the querystring
    Response.CodePage = 1252 ' Set the Response CodePage back to ANSI.
End Sub
Workaround()

I don't care about the "foo" query string, it may not even exist. I just do that to "touch" the ASP Query String deserialization engine. Aparently it decodes the all the query string values at the first time it is used during the request processing. So, even after setting the CodePage back to 1252, in my previous example, if I read the concrete query string Request.QueryString("value") it will be a length 1 string containing "ç", as intented.

I have put the workaround code in a workaround.inc file, and have included it at the beginning of most of my *.asp files, which solved the problem for now. But there are more than a thousand *.asp files, and more yet to be developed. It's impossible to make sure all of them are including the workaround.inc, that's why I wanted to run the code for all *.asp requests regardless of an include tag.

I appreciate your concern for my problem. If you can present a better solution I would be really happy. Thank you!

  • 1
    There isn't a lot of options apart from `#include` files except may be building your own HttpHandler and registering it with IIS. See [Http handler for classic ASP application for introducing a layer between client and server](http://softwareengineering.stackexchange.com/q/154102/131815). – user692942 Nov 29 '16 at 00:31
  • Sounds like a logger? It could be done by using a [Custom HTTP Module](https://msdn.microsoft.com/en-us/library/ms227673.aspx) (written in .NET) under an application pool with integrated pipeline. There may also be other ways, so I should ask. Which specific ASP objects are you planning to access? – Kul-Tigin Nov 29 '16 at 00:42
  • @Kul-Tigin It's not a logger. I need to access the 'Request' and 'Response' ASP objects. The reason for this is that I need to run a workaround code to handle requests with querystrings that are encoded in UTF-8 while my *.asp files are in ANSI. If I don't do nothing, the classic asp engine reads the 2 byte utf-8 single chars as 2 distinct ANSI characters. It reads correctly for the rest of the page if at the beginning I just set 'Response.CodePage = 65001' (utf-8), read a random querystring, and then set the 'Response.CodePage' back to it's original value. – Eduardo de Souza Cruz Nov 29 '16 at 11:58
  • 1
    I understood the concept about query string and the codepage. Could you give an example of the workaround that you want to work with each request, I mean the ASP code? You can update the question. I believe we can find a way to do it. – Kul-Tigin Nov 30 '16 at 03:37
  • @Kul-Tigin Thank you for your help, I have updated the question. – Eduardo de Souza Cruz Dec 01 '16 at 20:26
  • Sorry for late answer. One last question. What's the scope of `foo`. Do you need to access it in your whole application? I have a suggestion so I'm trying to make sure whether it's suitable for you. – Kul-Tigin Dec 05 '16 at 22:41
  • @Kul-Tigin Hi, thanks again! The scope of `foo` is irrelevant. There is nothing in this query string, it doesn't even exist. The variable will never be used again. It is really a "foo". You may encapsulate my code in a `Sub Workaraoud() ... End Sub` and then call it. What matters is the call to `Request.QueryString("foo")`, which triggers the classic ASP query string decoding engine using the forced UTF-8 codepage. – Eduardo de Souza Cruz Dec 07 '16 at 00:34

2 Answers2

0

For simplicity I would use a common #include which in itself could #include other files based on page criteria.

Brian T
  • 98
  • 3
-1

In classic ASP you can have a global.asa file and use the 2 events for Application as well 2 for Session (across the application)

Application (where server starts/stops)

Session (when a user session is created and completed/unloaded)

http://www.w3schools.com/asp/asp_globalasa.asp

as well, per page, you can use onLoad and onUnload events

https://msdn.microsoft.com/en-us/library/ms952648.aspx

balexandre
  • 73,608
  • 45
  • 233
  • 342
  • 1
    None of the events in the `global.asa` will trigger per request and the reference to `Window_OnLoad()` is just plain wrong as its client-side code not server-side. Also the fact you use w3schools as a reference just fills me with disbelief. – user692942 Nov 29 '16 at 00:29
  • Also `Application` Events don't happen when the server stops and starts it's when the Web Application stops and starts which is controlled by the Application Pool and whatever recycling schedule is defined. – user692942 Nov 29 '16 at 00:38
  • @Lankymart for someone thats into developing, *server starts/stops* means APP Pool on/off ... really, you going to pick on semantics now? – balexandre Nov 30 '16 at 00:13
  • Does it really? That's a bit of a stretch to be honest. May be I know what you mean doesn't mean others who come across this answer will. However my main issue with this answer is the mixed messages about client / server event usage. – user692942 Nov 30 '16 at 00:22