Feature #1307


Impossible to loop through the lighty.request or lighty.env fields

Added by Anonymous over 16 years ago. Updated about 14 years ago.

Target version:


In order to log all request headers or matching their names against a given pattern (i.e. proxy), it should be possible to traverse the lighty.request and lighty.env tables.

The following debug code however only processes what seems to be empty tables. Requesting a field directly, returns the value as exptected (see last line of output):

print('--------- BEGIN OF DUMP -----------')

-- loop through main "lighty" table and output its
-- type and contents (including subtables)
for key,val in pairs(lighty) do

  if type(val) == 'table' then
    print('TABLE:  ' .. key .. '(Length: ' .. #val .. ')')

-- loop through sub-table of "lighty" 
    for key2,val2 in pairs(val) do
      if val2 == nil then
        print(' - ' .. key2 .. ': (NULL)')
        print(' - ' .. key2 .. ': ' .. val2)
-- end of subtable

  elseif type(val) == 'string' then
    if val == nil then
      print ('STRING: ' .. key .. ': (NULL)')
      print ('STRING: ' .. key .. ': ' .. val)

    print ('ISTYPE: ' .. key .. ': ' .. type(val))

print('--------- END OF DUMP -------------')


GET / HTTP/1.1
Host: localhost
User-Agent: This is my User-Agent
Connection: close


--------- BEGIN OF DUMP ----------- 
TABLE:  header(Length: 0) 
ISTYPE: stat: function 
TABLE:  request(Length: 0) 
TABLE:  env(Length: 0) 
TABLE:  content(Length: 0) 
TABLE:  status(Length: 0) 
--------- END OF DUMP ------------- 
This is my User-Agent 

Tested on 1.4.16 (Linux x86_64).


mod_magnet.c.patch (1.73 KB) mod_magnet.c.patch Adds lighty.request.fields() through C functions magnet_reqhdr_fields() and magnet_reqhdr_fields_iterator() Anonymous, 2008-04-04 18:53
lighttpd-1.4.19-iterablemagnet.patch (16.2 KB) lighttpd-1.4.19-iterablemagnet.patch I have a patch here that I have applied to our production version of 1.4.19. It fully applies iteration [via pairs()] to the lighty variables that need it. It also does some other things like add in some of the documented (but not implemented) request var norganna, 2008-04-09 11:06

Related issues 1 (0 open1 closed)

Has duplicate Bug #2016: "Dumping" a table in mod_magnet does not workDuplicate2009-07-01Actions
Actions #1

Updated by Anonymous over 15 years ago

The attached patch against 1.4.19 defines the lighty.request.fields() function, which can be used as iterator in a generic for loop.
State data is passed through an additional C struct.

Example use:

for field in lighty.request.fields() do
  print(field .. ': ' .. lighty.request[field])
Actions #2

Updated by norganna over 15 years ago

The patch "lighttpd-1.4.19-iterablemagnet.patch" is one that I wrote to enable us to iterate over the lighty variables using the pairs() function. It incorporates some modifications to the lua pairs() function inspired by the following article:

The changes imposed are basically the addition of an __pairs metatable entry which returns an iterator for the associated object.

We then go on to add pairs metafunctions to the lighty objects.

Additionally, this patch adds in the request.method and request.protocol entries to the lighty.env table, which were documented as being present, but not functioning.

I also added a request.remote-ip entry to the lighty.env table, since I couldn't seem to find it elsewhere. (Basically I wrote the iteration code to make sure it wasn't hiding somewhere obvious)

I've also added a function lighty.acl(source, destination, netmask) which takes as parameters an IPv4 address in string dotted quad, or numerical equivalent, a destination network in string dotted quad, or numerical equivalent and optionally a netmask in string dotted quad, or numerical equivalent or string CIDR size.

It subsequently returns result, source_numerical, destination_numerical, netmask_numerical.

Result is true if source is in destination+netmask, or false if it is outside.
the additional *_numerical items returned on the stack are the numerical equivalents to the input variables. This is to speed up execution of processing many thousands of ACL entries since you don't need to reinterpret the IP addresses every time (we currently are using this to block botnets from our servers and have in excess of 100000 IP addresses that are being blocked. Traditional ACL blocking (in-config) does not help us as we need live blocking/unblocking.

While this functionality is not anything to do with the current bug, I included it in the patch on the off-chance that someone else finds it useful / worthy of inclusion. Also I would have had to extract it from the patch otherwise.

Anyhow, ENJOY!

norganna (

Actions #3

Updated by Anonymous over 15 years ago


Thanks for your patch. very usefull.

Actions #4

Updated by stbuehler about 15 years ago

  • Target version changed from 1.4.20 to 1.4.21
Actions #5

Updated by icy almost 15 years ago

  • Target version changed from 1.4.21 to 1.4.22
  • Patch available set to No
Actions #6

Updated by stbuehler almost 15 years ago

  • Target version changed from 1.4.22 to 1.4.23
Actions #7

Updated by stbuehler over 14 years ago

  • Target version changed from 1.4.23 to 1.4.24
Actions #8

Updated by stbuehler about 14 years ago

  • Status changed from New to Fixed
  • % Done changed from 0 to 100

Applied in changeset r2644.

Actions #9

Updated by stbuehler about 14 years ago

  • Missing in 1.5.x set to No
Actions #10

Updated by jani about 14 years ago

FYI: this broke BC. I get this error now: (mod_magnet.c.959) lua_pcall(): attempt to call a table value

As soon as I have time, I'll provide a test lua script..

Actions #11

Updated by stbuehler about 14 years ago

  • Status changed from Fixed to Reopened
  • Assignee deleted (jan)
  • Target version changed from 1.4.24 to 1.4.25

Workaround: either use _G.pairs(x) instead of pairs(x) or add pairs = _G.pairs at the top of your scripts.

Actions #12

Updated by stbuehler about 14 years ago

  • Status changed from Reopened to Fixed

Applied in changeset r2680.


Also available in: Atom