Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Apache and ScriptMaps - It's killing me!


:P
On this page:

Whenever I think I finally figured out one of the cryptic configuration settings Apache laughs at me yet again with a nice big fat "Gotcha sucka!".

I've struggled through all sorts of bullshit to get scriptmapping to work with Apache. So today I'm putting the final touches on an installation routine that installs a set of scriptmaps. I've tested this setup routine with a few different scenarios and it's worked just fine. Now though for the actual final installation in the application I need this to work and just won't cooperate and I'm starting to see double as I can't figure out why.

After a lot of tinkering I finally figured out that the order of the ScriptAliasMatch and the AddType extension mapping is vital. So if I have this set up like this:


Alias /wconnect/ "C:/Program Files/Apache2.2/htdocs/wconnect/"

<directory "C:/Program Files/Apache2.2/htdocs/wconnect/">
DirectoryIndex default.htm
Options ExecCGI
AddHandler webconnection-isapi-handler dll

AddType application/webconnection-scriptmap-wc .ap .wwd .wc .wcs .wcsx .wwsoap .blog .pho .wwr .wwt
Action application/webconnection-scriptmap-wc
"/wconnect/bin/wc.dll"
</directory>

ScriptAliasMatch (?i)^/wconnect/.*.(ap|wwd|wc|wcs|wcsx|wwsoap|blog|pho|wwr|wwt)$
"C:\Program Files\Apache2.2\htdocs\wconnect\bin\wc.dll"

it doesn't work. Apparently when AddType is hit and no matching file is found on disk for the request Apache gives a NOT FOUND response and never moves any further down the hierarchy for looking for files.

Now I can move the ScriptAlias before the <directory> tag and the AddType and then it DOES work in firing my request at least:


Alias /wconnect/ "C:/Program Files/Apache2.2/htdocs/wconnect/"

ScriptAliasMatch (?i)^/wconnect/.*.(ap|wwd|wc|wcs|wcsx|wwsoap|blog|pho|wwr|wwt)$
"C:\Program Files\Apache2.2\htdocs\wconnect\bin\wc.dll"

<directory "C:/Program Files/Apache2.2/htdocs/wconnect/">
DirectoryIndex default.htm
Options ExecCGI
AddHandler webconnection-isapi-handler dll

AddType application/webconnection-scriptmap-wc .ap .wwd .wc .wcs .wcsx .wwsoap .blog .pho .wwr .wwt
Action application/webconnection-scriptmap-wc
"/wconnect/bin/wc.dll"
</directory>

The problem with this arrangement is that in the latter scenario the ScriptAliasMatch is ALWAYS used and the real problem is that Apache blows away the physical path in the process.

When a ScriptAliasMatch is applied the physical path is mapped to the Executable (ie. c:\program files\...\bin\wconnect\wc.dll) and the original reference to the file is lost. There's a LOGICAL PATH, but no physical path that can establish the original file on disk that was actually requested.

AddType routed requests on the other correctly return the physical path for a file, but because of the way this ordering works

So...

Really what this all comes down to is consistency. What I need is to be able to ALWAYS retrieve the Physical Path.

I already have a custom Module that fixes up various Apache'isms to work more like IIS. However, I have not been able to figure out how to do Path Mapping with the Apache APIs. My code is based off Mod_ISAPI and in an ISAPI extension you can typically call ServerSupportFunction and ask for HSE_MAP_PATH to do a virtual to physical mapping. Unfortunately Apache returns the physical path to the DLL as above which for IIS based ISAPI is the wrong thing (IIS returns the original mapped path regardless of whether the request was remapped to a different handler).

In ASP.NET or ASP this sort of thing would be as easy as Server.MapPath( Request.ServerVariables["Logical_Path"]).

I suspect Apache has something similar in its core API but after digging through reams of source I'm not having any luck finding it.

Any Apache experts out there? Is there a way to do path mapping even if the requested file doesn't exist?

Looking around it also seems that there's next to no documentation on the Apache internal server APIs. Nor is there a public forum - only mailing lists. Is there some place where Apache developers that deal with lower level issues hang out? If so they're not easy to find <s>...

Any help greatly appreciated...

Posted in Web Connection  

The Voices of Reason


 

# DotNetSlackers: Apache and ScriptMaps - It's killing me!


Rick Strahl
June 25, 2007

