<% Option Explicit ' If this is your first time here, read the instructions after the configuration ' variables, just setting the conf. variables below might not be enough. ' See "Instructions" further down... ' ******* Configuration Variables ******** Dim fitAddress, fitPath ' * fitAddress: location of the Fast IssueTrack server. ' It's almost certainly the address below - unless you've changed the port... ' Put here your fit server url. PLEASE don't put any folders in this URL! ' oportunity to do this below. Don't add a trailing slash either. ' examples: ' If it's running on the same machine as IIS: fitAddress = "http://127.0.0.1:10000" ' If it's running on a different machine behind your firewall (put the ' apporopriate IP address / port...: 'fitAddress = "http://192.168.0.100:10000" ' The following should be your virtual host directory under IIS: ' If our virtual host is under the "test" directory: fitPath = "/test" ' * Advanced configuration variables Dim forceProtocol, forceHost, forcePort ' CJ: Probably best not to touch these... ' * forceXXX: force the values of where Zope will pretend to be ' These variables should be used when you need to use a load ' balancer, accelerator or other reverse proxy in front of IIS ' that doesn't forward, for instance, the "Host:" variable correctly. ' In this case, this script would guess wrong values for where ' Zope is pretending to be located. LEAVE THEM AS EMPTY STRINGS ' IF YOU WANT THIS SCRIPT TO GUESS THE VALUES FOR ITSELF (RECOMENDED) ' examples: ' forceProtocol = "https" ' forceHost = "accelerator.example.com" ' forcePort = "81" forceProtocol = "" forceHost = "" forcePort = "" ' * Really Advanced "DON'T TOUCH THIS UNLESS YOU ABSOLUTELY KNOW WHAT ' YOU'RE DOING" variables Dim WinHTTPProgID ' * WinHTTPProgID: The ProgID of the WinHTTP Request object, used to make ' HTTP requests on server side components. This should be ' "WinHttp.WinHttpRequest.5.1" unless you have WinNT 4, in which case you ' have to install the WinHTTP 5.0 component (google for 'download winhttp ' msdn', without the quotes) and change WinHTTPProgID to ' "WinHttp.WinHttpRequest.5". Since MS intends to discontinue the ' distribution of this component, WinNT4 users won't have where to go, ' unless we start distributing it, which we don't intend to. WinHTTPProgID = "WinHttp.WinHttpRequest.5.1" ' ******** End of configuration variables ******** ' ******** Instructions ******** ' * Add a Virtual Host Monster to the root of your Zope, if you don't ' already have one. Any id will do. Don't bother configuring it. ' ' * Put the address of the server in the fitAddress variable as ' documented above ' ' * Put the path to the virtual host folder ' ' * Put this file in the IIS folder you want to serve FIT from, e.g. ' if you want to serve FIT from the root of the IIS server, you ' should put this file in the C:\Inetpub\wwwroot folder. If you ' want to serve FIT from, say "http://iis.server/someFolder", ' you should put it in C:\Inetpub\wwwroot\someFolder. ' ' * Open the IIS Manager (in Win2k it's in "Control Panel -> ' Administrative Tools -> Internet Services Manager"). ' ' * If you want to serve fit from IIS root, right click "Default Web ' Site", otherwise right click the folder you want to serve FIT ' from, and choose "Properties". ' ' * In the "Custom Errors" tab, scroll down to find error 404, click ' "Edit Properties", choose "URL" in the "Message Type" drop down ' and type "/default.asp", if you want to serve FIT from IIS root, ' or "/someFolder/default.asp" if you want to serve FIT from ' "http://iis.serve/someFolder/" ' ' * Repeat the above for the 405 error ' ' * Make sure you've got "Default.asp" in the "Documents" tab ' ' * Enjoy! ' ' How it works: ' ' You define this page as the error handler for Not Found errors (404 ' and 405). 404 is a GET not found and 405 is a POST not found ' IIS does NOT send back the 404 header initially, but rather ' it passes the handling off to this page. This is not well-documented ' and somewhat non-standard, but very useful. ' The originally requested page headers and request parameters are ' extracted and then reformulated into a new request to the FIT server ' which can be on the same machine or even somewhere else ' The request is made via HTTP and the result returned to the client ' as if it came from this server. ' ' If you're browsing directly at the folder were you put this file ' the process is a little different, but the result is the same. ' Look below if you want details ' ******** End of instructions ******** ' ******** Copyright and License Info ******** ' This file is an edited version of the default.asp script from the ' Zope folks and the following individuals/organizations below... ' - Chris Justus - Alcea Technologies Inc 2003. ' Copyright Hiperlogica Informatica e Educacao Ltda, ' January 2003 ' This file is an almost complete rewrite of Andy McKay's error.asp ' found at http://www.fbt.org/Members/andym/ASP404 ' Copyright Andy McKay ' February 2002 ' ' Andy's error.asp is a modification of the ' on found at http://www.wc.cc.va.us/dtod/fbt/ ' from David Carter Tod. ' No Copyright information ' This file is licensed under the ZPL Version 2 ' http://www.fbt.org/Resources/ZPL ' ******** End copyright and License Info ******** ' The modified Zope code below... ' Not actually comments made by Alcea / CJ for the most part unless marked CJ Class RequestInfo ' Convenience placeholder for request information '"http" or "https" Dim protocol ' IIS server hostname, as seen in the browser url Dim host ' http port as a string, usually "80" Dim port ' the path and query-string part of the url Dim url ' path to the folder this script is in, with trailing slash Dim iisPath ' the parts of the above array Dim iisPathArray ' the above path with "_vh_" prefix in each step ' as needed by the Virtual Host Monster, with trailing slash Dim vhmIISPath Sub Class_Initialize ' Misnomer, it should be Instance_Initialize, but what does MS know? host = split(Request.ServerVariables("HTTP_HOST"),":")(0) ' why am I splitting?! because IIS puts, say, a ":81" at the end of the HTTP_HOST variable ' if SERVER_PORT is not 80 ' Why don't I use it to get the port variable below?! because they don't put :80 if it's 80 ' and I need it there! ' Gotta love MS consistency... ' Why am I using HTTP_HOST instead of SERVER_NAME? because HTTP_HOST comes from the ' browser, so I can be sure that urls generated with it can actually reach us. ' And why am I using this instead of the servername from the query string? because I don't ' trust it. It doesn't come with the port number when it's not :80, so it's definetly assembled. ' The HTTP_HOST variable comes straight from the browser. iisPath = Request.serverVariables("PATH_INFO") ' "/some/path/error.asp -> "/some/path" ' or "/error.asp" -> "" iisPath = left(iisPath, inStrRev(iisPath, "/") - 1) '"/some/path" -> ["some", "path"] or '"" -> [] iisPathArray = split(mid(iisPath, 2),"/") '"/some/path" -> "/some/path/" or '"" -> "/" iisPath = iisPath & "/" vhmIISPath = "/" Dim name For Each name in iisPathArray vhmIISPath = vhmIISPath & "_vh_" & name & "/" Next port = Request.ServerVariables("SERVER_PORT") protocol = "http" If Request.ServerVariables("HTTPS") <> "off" Then protocol = "https" End If Dim fullQuery fullQuery = Request.ServerVariables("QUERY_STRING") 'Response.write("URL1: " & fullQuery & "
") If fullQuery = "" Then ' We're in directory-listing-mode, and the imbecile IIS doesn't give us anything on QUERY_STRING. ' Let's fake one fullQuery = "http://server" & iisPath Else ' "404;http://iis.server/some/path?some=querystring" -> "http://iis.server/some/path?some=querystring" if ( InStr(fullQuery,";") <> 0) Then fullQuery = split(fullQuery,";",2)(1) End If End If ' "http://iis.server/some/path?some=querystring" -> ["http", "", "iis.server", "some/path?some=querystring"] 'CJ - FIT logic is different - serves all sorts of content... ' this makes things abit more flexible... if (InStr(fullQuery,"http") <> 0) Then url = "/" & split(fullQuery, "/", 4)(3) Else url = fitPath & "/?" & fullQuery End If 'Response.write("URL: " & url) 'Response.end End Sub End Class Sub copyHeadersFromBrowser(fitServer) ' copy request headers from the Request object to the WinHTTP object ' removing a few unwanted ones dim bValidHeader dim hLine, hPair, hName, hValue for each hLine in split(Request.ServerVariables("ALL_RAW"), vbnewline) bValidHeader = true if trim(hLine) <> "" then hPair=split(hLine, ":", 2) hName=hPair(0) hValue=trim(hPair(1)) Dim lhName lhName = LCase(hName) if lhName = "if-modified-since" then ' the presence of this header is causing slowdowns and ' timeouts with IE 5+ on Windos and Mac. Other browsers ' seem unaffected. We need to explore this further. bValidHeader = false end if if lhName = "host" then bValidHeader = false end if if hValue = "" then bValidHeader = false end if if bValidHeader then fitServer.setRequestHeader hName, hValue end if end if next End Sub Sub copyHeadersToBrowser(fitServer) ' copy response headers from the WinHTTP object to the Request object ' removing a few unwanted ones dim bValidHeader dim hLine, hPair, hName, hValue for each hLine in split(fitServer.getallResponseHeaders(), vbnewline) bValidHeader = true if trim(hLine) <> "" then hPair=split(hLine, ":", 2) hName=hPair(0) hValue=trim(hPair(1)) ' Response.addHeader only adds headers. it doesn't replace them ' so we remove the ones that would duplicate Dim lhName lhName = LCase(hName) if lhName = "server" then 'we pretend we are IIS of the Borg bValidHeader = false end if if lhName = "content-type" then ' there's a specific function to set Content-Type: Response.ContentType = hValue bValidHeader = false end if if lhName = "cache-control" then ' ditto for Cache-Control: Response.CacheControl = hValue bValidHeader = false end if if lhName = "expires" then ' ditto for Expires: 'Response.ExpiresAbsolute = hValue bValidHeader = false end if if lhName = "content-length" then ' let IIS figure out this one for itself bValidHeader = false end if if lhName = "date" then ' ditto bValidHeader = false end if if bValidHeader then Response.addheader hName, hValue end if end if next End Sub Sub debugShowServerVariables ' print all variables in ServerVariables. Useful for writing or ' debugging this script Dim strKey Dim line For Each strKey In Request.ServerVariables Response.Write("
" & strKey & "
") Next End Sub Function getStatusLine(fitServer) ' assemble the HTTP status line from the response, ' something like "200 OK" or "404 Not Found" getStatusLine = fitServer.status & " " & fitServer.statusText End Function Sub debugShowZopeResponse(fitServer) Response.Write("
Status: " & getStatusLine(fitServer) & "
") End Sub Response.buffer=true ' *** The magic begins *** ' show all server variables ' debugShowServerVariables ' Response.end ' First let's gather some info from our environment Dim reqInfo set reqInfo = new RequestInfo ' Ok, let's put together the request that goes to the server ' the Virtual Host Monster url Dim vhmURL vhmURL = fitAddress ' This should look like the ProxyPass or RewriteRule URL in an Apache+VHM configuration 'Response.Write("

" & vhmURL & "

") Dim browserRequest browserRequest = reqInfo.url Dim fitRequest fitRequest = vhmURL & browserRequest 'Response.Write("

" & fitRequest & "

") ' Now that we know who to call, lets pick up the phone ' WinHTTPRequest options: Const WinHttpRequestOption_UserAgentString = 0 Const WinHttpRequestOption_URL = 1 Const WinHttpRequestOption_URLCodePage = 2 Const WinHttpRequestOption_EscapePercentInURL = 3 Const WinHttpRequestOption_SslErrorIgnoreFlags = 4 Const WinHttpRequestOption_SelectCertificate = 5 Const WinHttpRequestOption_EnableRedirects = 6 Const WinHttpRequestOption_UrlEscapeDisable = 7 Const WinHttpRequestOption_UrlEscapeDisableQuery = 8 Const WinHttpRequestOption_SecureProtocols = 9 Const WinHttpRequestOption_EnableTracing = 10 Dim fitServer Dim try For try = 1 To 10 Set fitServer = Server.CreateObject(WinHTTPProgID) ' WinHTTPRequest object 'we don't want it following redirects for us 'we want the browser to follow redirects for itself fitServer.Option(WinHttpRequestOption_EnableRedirects) = False fitServer.Open Request.ServerVariables("REQUEST_METHOD"), fitRequest, False ' Send any pertinent request headers copyHeadersFromBrowser fitServer ' Pass the POST data, in case it exists Dim binaryData binaryData = Request.binaryRead(Request.totalBytes) On Error Resume Next fitServer.send(binaryData) If Err = 0 Then Exit For 'This gives you the error if you want it 'Response.write(Err.Description) End If Next ' uncomment this to see Zope response headers 'debugShowZopeResponse fitServer ' get the status line Response.Status = getStatusLine(fitServer) ' and all other response headers except a few unwanted ones copyHeadersToBrowser fitServer ' Finally, we send the body, unless we're in a redirect If not (fitServer.Status >= 300 and fitServer.Status < 400) Then Response.BinaryWrite(fitServer.responseBody) end if Response.end %>