Class: PHPServer::PHPHandler

Inherits:
HTTPServlet::AbstractServlet
  • Object
show all
Defined in:
lib/php-server/phphandler.rb

Constant Summary collapse

PHPCGI =
'php-cgi'
PHPFPM =
'php-fpm'

Instance Method Summary collapse

Constructor Details

#initialize(server, name) ⇒ PHPHandler

Returns a new instance of PHPHandler.



28
29
30
31
32
33
# File 'lib/php-server/phphandler.rb', line 28

def initialize(server, name)
  super(server, name)
  @phpcmd = [PHPFPM, PHPCGI].map{|bin| File.join(@server[:PHPPath], bin) }.detect{|path| File.exist?(path) }
  @php_fullpath_script = name
  @logger.info("phpcmd: #{@phpcmd}")
end

Instance Method Details

#do_GET(req, res) ⇒ Object Also known as: do_POST

Raises:

  • (WEBrick::HTTPStatus::InternalServerError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/php-server/phphandler.rb', line 35

def do_GET(req, res)
  data = nil
  status = -1

  meta = req.meta_vars
  meta["SCRIPT_FILENAME"] = @php_fullpath_script
  meta["REDIRECT_STATUS"] = "200" # php-cgi/apache specific value
  if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
    meta["SystemRoot"] = ENV["SystemRoot"]
  end
  meta["HTTP_SERVER_PORT"] = meta["SERVER_PORT"]
  meta["REQUEST_URI"] = meta["REQUEST_URI"].gsub /^https?:\/\/[^\/]+/, ''
  ENV.update(meta)

  require "open3"
  stdin, stdout, stderr, thr = Open3.popen3(ENV, @phpcmd)
  begin
    stdin.sync = true

    if req.body and req.body.bytesize > 0
      stdin.write(req.body)
    end
    stdin.close
  ensure
    data = stdout.read
    stdout.close
    stderr.close
    status = thr.value
    sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
  end

  @script_filename = meta['SCRIPT_NAME']
  if status != 0
    @logger.error("PHPHandler: #{@script_filename} exit with #{status}")
  end

  data = "" unless data
  raw_header, body = data.split(/^[\xd\xa]+/, 2)
  raise WEBrick::HTTPStatus::InternalServerError,
        "PHPHandler: Premature end of script headers: #{@script_filename}" if body.nil?

  begin
    header = WEBrick::HTTPUtils::parse_header(raw_header)
    if /^(\d+)/ =~ header['status'][0]
      res.status = $1.to_i
      header.delete('status')
    end
    if header.has_key?('location')
      # RFC 3875 6.2.3, 6.2.4
      res.status = 302 unless (300...400) === res.status
    end
    if header.has_key?('set-cookie')
      header['set-cookie'].each { |k|
        res.cookies << WEBrick::Cookie.parse_set_cookie(k)
      }
      header.delete('set-cookie')
    end
    header.each { |key, val| res[key] = val.join(", ") }
  rescue => ex
    raise WEBrick::HTTPStatus::InternalServerError, ex.message
  end
  res.body = body
end