Class: SWS::Adaptor::CGI

Inherits:
Generic show all
Defined in:
lib/sws/adaptor.rb

Overview

CGI Adaptor. CGI scripts are not persitant, so I had to use some ugly hacks (including drb) to make it work transparently for the user (and developer). It has a serious bug - if the response is bigger than 8kB it is not returned to the client correctly. The use of this adaptor is discouraged and it may be removed in future versions.

Constant Summary

Constants inherited from Generic

Generic::HEADER_TRANSLATION

Instance Attribute Summary

Attributes inherited from Generic

#base_path

Instance Method Summary collapse

Constructor Details

#initialize(drb_port = 2345) ⇒ CGI

Returns a new instance of CGI.



221
222
223
224
225
226
227
228
# File 'lib/sws/adaptor.rb', line 221

def initialize ( drb_port = 2345 )

  # 'Require' included here, so that DRb is not loaded if this adaptor is
  # not used
  require 'drb' 
  @drb_port = drb_port

end

Instance Method Details

#create_requestObject

Creates SWS::Request object from ENV variables



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/sws/adaptor.rb', line 295

def create_request ()
  
  request_method = ENV["REQUEST_METHOD"]
  path = ENV["PATH_INFO"] || "/"
  $stderr.puts( "Path: #{path}" )
  # This may be invalid - but it isn't propably important
  http_version = ENV["SERVER_PROTOCOL"]
  request = Request.new( request_method, path, http_version )

  HEADER_TRANSLATION.each do |env_variable,header_name|
    request.headers[header_name] = ENV[env_variable]
  end

  content_length = ENV["CONTENT_LENGTH"]
  if ( content_length )
    request.content = $stdin.read( content_length.to_i )
  end          
  
  request.process_headers()
  request.process_content() if ( request.has_content? )
  return request

end

#each_requestObject

Main adaptor methods - invokes block for each received request



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/sws/adaptor.rb', line 270

def each_request ()

  loop do
  
    @each_request_mutex.lock()
    response = yield( @current_request )
    # print( "Status: 200 OK\n" )
    # print( "Content-type: text/html;charset=iso-8859-2\n") 
    # print( "Pragma: no-cache\n" )
    # print( "Set-Cookie: session=6aa83079b309dd51d2dee0b1250719ca; path=/\n" )
    # print( "\n")
    print( "Status: #{response.status}\r\n" )
    $stderr.puts( "B1" )
    $stderr.puts( "BEfore Response: #{response.to_s}"  )
    print( response.to_s )
    print( "\r\n" )
    $stderr.puts( "After Response"  )
    @handle_request_mutex.unlock()

  end
  
end

#runObject

Setup DRb server. Remember the DRBObject is the adaptor itself.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/sws/adaptor.rb', line 232

def run ()

  request = create_request()

  # Base_path will be set on every request. This doesn't matter though,
  # because on the remote adaptor it will be set only once
  @base_path = ENV["SCRIPT_NAME"] + "/"
  
  begin
    
    adaptor = DRb::DRbObject.new_with_uri( "druby://localhost:#{@drb_port}" )
    # Try to use the remote Adaptor object
    adaptor.handle_request( request )

  rescue DRb::DRbConnError

    # Attempt to retrieve remote Adaptor object failed - need to start the DRb server
  
    # Probably not necessary
    trap( "SIGCLD", "IGNORE" ) 

    # Terminate parent and run child in daemon mode
    if ( fork() ) then exit(0) end
    DRb.start_service( "druby://localhost:#{@drb_port}", self )
    Process.setsid()

    @each_request_mutex = Mutex.new() 
    @each_request_mutex.lock() 
    @handle_request_mutex = Mutex.new()

    handle_request( request )

  end

end