All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jruby.rack.grizzly_helper.rb Maven / Gradle / Ivy

#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
# Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
# and Distribution License("CDDL") (collectively, the "License").  You
# may not use this file except in compliance with the License. You can obtain
# a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
# or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
# language governing permissions and limitations under the License.
#
# When distributing the software, include this License Header Notice in each
# file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
# Sun designates this particular file as subject to the "Classpath" exception
# as provided by Sun in the GPL Version 2 section of the License file that
# accompanied this code.  If applicable, add the following below the License
# Header, with the fields enclosed by brackets [] replaced by your own
# identifying information: "Portions Copyrighted [year]
# [name of copyright owner]"
#
# Contributor(s):
#
# If you wish your version of this file to be governed by only the CDDL or
# only the GPL Version 2, indicate your decision by adding "[Contributor]
# elects to include this software in this distribution under the [CDDL or GPL
# Version 2] license."  If you don't indicate a single choice of license, a
# recipient has the option to distribute your version of this file under
# either the CDDL, the GPL Version 2 or to extend the choice of license to
# its licensees as provided above.  However, if you add GPL Version 2 code
# and therefore, elected the GPL Version 2 license, then the option applies
# only if the new code is made subject to such option by the copyright
# holder.
#

module JRuby
  module Rack
    class Response
      include Java::com.sun.grizzly.jruby.rack.RackResponse
      def initialize(arr)
        @status, @headers, @body = *arr
      end

      def getStatus
        @status
      end

      def getHeaders
        @headers
      end

      def getBody
        b = ""
        begin
        @body.each {|part| b << part }
        ensure
          @body.close  if @body.respond_to? :close
        end
        b
      end

      def respond(response)
        if fwd = @headers["Forward"]
          fwd.call(response)
        else
            write_status(response)
            write_headers(response)
            write_body(response)
        end
      end

      def write_status(response)
        response.setStatus(@status.to_i)
      end

      def write_headers(response)
        mime_headers = response.getResponse().getMimeHeaders()

        @headers.each do |k,v|
          case k
          when /^Content-Type$/i
            response.content_type = v.to_s
          when /^Content-Length$/i
            response.content_length = v.to_i
          else
              if v.respond_to?(:each)                              
                v.each do |val|
                  len = rstrip_newline(val)
                  mime_headers.addValue(k.to_java_bytes,0, k.length).setBytes(val.to_java_bytes, 0, len)
                end
              else
                len = rstrip_newline(v)
                mime_headers.addValue(k.to_java_bytes,0, k.length).setBytes(val.to_java_bytes, 0, val.length)
              end
          end
        end
      end

      # Strips off any \r or \n from the end of the
      # v MUST not be null
      def rstrip_newline(v)
        len = v.size
        (v.size-1).downto(0) do |i|
          if(v[i] == 10 || v[i] == 13)
            len -= 1
          end
        end
        len
      end
      

      def write_body(response)
        stream = response.output_stream
        begin
          @body.each do |el|
            stream.write(el.to_java_bytes)
          end
        ensure
          @body.close  if @body.respond_to? :close
        end          
      end
    end


    class GrizzlyLog
      def initialize(logger = $logger)
        @logger = logger
      end
      def puts(msg)
        write msg.to_s
      end

      def write(msg)
        case $gf_ruby_log_level
          when 3,4,5 then @logger.severe("#{msg}")
          when 2 then @logger.warning("#{msg}")
          when 0,1 then @logger.info("#{msg}")
          else @logger.info("#{msg}") 
        end
      end

      def flush; end
      def close; end
    end

    class GrizzlyHelper
      attr_reader :public_root, :gem_path

      def initialize(glassfish_config = nil)
        @glassfish_config = glassfish_config || $glassfish_config
        @public_root = File.join(@glassfish_config.app_root, "public")
        @gem_path = @glassfish_config.gem_path
        setup_gems
      end

      def logdev
        @logdev ||= GrizzlyLog.new
      end

      def logger
        @logger ||= begin; require 'logger'; Logger.new(logdev); end
      end

      def setup_gems
        ENV['GEM_PATH'] = @gem_path
      end

      def self.instance
        @instance ||= self.new
      end
    end

    class Errors
      def initialize(file_server)
        @file_server = file_server
      end

      def call(env)
        [code = response_code(env), *response_content(env, code)]
      end

      def response_code(env)
        exc = env['rack.exception']
        if exc
          env['rack.showstatus.detail'] = exc.getMessage
          if exc.getCause.kind_of?(Java::JavaLang::InterruptedException)
            503
          else
            500
          end
        else
          500
        end
      end

      def response_content(env, code)
        @responses ||= Hash.new do |h,k|
          env["PATH_INFO"] = "/#{code}.html"
          response = @file_server.call(env)
          body = response[2]
          unless Array === body
            newbody = ""
            body.each do |chunk|
              newbody << chunk
            end
            response[2] = [newbody]
          end
          h[k] = response
        end
        response = @responses[code]
        if response[0] != 404
          env["rack.showstatus.detail"] = nil
          response[1..2]
        else
          [{}, []]
        end
      end
    end

    class ErrorsApp
      def self.new
        ::Rack::Builder.new {
          use ::Rack::ShowStatus
          run Errors.new(::Rack::File.new(GrizzlyHelper.instance.public_root))
        }.to_app
      end
    end
  end
end




© 2015 - 2025 Weber Informatics LLC | Privacy Policy