Class: SBSM::RackInterface

Inherits:
Object
  • Object
show all
Defined in:
lib/sbsm/app.rb

Constant Summary collapse

SESSION_ID =
'_session_id'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app:, validator: nil, trans_handler: nil, session_class: nil, persistence_layer: nil, unknown_user: nil, cookie_name: nil, multi_threaded: nil) ⇒ RackInterface

Base class for a SBSM based WebRick HTTP server

  • offer a call(env) method form handling the WebRick requests

This is all what is needed to be compatible with WebRick

optional arguments

  • app - A Ruby class used by the session

  • validator - A Ruby class overriding the SBSM::Validator class

  • trans_handler - A Ruby class overriding the SBSM::TransHandler class

  • session_class - A Ruby class overriding the SBSM::Session class

  • unknown_user - A Ruby class overriding the SBSM::UnknownUser class

  • persistence_layer - Persistence Layer to use

  • cookie_name - The cookie to save persistent user data

  • multi_threaded - Allow multi_threaded SBSM (default is false)

Examples

Look at steinwies.ch



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/sbsm/app.rb', line 69

def initialize(app:,
               validator: nil,
               trans_handler:  nil,
               session_class: nil,
               persistence_layer: nil,
               unknown_user: nil,
               cookie_name: nil,
               multi_threaded: nil
             )
  @@last_session = nil
  @app = app
  SBSM.info "initialize validator #{validator} th #{trans_handler} cookie #{cookie_name} session #{session_class} app #{app} multi_threaded #{multi_threaded}"
  @session_store = SessionStore.new(app: app,
                                    persistence_layer: persistence_layer,
                                    trans_handler: trans_handler,
                                    session_class: session_class,
                                    cookie_name: cookie_name,
                                    unknown_user: unknown_user,
                                    validator: validator,
                                    multi_threaded: multi_threaded)
  @unknown_user = unknown_user
end

Instance Attribute Details

#sessionObject

thread variable!



46
47
48
# File 'lib/sbsm/app.rb', line 46

def session
  @session
end

#session_storeObject (readonly)

Returns the value of attribute session_store.



47
48
49
# File 'lib/sbsm/app.rb', line 47

def session_store
  @session_store
end

#unknown_userObject (readonly)

Returns the value of attribute unknown_user.



47
48
49
# File 'lib/sbsm/app.rb', line 47

def unknown_user
  @unknown_user
end

Instance Method Details

#call(env) ⇒ Object

mimick sbsm/lib/app.rb



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/sbsm/app.rb', line 96

def call(env) ## mimick sbsm/lib/app.rb
  request = Rack::Request.new(env)
  response = Rack::Response.new
  if request.cookies[SESSION_ID] && request.cookies[SESSION_ID].length > 1
    session_id = request.cookies[SESSION_ID]
  else
    session_id = rand((2**(0.size * 8 -2) -1)*10240000000000).to_s(16)
  end
  if '/'.eql?(request.path)
    file_name = File.expand_path(File.join('doc', 'index.html'))
  else
    file_name = File.expand_path(File.join('doc', request.path))
  end

  if File.file?(file_name)
    if File.extname(file_name).length > 0
      mime_type = MimeMagic.by_extension(File.extname(file_name)).type
    else
      mime_type = MimeMagic.by_path(file_name)
    end
    mime_type ||= 'text/plain'
    SBSM.debug "file_name is #{file_name} checkin base #{File.basename(file_name)} MIME #{mime_type}"
    response.set_header('Content-Type', mime_type)
    response.write(File.open(file_name, File::RDONLY){|file| file.read})
    return response
  end

  return [400, {}, []] if /favicon.ico/i.match(request.path)
  Thread.current.thread_variable_set(:session, @session_store[session_id])
  session = Thread.current.thread_variable_get(:session)
  SBSM.debug "starting session_id #{session_id}  session #{session.class} #{request.path}: cookies #{@cookie_name} are #{request.cookies} @cgi #{@cgi.class}"
  res = session.process_rack(rack_request: request)
  thru = session.get_passthru
  if thru.size > 0
    begin
      file_name = thru.first.untaint
      raise Errno::ENOENT unless File.exist?(file_name)
      response.set_header('Content-Type', MimeMagic.by_extension(File.extname(file_name)).type)
      response.headers['Content-Disposition'] = "#{thru.last}; filename=#{File.basename(file_name)}"
      response.headers['Content-Length'] =  File.size(file_name).to_s
      response.write(File.open(file_name, File::RDONLY){|file| file.read})
    rescue Errno::ENOENT, IOError => err
      error_msg = "#{file_name} Not found\n"
      SBSM.error("#{err.message} #{thru.first} => #{error_msg}")
      return [404, {'Content-Type' => 'text/html', 'Content-Length' => error_msg.size.to_s}, [error_msg]]
    end
  else
    response.write res unless request.request_method.eql?('HEAD')
    response.headers['Content-Type'] ||= 'text/html; charset=utf-8'
    response.headers.merge!(session.http_headers)
  end

  if (result = response.headers.find { |k,v| /status/i.match(k) })
    response.status = result.last.to_i
    response.headers.delete(result.first)
  end
  response.set_cookie(session.persistent_cookie_name,
                      { :value    => session.cookie_pairs,
                        :path     => "/",
                        :expires  => (Time.now + (60 * 60 * 24 * 365 * 10))})
  response.set_cookie(SESSION_ID, { :value => session_id, :path => '/' ,  :expires => (Time.now + (60 * 60 * 24 * 365 * 10)) })
  # bad idea to reset rack_request if we need more page
  @@last_session = session
  if response.headers['Set-Cookie'].to_s.index(session_id)
    SBSM.debug "finish session_id.1 #{session_id}: matches response.headers['Set-Cookie'] #{response.headers['Set-Cookie']}"
  else
    SBSM.debug "finish session_id.2 #{session_id}: headers #{response.headers}"
  end
  response.status = 302 if response.headers['Location']
  response.finish
end

#last_sessionObject



92
93
94
# File 'lib/sbsm/app.rb', line 92

def last_session
  @@last_session
end