# re: Apache and ScriptMaps - It's killing me!

After some more experimentation I finally ended up hacking together a custom path mapping routine with Apache in my modified ISAPI module.

Apache supports calling ServerSupportFunction() with an empty path input which causes Apache to return the the path physical path of the current request either as a path or if there's a default document applied with the default document. My code basically looks at this path strips the file path if there is any and then stores this path into the Path_Translated variable which passes forward properly to the ISAPI extension. So now I can get a reliable reading of PATH_TRANSLATED as far as I can tell.

// *** RAS 
// Override to fix up the PATH_TRANSLATED to the physical path
// lpszPathTranslated won't be set at this point when redirected
if (cid->ecb->lpszPathTranslated == NULL)
{
    strcpy(pathInfo,"");
    ServerSupportFunction(cid,HSE_REQ_MAP_URL_TO_PATH,pathInfo,&bufSize,NULL);
    
    // get path for the retrieved path
    if ( pathInfo[strlen(pathInfo)-1] != '\\')
    {
        // *** Strip off filename
        pos = strrchr(pathInfo,'\\');
        if (pos)
        {
            *pos = '\0';    
            strcat(pathInfo,"\\");
        }
    }

    // *** Get just the script name
    strcpy(scriptName,r->uri);
    if ( scriptName[strlen(scriptName)-1] == '\\' )
        strcpy(scriptName,"");
    else
    {
        pos = strrchr(scriptName,'/');
        pos++;
        strcpy(scriptName,pos);
    }
    
    strcat(pathInfo,scriptName);        
    cid->ecb->lpszPathTranslated = pathInfo;
}
// *** RAS


It's ugly and there may be a more direct way to do this in Apache, but this works with all combinations of URLs I threw at it.

This code works with Apache for Windows 2.2 and can be added to the bottom of the mod-isapi module code after the ecb is set up. It also works with Apache 2.0 modules although a couple of changes are required to make up for the / slashes in the physical path returned.

Hope this helps out somebody.

Joe Brinkman
June 26, 2007

# re: Apache and ScriptMaps - It's killing me!

It is easy to see now why Linux is set to take over the Desktop... NOT! This is typical of my experience with all things in the Linux and Java camps. Lots and lots of cryptic config files. And just think, as .Net continues to evolve we get these same solutions for our apps. Just wonderful.

Rick Strahl
June 26, 2007

# re: Apache and ScriptMaps - It's killing me!

Joe, I try not to be biased, but truthfully I feel the same way. But also to be fair there are many things on Windows that require configuration in ways that are anything but clear as well. One look at a web.config file that has MS Ajax extensions enabled is a good way to get lost <s>...

But what really bugs me about this particular episode is that there's so little easily discoverable content related to these topics. Apache is supposedly the most used Web Server but if you search for specific configuration or worse development related information relatively little information comes up. There's no real consolidated community either - crap is scattered all over the place. It takes a few minutes to find a qualified forum for just about any Microsoft technology and to get an answer to what (in the above case) should be a simple question is probably answered in a matter of an hour.

Steve from Pleasant Hill
June 26, 2007

# re: Apache and ScriptMaps - It's killing me!

It may be a function of the size of the web and search engine characteristics. I search for stuff today that I used to be able to find in minutes. I see the same post on multiple sites, etc. I "know" it's out there but search engines seem to pull up everyone else's confusion rather than the answer.

Six months ago I found a site that did a better job of Windows updates because MS updates would not install. A beautiful site. Cannot find the damn thing now (like a dumb-a@@ I didn't bookmark it).

Rick Strahl
June 26, 2007

# re: Apache and ScriptMaps - It's killing me!

That may be true for some things but not for very focused search. For example, I ran a few searches on specific Apache server API function calls. All the links that showed up where Chinese - all 5 of them.

These means that a) there's no public documentation at Apache of these API calls (pitiful) and b) that there hasn't been much public discussion of these API calls. These are sure not uncommon API's either as they relate to resolving Uris and will be used frequently in any Apache custom code.

As much as I often lament Microsoft Documentation as being inadequate it's very rare that you can't find ANY information on an API call in the huge pile of APIs Microsoft has. It just doesn't happen.

I guess the code's the documentation - all 90 projects of it... oh and if it would actually compile without having to fix half the projects due to invalid pre-compiler strings <s>...

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2019