I'm building a simple reverse proxy to save me porting a low-usage but complex application to .net and it is slowly but surely driving me mad. All I need to do is have the proxy on Server1 forward all the requests to a local server, Server2 and then pass all
the responses directly back. I'm doing alright so far- I can do GET and POST requests and pass data back and forth, but when the page on Server2 sends a response.redirect Server1 interprets that as "make another get request to the same page". On Server2 I've
got code a bit like response.addCookie("MyCookie", "MyVal"); response.redirect("Page2.jsp");
but when I iterate my way through the response headers on my HttpWebResponse object and send them to the Trace it looks like this:
Header: Set-Cookie = JSESSIONID=DFD05A6799CE3C9D962761065FEF3ADF; Path=/myPath Header: Content-Type = text/html;charset=ISO-8859-1 Header: Content-Length = 636 1.414063 0.000054 Header: Date = Mon, 07 Mar 2005 17:47:03 GMT Header: Server = Apache-Coyote/1.1
Header: Connection = close Target uri: http://Server2/myPath/Page1.jsp I'm not expert in the use of these classes but it seems to me that there should be some more headers happening here- any idea what may have become of them?
Right, I've done a bit more investigating and worked out what is happening, approximately. The request is being redirected to Page2 but that page is checking for the value of the the "MyCookie" cookie and, upon not finding it, it is redirecting back to Page1.
What I'm doing is something like this: HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); } catch(System.Net.WebException we) { context.Trace.Write("Exception with response find: "+we.Message); context.Trace.Write("More
detail: "+we.StackTrace); return; } byte[] myBytes = new byte[1024]; int byteCount = 0; while( ( myBytes = receiveStream.Read( byteCount, 0, 1024 ) ) > 0 ) { context.Response.OutputStream.Write (myBytes, 0, byteCount ); } response.Close(); context.Response.End();
What seems to be happening is roughly this: request -- > Page1 response -- forwards to --> Page2 (checks cookie) -- forwards to --> Page1 --> response to browser Why are the intermediate responses not being passed back to the browser? Is there a way
to make them accessible to my code? Everything works correctly when I access the pages directly.
I am passing them through, yes. The problem appears to be that it is treating the request with the form data, the return with the cookies, the redirect to the second page and the redirect back to the first page as a single HttpResponse so the cookies don't
get added to the browser. So if we have page1 as our login page and page2 as our target page I'm getting something like this: Browser Form variables =====> Proxy =======> Page1 form handler .................................................. Proxy <=======
Page1 set cookies, redirect to Page 2 .................................................. Proxy =======> Page2 ask for browser cookies (fail) .................................................. Proxy <======= Page2 redirect to Page 1 ..................................................
Proxy =======> Page1 Browser <=============== Proxy <======= Page1 The browser never gets the cookies set because all the response redirects happen between the proxy and the pages. It comes back as a single integrated request. Is there a way to break it up
so I can add the cookies to my request object before it gets forwarded on?
Then the Proxy has to add the cookies to the Request passed to Page2 so that Page2 will see the cookies and do its thing... Is there any way you can restructure your calls so that you don't need to hit both Page1 and Page2 when coming from the browser?
Basically page1 is the authentication page and once the user is authenticated it should automatically redirect them to page2. I do still need the user to be authenticated and I don't really have time to rework the code on the other side of the proxy. What I
expected was that the request and response would behave in a more transparent way so that the redirect to page2 would be handed back to be browser which would ask the proxy for page2 on a new request, but that doesn't seem to be the case at all. I thought
I'd found the problem when I noticed there was an AllowAutoRedirect property I could set to false, on the HttpWebRequest object but that doesn't appear to have made a great difference. Given that all of the redirects are being followed automatically by the
request.GetResponse() call I guess I'm going to have to work out the response stream methods instead.
So I got it sorted in the end, but it was a rather inelegant fix.
Firstly I killed the response redirects so that when you authenticated the page showed you a response with a link to the homepage for authenticated users rather than trying to forward them.
I was still having problems logging in, though, and I discovered that although I had a "Set-Cookie" header it didn't register the contents of that as cookies. Not sure what was going on there. When I parsed the header manually and created cookies from it
that finally seemed to sort the problem out...
If you're working with HttpWebRequest/HttpWebResponse you need to add a simple extra steps to get cookies to work. To do this, you need to set an instance of a CookieContainer to the Request.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("..."); request.CookieContainer = new CookieContainer(); // add this line. ... HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Cookies ... // now works
Without an instance to the System.Net.CookieContainer, you won't be able to track cookies.
Thank you very much- that is the most useful response I have ever received on these forums. The annoying thing was that I was creating the cookie container on the request, but only if there were some cookies to put in it...
None
0 Points
60 Posts
Catching a redirect through HttpWebResponse
Mar 07, 2005 12:42 PM|Breakfast|LINK
response.addCookie("MyCookie", "MyVal"); response.redirect("Page2.jsp");
but when I iterate my way through the response headers on my HttpWebResponse object and send them to the Trace it looks like this:Header: Set-Cookie = JSESSIONID=DFD05A6799CE3C9D962761065FEF3ADF; Path=/myPath Header: Content-Type = text/html;charset=ISO-8859-1 Header: Content-Length = 636 1.414063 0.000054 Header: Date = Mon, 07 Mar 2005 17:47:03 GMT Header: Server = Apache-Coyote/1.1 Header: Connection = close Target uri: http://Server2/myPath/Page1.jsp
I'm not expert in the use of these classes but it seems to me that there should be some more headers happening here- any idea what may have become of them?None
0 Points
60 Posts
Re: Catching a redirect through HttpWebResponse
Mar 10, 2005 06:57 AM|Breakfast|LINK
HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); } catch(System.Net.WebException we) { context.Trace.Write("Exception with response find: "+we.Message); context.Trace.Write("More detail: "+we.StackTrace); return; } byte[] myBytes = new byte[1024]; int byteCount = 0; while( ( myBytes = receiveStream.Read( byteCount, 0, 1024 ) ) > 0 ) { context.Response.OutputStream.Write (myBytes, 0, byteCount ); } response.Close(); context.Response.End();
What seems to be happening is roughly this: request -- > Page1 response -- forwards to --> Page2 (checks cookie) -- forwards to --> Page1 --> response to browser Why are the intermediate responses not being passed back to the browser? Is there a way to make them accessible to my code? Everything works correctly when I access the pages directly.Contributor
3294 Points
3302 Posts
Re: Catching a redirect through HttpWebResponse
Mar 19, 2005 10:59 PM|stiletto|LINK
None
0 Points
60 Posts
Re: Catching a redirect through HttpWebResponse
Mar 21, 2005 12:14 PM|Breakfast|LINK
Contributor
3294 Points
3302 Posts
Re: Catching a redirect through HttpWebResponse
Mar 21, 2005 01:13 PM|stiletto|LINK
None
0 Points
60 Posts
Re: Catching a redirect through HttpWebResponse
Mar 22, 2005 05:28 AM|Breakfast|LINK
None
0 Points
60 Posts
Re: Catching a redirect through HttpWebResponse
Apr 04, 2005 10:35 AM|Breakfast|LINK
So I got it sorted in the end, but it was a rather inelegant fix.
Firstly I killed the response redirects so that when you authenticated the page showed you a response with a link to the homepage for authenticated users rather than trying to forward them.
I was still having problems logging in, though, and I discovered that although I had a "Set-Cookie" header it didn't register the contents of that as cookies. Not sure what was going on there. When I parsed the header manually and created cookies from it that finally seemed to sort the problem out...
Member
30 Points
120 Posts
Re: Catching a redirect through HttpWebResponse
Apr 04, 2005 04:01 PM|rbuckton|LINK
If you're working with HttpWebRequest/HttpWebResponse you need to add a simple extra steps to get cookies to work. To do this, you need to set an instance of a CookieContainer to the Request.
Without an instance to the System.Net.CookieContainer, you won't be able to track cookies.
[seealso: ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/cpref/html/frlrfSystemNetHttpWebRequestClassCookieContainerTopic.htm]
Senior Consultant
Microsoft
None
0 Points
60 Posts
Re: Catching a redirect through HttpWebResponse
Apr 05, 2005 04:50 AM|Breakfast|LINK