I am using westwind 6.15
response.TransmitFile(this.oRequest.GetPhysicalPath(),[text/html] )
The command above works fine as long as the file I attempt to reach is in the root like: http://localhost/sumptuous.html but if it is in a subfolder off the root like: http://localhost/carpet/residential/sumptuous/sumptuous.html
I get the following error (NOTE: the folder path is DUPLICATED in the error message):
Unable to download file We were unable to send the requested file to the client. Could not find a part of the path 'C:\inetpub\wwwroot\carpet-wholesale\carpet\residential\sumptuous\carpet\residential\sumptuous\sumptuous.html'.
I have thoroughly stepped thru all of the code and it all seems to work perfectly. It creates this response file in the temp directory when the server is in file mode (note it has the correct file content length and file path and name):
HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 RequestId: 13_1ca464c6 Content-Length: 52252
WC_TRANSMITFILE: C:\inetpub\wwwroot\carpet-wholesale\carpet\residential\sumptuous\sumptuous.html
So it seems to be a problem outside of my compiled exe and inside the web handling mechanism. I get the same error when it is run in Com mode.
Thanks for all your great service Rick!
Not quite sure how that can happen - Are you using the .NET Module or ISAPI? If you're using ISAPI there are some restrictions on files that are served in that they have to be part of the Virtual Web folder of your application (which should be fine if you're using Request.GetPhysicalPath()
).
Either way when the filename is sent to the module/handler the filename is passed straight through to underlying platform APIs in both ISAPI and .NET. So if the file name gets mangled it's actually happening inside of the native APIs. However, I'm not sure why that would be.
The only thing I can think of is that the folder you're trying to get the file from actually lives in another separate Virtual directory/application and there's some file name fixup occurring to account for the separate virtual.
+++ Rick ---
Thanks Rick. I no longer use ISAPI on either my development machine or the live server.
On the live server, we do mount a drive as the carpet-wholesale folder in wwwroot, but we don't do anything unusual on my development machine and the problem exists on both.
Could it be something in the web.config like urlrewrite that causes it?
Ok so I took a look here on my local setup and I guess I'm not sure what you're actually doing to make this fail.
The following examples should demonstrate even though I'm not using the physical path, but that really shouldn't matter.
Both of these work for me (assuming the file exists):
FUNCTION Test()
* Response.TransmitFile("~/default.htm","text/plain")
Response.TransmitFile("~/wcscripts/customertable.wcs","text/plain")
ENDFUNC
* Test
Maybe try running running something like this explicitly to point at the file you're sending.
if the file doesn't exist, Web Connection actually throws an error before the request is passed on to the IIS handler. So if you get to the point of the wc_transmitfile
header in the output that should mean the file is valid and exists.
As to the fixup I really don't know - I can't imagine what would do that if the output in with wc_transmitfile
is correct. I can see how GetPhysicalPath()
may return an invalid result if you're virtuals are misconfigured but since the file name in the output appears to be valid that can't be the problem. You double checked, correct?
The module code (in C#) passes the raw value that's passed directly to Response.TransmitFile()
in the ASP.NET Apis and those in turn call straight down into IIS apis. TransmitFile is a raw low level API and it's not subject to redirection from the Web server because it deals with physical files on the drive, not URLs. By the time it's called the request is in its output stage.
So I'm not sure what could possibly be causing the path to get mangled.
+++ Rick ---
I just re-checked to make sure the wc_transmitfile was correct and it is.
I also tried creating the bogus directory it was looking in (because the error indicated it couldn't find part of the path) and that didn't change anything, but if I copy the file into that bogus directory and edit the content so I can tell which file it is returning, it will indeed deliver up the file in the bogus directory.
Entering the URL: http://localhost/t1/sumptuous5.html
returns the file located in: C:\inetpub\wwwroot\carpet-wholesale\t1\t1\sumptuous5.html
The file has to be in both places of course since webconnect verifies the file exists before it does the transmit.
I can just work around this so I don't use transmitfile anymore. So don't worry about it.
Thanks for all your help.
Well you can use Response.Write(FileToStr(Request.GetPhysicalPath()))
which will do the trick. It's just not as efficient as IIS serving (and caching and possibly compressing) the document.
Still puzzled what's happening there. When I get a chance I'll take a look at the .NET path to see whether I do any fix up but pretty damn sure I'm not - I don't see why I would change anything about the path that was passed in.
+++ Rick ---
Eddie -
Entering the URL: http://localhost/t1/sumptuous5.html
returns the file located in: C:\inetpub\wwwroot\carpet-wholesale\t1\t1\sumptuous5.html
Assuming that link is being served up directly from IIS (that is, the .html extension isn't mapped to be handled by the web app), I would check what is set as the root folder for your 'localhost' website, and the path of the 't1' virtual. Something in the IIS configuration has to be adding '\carpet-wholesale' and the extra '\t1' in the path.
Regarding the TransmitFile() call - are you running your Web Connection app directly on the webserver itself, or is it running on another machine separate from the webserver? The latter case requires some adjustments to specify the filename based on where the webserver would find it. I doubt this is your scenario, but thought I'd mention it.
- Mike McDonald
It is all being run on one machine.
The .HTML extension is being mapped at the root and not over-ridden anywhere down the path:
Westwind.WebConnection.WebconnectionHandler,WebConnectionModule
So I took a look at the how the DLL handles the path and sure enough there's some fix up happening. However, all it really does is stripp off the physical path and then let ASP.NET fix up the relative path.
So I'm thinking in your case you likely have multiple mappings to your folder or maybe a virtual inside of a virtual that's accounting for the double path fixup.
The behavior is really a legacy thing - ASP.NET 2.0 didn't allow physical paths in certain execution policy environments so only relative paths worked. In 4.0 this has been addressed so now any path can be passed so the code I have can probably be simplified quite a bit.
I made a few changes to webconnectionmodule.dll
and wwPageResponse.prg
that reflect this and you can pick it up in WebConnectionExperimental.zip. Basically Web Connection now passes the raw file you provide through - either as a physical path or the an IIS virtual path ~/folder/item.html
.
+++ Rick ---