非常教程

Ruby 2.4参考手册

CGI

CGI::QueryExtension

Mixin模块提供以下功能:

  1. 作为方法访问CGI环境变量。有关这些变量的列表,请参阅CGI类的文档。通过删除前导HTTP_(如果存在)并降低名称来暴露这些方法。例如,auth_type将返回环境变量AUTH_TYPEaccept并将返回值HTTP_ACCEPT

2. 访问cookie,包括cookie属性。

3. 访问参数,包括params属性,并重载[]以通过键执行参数值查找。

4. #initialize_query方法用于初始化上述机制,处理多部分表单以及允许在“脱机”模式下使用该类。

属性

cookiesRW

获取cookie作为cookie-name => Cookie对的散列。

filesR

将上传的文件作为名称=>值对的散列

paramsR

获取参数作为name => values对的散列值,其中values是一个Array。

公共实例方法

显示来源

用给定的键获取参数的值。

如果该参数具有多个值,则仅检索第一个值; 使用参数来获取值的数组。

# File lib/cgi/core.rb, line 694
def [](key)
  params = @params[key]
  return '' unless params
  value = params[0]
  if @multipart
    if value
      return value
    elsif defined? StringIO
      StringIO.new("".force_encoding(Encoding::ASCII_8BIT))
    else
      Tempfile.new("CGI",encoding: Encoding::ASCII_8BIT)
    end
  else
    str = if value then value.dup else "" end
    str
  end
end

has_key?(*args) Show source

如果给定的查询字符串参数存在,则返回true。

# File lib/cgi/core.rb, line 718
def has_key?(*args)
  @params.has_key?(*args)
end

还有别名:key ?,包括?

include?(*args)

Alias for: has_key?

key?(*args)

Alias for: has_key?

keys(*args) Show source

将所有查询参数名称返回为String数组。

# File lib/cgi/core.rb, line 713
def keys(*args)
  @params.keys(*args)
end

multipart?()显示源文件

返回表单是否包含multipart / form-data

# File lib/cgi/core.rb, line 686
def multipart?
  @multipart
end

params=(hash) 显示源文件

设置所有参数。

# File lib/cgi/core.rb, line 455
def params=(hash)
  @params.clear
  @params.update(hash)
end

raw_cookie()显示源文件

将原始cookie作为字符串获取。

# File lib/cgi/core.rb, line 435
def raw_cookie
  env_table["HTTP_COOKIE"]
end

raw_cookie2()显示源文件

将原始RFC2965 Cookie作为字符串获取。

# File lib/cgi/core.rb, line 440
def raw_cookie2
  env_table["HTTP_COOKIE2"]
end

私有实例方法

initialize_query()显示源文件

一个包装类,用于将StringIO对象作为主体,并在传入阈值时切换到TempFile。初始化查询中的数据。

处理多部分表单(特别是涉及文件上传的表单)。在@params字段中读取查询参数,并将cookie写入@cookies。

# File lib/cgi/core.rb, line 641
def initialize_query()
  if ("POST" == env_table['REQUEST_METHOD']) and
    %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|.match(env_table['CONTENT_TYPE'])
    current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length
    raise StandardError.new("too large multipart data.") if env_table['CONTENT_LENGTH'].to_i > current_max_multipart_length
    boundary = $1.dup
    @multipart = true
    @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
  else
    @multipart = false
    @params = CGI::parse(
                case env_table['REQUEST_METHOD']
                when "GET", "HEAD"
                  if defined?(MOD_RUBY)
                    Apache::request.args or ""
                  else
                    env_table['QUERY_STRING'] or ""
                  end
                when "POST"
                  stdinput.binmode if defined? stdinput.binmode
                  stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
                else
                  read_from_cmdline
                end.dup.force_encoding(@accept_charset)
              )
    unless Encoding.find(@accept_charset) == Encoding::ASCII_8BIT
      @params.each do |key,values|
        values.each do |value|
          unless value.valid_encoding?
            if @accept_charset_error_block
              @accept_charset_error_block.call(key,value)
            else
              raise InvalidEncoding,"Accept-Charset encoding error"
            end
          end
        end
      end
    end
  end

  @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
end

read_from_cmdline()显示源文件

离线模式。在标准输入上读取名称=值对。

