~ubuntu-branches/ubuntu/wily/lua-lgi/wily-proposed

« back to all changes in this revision

Viewing changes to samples/soupsvr.lua

  • Committer: Package Import Robot
  • Author(s): Enrico Tassi
  • Date: 2012-06-25 13:36:04 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: package-import@ubuntu.com-20120625133604-3v03ss7t7cwdmp6z
Tags: upstream-0.7.1
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env lua
 
2
 
 
3
--
 
4
-- Sample server using libsoup library.  Listens on 1080 port and serves
 
5
-- local files from current directory.  Allows to be terminated by query
 
6
-- for /quit file (i.e. curl http://localhost:1080/quit)
 
7
--
 
8
 
 
9
local coroutine = require 'coroutine'
 
10
 
 
11
local lgi = require 'lgi'
 
12
local bytes = require 'bytes'
 
13
local GLib = lgi.GLib
 
14
local Gio = lgi.Gio
 
15
local Soup = lgi.Soup
 
16
 
 
17
local app = Gio.Application { application_id = 'org.lgi.soupsvr' }
 
18
function app:on_activate()
 
19
   app:hold()
 
20
 
 
21
   local server = Soup.Server { port = 1080 }
 
22
 
 
23
   -- Set up quit handler.
 
24
   server:add_handler('/quit', function(server, msg, path, query, ctx)
 
25
      msg.status_code = 200
 
26
      msg.response_body:complete()
 
27
      server:quit()
 
28
      app:release()
 
29
   end)
 
30
 
 
31
   -- Set up file retriever handler.
 
32
   server:add_handler('/', function(server, msg, path, query, ctx)
 
33
      local stream = Gio.File.new_for_path(path:sub(2)):read()
 
34
      if stream then
 
35
         -- The whole is send by function running in coroutine.
 
36
         -- Coroutine yields when it waits either for data from the
 
37
         -- disk or signal that chunk was successfully sent.
 
38
         local next_chunk = coroutine.wrap(function()
 
39
            local buffer = bytes.new(4096)
 
40
            while true do
 
41
               -- Read another chunk of data from the source to the
 
42
               -- buffer.
 
43
               stream:read_async(buffer, #buffer, GLib.PRIORITY_DEFAULT, nil,
 
44
                                 coroutine.running())
 
45
               local size = stream.read_finish(coroutine.yield())
 
46
               if size < 0 then
 
47
                  -- IO error reading disk, this simply shuts our toy
 
48
                  -- server down.
 
49
                  server:quit()
 
50
                  app:release()
 
51
                  return
 
52
               end
 
53
 
 
54
               -- Send the chunk to the message body.
 
55
               msg.response_body:append(tostring(buffer):sub(1, size))
 
56
               server:unpause_message(msg)
 
57
 
 
58
               -- Wait until soup signalizes that chunk was written.
 
59
               coroutine.yield()
 
60
               if (size < #buffer) then break end
 
61
            end
 
62
            msg.response_body:complete()
 
63
         end)
 
64
 
 
65
         -- Prepare sending using chunked method.
 
66
         msg.status_code = 200
 
67
         msg.response_headers:set_encoding('CHUNKED')
 
68
 
 
69
         -- When headers are written, start writing body by initial
 
70
         -- resuming of sending coroutine.
 
71
         msg.on_wrote_headers = next_chunk
 
72
 
 
73
         -- When the chunk is sent, resume coroutine so that it starts
 
74
         -- reading and sending another chunk.
 
75
         msg.on_wrote_chunk = next_chunk
 
76
      else
 
77
         -- File was not found, send proper code.
 
78
         msg.status_code = 404
 
79
         msg.response_body:complete()
 
80
      end
 
81
   end)
 
82
 
 
83
   -- Start the server running asynchronously.
 
84
   server:run_async()
 
85
end
 
86
 
 
87
app:run { arg[0], ... }