Last post Mar 14, 2007 05:30 PM by alangrutter
Mar 06, 2007 09:02 PM|alangrutter|LINK
I have a HttpHandler that is acting as a reverse proxy. I've got it copying headers, cookies etc and it works fine for most pages I retrieve. One of the pages on the site that I am trying to access though does not load properly. It uses custom controls and
throws exceptions because the objects haven't been loaded.
I ran an Ethereal (Wireshark) trace for both a direct request and a request via the reverse proxy and I noticed that the request via the proxy does not seem to request any of the aspx files for the custom controls that are contained in @ Register directives,
however the direct request does. It is these files that contain the code for the objects on which exceptions get thrown.
(e.g. gifs, css and js)
Can anyone advise on how/where the @Register directive gets processed in the ASP.NET request/response chain. I am hoping someone out there knows what I might be doing wrong.
Mar 08, 2007 04:15 PM|Svante|LINK
There are few things that needs to be cleared up first, I think. You say that you have a HttpHandler acting as a reverse proxy "copying headers, cookies etc" - so presumably you're creating a System.Net.HttpWebRequest from the original request.
First question is where do the pages you're trying to access reside? If they are in the same app as your 'reverse proxy', you probably want to to URL Rewriting instead. If they're in a completely different site or server, you're probably on the right track.
Second question is you refer to "aspx" files for the "custom controls". This is confusing - user controls reside in "ascx" files, and custom controls in assemblies normally built from plain .cs files. Probably just a typo, but can you please clarify?
Third question is just to ensure that I've understood correctly - i.e. that your code does what I guess it does. If so, I can see no reasonable reason why a request via HttpWebRequest would differ from a direct request, except possibly for passing of credentials
etc. There's an issue with Windows Integrated authentication when you 'hop' to another server that causes problems - you need to set the server 'trusted for delegation'.
Mar 11, 2007 05:08 PM|alangrutter|LINK
Thanks for your response. Just to confirm, I am creating a HttpWebRequest from the original request, setting the correct headers, cookies etc.
The pages we are trying to access reside on a different site/server to where the reverse proxy handler is installed. The custom controls are in .ascx files, with the code .ascx.cs files. Sorry for the confusion.
I was wondering if I need a DLL containing the controls to be installed in the GAC or web.config on the server where the http handler is running. Additionally I do not know if simply passing the response through as binary is having any effect, since in other
It is only the stuff being referenced in @Register that does not seem to be requested.
Mar 11, 2007 05:42 PM|Svante|LINK
There's more to clear up. First of all, if the user control resides in a .ascx (plus .ascx.cs codebehind) it's not a custom control, it's a user control. Presumably you register this in the requested .aspx page something like this:
<% @register tagprefix=".." tagname=".." src="YourUserControl.ascx" %>
Now, you said initially that you saw requests "on the wire" for the .ascx files being registered in the .aspx when you accessed it directly, without the proxy? That does not make sense. The user controls are compiled dynamically, and the @register is just
way to refer to them in the .aspx. You do use a tagprefix, and you do use one != "asp"? That is essential, otherwise it won't find the compiled assembly and you get an exception.
To repeat, you're not supposed to see any requests for the things you @Register, so that's not the problem.
You do not need the assembly with the controls in the proxy. It should be on the server running the pages that refer to the controls.
If you're compiling the user controls into a separately deployed assembly, different from the one containing the .aspx pages, i.e. they're not part of the same assembly you need to write custom controls instead.
Is it possible that the src path given in the @Register prefix is absolute (begins with a '/'), and not correct for the site accessed via the proxy? I'm getting the feeling there's more differences than just the proxy when you access the site directly, which
according to your intial post does work. Can you think of anything else that differs? Perhaps it's really not quite the same site, perhaps development vs. production or something like that?
By the way, I'm assuming this is ASP.NET 2.0 ...
Mar 11, 2007 06:31 PM|anjelinio|LINK
Mar 11, 2007 09:22 PM|alangrutter|LINK
The HttpHandler is running on my local machine (server) talking to a remote server where the real pages are. So I call http://localhost and get redirected to http://someothersite. This works fine to a degree - I don't have problems with Google for example.
For the site we want it to work with, there are pages that use Infragistics controls. These are included in our aspx pages using the @Register directive. The controls themselves are .ascx files (with code behind) as previously mentioned.
When I use a packet sniffer (Wireshark), I see the correct page source and the code and script blocks inserted by the control. This is the same regardless whether I use a real request or go via the proxy. For a real request that goes direct to the site instead
which is why the page does not load correctly.
Mar 12, 2007 02:13 AM|Svante|LINK
It's not a problem with the user controls loading then, originally it sounded like there were exceptions on the remote server not being able to load the controls. Now it appears to work as far as the controls actually being loaded and even rendered to the
proxy, as well as the client.
This often happens when the HTML contains URLs which are absolute and refer to URLs which are not reachable from the client.
Consider for example the simple case of the remote server being accessed via different names from the proxy or from the client directly. From the client you might use
http://someothersite.com/.... while you might use
to the proxy, if the code rendering the HTML has the bad habit of emitting absolute URLs based on the incoming request or it's own knowledge of the server it's running on. The proxy then resends this to the client, ending up making a request to 192.168.0.1
which in all likelyhood is not reachable from the client. This is probably a too simple case, it depends on how you've configured your ethernet tracer what you actually see, the request may in fact be made but to an IP you're not configured to log for example.
More likely it's to a DNS name that's not resolvable from the client, or you're switching scheme from https to http for example in the proxy.
For a simple reverse proxy to work, all URLs coming from the real server must be relative, or depending on the situation root-relative (i.e.start with a slash, but no scheme or host). If it contains a scheme and host, the HTML going out must be rewritten,
otherwise you'll get situations like this. Other things that might not work is that links will go the the real server instead of the proxy when clicked.
proxying for a specific application, you're better off ensuring that no absolute URLs are sent to the requestor from the remote server.
Mar 12, 2007 06:41 PM|alangrutter|LINK
Thanks for your thoughts and suggestions.
Both my local machine and the target server are on our intranet, so I have access to both. What we want is to be able to access the servers externally via a gateway server (proxy) but our clients do not want to use ISA. Wireshark (Ethereal) is a packet sniffer
and shows all the packets/protocols on the network - I never see an HTTP request for the .js files - I would have thought I should, at the very least, see the request and maybe a 'File not found' error if the path was wrong. The URLs in the HTML/script which
the controls write are all root relative(begin with a slash).
Mar 13, 2007 02:26 AM|Svante|LINK
Well, there you are. The script files are root relative, and will thus be issued to your proxy by the client browser. You do handle .js-files in your proxy, right? I guess the sniffer is checking the communication between the proxy and the remote server,
not between the client and the proxy - or?
If the HTML is reaching the client browser, looks like it should, and contains the correct references to the .js-files there's not much that can go wrong :-) You should also flush the browser cache - once again, I recommed trying to run with IEWatch or Firebug,
this will give you a clear view of what's happening in the browser.
Mar 13, 2007 09:20 PM|alangrutter|LINK
I am probably being really dense or something, so the script files are root relative - the significance of this being precisely?
error, could not load file or assembly 'ReverseProxy' or one of its dependencies. The system cannot find the file specified.'
The URL is shown as http://localhost/ig_common/<filename> - so this will get remapped to http://<realhost>/ig_common/<filename> in the outgoing request from the proxy.
Mar 14, 2007 02:07 AM|Svante|LINK
What I mean is that since they are root-relative, the client browser will send the request for the .js-file to the reverse proxy. This means that the reverse proxy must handle the .js-file. Are you sure that the request for the .js-file actually reaches
the reverse proxy code, for remapping and retransmission to <realhost>? Your typical IIS installation will not map .js-files to ASP.NET, IIS will just serve the files directly to the client.
There must be something else in play though, the error message you describe does not seem quite right for that scenario, you should get a simple 404 if that's the direct cause. Just where does the string 'ReverseProxy' come from in the request? Is it part
of the URL sent for the .js-file request, i.e. a subdirectory, or what?
Can you also please confirm that the sniffer previously listened to the traffic between the reverse proxy and <realhost>, since I seem to recall that you said you could not see the request for .js-files at all - but from what you say now it does sound like
the request is issued.
Also (you may have mentioned before, but I can't see the full thread right now) can you confirm that in this setup, you're running the reverse proxy on the same system as the client browser? I.e. there are only two machines involved, presumably your development
machine and the <realhost>.
Finally, since if you have not configured the reverse proxy IIS to handle .js, can you confirm that you've not changed the 404-handler on the reverse proxy system. A possible cause for the above would be that the request for the .js-files is sent to the
reverse proxy, which does not have IIS configured to handle .js-files, which thus gets a 404, which makes IIS invoke the 404-page - and if that page in turn does not work you could get such a situation. You could try to send a request manually from your browser
for a file that is not mapped to IIS, such as .html to the reverse proxy and see if you get the same error response.
Mar 14, 2007 04:09 PM|alangrutter|LINK
You are correct in that there are only two machines involved, my development machine (which is running IIS, Reverse Proxy HttpHandler and the client browser) and the real server where the pages etc are actually located.
IIS has been configured with a wildcard application map to .NET 2.0 aspnet_isapi.dll.
Mar 14, 2007 04:42 PM|Svante|LINK
So, you you see the .aspx request-page being correctly forwarded, and content returned to the browser, both in firebug, and with the packet sniffer. But, the subsequent requests for .js-files fail with a 500-error.
- Have you unchecked the 'check that file exists' checkbox in the wildcard application map? If not, it might be the case that the .aspx-file actually exist on the expected path (since it's your development system), but the .js-files do not.
- When debugging or logging your reverse proxy, can you see if the .js-requests ever reach your code? The point being to determine if the error occurrs in your code, or if it never gets the chance to execute.
- What happens if you type exactly the same URL to one of the .js-files in the browser adress bar? Do you get the same 500-error?
- Since you're using a HttpHandler (not a HttpModule, right?) you must also remap in Web.Config, the <httpHandlers> section. Is that done? In your case I guess you need to <clear /> the list, and <add ... /> "*" to map to your HttpHandler. I don't quite
see how you could get anything working if this is not done, but...
- If I understand it correctly, the actual target site is also developed by you. If so, have you ensured that there's no risk of accessing a local copy of the remote target site on your development machine? That could confuse things a bit...
Mar 14, 2007 05:24 PM|alangrutter|LINK
The 'check file exists' checkbox is unchecked in the wildcard mapping. I put in logging into my application but I could not see any requests for the js files.
If i try to request the js file directly through the browser I get the following:
Line 9: <authentication mode="None"/>Line 10: <httpHandlers>Line 11: <add verb="*" path="*" type="ReverseProxy.ReverseProxy, ReverseProxy"/>Line 12: </httpHandlers>Line 13: <authorization>
My web.config contains the following
<add verb="*" path="*" type="ReverseProxy.ReverseProxy, ReverseProxy"/>
Mar 14, 2007 05:30 PM|alangrutter|LINK
I did have a local copy of the infragistics directories in my IIS configuration. I've removed these and now it works.
Many thanks for all your help and patience.
PS: Firebug is great!!