# File lib/cgi/core.rb, line 606
def read_from_cmdline
  require "shellwords"

  string = unless ARGV.empty?
    ARGV.join(' ')
  else
    if STDIN.tty?
      STDERR.print(
        %Q|(offline mode: enter name=value pairs on standard input)\n|
      )
    end
    array = readlines rescue nil
    if not array.nil?
        array.join(' ').gsub(/\n/n, '')
    else
        ""
    end
  end.gsub(/\=/n, '%3D').gsub(/\&/n, '%26')

  words = Shellwords.shellwords(string)

  if words.find{|x| /=/n.match(x) }
    words.join('&')
  else
    words.join('+')
  end
end

read_multipart(boundary, content_length)显示源

根据分析多部分表单元素

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

根据多部分表单元素是否超过10 KB,返回多部分表单参数与StringIO或Tempfile类型主体的散列

params[name => body]
# File lib/cgi/core.rb, line 469
def read_multipart(boundary, content_length)
  ## read first boundary
  stdin = stdinput
  first_line = "--#{boundary}#{EOL}"
  content_length -= first_line.bytesize
  status = stdin.read(first_line.bytesize)
  raise EOFError.new("no content body")  unless status
  raise EOFError.new("bad content body") unless first_line == status
  ## parse and set params
  params = {}
  @files = {}
  boundary_rexp = /--#{Regexp.quote(boundary)}(#{EOL}|--)/
  boundary_size = "#{EOL}--#{boundary}#{EOL}".bytesize
  buf = ''
  bufsize = 10 * 1024
  max_count = MAX_MULTIPART_COUNT
  n = 0
  tempfiles = []
  while true
    (n += 1) < max_count or raise StandardError.new("too many parameters.")
    ## create body (StringIO or Tempfile)
    body = create_body(bufsize < content_length)
    tempfiles << body if defined?(Tempfile) && body.kind_of?(Tempfile)
    class << body
      if method_defined?(:path)
        alias local_path path
      else
        def local_path
          nil
        end
      end
      attr_reader :original_filename, :content_type
    end
    ## find head and boundary
    head = nil
    separator = EOL * 2
    until head && matched = boundary_rexp.match(buf)
      if !head && pos = buf.index(separator)
        len  = pos + EOL.bytesize
        head = buf[0, len]
        buf  = buf[(pos+separator.bytesize)..-1]
      else
        if head && buf.size > boundary_size
          len = buf.size - boundary_size
          body.print(buf[0, len])
          buf[0, len] = ''
        end
        c = stdin.read(bufsize < content_length ? bufsize : content_length)
        raise EOFError.new("bad content body") if c.nil? || c.empty?
        buf << c
        content_length -= c.bytesize
      end
    end
    ## read to end of boundary
    m = matched
    len = m.begin(0)
    s = buf[0, len]
    if s =~ /(\r?\n)\z/
      s = buf[0, len - $1.bytesize]
    end
    body.print(s)
    buf = buf[m.end(0)..-1]
    boundary_end = m[1]
    content_length = -1 if boundary_end == '--'
    ## reset file cursor position
    body.rewind
    ## original filename
    /Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
    filename = $1 || $2 || ''
    filename = CGI.unescape(filename) if unescape_filename?()
    body.instance_variable_set(:@original_filename, filename.taint)
    ## content type
    /Content-Type: (.*)/i.match(head)
    (content_type = $1 || '').chomp!
    body.instance_variable_set(:@content_type, content_type.taint)
    ## query parameter name
    /Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
    name = $1 || $2 || ''
    if body.original_filename.empty?
      value=body.read.dup.force_encoding(@accept_charset)
      body.close! if defined?(Tempfile) && body.kind_of?(Tempfile)
      (params[name] ||= []) << value
      unless value.valid_encoding?
        if @accept_charset_error_block
          @accept_charset_error_block.call(name,value)
        else
          raise InvalidEncoding,"Accept-Charset encoding error"
        end
      end
      class << params[name].last;self;end.class_eval do
        define_method(:read){self}
        define_method(:original_filename){""}
        define_method(:content_type){""}
      end
    else
      (params[name] ||= []) << body
      @files[name]=body
    end
    ## break loop
    break if content_length == -1
  end
  raise EOFError, "bad boundary end of body part" unless boundary_end =~ /--/
  params.default = []
  params
rescue Exception
  if tempfiles
    tempfiles.each {|t|
      if t.path
        t.close!
      end
    }
  end
  raise
end
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct