#--
## Riassence Framework
# Copyright 2008 Riassence Inc.
# http://riassence.com/
#
# You should have received a copy of the GNU General Public License along
# with this software package. If not, contact licensing@riassence.com
##
#++
require 'rubygems'
begin
require 'RMagick'
rescue LoadError
warn "Warning: RMagick not installed, ticketserve images will not be supported."
end
require 'randgen'
## TicketServe serves static and disposable data and images.
## It accepts Magick::Image objects too to render them only when really needed.
## Each serve-call returns an unique uri to pass to the client.
## It performs clean-ups based on session and request time-outs.
class TicketServe < Servlet
# the library path of this plugin
lib_path = File.join( @@bundle_path, 'lib' )
# common functionality
require File.join(lib_path,'common')
include TicketService::Common
# rsrc-related functionality
require File.join(lib_path,'rsrc')
include TicketService::Rsrc
# file-related functionality
require File.join(lib_path,'file')
include TicketService::TicketFile
# upload-related functionality
require File.join(lib_path,'upload')
include TicketService::Upload
# img-related functionality
require File.join(lib_path,'img')
include TicketService::Img
# favicon-related functionality
require File.join(lib_path,'favicon')
include TicketService::Favicon
# smart object wrapper
require File.join(lib_path,'objblob')
include TicketService::ObjBlob
def broker_urls
::RSence.config[:broker_urls]
end
def match( uri, request_type )
if request_type == :post
return true if uri[0..2] == broker_urls[:u]
elsif request_type == :get
if uri.match( /^#{broker_urls[:i]}/ )
return true
elsif uri.match( /^#{broker_urls[:d]}/ )
return true
elsif uri.match( /^#{broker_urls[:f]}/ )
return true
elsif uri.match( /^#{broker_urls[:b]}/ )
return true
elsif uri == broker_urls[:favicon]
return true
elsif uri == broker_urls[:uploader_iframe]
return true
end
end
return false
end
def get( req, res, ses )
uri = req.fullpath
if uri.match( /^#{broker_urls[:i]}/ )
puts "/i: #{uri.inspect}" if RSence.args[:verbose]
get_ticket( req, res, :img )
elsif uri.match( /^#{broker_urls[:d]}/ )
puts "/d: #{uri.inspect}" if RSence.args[:verbose]
get_ticket( req, res, :rsrc )
elsif uri.match( /^#{broker_urls[:f]}/ )
puts "/f: #{uri.inspect}" if RSence.args[:verbose]
get_ticket( req, res, :file )
elsif uri.match( /^#{broker_urls[:b]}/ )
puts "/b: #{uri.inspect}" if RSence.args[:verbose]
get_ticket( req, res, :blobobj )
elsif uri == broker_urls[:favicon]
favicon( req, res )
elsif uri == broker_urls[:uploader_iframe]
puts "/U/iframe_html: #{uri.inspect}" if RSence.args[:verbose]
res.status = 200
http_body = '
Empty Iframe for Uploading'
res['content-type'] = 'text/html; charset=UTF-8'
res['content-length'] = http_body.size.to_s
res.body = http_body
end
end
def post( req, res, ses )
uri = req.fullpath
if uri[0..2] == broker_urls[:u]
puts "/U: #{uri.inspect}" if RSence.args[:verbose]
upload( req, res )
end
end
# Initializes storage.
def init # :nodoc:
# storage for tickets to be expired by expiry time
# as the key and an array of ids in array as the value
@expires = {}
@expire_files = {}
@expire_blobobj = {}
# storage for disposable images
@imgs = {
# id is used as the uri
:by_id => {},
# list of image ids by session id
:ses_ids => {}
}
# storage for other disposable data
@files = {
# id is used as the uri
:by_id => {},
# list of image ids by session id
:ses_ids => {}
}
# an randgen instance used for generating ids (84B long)
@randgen = RandGen.new( 84 )
# supported image content types
@content_types = {
'GIF' => 'image/gif',
'PNG' => 'image/png',
'JPG' => 'image/jpeg'
}
# static data, initially for invalid/not found error-gif
# also all serve_rsrc items
@raw_uris = {
'invalid.gif' => ['image/gif','53',['749464839316700090000800000000004e7ebe129f400000000000c200000000700090000020c0c8f70a9c810e0229ea2da1a000b3'].pack('h*')],
'favicon.ico' => ['image/gif','371',['749464839316010001005d00005e5e3dd1d1a1ca7dbf983cfeb9dc5ff8f848db1effbd1fff27279609a600cacae9e0e0d0dcaeff8e8fff030303010101848424afffff0000007be7008c8c9bffffff878b9e0eba712fcfffb2b282e9c6000d5900020202bd3a70ababbaf8f834f9f9f9f8f8f887fafafafa49060606fefefe0707700707074e3bc2939353ce6cd50404007d7d6cfafafa8edb34dcfcfc0f0d97fbfbfb000000000000000000000000000000000000000000000000000000000000000000000000000000000000129f401000000000c20000000001000100006009040801058c8420e91a258ca41744380506934656846910140e04051092ca650688d282bc2072bb5303e0728c2330d6fbb15a78249291bbf0d0811102353410124677285190b2e524e110e0f208b890a13176a480b0725211c889b16227a44101f0027931b1d171a745a010b2caea82f15845c9627182e2a2e050f5007af0f1a203329bf52be032d2213ca4501021501400b3'].pack('h*')]
}
@upload_slots = {
# upload slots
:by_id => {
# random key mime max_size session_id
# 'test123' => [ '*/*', 15000, 12 ]
},
# processed uploads
:uploaded => {
# same key as :by_id rsence_uploads:id
# 'test123' => [37483,37546,38759]
},
# upload ids by session id
:ses_ids => {
# 12 => ['test123']
}
}
@blob_objs = {
:by_id => {},
:ses_ids => {}
}
@db = Sequel.connect( ::RSence.config[:database][:ses_db] )
end
end
ticketserve = TicketServe.new
# Plugin API for ticket services
class TicketAPI < Plugin
class BlobObj
def initialize(data,mime)
@data = data
@mime = mime
end
def mime
return @mime
end
def data
return @data
end
def size
return @data.size
end
def close
end
end
def set_ticketserve( ticketserve )
@ticketserve = ticketserve
end
def serve( msg, content, format='PNG', type=:img )
@ticketserve.serve( msg, content, format, type )
end
def expire_ses( msg )
@ticketserve.expire_ses( msg.ses_id )
end
def set_favicon( ico_data, content_type=false )
@ticketserve.set_favicon( ico_data, content_type )
end
def del_file( msg, file_id )
@ticketserve.del_file( file_id, msg.ses_id )
end
def serve_file( msg, content='', content_type='text/plain', filename='' )
@ticketserve.serve_file( msg, content, content_type, filename )
end
def del_img( msg, img_id )
@ticketserve.del_img( img_id, msg.ses_id )
end
def serve_img( msg, content, format='PNG', type=:img )
@ticketserve.serve_img( msg, content, format, type )
end
def proto_obj
return BlobObj
end
def serve_obj( msg, blob_obj, no_expire=false )
@ticketserve.serve_blobobj( msg, blob_obj, no_expire )
end
def del_obj( msg, ticket_id )
@ticketserve.del_blobobj( ticket_id, msg.ses_id )
end
def del_rsrc( rsrc_id )
@ticketserve.del_rsrc( rsrc_id )
end
def serve_rsrc( content, content_type )
@ticketserve.serve_rsrc( content, content_type )
end
def get_uploads( ticket_id, with_data=false )
@ticketserve.get_uploads( ticket_id, with_data )
end
def del_upload( ticket_id, row_id )
@ticketserve.del_upload( ticket_id, row_id )
end
def del_uploads( msg, ticket_id )
@ticketserve.del_uploads( ticket_id, msg.ses_id )
end
def upload_key( msg, value_key, max_size=1000000, mime_allow=/(.*?)\/(.*?)/, allow_multi=true )
@ticketserve.upload_key( msg, value_key, max_size, mime_allow, allow_multi )
end
end
ticket = TicketAPI.new
ticket.register( 'ticket' )
ticket.set_ticketserve( ticketserve )