lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


You'll need a function that creates the urlargs for the form's fields, and then use that as the body (second argument) in a call to socket.http.request. How you create the body is ultimately up to you: if you want to create them from a table, then the way you would do it (from your example) would be thus:

  function url_encode(str)
      str = string.gsub (str, "\n", "\r\n")
      str = string.gsub (str, "([^%w%-%_%. ])",
          function (c) return string.format ("%%%02X", string.byte(c)) end)
      return string.gsub (str, " ", "+")
  end

  function url_formencode(params)
    --table of argument strings
    local argts, i= {}, 1
    for k, v in pairs(params) do
      argts[i]=url_encode(k).."="..url_encode(v)
      i=i+1
    end
    return table.concat(argts,'&')
  end

  form={
    body="",
    recipient="recipient@somedomain.com",
    realname="Real name goes here",
    subject="Subject goes here",
--Submit="Submit" -- technically this gets submitted too with web browsers but I can't even find details in RFC 1866 so I'm just assuming nobody's going to be looking for it
  }

url_formencode(form) will give you something like "body=&recipient=recipient%40somedomain.com&realname=Real+name+goes+here&subject=Subject+goes+here", but not necessarily in that order (indeed, probably not) because pairs, as it operates over arbitrary keys, has no specific order. Technically, the RFC states that the arguments should be in the order of the elements of the form, so if this non-compliance actually causes problems with your implementation, you can make another table for an array that dictates the order of the fields, then traverse the form by the keys as ordered by the array:

  order={"body","recipient","realname","subject"}

  function url_orderedformencode(params,order)
    --table of argument strings
    local argts = {}
    for i=1, #order do
      argts[i]=url_encode(order[i]).."="..url_encode(params[order[i]])
    end
    return table.concat(argts,'&')
  end

in which case you can get "body=&recipient=recipient%40somedomain.com&realname=Real+name+goes+here&subject=Subject+goes+here" definitely by calling url_orderedformencode(form,order). (In practice, though, I've found most sites don't actually care about the field order, as the underlying tech just places them into a dictionary by key.)

Of course, you don't have to use such a generalized table-based approach if you're always creating the same form. This simpler function creates the request body for this form just as well (when called with the equivalent parameters):

  function formmail(body, recipient, realname, subject)
    return string.format("body=%s&recipient=%s&realname=%s&subject=%s",
url_encode(body), url_encode(recipient), url_encode(realname), url_encode(subject))
  end

Once you've got your URL-encoded body from url_formencode(form) or url_orderedformencode(form, order) or formmail("", "recipient@somedomain.com", "Real name goes here", "Subject goes here") it's trivial to submit the form:

  local http = require "socket.http"
  http.request("/cgi-bin/formmail.pl",body)

This will submit a POST (if http.request is called with just a URL, it would do a get, but with a body it does a POST) to the given address (you'll need to change the URL to include the base server name, ie. "http://numerix-dsp.com/cgi-bin/formmail.pl";).

On Sat, 29 May 2010 15:13:53 -0700, John Edwards <jedwards@numerix-dsp.com> wrote:

Dear All,

I would like to be able to use Lua to automate the submission of a web form
E.G. :

<form method="post" action="/cgi-bin/formmail.pl">
<input name="body" value="" type="hidden">
<input name="recipient" value="recipient@somedomain.com" type="hidden">
<strong>Name : </strong><input size="40" name="realname" type="text"><br>
<strong>Subject : </strong><input size="40" name="subject" type="text"><br>
<input value="Submit" type="submit"></p>
</form>

I have seen luasocket but can't find any examples of how to use it to submit
a form.
I guess my first question should be is luasocket the correct technique and
if so, how should I do it ?

Please excuse my lack of knowledge of Lua but I am new to it and hoping to
find a high level solution such as perl's WWW::Mechanize / LWP.

Thank you very much,

John

PS if this is a FAQ please feel free to point me in the right direction.