Search code examples
pythonpostlighttpdweb.py

Any POST request creates error 413


I'm trying to host a website off a Beaglebone Black using lighttpd and web.py. Any post request creates Error 413 - Request Entity Too Large. I am very new to web development, so I apologize if I've used the wrong terminology. To be clear, I am not attempting to upload any file of any kind. I created a simple page, test, to illustrate the error. My code:

First, Monitor.py:

#!/usr/bin/env python

import web
import Model
from Account  import Account
from Forgot   import Forgot
from Login    import Login
from Reset    import Reset
from Subscribe import Subscribe
from Success  import Success
from Status   import Status
from Test     import Test

urls = ('/', 'Status',
       '/test', 'Test',
       '/account', 'Account',
       '/forgot', 'Forgot',
       '/login', 'Login',
       '/reset/(\d+)', 'Reset',
       '/success', 'Success',
       '/subscribe', 'Subscribe',
)

render = web.template.render('templates')
app = web.application(urls, globals())
web.config.debug = False
session = Model.create_session(app)

if __name__ == '__main__':
       app.run()

Now, Test.py:

#!/usr/bin/env python

import web
import Model

render = web.template.render('templates')

class Test:

       def GET(self):
              return render.test()

       def POST(self):
              i = web.input()
              raise web.seeother('/test')

Now, the html file, located in the templates folder:

$def with()
<html>
<head>
    <link rel="stylesheet" href="static/stylesheet.css" type="text/css" media="screen" charset="utf-8"/>
    <title>Account Page</title>
</head>
<body>
       div>
              <form action="/test" method="POST">
                     <table class="std-element">
                            <tr>
                                   <th>
                                          <input type="text" name="example_text">
                                   </th>
                            </tr>
                     </table>
              </form>
       </div>
</body>
</html>

The relevant portion of the model file:

session = None

def create_session(app):
       global session
       session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'username':default_username})
       session['username'] = default_username
       return session

def get_session():
       global session
       return session

And, finally, the lighttpd.config file:

server.modules = (
       "mod_access",
       "mod_accesslog",
       "mod_alias",
       "mod_compress",
)

server.document-root = "/var/www/"
server.upload-dirs   = ( "/var/cache/lighttpd/uploads" )
server.errorlog      = "/var/log/lighttpd/error.log"
server.pid-file      = "/var/run/lighttpd.pid"
server.username      = "www-data"
server.groupname     = "www-data"
server.port          = 80
server.breakagelog   = "/var/log/lighttpd/breakage.log"
server.max-request-size=100000000
server.uploads-dirs=("/mnt")
server.network-backend="write"

## Use ipv6 if available
#include_shell "/usr/share/lighttpd/use-ipv6.pl"


compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/x-javascript", "text/css", "text/html", "text/plain" )

include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

Solution

  • server.max-request-size=100000000 is way too large. It is measured in KB. Internally, lighttpd left-shifts that number 10 bits, which, in your version of lighttpd, results in any POST being compared with 0 and rejected because it is too large. This has been fixed in lighttpd 1.4.40, but you should probably reduce that limit anyway. Having a 100 TB (!) request size limit is probably not going to protect your Beaglebone. Try this: server.max-request-size=1024 will set a 1 MB limit on POST requests. (Again, that config directive is in KB)