Hello list, I'm using VHM and I need the (real) remote IP, as given by HTTP_X_FORWARDED_FOR. However, when accessing the page without any virtualization, I need to fall back on REMOTE_ADDR. Now, any idea why the following <p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p> doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR. I've overcomed the problem using "or" in python, but I got puzzled with this situation. Is this a bug or am I missing something? Cheers, Fernando
Fernando Martins wrote at 2003-10-14 21:44 +0200:
I'm using VHM and I need the (real) remote IP, as given by HTTP_X_FORWARDED_FOR. However, when accessing the page without any virtualization, I need to fall back on REMOTE_ADDR.
Now, any idea why the following
<p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p>
doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR.
This means that something defined "HTTP_X_FORWARDED_FOR" even when you did not use virtualisation. You know, that you can view the request with '<p tal:content="structure request">'? Dieter
Ugh, I've just cross-posted to zope-dev and zpt because I didn't had a reply... Dieter Maurer:
Fernando Martins wrote at 2003-10-14 21:44 +0200:
I'm using VHM and I need the (real) remote IP, as given by HTTP_X_FORWARDED_FOR. However, when accessing the page without any virtualization, I need to fall back on REMOTE_ADDR.
Now, any idea why the following
<p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p>
doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR.
This means that something defined "HTTP_X_FORWARDED_FOR" even when you did not use virtualisation.
You know, that you can view the request with '<p tal:content="structure request">'?
Yes, and I think it's a bug because it doesn't appear in the request. Thanks Dieter, Fernando
On Sunday, October 19, 2003, at 06:00 PM, Fernando Martins wrote:
<p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p>
doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR.
This means that something defined "HTTP_X_FORWARDED_FOR" even when you did not use virtualisation.
You know, that you can view the request with '<p tal:content="structure request">'?
Yes, and I think it's a bug because it doesn't appear in the request.
If you want to confirm this, you should try to use container.REQUEST.HTTP_X_FORWARDED_FOR from a Python script, or maybe just tal:content="python: repr(request.HTTP_X_FORWARDED_FOR)" -- even though the request doesn't list that variable among its headers, it may still return a value for that attribute. The only way to test if an attribute exists is to attempt to get the attribute. Perhaps (I don't know) the request object returns "" for any HTTP_* attribute that is not found. -- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org
Ian Bicking wrote:
On Sunday, October 19, 2003, at 06:00 PM, Fernando Martins wrote:
<p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p>
doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR.
This means that something defined "HTTP_X_FORWARDED_FOR" even when you did not use virtualisation.
You know, that you can view the request with '<p tal:content="structure request">'?
Yes, and I think it's a bug because it doesn't appear in the request.
If you want to confirm this, you should try to use container.REQUEST.HTTP_X_FORWARDED_FOR from a Python script, or maybe just tal:content="python: repr(request.HTTP_X_FORWARDED_FOR)" -- even though the request doesn't list that variable among its headers, it may still return a value for that attribute. The only way to test if an attribute exists is to attempt to get the attribute. Perhaps (I don't know) the request object returns "" for any HTTP_* attribute that is not found.
Ok, tried it and got no error, just an empty string. So, it is either a bug on the request object which contains the attribute HTTP_X_FORWARDED_FOR when it shouldn't (i.e., when the request went from the client straight to Zope). But maybe it should always have it. Or it is a bug in the "structure request" which doesn't display the attribute even if it is there. BTW, which method is implicitly called to generate the HTML representation of the objects (like in "structure request")? Cheers, Fernando
Fernando Martins wrote:
Ok, tried it and got no error, just an empty string.
So, it is either a bug on the request object which contains the attribute HTTP_X_FORWARDED_FOR when it shouldn't (i.e., when the request went from the client straight to Zope). But maybe it should always have it.
It's either a bug or feature of the request object -- I suspect some kind of blanket attempt at future-proofing againt new HTTP headers, since *anything* starting with "HTTP_" that isn't actually there will return an empty string. Try this: <p tal:condition="python:request['HTTP_SQUEE_HONK']==''">Yep.</p>
BTW, which method is implicitly called to generate the HTML representation of the objects (like in "structure request")?
The request object has an __str__ method that gets called to convert it into a string. This has little to do with ZPT, though. Cheers, Evan @ 4-am
On Monday, October 20, 2003, at 02:37 PM, Fernando Martins wrote:
Ian Bicking wrote:
On Sunday, October 19, 2003, at 06:00 PM, Fernando Martins wrote:
<p tal:content="request/HTTP_X_FORWARDED_FOR | request/REMOTE_ADDR"></p>
doesn't work as expected: HTTP_X_FORWARDED_FOR returns an empty string rather than failling in favor of REMOTE_ADDR.
This means that something defined "HTTP_X_FORWARDED_FOR" even when you did not use virtualisation.
You know, that you can view the request with '<p tal:content="structure request">'?
Yes, and I think it's a bug because it doesn't appear in the request.
If you want to confirm this, you should try to use container.REQUEST.HTTP_X_FORWARDED_FOR from a Python script, or maybe just tal:content="python: repr(request.HTTP_X_FORWARDED_FOR)" -- even though the request doesn't list that variable among its headers, it may still return a value for that attribute. The only way to test if an attribute exists is to attempt to get the attribute. Perhaps (I don't know) the request object returns "" for any HTTP_* attribute that is not found.
Ok, tried it and got no error, just an empty string.
So, it is either a bug on the request object which contains the attribute HTTP_X_FORWARDED_FOR when it shouldn't (i.e., when the request went from the client straight to Zope). But maybe it should always have it.
Or it is a bug in the "structure request" which doesn't display the attribute even if it is there.
I assume it was a design choice, and changing it would break backward compatibility. I'd recommend just using tal:content="python: request.HTTP_X_FORWARDED_FOR or request.REMOTE_ADDR".
BTW, which method is implicitly called to generate the HTML representation of the objects (like in "structure request")?
__str__ should be it. You'll want to pay attention to __getattr__ as well, as HTTPRequest's __getattr__ probably is what returns an empty string for HTTP_* variables that aren't found. -- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org
Thanks, Ian and Evan, for your replies, Ian Bicking wrote:
On Monday, October 20, 2003, at 02:37 PM, Fernando Martins wrote: [...]
So, it is either a bug on the request object which contains the attribute HTTP_X_FORWARDED_FOR when it shouldn't (i.e., when the request went from the client straight to Zope). But maybe it should always have it.
Or it is a bug in the "structure request" which doesn't display the attribute even if it is there.
I assume it was a design choice, and changing it would break backward compatibility.
I'm afraid I don't see the issue here. The way I see it, there is an (undocumented?) inconsistency between __str__ and __getattr__ (which gave me a bug). Does it make sense to have these virtual HTTP_* attributes? Why would someone rely on it? Also, if I make a typo in say HTTP_C00KIE, I'm getting a bug which could have been spotted imediately at the first run.
I'd recommend just using tal:content="python: request.HTTP_X_FORWARDED_FOR or request.REMOTE_ADDR".
I had it already solved with request['HTTP_X_FORWARDED_FOR'] or request['REMOTE_ADDR'] which I believe is the same, i.e. both should be calling __getattr__, right? Cheers, Fernando
On Tuesday, October 21, 2003, at 04:05 PM, Fernando Martins wrote:
Ian Bicking wrote:
On Monday, October 20, 2003, at 02:37 PM, Fernando Martins wrote: [...]
So, it is either a bug on the request object which contains the attribute HTTP_X_FORWARDED_FOR when it shouldn't (i.e., when the request went from the client straight to Zope). But maybe it should always have it.
Or it is a bug in the "structure request" which doesn't display the attribute even if it is there.
I assume it was a design choice, and changing it would break backward compatibility.
I'm afraid I don't see the issue here. The way I see it, there is an (undocumented?) inconsistency between __str__ and __getattr__ (which gave me a bug). Does it make sense to have these virtual HTTP_* attributes? Why would someone rely on it? Also, if I make a typo in say HTTP_C00KIE, I'm getting a bug which could have been spotted imediately at the first run.
It probably is meant to cover up some browser-compatibility issues. Most browsers people use for testing act reasonably similar, but some HTTP/1.0 robots or old browsers will act funky and do dumb things -- but you'll never really notice it during testing. (OTOH, I wouldn't really care if these browsers and robots got exceptions, they're broken and very obsolete) I think it's okay that __str__ and __getattr__ aren't entirely consistent -- certainly in this case __str__ can't enumerate all possible HTTP_* headers. It would be more concerning if the documentation for HTTPRequest weren't consistent with its behavior. But I've yet to find good, thorough documentation for these basic objects, and nothing that is thorough enough that it covers this kind of behavior (though I guess I stopped looking for good Zope documentation of this sort a while ago -- maybe it exists and I just haven't seen it) -- so in the absence of documentation there's no such thing as Right and Wrong, just Is and Is Not (I'm not sure whether to wink or panic in response to that). -- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org
Ian Bicking wrote: [...]
I think it's okay that __str__ and __getattr__ aren't entirely consistent -- certainly in this case __str__ can't enumerate all possible HTTP_* headers. It would be more concerning if the documentation for HTTPRequest weren't consistent with its behavior. But I've yet to find good, thorough documentation for these basic objects, and nothing that is thorough enough that it covers this kind of behavior (though I guess I stopped looking for good Zope documentation of this sort a while ago -- maybe it exists and I just haven't seen it) -- so in the absence of documentation there's no such thing as Right and Wrong, just Is and Is Not (I'm not sure whether to wink or panic in response to that).
I can live with this :-) (and a great community to back up!) Cheers, Fernando
participants (4)
-
Dieter Maurer -
Evan Simpson -
Fernando Martins -
Ian Bicking