1# frozen_string_literal: true
2#
3# cgi.rb - cgi support library
4#
5# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
6#
7# Copyright (C) 2000  Information-technology Promotion Agency, Japan
8#
9# Author: Wakou Aoyama <wakou@ruby-lang.org>
10#
11# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
12#
13
14# == Overview
15#
16# The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP
17# request from a web server to a standalone program, and returning the output
18# to the web browser.  Basically, a CGI program is called with the parameters
19# of the request passed in either in the environment (GET) or via $stdin
20# (POST), and everything it prints to $stdout is returned to the client.
21#
22# This file holds the CGI class.  This class provides functionality for
23# retrieving HTTP request parameters, managing cookies, and generating HTML
24# output.
25#
26# The file CGI::Session provides session management functionality; see that
27# class for more details.
28#
29# See http://www.w3.org/CGI/ for more information on the CGI protocol.
30#
31# == Introduction
32#
33# CGI is a large class, providing several categories of methods, many of which
34# are mixed in from other modules.  Some of the documentation is in this class,
35# some in the modules CGI::QueryExtension and CGI::HtmlExtension.  See
36# CGI::Cookie for specific information on handling cookies, and cgi/session.rb
37# (CGI::Session) for information on sessions.
38#
39# For queries, CGI provides methods to get at environmental variables,
40# parameters, cookies, and multipart request data.  For responses, CGI provides
41# methods for writing output and generating HTML.
42#
43# Read on for more details.  Examples are provided at the bottom.
44#
45# == Queries
46#
47# The CGI class dynamically mixes in parameter and cookie-parsing
48# functionality,  environmental variable access, and support for
49# parsing multipart requests (including uploaded files) from the
50# CGI::QueryExtension module.
51#
52# === Environmental Variables
53#
54# The standard CGI environmental variables are available as read-only
55# attributes of a CGI object.  The following is a list of these variables:
56#
57#
58#   AUTH_TYPE               HTTP_HOST          REMOTE_IDENT
59#   CONTENT_LENGTH          HTTP_NEGOTIATE     REMOTE_USER
60#   CONTENT_TYPE            HTTP_PRAGMA        REQUEST_METHOD
61#   GATEWAY_INTERFACE       HTTP_REFERER       SCRIPT_NAME
62#   HTTP_ACCEPT             HTTP_USER_AGENT    SERVER_NAME
63#   HTTP_ACCEPT_CHARSET     PATH_INFO          SERVER_PORT
64#   HTTP_ACCEPT_ENCODING    PATH_TRANSLATED    SERVER_PROTOCOL
65#   HTTP_ACCEPT_LANGUAGE    QUERY_STRING       SERVER_SOFTWARE
66#   HTTP_CACHE_CONTROL      REMOTE_ADDR
67#   HTTP_FROM               REMOTE_HOST
68#
69#
70# For each of these variables, there is a corresponding attribute with the
71# same name, except all lower case and without a preceding HTTP_.
72# +content_length+ and +server_port+ are integers; the rest are strings.
73#
74# === Parameters
75#
76# The method #params() returns a hash of all parameters in the request as
77# name/value-list pairs, where the value-list is an Array of one or more
78# values.  The CGI object itself also behaves as a hash of parameter names
79# to values, but only returns a single value (as a String) for each
80# parameter name.
81#
82# For instance, suppose the request contains the parameter
83# "favourite_colours" with the multiple values "blue" and "green".  The
84# following behavior would occur:
85#
86#   cgi.params["favourite_colours"]  # => ["blue", "green"]
87#   cgi["favourite_colours"]         # => "blue"
88#
89# If a parameter does not exist, the former method will return an empty
90# array, the latter an empty string.  The simplest way to test for existence
91# of a parameter is by the #has_key? method.
92#
93# === Cookies
94#
95# HTTP Cookies are automatically parsed from the request.  They are available
96# from the #cookies() accessor, which returns a hash from cookie name to
97# CGI::Cookie object.
98#
99# === Multipart requests
100#
101# If a request's method is POST and its content type is multipart/form-data,
102# then it may contain uploaded files.  These are stored by the QueryExtension
103# module in the parameters of the request.  The parameter name is the name
104# attribute of the file input field, as usual.  However, the value is not
105# a string, but an IO object, either an IOString for small files, or a
106# Tempfile for larger ones.  This object also has the additional singleton
107# methods:
108#
109# #local_path():: the path of the uploaded file on the local filesystem
110# #original_filename():: the name of the file on the client computer
111# #content_type():: the content type of the file
112#
113# == Responses
114#
115# The CGI class provides methods for sending header and content output to
116# the HTTP client, and mixes in methods for programmatic HTML generation
117# from CGI::HtmlExtension and CGI::TagMaker modules.  The precise version of HTML
118# to use for HTML generation is specified at object creation time.
119#
120# === Writing output
121#
122# The simplest way to send output to the HTTP client is using the #out() method.
123# This takes the HTTP headers as a hash parameter, and the body content
124# via a block.  The headers can be generated as a string using the #http_header()
125# method.  The output stream can be written directly to using the #print()
126# method.
127#
128# === Generating HTML
129#
130# Each HTML element has a corresponding method for generating that
131# element as a String.  The name of this method is the same as that
132# of the element, all lowercase.  The attributes of the element are
133# passed in as a hash, and the body as a no-argument block that evaluates
134# to a String.  The HTML generation module knows which elements are
135# always empty, and silently drops any passed-in body.  It also knows
136# which elements require matching closing tags and which don't.  However,
137# it does not know what attributes are legal for which elements.
138#
139# There are also some additional HTML generation methods mixed in from
140# the CGI::HtmlExtension module.  These include individual methods for the
141# different types of form inputs, and methods for elements that commonly
142# take particular attributes where the attributes can be directly specified
143# as arguments, rather than via a hash.
144#
145# === Utility HTML escape and other methods like a function.
146#
147# There are some utility tool defined in cgi/util.rb .
148# And when include, you can use utility methods like a function.
149#
150# == Examples of use
151#
152# === Get form values
153#
154#   require "cgi"
155#   cgi = CGI.new
156#   value = cgi['field_name']   # <== value string for 'field_name'
157#     # if not 'field_name' included, then return "".
158#   fields = cgi.keys            # <== array of field names
159#
160#   # returns true if form has 'field_name'
161#   cgi.has_key?('field_name')
162#   cgi.has_key?('field_name')
163#   cgi.include?('field_name')
164#
165# CAUTION! cgi['field_name'] returned an Array with the old
166# cgi.rb(included in Ruby 1.6)
167#
168# === Get form values as hash
169#
170#   require "cgi"
171#   cgi = CGI.new
172#   params = cgi.params
173#
174# cgi.params is a hash.
175#
176#   cgi.params['new_field_name'] = ["value"]  # add new param
177#   cgi.params['field_name'] = ["new_value"]  # change value
178#   cgi.params.delete('field_name')           # delete param
179#   cgi.params.clear                          # delete all params
180#
181#
182# === Save form values to file
183#
184#   require "pstore"
185#   db = PStore.new("query.db")
186#   db.transaction do
187#     db["params"] = cgi.params
188#   end
189#
190#
191# === Restore form values from file
192#
193#   require "pstore"
194#   db = PStore.new("query.db")
195#   db.transaction do
196#     cgi.params = db["params"]
197#   end
198#
199#
200# === Get multipart form values
201#
202#   require "cgi"
203#   cgi = CGI.new
204#   value = cgi['field_name']   # <== value string for 'field_name'
205#   value.read                  # <== body of value
206#   value.local_path            # <== path to local file of value
207#   value.original_filename     # <== original filename of value
208#   value.content_type          # <== content_type of value
209#
210# and value has StringIO or Tempfile class methods.
211#
212# === Get cookie values
213#
214#   require "cgi"
215#   cgi = CGI.new
216#   values = cgi.cookies['name']  # <== array of 'name'
217#     # if not 'name' included, then return [].
218#   names = cgi.cookies.keys      # <== array of cookie names
219#
220# and cgi.cookies is a hash.
221#
222# === Get cookie objects
223#
224#   require "cgi"
225#   cgi = CGI.new
226#   for name, cookie in cgi.cookies
227#     cookie.expires = Time.now + 30
228#   end
229#   cgi.out("cookie" => cgi.cookies) {"string"}
230#
231#   cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }
232#
233#   require "cgi"
234#   cgi = CGI.new
235#   cgi.cookies['name'].expires = Time.now + 30
236#   cgi.out("cookie" => cgi.cookies['name']) {"string"}
237#
238# === Print http header and html string to $DEFAULT_OUTPUT ($>)
239#
240#   require "cgi"
241#   cgi = CGI.new("html4")  # add HTML generation methods
242#   cgi.out do
243#     cgi.html do
244#       cgi.head do
245#         cgi.title { "TITLE" }
246#       end +
247#       cgi.body do
248#         cgi.form("ACTION" => "uri") do
249#           cgi.p do
250#             cgi.textarea("get_text") +
251#             cgi.br +
252#             cgi.submit
253#           end
254#         end +
255#         cgi.pre do
256#           CGI::escapeHTML(
257#             "params: #{cgi.params.inspect}\n" +
258#             "cookies: #{cgi.cookies.inspect}\n" +
259#             ENV.collect do |key, value|
260#               "#{key} --> #{value}\n"
261#             end.join("")
262#           )
263#         end
264#       end
265#     end
266#   end
267#
268#   # add HTML generation methods
269#   CGI.new("html3")    # html3.2
270#   CGI.new("html4")    # html4.01 (Strict)
271#   CGI.new("html4Tr")  # html4.01 Transitional
272#   CGI.new("html4Fr")  # html4.01 Frameset
273#   CGI.new("html5")    # html5
274#
275# === Some utility methods
276#
277#   require 'cgi/util'
278#   CGI.escapeHTML('Usage: foo "bar" <baz>')
279#
280#
281# === Some utility methods like a function
282#
283#   require 'cgi/util'
284#   include CGI::Util
285#   escapeHTML('Usage: foo "bar" <baz>')
286#   h('Usage: foo "bar" <baz>') # alias
287#
288#
289
290class CGI
291end
292
293require 'cgi/core'
294require 'cgi/cookie'
295require 'cgi/util'
296CGI.autoload(:HtmlExtension, 'cgi/html')
297