[Zope3-dev] 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

[Zope3-dev] 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-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



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

2006-09-18 Thread Simon Hang
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-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] (zope/app/cache/ram.py) class Storage's cleanup problem.

2005-12-30 Thread Simon Hang
Hi Stephan,

Is these code all right?

Regards,
SimonOn 11/13/05, Simon Hang [EMAIL PROTECTED] wrote:
Thanks Stephan,

Here is the test:(test_ramcache.py)

class TestStorage(TestCase):

 def test_getEntry(self):

 --snipped--

 def test_getEntry_do_cleanup(self):
 from zope.app.cache.ram import Storage

 s = Storage(cleanupInterval=300, maxAge=300)
 object = 'object'
 key = ('view', (), ('answer', 42))
 value = 'yes'

 s.setEntry(object, key, value)

 s._data[object][key][1] = time() - 400
 s.lastCleanup = time() - 400

 try:
 s.getEntry(object, key)
 except KeyError:
 pass
 else:
 raise cleanup not called

 def test_setEntry(self): --snipped--

On 11/12/05, Stephan Richter [EMAIL PROTECTED]
 wrote:
On Tuesday 01 November 2005 05:10, Simon Hang wrote: Dear all, I'm happen to find out call Storage only do cleanup when new Entry comes and do nothing when entries get from storage. So entries will be next
 expired if there are only read activities.I agree with your analysis and solution. If you provide a test for the fix,I'll check it in. If you cannot write a test, please add least add an issueto the issue collector.
Regards,Stephan--Stephan RichterCBU Physics  Chemistry (B.S.) / Tufts Physics (Ph.D. student)Web2k - Web Software Design, Development and Training


___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] (zope/app/cache/ram.py) class Storage's cleanup problem.

2005-11-12 Thread Simon Hang
Thanks Stephan,

Here is the test:(test_ramcache.py)

class TestStorage(TestCase):

 def test_getEntry(self):

 --snipped--

 def test_getEntry_do_cleanup(self):
 from zope.app.cache.ram import Storage

 s = Storage(cleanupInterval=300, maxAge=300)
 object = 'object'
 key = ('view', (), ('answer', 42))
 value = 'yes'

 s.setEntry(object, key, value)

 s._data[object][key][1] = time() - 400
 s.lastCleanup = time() - 400

 try:
 s.getEntry(object, key)
 except KeyError:
 pass
 else:
 raise cleanup not called

 def test_setEntry(self): --snipped--

On 11/12/05, Stephan Richter [EMAIL PROTECTED] wrote:
On Tuesday 01 November 2005 05:10, Simon Hang wrote: Dear all, I'm happen to find out call Storage only do cleanup when new Entry comes and do nothing when entries get from storage. So entries will be next
 expired if there are only read activities.I agree with your analysis and solution. If you provide a test for the fix,I'll check it in. If you cannot write a test, please add least add an issueto the issue collector.
Regards,Stephan--Stephan RichterCBU Physics  Chemistry (B.S.) / Tufts Physics (Ph.D. student)Web2k - Web Software Design, Development and Training
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



[Zope3-dev] (zope/app/cache/ram.py) class Storage's cleanup problem.

2005-11-02 Thread Simon Hang
Dear all,

I'm happen to find out call Storage only do cleanup when new Entry
comes and do nothing when entries get from storage. So entries will be
next expired if there are only read activities.

So I suggest we may change the getEntry as below:

 def getEntry(self, ob, key):
 # start of insert
 if self.lastCleanup = time() - self.cleanupInterval:

 self.cleanup()
 # end of insert
 try:
 data = "">
 except KeyError:
 if ob not in self._misses:
 self._misses[ob] = 0
 self._misses[ob] += 1
 raise
 else:

data[2] +=
1
# increment access count
 return data[0]

Can somebody update this into the repository?

Thanks,
Simon
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com