I am running the official version 1.91.6.
On Jan 19, 1:24 pm, Massimo Di Pierro <[email protected]> wrote: > Thanks this is very helpful and I will try reproduce it. > Are you running the trunk version or which other version? > > Massimo > > On Jan 19, 12:45 pm, VP <[email protected]> wrote: > > > UPDATE: I am able to reproduce this "Premature end of script headers: > > wsgihandler.py" error with a slightly modified app based on the image > > blog in the web2py book. I modified it so that images are shown in > > the index page, instead of having just the titles listed. > > > Testing using: ab -kc 100 -t 20https://domain.com/imageblog/default/index/ > > > If I am simply doing this, there's no error. BUT when I was running > > this test, while simultaneously browsing the website, clicking on > > images, etc., then the error appeared, consistently. > > > Monitoring available RAM while running this test showed system RAM > > peeked at about 500MB, still a few hundreds MB available. This is on > > the same server as the other app. VPS. 768MB RAM. 1GB RAM > > Burstable. About 129 apache2 processes running and 11,000 files > > openning. > > > sudo ps aux | grep apache2 | wc > > 129 1675 11847 > > > sudo lsof | wc > > 10982 106870 1313126 > > > ================================================= > > Here's a typical Apache Bench result: > > > Server Software: Apache/2.2.9 > > Server Port: 443 > > SSL/TLS Protocol: TLSv1/SSLv3,DHE-RSA-AES256-SHA,1024,256 > > > Document Path: /imageblog/default/index/ > > Document Length: 13130 bytes > > > Concurrency Level: 100 > > Time taken for tests: 20.004 seconds > > Complete requests: 588 > > Failed requests: 15 > > (Connect: 0, Receive: 0, Length: 15, Exceptions: 0) > > Write errors: 0 > > Non-2xx responses: 15 > > Keep-Alive requests: 573 > > Total transferred: 7875930 bytes > > HTML transferred: 7564607 bytes > > Requests per second: 29.39 [#/sec] (mean) > > Time per request: 3401.991 [ms] (mean) > > Time per request: 34.020 [ms] (mean, across all concurrent > > requests) > > Transfer rate: 384.50 [Kbytes/sec] received > > > Connection Times (ms) > > min mean[+/-sd] median max > > Connect: 0 912 2146.5 0 7265 > > Processing: 86 2234 1303.3 2781 4427 > > Waiting: 85 2136 1281.0 2759 4316 > > Total: 86 3146 2410.6 3017 10478 > > > Percentage of the requests served within a certain time (ms) > > 50% 3017 > > 66% 3222 > > 75% 3939 > > 80% 4029 > > 90% 7089 > > 95% 9409 > > 98% 10098 > > 99% 10223 > > 100% 10478 (longest request) > > > ================================================= > > > Relevant excerpt of db.py: > > > db = DAL('postgres://username:password@localhost:5432/imageblog', > > pool_size=20) > > > ================================================= > > Model: > > > db.define_table('image', > > Field('title'), > > Field('file', 'upload')) > > > db.define_table('comment', > > Field('image_id', db.image), > > Field('author'), > > Field('email'), > > Field('body', 'text')) > > > db.image.title.requires = IS_NOT_IN_DB(db, db.image.title) > > db.comment.image_id.requires = IS_IN_DB(db, db.image.id, '%(title)s') > > db.comment.author.requires = IS_NOT_EMPTY() > > db.comment.email.requires = IS_EMAIL() > > db.comment.body.requires = IS_NOT_EMPTY() > > > ================================================= > > Controller: > > > def index(): > > images = db().select(db.image.ALL, orderby=db.image.title) > > return dict(images=images) > > > @auth.requires_login() > > def add(): > > form = crud.create(db.image, next = URL('index')) > > return dict(form=form) > > > def show(): > > image = db(db.image.id==request.args(0)).select().first() > > form = SQLFORM(db.comment) > > form.vars.image_id = image.id > > if form.accepts(request.vars, session): > > response.flash = 'your comment is posted' > > comments = db(db.comment.image_id==image.id).select() > > return dict(image=image, comments=comments, form=form) > > > def user(): > > """ > > exposes: > > http://..../[app]/default/user/login > > http://..../[app]/default/user/logout > > http://..../[app]/default/user/register > > http://..../[app]/default/user/profile > > http://..../[app]/default/user/retrieve_password > > http://..../[app]/default/user/change_password > > use @auth.requires_login() > > @auth.requires_membership('group name') > > @auth.requires_permission('read','table name',record_id) > > to decorate functions that need access control > > """ > > return dict(form=auth()) > > > def download(): > > """ > > allows downloading of uploaded files > > http://..../[app]/default/download/[filename] > > """ > > return response.download(request,db) > > > def call(): > > """ > > exposes services. for example: > > http://..../[app]/default/call/jsonrpc > > decorate with @services.jsonrpc the functions to expose > > supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv > > """ > > session.forget() > > return service() > > > ================================================= > > View (index.html) > > > {{extend 'layout.html'}} > > <h1>Current Images</h1> > > > {{for image in images:}} > > <div class="entry" style="padding:1em; border-bottom:1px dashed > > #999;"> > > <div class="entrytitle" style="font-size:150%;">{{=A(image.title, > > _href=URL("show", args=image.id))}}</div> > > <div class="entryimage"><img src="{{=URL('download', > > args=image.file)}}"></div> > > </div> > > > {{pass}} > > > ================================================= > > > Apache's site-enabled/000-default: > > > <VirtualHost *:80> > > WSGIDaemonProcess web2py user=username group=username \ > > display-name=%{GROUP} > > WSGIProcessGroup web2py > > WSGIScriptAlias / /home/username/web2py/wsgihandler.py > > > Alias /awstats-icon/ /usr/share/awstats/icon/ > > <Directory /usr/share/awstats/icon> > > Options None > > AllowOverride None > > Order allow,deny > > Allow from all > > </Directory> > > > <Directory /home/username/web2py> > > AllowOverride None > > Order Allow,Deny > > Deny from all > > <Files wsgihandler.py> > > Allow from all > > </Files> > > </Directory> > > > AliasMatch ^/([^/]+)/static/(.*) \ > > /home/username/web2py/applications/$1/static/$2 > > > <Directory /home/username/web2py/applications/*/static/> > > Options -Indexes > > Order Allow,Deny > > Allow from all > > </Directory> > > > <Location /admin> > > Deny from all > > </Location> > > > <LocationMatch ^/([^/]+)/appadmin> > > Deny from all > > </LocationMatch> > > > CustomLog /var/log/apache2/access.log common > > ErrorLog /var/log/apache2/error.log > > </VirtualHost> > >

