[Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-22 Thread Philipp von Weitershausen
Looks better now. I suggest filing a collector issue and attaching the 
patch. Somebody knowledgeable can then look at it.


Simon Hang wrote:

Philipp,
Sorry for being lazy, and thanks for the tips.  Here is my update version.
--- httptask.py.origFri Jan 06 02:15:48 2006
+++ httptask.py Fri Sep 22 09:13:48 2006
@@ -126,6 +126,11 @@
 else:
 close_it = 1
 elif version == '1.1':
+#modified by Simon
+if 'connection: close' in (header.lower() for header in
+self.accumulated_headers):
+#Close if 'connection: close' found in http response's 
header

+close_it = 1
 if connection == 'close':
 close_it = 1
 elif 'Transfer-Encoding' in response_headers:
@@ -134,8 +139,13 @@
 elif self.status == '304':
 # Replying with headers only.
 pass
+#modified by simon
 elif not ('Content-Length' in response_headers):
-close_it = 1
+if 'content-length' not in (header[:14].lower() for 
header in

+self.accumulated_headers):
+#Close if 'content-length' not found in
+#http response's header and self.response_headers
+close_it = 1
 else:
 # Close if unrecognized HTTP version.
 close_it = 1


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-21 Thread Philipp von Weitershausen

Simon Hang wrote:

How about below changes?


There aren't many of us who know the zope.server code that well, 
unfortunately. This is one of the reasons we want to get out of the 
server business.


That said, it would *much* easier to understand what you're trying to do 
if you provided *unified diffs* (create them with svn diff or diff -u).


Philipp


 
in httptask.py


def prepareResponseHeaders(self):
version = self.version
# Figure out whether the connection should be closed.
connection = self.request_data.headers.get('CONNECTION', '').lower()
close_it = 0
response_headers = self.response_headers

if version == '1.0':
if connection == 'keep-alive':
if not ('Content-Length' in response_headers):
close_it = 1
else:
response_headers['Connection'] = 'Keep-Alive'
else:
close_it = 1
elif version == '1.1':
#insert by Simon
thisflag = False
for each in self.accumulated_headers:
if each.lower() == 'connection: keep-alive':
thisflag = True
break
if thisflag == False:
close_it = 1
#end of insert
if connection == 'close':
close_it = 1
elif 'Transfer-Encoding' in response_headers:
if not response_headers['Transfer-Encoding'] == 'chunked':
close_it = 1
elif self.status == '304':
# Replying with headers only.
pass
#insert by simon
elif not ('Content-Length' in response_headers):
thisflag = False
for each in self.accumulated_headers:
if each[:14].upper() == 'CONTENT-LENGTH':
thisflag = True
break
if thisflag == False: #only CONTENT_LENGTH not exist in 
accumulated headers too


  #end of insert
close_it = 1
else:
# Close if unrecognized HTTP version.
close_it = 1

self.close_on_finish = close_it
if close_it:
self.response_headers['Connection'] = 'close'



 
On 9/19/06, *Simon Hang* 
[EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


Dear all,
 
While I was exploring my options to implement NTLM authentication, I

found some strange behavior of Zope HTTP server.
 
in zope.server.http.wsgihttpserver.WSGIHTTPServer,

It use below function to handle response's head:

def start_response(status, headers):
# Prepare the headers for output
status, reason = re.match('([0-9]*) (.*)', status).groups()
task.setResponseStatus(status, reason)
task.appendResponseHeaders(['%s: %s' % i for i in headers])

# Return the write method used to write the response data.
return fakeWrite

The result is all response's head from the content part of program
will be stored in task.accumulated_headers. See below function from
zope.server.http.httptask.HTTPTask.

def appendResponseHeaders(self, lst):
See zope.publisher.interfaces.http.IHeaderOutput
accum = self.accumulated_headers
if accum is None:
self.accumulated_headers = accum = []
accum.extend(lst)

But, the problem is while httptask to determin whether to close the
connection or not, it use below code. The code is only checking
self.response_headers which has nothing to do with the response our
application generated. So zope ends up to disconnect connection for
each single request.

   def prepareResponseHeaders(self):
version = self.version
# Figure out whether the connection should be closed.
connection = self.request_data.headers.get('CONNECTION',
'').lower()
close_it = 0
response_headers = self.response_headers

if version == '1.0':
if connection == 'keep-alive':
if not ('Content-Length' in response_headers):
close_it = 1
else:
response_headers['Connection'] = 'Keep-Alive'
else:
close_it = 1
elif version == '1.1':
thisflag = False
   
if connection == 'close':

close_it = 1
elif 'Transfer-Encoding' in response_headers:
if not response_headers['Transfer-Encoding'] ==
'chunked':
close_it = 1
elif self.status == '304':
# Replying with headers only.
pass
elif not ('Content-Length' 

Re: [Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-21 Thread Simon Hang
Thanks Philipp, here is the unified diffs.
--- httptask.py.orig Fri Jan 06 02:15:48 2006+++ httptask.py Thu Sep 21 17:31:17 2006@@ -126,6 +126,15 @@ else: close_it = 1 elif version == '1.1':+ #modified by Simon
+ thisflag = False+ for each in self.accumulated_headers:+ if each.lower() == 'connection: keep-alive':+ thisflag = True+ break
+ if thisflag == False:+ close_it = 1+ if connection == 'close': close_it = 1 elif 'Transfer-Encoding' in response_headers:@@ -134,8 +143,15 @@
 elif self.status == '304': # Replying with headers only. pass+ #modified by simon elif not ('Content-Length' in response_headers):
- close_it = 1+ thisflag = False+ for each in self.accumulated_headers:+ if each[:14].lower() == 'content-length':+ thisflag = True
+ break+ if thisflag == False: #only content_length not exist in accumulated headers too+ close_it = 1 else: # Close if unrecognized HTTP version.
 close_it = 1
On 9/21/06, Philipp von Weitershausen [EMAIL PROTECTED] wrote:
Simon Hang wrote: How about below changes?There aren't many of us who know the zope.server
 code that well,unfortunately. This is one of the reasons we want to get out of theserver business.That said, it would *much* easier to understand what you're trying to doif you provided *unified diffs* (create them with svn diff or diff -u).
Philipp in httptask.py def prepareResponseHeaders(self): version = self.version # Figure out whether the connection should be closed.
 connection = self.request_data.headers.get('CONNECTION', '').lower() close_it = 0 response_headers = self.response_headers if version == '1.0': if connection == 'keep-alive':
 if not ('Content-Length' in response_headers): close_it = 1 else: response_headers['Connection'] = 'Keep-Alive' else:
 close_it = 1 elif version == '1.1': #insert by Simon thisflag = False for each in self.accumulated_headers: if 
each.lower() == 'connection: keep-alive': thisflag = True break if thisflag == False: close_it = 1 #end of insert
 if connection == 'close': close_it = 1 elif 'Transfer-Encoding' in response_headers: if not response_headers['Transfer-Encoding'] == 'chunked':
 close_it = 1 elif self.status == '304': # Replying with headers only. pass #insert by simon elif not ('Content-Length' in response_headers):
 thisflag = False for each in self.accumulated_headers: if each[:14].upper() == 'CONTENT-LENGTH': thisflag = True
 break if thisflag == False: #only CONTENT_LENGTH not exist in accumulated headers too #end of insert close_it = 1
 else: # Close if unrecognized HTTP version. close_it = 1 self.close_on_finish = close_it if close_it: self.response_headers
['Connection'] = 'close' On 9/19/06, *Simon Hang* [EMAIL PROTECTED] mailto:
[EMAIL PROTECTED] wrote: Dear all, While I was exploring my options to implement NTLM authentication, I found some strange behavior of Zope HTTP server.
 in zope.server.http.wsgihttpserver.WSGIHTTPServer, It use below function to handle response's head: def start_response(status, headers): # Prepare the headers for output
 status, reason = re.match('([0-9]*) (.*)', status).groups() task.setResponseStatus(status, reason) task.appendResponseHeaders(['%s: %s' % i for i in headers])
 # Return the write method used to write the response data. return fakeWrite The result is all response's head from the content part of program
 will be stored in task.accumulated_headers. See below function from zope.server.http.httptask.HTTPTask. def appendResponseHeaders(self, lst): See 
zope.publisher.interfaces.http.IHeaderOutput accum = self.accumulated_headers if accum is None: self.accumulated_headers = accum = [] 
accum.extend(lst) But, the problem is while httptask to determin whether to close the connection or not, it use below code. The code is only checking self.response_headers which has nothing to do with the response our
 application generated. So zope ends up to disconnect connection for each single request.def prepareResponseHeaders(self): version = self.version # Figure out whether the connection should be closed.
 connection = self.request_data.headers.get('CONNECTION', '').lower() close_it = 0 response_headers = self.response_headers if version == '
1.0': if connection == 'keep-alive': if not ('Content-Length' in response_headers): close_it = 1 else: response_headers['Connection'] = 'Keep-Alive'
 else: close_it = 1 elif version == '1.1': thisflag = False if connection == 'close': close_it = 1
 elif 'Transfer-Encoding' in response_headers: if not response_headers['Transfer-Encoding'] == 'chunked': close_it = 1 elif 
self.status == '304': # Replying with headers only. pass elif not ('Content-Length' in response_headers): close_it = 1
 else: # Close if unrecognized HTTP version. close_it = 1 self.close_on_finish = close_it if close_it:
 self.response_headers['Connection'] = 'close' Can somebody tell me why the thing is implement like this, is there special reason to do this? Or can we change it a little bit to let
 zope support persistence connection? Thanks, Simon 

Re: [Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-21 Thread Philipp von Weitershausen

Hi Simon,

I have a few comments regarding style. First::

  if thisflag == False:
  ...

is unnecessarily long. Just write::

  if not thisflag:
  ...

Also, what is thisflag? It'd be better to give it a descriptive name.


--- httptask.py.origFri Jan 06 02:15:48 2006
+++ httptask.py Thu Sep 21 17:31:17 2006
@@ -126,6 +126,15 @@
 else:
 close_it = 1
 elif version == '1.1':
+#modified by Simon
+thisflag = False
+for each in self.accumulated_headers:
+if each.lower() == 'connection: keep-alive':
+thisflag = True
+break
+if thisflag == False:
+close_it = 1
+


I think you make this a lot simpler::

  if 'connection: keep-alive' not in (header.lower() for header in
  self.accumulated_headers):
  close_it = 1

(instead of the lines you added)


 if connection == 'close':
 close_it = 1
 elif 'Transfer-Encoding' in response_headers:
@@ -134,8 +143,15 @@
 elif self.status == '304':
 # Replying with headers only.
 pass
+#modified by simon
 elif not ('Content-Length' in response_headers):
-close_it = 1
+thisflag = False
+for each in self.accumulated_headers:
+if each[:14].lower() == 'content-length':
+thisflag = True
+break
+if thisflag == False: #only content_length not exist in 
accumulated headers too

+close_it = 1


I don't understand the comment (English grammar not correct), but my 
suggestion would apply here as well, I think.

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-21 Thread Simon Hang
Philipp,
Sorry for being lazy, and thanks for the tips. Here is my update version.
--- httptask.py.orig Fri Jan 06 02:15:48 2006+++ httptask.py Fri Sep 22 09:13:48 2006@@ -126,6 +126,11 @@ else: close_it = 1 elif version == '1.1':+ #modified by Simon
+ if 'connection: close' in (header.lower() for header in+ self.accumulated_headers):+ #Close if 'connection: close' found in http response's header
+ close_it = 1 if connection == 'close': close_it = 1 elif 'Transfer-Encoding' in response_headers:@@ -134,8 +139,13 @@ elif self.status
 == '304': # Replying with headers only. pass+ #modified by simon elif not ('Content-Length' in response_headers):- close_it = 1
+ if 'content-length' not in (header[:14].lower() for header in+ self.accumulated_headers):+ #Close if 'content-length' not found in
+ #http response's header and self.response_headers+ close_it = 1 else: # Close if unrecognized HTTP version. close_it = 1

On 9/21/06, Philipp von Weitershausen [EMAIL PROTECTED] wrote:
Hi Simon,I have a few comments regarding style. First::if thisflag == False:...
is unnecessarily long. Just write::if not thisflag:...Also, what is thisflag? It'd be better to give it a descriptive name. --- httptask.py.origFri Jan 06 02:15:48 2006
 +++ httptask.py Thu Sep 21 17:31:17 2006 @@ -126,6 +126,15 @@else:close_it = 1elif version == '1.1': +#modified by Simon
 +thisflag = False +for each in self.accumulated_headers: +if each.lower() == 'connection: keep-alive': +thisflag = True +break
 +if thisflag == False: +close_it = 1 +I think you make this a lot simpler::if 'connection: keep-alive' not in (header.lower() for header in
self.accumulated_headers):close_it = 1(instead of the lines you added)if connection == 'close':close_it = 1elif 'Transfer-Encoding' in response_headers:
 @@ -134,8 +143,15 @@elif self.status == '304':# Replying with headers only.pass +#modified by simonelif not ('Content-Length' in response_headers):
 -close_it = 1 +thisflag = False +for each in self.accumulated_headers: +if each[:14].lower() == 'content-length': +thisflag = True
 +break +if thisflag == False: #only content_length not exist in accumulated headers too +close_it = 1I don't understand the comment (English grammar not correct), but my
suggestion would apply here as well, I think.
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

2006-09-20 Thread Simon Hang
How about below changes?

in httptask.py

 def prepareResponseHeaders(self): version = self.version # Figure out whether the connection should be closed. connection = self.request_data.headers.get('CONNECTION', '').lower()
 close_it = 0 response_headers = self.response_headers
 if version == '1.0': if connection == 'keep-alive': if not ('Content-Length' in response_headers): close_it = 1 else: response_headers['Connection'] = 'Keep-Alive'
 else: close_it = 1 elif version == '1.1': #insert by Simon thisflag = False for each in self.accumulated_headers: if 
each.lower() == 'connection: keep-alive': thisflag = True break if thisflag == False: close_it = 1 #end of insert if connection == 'close':
 close_it = 1 elif 'Transfer-Encoding' in response_headers: if not response_headers['Transfer-Encoding'] == 'chunked': close_it = 1 elif 
self.status == '304': # Replying with headers only. pass #insert by simon elif not ('Content-Length' in response_headers): thisflag = False
 for each in self.accumulated_headers: if each[:14].upper() == 'CONTENT-LENGTH': thisflag = True break if thisflag == False: #only CONTENT_LENGTH not exist in accumulated headers too

 #end of insert close_it = 1 else: # Close if unrecognized HTTP version. close_it = 1
 self.close_on_finish = close_it if close_it: self.response_headers['Connection'] = 'close'
On 9/19/06, Simon Hang [EMAIL PROTECTED] wrote:


Dear all,

While I was exploringmy options to implement NTLM authentication, I found some strange behavior of Zope HTTP server.

in zope.server.http.wsgihttpserver.WSGIHTTPServer, 
It use below function to handle response's head:

 def start_response(status, headers): # Prepare the headers for output status, reason = re.match('([0-9]*) (.*)', status).groups() task.setResponseStatus(status, reason) 
 task.appendResponseHeaders(['%s: %s' % i for i in headers])
 # Return the write method used to write the response data. return fakeWrite
The result is all response's head from the content part of program will be stored in task.accumulated_headers. See below function from zope.server.http.httptask.HTTPTask.
 def appendResponseHeaders(self, lst): See zope.publisher.interfaces.http.IHeaderOutput accum = self.accumulated_headers if accum is None: 
self.accumulated_headers = accum = [] accum.extend(lst)
But, the problem is while httptask to determin whether to close the connection or not, it use below code. The code is only checking self.response_headers which has nothing to do with the response our application generated. So zope ends up to disconnect connection for each single request. 

 def prepareResponseHeaders(self): version = self.version # Figure out whether the connection should be closed. connection = self.request_data.headers.get('CONNECTION', '').lower()
 close_it = 0 response_headers = self.response_headers
 if version == '1.0': if connection == 'keep-alive': if not ('Content-Length' in response_headers): close_it = 1 else: response_headers['Connection'] = 'Keep-Alive' 
 else: close_it = 1 elif version == '1.1': thisflag = False if connection == 'close': close_it = 1 elif 'Transfer-Encoding' in response_headers: 
 if not response_headers['Transfer-Encoding'] == 'chunked': close_it = 1 elif self.status == '304': # Replying with headers only. pass 
 elif not ('Content-Length' in response_headers): close_it = 1 else: # Close if unrecognized HTTP version. close_it = 1
 self.close_on_finish = close_it if close_it: self.response_headers['Connection'] = 'close'
Can somebody tell me why the thing is implement like this, is there special reason to do this? Or can we change it a little bit to let zope support persistence connection?
Thanks,Simon

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users