First integration of the new GW_ design more centralized on connector, and does not require specific feature on GW_APPLICATION depending on the connector.
So this is really more flexible this way, and much easier to write application supporting CGI, FCGI, Nino and so on .. as demonstrated in hello_world This is a first version, more will come later, mainly migrating from Eiffel Web Reloaded to this Eiffel Web Framework project.
This commit is contained in:
Submodule ext/server/nino updated: c772fc5194...de77802546
16
library/error/error-safe.ecf
Normal file
16
library/error/error-safe.ecf
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="error" uuid="C2DFF741-7091-43C7-B8B1-B075E7FF914F" library_target="error">
|
||||
<target name="error">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
16
library/error/error.ecf
Normal file
16
library/error/error.ecf
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="error" uuid="C2DFF741-7091-43C7-B8B1-B075E7FF914F" library_target="error">
|
||||
<target name="error">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
1
library/error/license.lic
Normal file
1
library/error/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
80
library/error/src/error.e
Normal file
80
library/error/src/error.e
Normal file
@@ -0,0 +1,80 @@
|
||||
note
|
||||
description : "Objects that represent an error"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
ERROR
|
||||
|
||||
feature -- Access
|
||||
|
||||
code: INTEGER
|
||||
deferred
|
||||
ensure
|
||||
result_not_zero: Result /= 0
|
||||
end
|
||||
|
||||
name: STRING
|
||||
deferred
|
||||
ensure
|
||||
result_attached: Result /= Void
|
||||
end
|
||||
|
||||
message: detachable STRING_32
|
||||
-- Potential error message
|
||||
deferred
|
||||
end
|
||||
|
||||
parent: detachable ERROR
|
||||
-- Eventual error prior to Current
|
||||
|
||||
feature -- String representation
|
||||
|
||||
string_representation: STRING_32
|
||||
-- String representation for Current
|
||||
do
|
||||
create Result.make_from_string (name.as_string_32)
|
||||
Result.append_character (' ')
|
||||
Result.append_character ('(')
|
||||
Result.append_integer (code)
|
||||
Result.append_character (')')
|
||||
if attached message as m then
|
||||
Result.append_character (':')
|
||||
Result.append_character (' ')
|
||||
Result.append_string (m)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_parent (a_parent: like parent)
|
||||
-- Set `parent' to `a_parent'
|
||||
do
|
||||
parent := a_parent
|
||||
end
|
||||
|
||||
feature -- Visitor
|
||||
|
||||
process (a_visitor: ERROR_VISITOR)
|
||||
-- Process Current using `a_visitor'.
|
||||
require
|
||||
a_visitor_not_void: a_visitor /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
invariant
|
||||
name_attached: name /= Void
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
57
library/error/src/error_custom.e
Normal file
57
library/error/src/error_custom.e
Normal file
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description : "Objects that represent a custom error"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_CUSTOM
|
||||
|
||||
inherit
|
||||
ERROR
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_code: INTEGER; a_name: STRING; a_message: detachable like message)
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
code := a_code
|
||||
name := a_name
|
||||
if attached a_message then
|
||||
message := a_message
|
||||
else
|
||||
message := "Error: " + a_name + " (code=" + a_code.out + ")"
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
code: INTEGER
|
||||
|
||||
name: STRING
|
||||
|
||||
message: STRING_32
|
||||
|
||||
feature -- Visitor
|
||||
|
||||
process (a_visitor: ERROR_VISITOR)
|
||||
-- Process Current using `a_visitor'.
|
||||
do
|
||||
a_visitor.process_custom (Current)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
75
library/error/src/error_group.e
Normal file
75
library/error/src/error_group.e
Normal file
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description : "Objects that represent a group of errors"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_GROUP
|
||||
|
||||
inherit
|
||||
ERROR
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_errors: LIST [ERROR])
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
name := a_errors.count.out + " errors"
|
||||
create {ARRAYED_LIST [ERROR]} sub_errors.make (a_errors.count)
|
||||
sub_errors.fill (a_errors)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
code: INTEGER = -1
|
||||
|
||||
name: STRING
|
||||
|
||||
message: detachable STRING_32
|
||||
do
|
||||
create Result.make_from_string (name)
|
||||
from
|
||||
sub_errors.start
|
||||
until
|
||||
sub_errors.after
|
||||
loop
|
||||
if
|
||||
attached sub_errors.item as e and then
|
||||
attached e.message as m
|
||||
then
|
||||
|
||||
Result.append_character ('%N')
|
||||
Result.append_string (m)
|
||||
end
|
||||
sub_errors.forth
|
||||
end
|
||||
end
|
||||
|
||||
sub_errors: LIST [ERROR]
|
||||
-- Error contained by Current
|
||||
|
||||
feature -- Visitor
|
||||
|
||||
process (a_visitor: ERROR_VISITOR)
|
||||
-- Process Current using `a_visitor'.
|
||||
do
|
||||
a_visitor.process_group (Current)
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
92
library/error/src/error_handler.e
Normal file
92
library/error/src/error_handler.e
Normal file
@@ -0,0 +1,92 @@
|
||||
note
|
||||
description : "Objects that handle error..."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_HANDLER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
create {ARRAYED_LIST [ERROR]} errors.make (3)
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Has error?
|
||||
do
|
||||
Result := count > 0
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
do
|
||||
Result := errors.count
|
||||
end
|
||||
|
||||
errors: LIST [ERROR]
|
||||
-- Errors container
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
add_error (a_error: ERROR)
|
||||
-- Add `a_error' to the stack of error
|
||||
do
|
||||
errors.force (a_error)
|
||||
end
|
||||
|
||||
add_error_details, add_custom_error (a_code: INTEGER; a_name: STRING; a_message: detachable STRING_32)
|
||||
-- Add custom error to the stack of error
|
||||
local
|
||||
e: ERROR_CUSTOM
|
||||
do
|
||||
create e.make (a_code, a_name, a_message)
|
||||
add_error (e)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_single_error: detachable ERROR
|
||||
do
|
||||
if count > 1 then
|
||||
create {ERROR_GROUP} Result.make (errors)
|
||||
elseif count > 0 then
|
||||
Result := errors.first
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element changes
|
||||
|
||||
concatenate
|
||||
-- Concatenate into a single error if any
|
||||
do
|
||||
if count > 1 and then attached as_single_error as e then
|
||||
wipe_out
|
||||
add_error (e)
|
||||
end
|
||||
end
|
||||
|
||||
reset, wipe_out
|
||||
do
|
||||
errors.wipe_out
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
49
library/error/src/visitor/error_iterator.e
Normal file
49
library/error/src/visitor/error_iterator.e
Normal file
@@ -0,0 +1,49 @@
|
||||
note
|
||||
description : "Error list iterator"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_ITERATOR
|
||||
|
||||
inherit
|
||||
ERROR_VISITOR
|
||||
|
||||
feature -- Access
|
||||
|
||||
process_error (e: ERROR)
|
||||
do
|
||||
end
|
||||
|
||||
process_custom (e: ERROR_CUSTOM)
|
||||
do
|
||||
process_error (e)
|
||||
end
|
||||
|
||||
process_group (g: ERROR_GROUP)
|
||||
do
|
||||
if attached g.sub_errors as err then
|
||||
from
|
||||
err.start
|
||||
until
|
||||
err.after
|
||||
loop
|
||||
process_error (err.item)
|
||||
err.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
38
library/error/src/visitor/error_null_visitor.e
Normal file
38
library/error/src/visitor/error_null_visitor.e
Normal file
@@ -0,0 +1,38 @@
|
||||
note
|
||||
description : "Null error visitor"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_NULL_VISITOR
|
||||
|
||||
inherit
|
||||
ERROR_VISITOR
|
||||
|
||||
feature -- Access
|
||||
|
||||
process_error (e: ERROR)
|
||||
do
|
||||
end
|
||||
|
||||
process_custom (e: ERROR_CUSTOM)
|
||||
do
|
||||
end
|
||||
|
||||
process_group (g: ERROR_GROUP)
|
||||
do
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
35
library/error/src/visitor/error_visitor.e
Normal file
35
library/error/src/visitor/error_visitor.e
Normal file
@@ -0,0 +1,35 @@
|
||||
note
|
||||
description : "Objects to visit an ERROR"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
ERROR_VISITOR
|
||||
|
||||
feature -- Access
|
||||
|
||||
process_error (e: ERROR)
|
||||
deferred
|
||||
end
|
||||
|
||||
process_custom (e: ERROR_CUSTOM)
|
||||
deferred
|
||||
end
|
||||
|
||||
process_group (g: ERROR_GROUP)
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
53
library/error/src/visitor/file_output_error_visitor.e
Normal file
53
library/error/src/visitor/file_output_error_visitor.e
Normal file
@@ -0,0 +1,53 @@
|
||||
note
|
||||
description: "File error output visitor"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
FILE_OUTPUT_ERROR_VISITOR
|
||||
|
||||
inherit
|
||||
OUTPUT_ERROR_VISITOR
|
||||
redefine
|
||||
output_integer,
|
||||
output_new_line
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make (f: like file)
|
||||
require
|
||||
f_open_write: f /= Void and then f.is_open_write
|
||||
do
|
||||
file := f
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
file: FILE
|
||||
|
||||
feature -- Output
|
||||
|
||||
output_string (a_str: detachable STRING_GENERAL)
|
||||
-- Output Unicode string
|
||||
do
|
||||
if a_str /= Void then
|
||||
to_implement ("Convert into UTF-8 or console encoding before output")
|
||||
file.put_string (a_str.as_string_8)
|
||||
end
|
||||
end
|
||||
|
||||
output_integer (i: INTEGER)
|
||||
do
|
||||
file.put_integer (i)
|
||||
end
|
||||
|
||||
output_new_line
|
||||
do
|
||||
file.put_new_line
|
||||
end
|
||||
|
||||
end
|
||||
93
library/error/src/visitor/output_error_visitor.e
Normal file
93
library/error/src/visitor/output_error_visitor.e
Normal file
@@ -0,0 +1,93 @@
|
||||
note
|
||||
description: "General error output visitor"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
OUTPUT_ERROR_VISITOR
|
||||
|
||||
inherit
|
||||
ERROR_VISITOR
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature -- Output
|
||||
|
||||
output_string (a_str: detachable STRING_GENERAL)
|
||||
-- Output Unicode string
|
||||
deferred
|
||||
end
|
||||
|
||||
output_any (obj: detachable ANY)
|
||||
-- Output Unicode string
|
||||
do
|
||||
if attached {STRING_GENERAL} obj as l_str then
|
||||
to_implement ("Convert into UTF-8 or console encoding before output")
|
||||
output_string (l_str)
|
||||
elseif obj /= Void then
|
||||
output_string (obj.out)
|
||||
end
|
||||
end
|
||||
|
||||
output_integer (i: INTEGER)
|
||||
do
|
||||
output_string (i.out)
|
||||
end
|
||||
|
||||
output_new_line
|
||||
do
|
||||
output_string ("%N")
|
||||
end
|
||||
|
||||
feature -- Process
|
||||
|
||||
process_error (e: ERROR)
|
||||
do
|
||||
output_string ({STRING_32}"Error Name: ")
|
||||
output_string (e.name)
|
||||
output_string ({STRING_32}"Code: ")
|
||||
output_integer (e.code)
|
||||
output_new_line
|
||||
output_string ({STRING_32}"%TMessage: ")
|
||||
output_string (e.message)
|
||||
output_new_line
|
||||
end
|
||||
|
||||
process_custom (e: ERROR_CUSTOM)
|
||||
do
|
||||
output_string ({STRING_32}"Error Name: ")
|
||||
output_string (e.name)
|
||||
output_string ({STRING_32}"Code: ")
|
||||
output_integer (e.code)
|
||||
output_new_line
|
||||
output_string ({STRING_32}"%TMessage: ")
|
||||
output_string (e.message)
|
||||
output_new_line
|
||||
end
|
||||
|
||||
process_group (g: ERROR_GROUP)
|
||||
local
|
||||
l_errors: LIST [ERROR]
|
||||
do
|
||||
from
|
||||
l_errors := g.sub_errors
|
||||
l_errors.start
|
||||
until
|
||||
l_errors.after
|
||||
loop
|
||||
l_errors.item.process (Current)
|
||||
l_errors.forth
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
53
library/error/src/visitor/text_output_error_visitor.e
Normal file
53
library/error/src/visitor/text_output_error_visitor.e
Normal file
@@ -0,0 +1,53 @@
|
||||
note
|
||||
description: "Text error output visitor"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
TEXT_OUTPUT_ERROR_VISITOR
|
||||
|
||||
inherit
|
||||
OUTPUT_ERROR_VISITOR
|
||||
redefine
|
||||
output_integer,
|
||||
output_new_line
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make (buf: like buffer)
|
||||
require
|
||||
buf_attached: buf /= Void
|
||||
do
|
||||
buffer := buf
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
buffer: STRING
|
||||
|
||||
feature -- Output
|
||||
|
||||
output_string (a_str: detachable STRING_GENERAL)
|
||||
-- Output Unicode string
|
||||
do
|
||||
if a_str /= Void then
|
||||
to_implement ("Convert into UTF-8 or console encoding before output")
|
||||
buffer.append_string_general (a_str)
|
||||
end
|
||||
end
|
||||
|
||||
output_integer (i: INTEGER)
|
||||
do
|
||||
buffer.append_integer (i)
|
||||
end
|
||||
|
||||
output_new_line
|
||||
do
|
||||
buffer.append_character ('%N')
|
||||
end
|
||||
|
||||
end
|
||||
17
library/protocol/http/http-safe.ecf
Normal file
17
library/protocol/http/http-safe.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="http" uuid="F8BE3C55-88E8-4103-A936-B1E5CB1D330E" library_target="http">
|
||||
<target name="http">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
18
library/protocol/http/http.ecf
Normal file
18
library/protocol/http/http.ecf
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="http" uuid="F8BE3C55-88E8-4103-A936-B1E5CB1D330E" library_target="http">
|
||||
<target name="http">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
97
library/protocol/http/src/http_constants.e
Normal file
97
library/protocol/http/src/http_constants.e
Normal file
@@ -0,0 +1,97 @@
|
||||
note
|
||||
description: "Summary description for {HTTP_CONSTANTS}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTTP_CONSTANTS
|
||||
|
||||
feature -- Ports
|
||||
|
||||
default_http_port: INTEGER = 80
|
||||
default_https_port: INTEGER = 443
|
||||
|
||||
feature -- Method
|
||||
|
||||
method_get: STRING = "GET"
|
||||
method_post: STRING = "POST"
|
||||
method_put: STRING = "PUT"
|
||||
method_delete: STRING = "DELETE"
|
||||
method_head: STRING = "HEAD"
|
||||
method_download: STRING = "DOWNLOAD"
|
||||
|
||||
feature -- Content type
|
||||
|
||||
octet_stream: STRING = "application/octet-stream"
|
||||
-- Octet stream content-type header
|
||||
multipart_form: STRING = "multipart/form-data"
|
||||
-- Starting chars of multipart form data content-type header
|
||||
form_encoded: STRING = "application/x-www-form-urlencoded"
|
||||
-- Starting chars of form url-encoded data content-type header
|
||||
xml_text: STRING = "text/xml"
|
||||
-- XML text content-type header
|
||||
html_text: STRING = "text/html"
|
||||
-- HTML text content-type header
|
||||
json_text: STRING = "text/json"
|
||||
-- JSON text content-type header
|
||||
json_app: STRING = "application/json"
|
||||
-- JSON application content-type header
|
||||
js_text: STRING = "text/javascript"
|
||||
-- Javascript text content-type header
|
||||
js_app: STRING = "application/javascript"
|
||||
-- JavaScript application content-type header
|
||||
plain_text: STRING = "text/plain"
|
||||
-- Plain text content-type header
|
||||
|
||||
feature -- Server
|
||||
|
||||
http_version_1_0: STRING = "HTTP/1.0"
|
||||
http_host_header: STRING = "Host"
|
||||
http_authorization_header: STRING = "Authorization: "
|
||||
http_end_of_header_line: STRING = "%R%N"
|
||||
http_end_of_command: STRING = "%R%N%R%N"
|
||||
http_content_length: STRING = "Content-Length: "
|
||||
http_content_type: STRING = "Content-Type: "
|
||||
http_content_location: STRING = "Content-Location: "
|
||||
http_content_disposition: STRING = "Content-Disposition: "
|
||||
http_path_translated: STRING = "Path-Translated: "
|
||||
http_agent: STRING = "User-agent: "
|
||||
http_from: STRING = "From: "
|
||||
|
||||
feature -- Server: header
|
||||
|
||||
header_host: STRING = "Host"
|
||||
header_authorization: STRING = "Authorization"
|
||||
header_content_length: STRING = "Content-Length"
|
||||
header_content_type: STRING = "Content-Type"
|
||||
header_content_location: STRING = "Content-Location"
|
||||
header_content_disposition: STRING = "Content-Disposition"
|
||||
header_cache_control: STRING = "Cache-Control"
|
||||
header_path_translated: STRING = "Path-Translated"
|
||||
header_agent: STRING = "User-Agent"
|
||||
header_referer: STRING = "Referer" -- Officially mispelled in std
|
||||
header_location: STRING = "Location"
|
||||
header_from: STRING = "From"
|
||||
header_status: STRING = "Status"
|
||||
header_multipart_tag_value_separator: CHARACTER = ';'
|
||||
|
||||
feature -- Misc
|
||||
|
||||
http_status_ok: STRING = "200 OK"
|
||||
|
||||
default_bufsize: INTEGER = 16384 --| 16K
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
71
library/protocol/http/src/http_date_time_utilities.e
Normal file
71
library/protocol/http/src/http_date_time_utilities.e
Normal file
@@ -0,0 +1,71 @@
|
||||
note
|
||||
description: "Summary description for {HTTP_DATE_TIME_UTILITIES}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTTP_DATE_TIME_UTILITIES
|
||||
|
||||
feature -- Access
|
||||
|
||||
now_utc: DATE_TIME
|
||||
do
|
||||
create Result.make_now_utc
|
||||
end
|
||||
|
||||
epoch: DATE_TIME
|
||||
once ("THREAD")
|
||||
create Result.make_from_epoch (0)
|
||||
end
|
||||
|
||||
feature -- Unix time stamp
|
||||
|
||||
unix_time_stamp (dt: detachable DATE_TIME): INTEGER_64
|
||||
-- Unix time stamp from `dt' if attached or from epoch is detached
|
||||
local
|
||||
l_date_time: DATE_TIME
|
||||
do
|
||||
if dt /= Void then
|
||||
l_date_time := dt
|
||||
else
|
||||
l_date_time := now_utc
|
||||
end
|
||||
Result := l_date_time.definite_duration (epoch).seconds_count
|
||||
end
|
||||
|
||||
fine_unix_time_stamp (dt: detachable DATE_TIME): DOUBLE
|
||||
-- Fine unix time stamp from `dt' if attached or from epoch is detached
|
||||
local
|
||||
l_date_time: DATE_TIME
|
||||
do
|
||||
if dt /= Void then
|
||||
l_date_time := dt
|
||||
else
|
||||
l_date_time := now_utc
|
||||
end
|
||||
Result := l_date_time.definite_duration (epoch).fine_seconds_count
|
||||
end
|
||||
|
||||
feature -- Unix time stamp conversion
|
||||
|
||||
unix_time_stamp_to_date_time (i64: INTEGER_64): DATE_TIME
|
||||
-- Date time related to `i64'
|
||||
do
|
||||
create Result.make_from_epoch (i64.as_integer_32)
|
||||
ensure
|
||||
same_unix_time_stamp: unix_time_stamp (Result) = i64
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
106
library/protocol/http/src/http_status_code.e
Normal file
106
library/protocol/http/src/http_status_code.e
Normal file
@@ -0,0 +1,106 @@
|
||||
note
|
||||
description: "[
|
||||
Status code constants pertaining to the HTTP protocol
|
||||
See http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTTP_STATUS_CODE
|
||||
|
||||
feature -- 1xx : Informational
|
||||
|
||||
continue: INTEGER = 100
|
||||
switching_protocols: INTEGER = 101
|
||||
processing: INTEGER = 102 -- WebDAV RFC 2518
|
||||
ie7_request_uri_too_long: INTEGER = 122 -- non standard, IE7 only
|
||||
|
||||
feature -- 2xx : Success
|
||||
|
||||
ok: INTEGER = 200
|
||||
created: INTEGER = 201
|
||||
accepted: INTEGER = 202
|
||||
nonauthoritative_info: INTEGER = 203
|
||||
no_content: INTEGER = 204
|
||||
reset_content: INTEGER = 205
|
||||
partial_content: INTEGER = 206
|
||||
multistatus: INTEGER = 207 -- WebDAV RFC 4918
|
||||
im_used: INTEGER = 226 -- RFC 4918
|
||||
|
||||
feature -- 3xx : Redirection
|
||||
|
||||
multiple_choices: INTEGER = 300
|
||||
moved_permanently: INTEGER = 301
|
||||
found: INTEGER = 302
|
||||
see_other: INTEGER = 303
|
||||
not_modified: INTEGER = 304
|
||||
use_proxy: INTEGER = 305
|
||||
switch_proxy: INTEGER = 306
|
||||
temp_redirect: INTEGER = 307
|
||||
|
||||
feature -- 4xx : Client Error
|
||||
|
||||
bad_request: INTEGER = 400
|
||||
unauthorized: INTEGER = 401
|
||||
payment_required: INTEGER = 402
|
||||
forbidden: INTEGER = 403
|
||||
not_found: INTEGER = 404
|
||||
method_not_allowed: INTEGER = 405
|
||||
not_acceptable: INTEGER = 406
|
||||
proxy_auth_required: INTEGER = 407
|
||||
request_timeout: INTEGER = 408
|
||||
conflict: INTEGER = 409
|
||||
gone: INTEGER = 410
|
||||
length_required: INTEGER = 411
|
||||
precondition_failed: INTEGER = 412
|
||||
request_entity_too_large: INTEGER = 413
|
||||
request_uri_too_long: INTEGER = 414
|
||||
unsupported_media_type: INTEGER = 415
|
||||
request_range_not_satisfiable: INTEGER = 416
|
||||
expectation_failed: INTEGER = 417
|
||||
teapot: INTEGER = 418
|
||||
|
||||
feature -- 4xx : Client Error : WebDAV errors
|
||||
|
||||
too_many_connections: INTEGER = 421
|
||||
unprocessable_entity: INTEGER = 422
|
||||
locked: INTEGER = 423
|
||||
failed_dependency: INTEGER = 424
|
||||
unordered_collection: INTEGER = 425
|
||||
|
||||
upgrade_required: INTEGER = 426
|
||||
no_response: INTEGER = 444
|
||||
retry_with: INTEGER = 449
|
||||
blocked_parental: INTEGER = 450
|
||||
client_closed_request: INTEGER = 499
|
||||
|
||||
feature -- 5xx : Server Error
|
||||
|
||||
internal_server_error: INTEGER = 500
|
||||
not_implemented: INTEGER = 501
|
||||
bad_gateway: INTEGER = 502
|
||||
service_unavailable: INTEGER = 503
|
||||
gateway_timeout: INTEGER = 504
|
||||
http_version_not_supported: INTEGER = 505
|
||||
variant_also_negotiates: INTEGER = 506
|
||||
insufficient_storage: INTEGER = 507 -- WebDAV RFC 4918
|
||||
|
||||
bandwidth_limit_exceeded: INTEGER = 509
|
||||
not_extended: INTEGER = 510
|
||||
|
||||
user_access_denied: INTEGER = 530
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
160
library/protocol/http/src/http_status_code_messages.e
Normal file
160
library/protocol/http/src/http_status_code_messages.e
Normal file
@@ -0,0 +1,160 @@
|
||||
note
|
||||
description: "[
|
||||
Status code constants pertaining to the HTTP protocol
|
||||
See http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTTP_STATUS_CODE_MESSAGES
|
||||
|
||||
inherit
|
||||
HTTP_STATUS_CODE
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_valid_http_status_code (v: INTEGER): BOOLEAN
|
||||
-- Is the given value a valid http status code?
|
||||
do
|
||||
Result := v >= continue and v <= user_access_denied
|
||||
end
|
||||
|
||||
feature -- Status messages
|
||||
|
||||
http_status_code_message (a_code: INTEGER): detachable STRING
|
||||
-- Header message related to HTTP status code `a_code'
|
||||
do
|
||||
inspect a_code
|
||||
when continue then
|
||||
Result := "Continue"
|
||||
when switching_protocols then
|
||||
Result := "Switching Protocols"
|
||||
when processing then
|
||||
Result := "Processing"
|
||||
when ok then
|
||||
Result := "OK"
|
||||
when created then
|
||||
Result := "Created"
|
||||
when accepted then
|
||||
Result := "Accepted"
|
||||
when nonauthoritative_info then
|
||||
Result := "Non-Authoritative Information"
|
||||
when no_content then
|
||||
Result := "No Content"
|
||||
when reset_content then
|
||||
Result := "Reset Content"
|
||||
when partial_content then
|
||||
Result := "Partial Content"
|
||||
when multistatus then
|
||||
Result := "Multi-Status"
|
||||
when multiple_choices then
|
||||
Result := "Multiple Choices"
|
||||
when moved_permanently then
|
||||
Result := "Moved Permanently"
|
||||
when found then
|
||||
Result := "Found"
|
||||
when see_other then
|
||||
Result := "See Other"
|
||||
when not_modified then
|
||||
Result := "Not Modified"
|
||||
when use_proxy then
|
||||
Result := "Use Proxy"
|
||||
when switch_proxy then
|
||||
Result := "Switch Proxy"
|
||||
when temp_redirect then
|
||||
Result := "Temporary Redirect"
|
||||
when bad_request then
|
||||
Result := "Bad Request"
|
||||
when unauthorized then
|
||||
Result := "Unauthorized"
|
||||
when payment_required then
|
||||
Result := "Payment Required"
|
||||
when forbidden then
|
||||
Result := "Forbidden"
|
||||
when not_found then
|
||||
Result := "Not Found"
|
||||
when method_not_allowed then
|
||||
Result := "Method Not Allowed"
|
||||
when not_acceptable then
|
||||
Result := "Not Acceptable"
|
||||
when proxy_auth_required then
|
||||
Result := "Proxy Authentication Required"
|
||||
when request_timeout then
|
||||
Result := "Request Timeout"
|
||||
when conflict then
|
||||
Result := "Conflict"
|
||||
when gone then
|
||||
Result := "Gone"
|
||||
when length_required then
|
||||
Result := "Length Required"
|
||||
when precondition_failed then
|
||||
Result := "Precondition Failed"
|
||||
when request_entity_too_large then
|
||||
Result := "Request Entity Too Large"
|
||||
when request_uri_too_long then
|
||||
Result := "Request-URI Too Long"
|
||||
when unsupported_media_type then
|
||||
Result := "Unsupported Media Type"
|
||||
when request_range_not_satisfiable then
|
||||
Result := "Requested Range Not Satisfiable"
|
||||
when expectation_failed then
|
||||
Result := "Expectation Failed"
|
||||
when teapot then
|
||||
Result := "I'm a teapot"
|
||||
when too_many_connections then
|
||||
Result := "There are too many connections from your internet address"
|
||||
when unprocessable_entity then
|
||||
Result := "Unprocessable Entity"
|
||||
when locked then
|
||||
Result := "Locked"
|
||||
when failed_dependency then
|
||||
Result := "Failed Dependency"
|
||||
when unordered_collection then
|
||||
Result := "Unordered Collection"
|
||||
when upgrade_required then
|
||||
Result := "Upgrade Required"
|
||||
when retry_with then
|
||||
Result := "Retry With"
|
||||
when blocked_parental then
|
||||
Result := "Blocked by Windows Parental Controls"
|
||||
when internal_server_error then
|
||||
Result := "Internal Server Error"
|
||||
when not_implemented then
|
||||
Result := "Not Implemented"
|
||||
when bad_gateway then
|
||||
Result := "Bad Gateway"
|
||||
when service_unavailable then
|
||||
Result := "Service Unavailable"
|
||||
when gateway_timeout then
|
||||
Result := "Gateway Timeout"
|
||||
when http_version_not_supported then
|
||||
Result := "HTTP Version Not Supported"
|
||||
when variant_also_negotiates then
|
||||
Result := "Variant Also Negotiates"
|
||||
when insufficient_storage then
|
||||
Result := "Insufficient Storage"
|
||||
when bandwidth_limit_exceeded then
|
||||
Result := "Bandwidth Limit Exceeded"
|
||||
when not_extended then
|
||||
Result := "Not Extended"
|
||||
when user_access_denied then
|
||||
Result := "User access denied"
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
16
library/server/ewsgi/connectors/cgi/cgi-safe.ecf
Normal file
16
library/server/ewsgi/connectors/cgi/cgi-safe.ecf
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_cgi" uuid="3BCBC1C5-9D99-45BB-B15D-B03D2C069CED" library_target="connector_cgi">
|
||||
<target name="connector_cgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
16
library/server/ewsgi/connectors/cgi/cgi.ecf
Normal file
16
library/server/ewsgi/connectors/cgi/cgi.ecf
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_cgi" uuid="3BCBC1C5-9D99-45BB-B15D-B03D2C069CED" library_target="connector_cgi">
|
||||
<target name="connector_cgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
1
library/server/ewsgi/connectors/cgi/license.lic
Normal file
1
library/server/ewsgi/connectors/cgi/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
36
library/server/ewsgi/connectors/cgi/src/gw_cgi_connector.e
Normal file
36
library/server/ewsgi/connectors/cgi/src/gw_cgi_connector.e
Normal file
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Summary description for {GW_CGI_CONNECTOR}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_CGI_CONNECTOR
|
||||
|
||||
inherit
|
||||
GW_CONNECTOR
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Execution
|
||||
|
||||
launch
|
||||
local
|
||||
env: GW_ENVIRONMENT_VARIABLES
|
||||
do
|
||||
create env.make_with_variables ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables)
|
||||
application.process (env, create {GW_CGI_INPUT_STREAM}.make, create {GW_CGI_OUTPUT_STREAM}.make)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
note
|
||||
description: "Summary description for GW_CGI_INPUT_STREAM."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_CGI_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_INPUT_STREAM
|
||||
|
||||
CONSOLE
|
||||
rename
|
||||
make as console_make
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
make_open_stdin ("stdin")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
note
|
||||
description: "Summary description for GW_CGI_OUTPUT_STREAM."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_CGI_OUTPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_OUTPUT_STREAM
|
||||
|
||||
CONSOLE
|
||||
rename
|
||||
make as console_make
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
make_open_stdout ("stdout")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
17
library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf
Normal file
17
library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_libfcgi" uuid="59C57E56-3EE6-4EF7-873F-7ED084B0EB22" library_target="connector_libfcgi">
|
||||
<target name="connector_libfcgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="libfcgi" location="..\..\..\libfcgi\libfcgi-safe.ecf" />
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
17
library/server/ewsgi/connectors/libfcgi/libfcgi.ecf
Normal file
17
library/server/ewsgi/connectors/libfcgi/libfcgi.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_libfcgi" uuid="59C57E56-3EE6-4EF7-873F-7ED084B0EB22" library_target="connector_libfcgi">
|
||||
<target name="connector_libfcgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
|
||||
<library name="libfcgi" location="..\..\libfcgi\libfcgi.ecf" />
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
1
library/server/ewsgi/connectors/libfcgi/license.lic
Normal file
1
library/server/ewsgi/connectors/libfcgi/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
@@ -0,0 +1,81 @@
|
||||
note
|
||||
description: "Summary description for {GW_LIBFCGI_CONNECTOR}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_LIBFCGI_CONNECTOR
|
||||
|
||||
inherit
|
||||
GW_CONNECTOR
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
create fcgi.make
|
||||
create {GW_LIBFCGI_INPUT_STREAM} input.make (fcgi)
|
||||
create {GW_LIBFCGI_OUTPUT_STREAM} output.make (fcgi)
|
||||
end
|
||||
|
||||
feature -- Server
|
||||
|
||||
launch
|
||||
local
|
||||
res: INTEGER
|
||||
do
|
||||
from
|
||||
res := fcgi.fcgi_listen
|
||||
until
|
||||
res < 0
|
||||
loop
|
||||
process_fcgi_request (fcgi.updated_environ_variables, input, output)
|
||||
res := fcgi.fcgi_listen
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process_fcgi_request (vars: HASH_TABLE [STRING, STRING]; a_input: like input; a_output: like output)
|
||||
local
|
||||
gw_env: GW_ENVIRONMENT_VARIABLES
|
||||
do
|
||||
create gw_env.make_with_variables (vars)
|
||||
application.process (gw_env, a_input, a_output)
|
||||
end
|
||||
|
||||
feature -- Input/Output
|
||||
|
||||
input: GW_INPUT_STREAM
|
||||
-- Input from client (from httpd server via FCGI)
|
||||
|
||||
output: GW_OUTPUT_STREAM
|
||||
-- Output to client (via httpd server/fcgi)
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
fcgi: FCGI
|
||||
|
||||
invariant
|
||||
fcgi_attached: fcgi /= Void
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
note
|
||||
description: "Summary description for GW_LIBFCGI_INPUT_STREAM."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_LIBFCGI_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_INPUT_STREAM
|
||||
|
||||
STRING_HANDLER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_fcgi: like fcgi)
|
||||
require
|
||||
valid_fcgi: a_fcgi /= Void
|
||||
do
|
||||
fcgi := a_fcgi
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize Current
|
||||
do
|
||||
create last_string.make_empty
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
read_stream (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' bound characters
|
||||
-- or until end of file.
|
||||
-- Make result available in `last_string'.
|
||||
do
|
||||
fcgi.fill_string_from_stdin (last_string, nb_char)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
last_string: STRING
|
||||
-- Last string read
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
fcgi: FCGI;
|
||||
-- Bridge to FCGI world
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description: "Summary description for {GW_LIBFCGI_OUTPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_LIBFCGI_OUTPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_OUTPUT_STREAM
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_fcgi: like fcgi)
|
||||
require
|
||||
valid_fcgi: a_fcgi /= Void
|
||||
do
|
||||
fcgi := a_fcgi
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
put_string (s: STRING)
|
||||
-- Send `s' to http client
|
||||
do
|
||||
fcgi.put_string (s)
|
||||
end
|
||||
|
||||
flush
|
||||
do
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
fcgi: FCGI
|
||||
-- Bridge to FCGI world
|
||||
|
||||
invariant
|
||||
fcgi_attached: fcgi /= Void
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
1
library/server/ewsgi/connectors/nino/license.lic
Normal file
1
library/server/ewsgi/connectors/nino/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
17
library/server/ewsgi/connectors/nino/nino-safe.ecf
Normal file
17
library/server/ewsgi/connectors/nino/nino-safe.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_nino" uuid="F91861FB-4FEA-455F-9570-828D7903DC64" library_target="connector_nino">
|
||||
<target name="connector_nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
17
library/server/ewsgi/connectors/nino/nino.ecf
Normal file
17
library/server/ewsgi/connectors/nino/nino.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector_nino" uuid="F91861FB-4FEA-455F-9570-828D7903DC64" library_target="connector_nino">
|
||||
<target name="connector_nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi.ecf" readonly="false"/>
|
||||
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
93
library/server/ewsgi/connectors/nino/src/gw_nino_connector.e
Normal file
93
library/server/ewsgi/connectors/nino/src/gw_nino_connector.e
Normal file
@@ -0,0 +1,93 @@
|
||||
note
|
||||
description: "Summary description for {GW_NINO_CONNECTOR}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_NINO_CONNECTOR
|
||||
|
||||
inherit
|
||||
GW_CONNECTOR
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_base
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_base (a_app: like application; a_base: like base)
|
||||
do
|
||||
make (a_app)
|
||||
base := a_base
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
local
|
||||
cfg: HTTP_SERVER_CONFIGURATION
|
||||
do
|
||||
create cfg.make
|
||||
create server.make (cfg)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
server: HTTP_SERVER
|
||||
|
||||
configuration: HTTP_SERVER_CONFIGURATION
|
||||
do
|
||||
Result := server.configuration
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
base: detachable STRING
|
||||
-- Root url base
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_base (b: like base)
|
||||
do
|
||||
base := b
|
||||
end
|
||||
|
||||
feature -- Server
|
||||
|
||||
launch
|
||||
local
|
||||
l_http_handler : HTTP_HANDLER
|
||||
do
|
||||
create {GW_NINO_HANDLER} l_http_handler.make_with_callback (server, "GW_NINO_HANDLER", Current)
|
||||
debug ("nino")
|
||||
if attached base as l_base then
|
||||
print ("Base=" + l_base + "%N")
|
||||
end
|
||||
end
|
||||
server.setup (l_http_handler)
|
||||
end
|
||||
|
||||
process_request (env: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
|
||||
local
|
||||
gw_env: GW_ENVIRONMENT_VARIABLES
|
||||
do
|
||||
create gw_env.make_with_variables (env)
|
||||
gw_env.set_variable ("RAW_HEADER_DATA", a_headers_text)
|
||||
application.process (gw_env, create {GW_NINO_INPUT_STREAM}.make (a_input), create {GW_NINO_OUTPUT_STREAM}.make (a_output))
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
156
library/server/ewsgi/connectors/nino/src/gw_nino_handler.e
Normal file
156
library/server/ewsgi/connectors/nino/src/gw_nino_handler.e
Normal file
@@ -0,0 +1,156 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
GW_NINO_HANDLER
|
||||
|
||||
inherit
|
||||
HTTP_CONNECTION_HANDLER
|
||||
|
||||
create
|
||||
make_with_callback
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_callback (a_main_server: like main_server; a_name: STRING; a_callback: like callback)
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
make (a_main_server, a_name)
|
||||
callback := a_callback
|
||||
end
|
||||
|
||||
callback: GW_NINO_CONNECTOR
|
||||
|
||||
feature -- Access
|
||||
|
||||
base: detachable STRING
|
||||
-- Root url base
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_base (a_uri: like base)
|
||||
-- Set `base' to `a_uri'
|
||||
do
|
||||
base := a_uri
|
||||
end
|
||||
|
||||
feature -- Request processing
|
||||
|
||||
process_request (a_handler: HTTP_CONNECTION_HANDLER; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
|
||||
-- Process request ...
|
||||
local
|
||||
env, vars: HASH_TABLE [STRING, STRING]
|
||||
p: INTEGER
|
||||
l_request_uri, l_script_name, l_query_string, l_path_info: STRING
|
||||
l_server_name, l_server_port: detachable STRING
|
||||
a_headers_map: HASH_TABLE [STRING, STRING]
|
||||
vn: STRING
|
||||
|
||||
e: EXECUTION_ENVIRONMENT
|
||||
do
|
||||
l_request_uri := a_handler.uri
|
||||
a_headers_map := a_handler.request_header_map
|
||||
create e
|
||||
vars := e.starting_environment_variables
|
||||
env := vars.twin
|
||||
|
||||
--| for Any Abc-Def-Ghi add (or replace) the HTTP_ABC_DEF_GHI variable to `env'
|
||||
from
|
||||
a_headers_map.start
|
||||
until
|
||||
a_headers_map.after
|
||||
loop
|
||||
vn := a_headers_map.key_for_iteration.as_upper
|
||||
vn.replace_substring_all ("-", "_")
|
||||
add_environment_variable (a_headers_map.item_for_iteration, vn, env)
|
||||
a_headers_map.forth
|
||||
end
|
||||
|
||||
--| Specific cases
|
||||
|
||||
p := l_request_uri.index_of ('?', 1)
|
||||
if p > 0 then
|
||||
l_script_name := l_request_uri.substring (1, p - 1)
|
||||
l_query_string := l_request_uri.substring (p + 1, l_request_uri.count)
|
||||
else
|
||||
l_script_name := l_request_uri.string
|
||||
l_query_string := ""
|
||||
end
|
||||
if attached a_headers_map.item ("Host") as l_host then
|
||||
add_environment_variable (l_host, "HTTP_HOST", env)
|
||||
p := l_host.index_of (':', 1)
|
||||
if p > 0 then
|
||||
l_server_name := l_host.substring (1, p - 1)
|
||||
l_server_port := l_host.substring (p+1, l_host.count)
|
||||
else
|
||||
l_server_name := l_host
|
||||
l_server_port := "80" -- Default
|
||||
end
|
||||
end
|
||||
|
||||
if attached a_headers_map.item ("Authorization") as l_authorization then
|
||||
add_environment_variable (l_authorization, "HTTP_AUTHORIZATION", env)
|
||||
p := l_authorization.index_of (' ', 1)
|
||||
if p > 0 then
|
||||
add_environment_variable (l_authorization.substring (1, p - 1), "AUTH_TYPE", env)
|
||||
end
|
||||
end
|
||||
|
||||
add_environment_variable ("CGI/1.1", "GATEWAY_INTERFACE", env)
|
||||
add_environment_variable (l_query_string, "QUERY_STRING", env)
|
||||
|
||||
if attached a_handler.remote_info as l_remote_info then
|
||||
add_environment_variable (l_remote_info.addr, "REMOTE_ADDR", env)
|
||||
add_environment_variable (l_remote_info.hostname, "REMOTE_HOST", env)
|
||||
add_environment_variable (l_remote_info.port.out, "REMOTE_PORT", env)
|
||||
-- add_environment_variable (Void, "REMOTE_IDENT", env)
|
||||
-- add_environment_variable (Void, "REMOTE_USER", env)
|
||||
end
|
||||
|
||||
add_environment_variable (l_request_uri, "REQUEST_URI", env)
|
||||
add_environment_variable (a_handler.method, "REQUEST_METHOD", env)
|
||||
|
||||
add_environment_variable (l_script_name, "SCRIPT_NAME", env)
|
||||
add_environment_variable (l_server_name, "SERVER_NAME", env)
|
||||
add_environment_variable (l_server_port, "SERVER_PORT", env)
|
||||
add_environment_variable (a_handler.version, "SERVER_PROTOCOL", env)
|
||||
add_environment_variable ({HTTP_SERVER_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", env)
|
||||
|
||||
--| Apply `base' value
|
||||
if attached base as l_base and then l_request_uri /= Void then
|
||||
if l_request_uri.starts_with (l_base) then
|
||||
l_path_info := l_request_uri.substring (l_base.count + 1, l_request_uri.count)
|
||||
p := l_path_info.index_of ('?', 1)
|
||||
if p > 0 then
|
||||
l_path_info.keep_head (p - 1)
|
||||
end
|
||||
env.force (l_path_info, "PATH_INFO")
|
||||
env.force (l_base, "SCRIPT_NAME")
|
||||
end
|
||||
end
|
||||
|
||||
callback.process_request (env, a_handler.request_header, a_input, a_output)
|
||||
end
|
||||
|
||||
add_environment_variable (a_value: detachable STRING; a_var_name: STRING; env: HASH_TABLE [STRING, STRING])
|
||||
-- Add variable `a_var_name => a_value' to `env'
|
||||
do
|
||||
if a_value /= Void then
|
||||
env.force (a_value, a_var_name)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
note
|
||||
description: "Summary description for {GW_NINO_INPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_NINO_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_INPUT_STREAM
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_nino_input: like nino_input)
|
||||
do
|
||||
create last_string.make_empty
|
||||
set_nino_input (a_nino_input)
|
||||
end
|
||||
|
||||
feature {GW_NINO_APPLICATION} -- Nino
|
||||
|
||||
set_nino_input (i: like nino_input)
|
||||
do
|
||||
nino_input := i
|
||||
end
|
||||
|
||||
nino_input: HTTP_INPUT_STREAM
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
read_stream (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' bound characters
|
||||
-- or until end of file.
|
||||
-- Make result available in `last_string'.
|
||||
do
|
||||
nino_input.read_stream (nb_char)
|
||||
last_string := nino_input.last_string
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
last_string: STRING
|
||||
-- Last string read
|
||||
|
||||
;note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "Summary description for {GW_NINO_OUTPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_NINO_OUTPUT_STREAM
|
||||
|
||||
inherit
|
||||
GW_OUTPUT_STREAM
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_nino_output: like nino_output)
|
||||
do
|
||||
set_nino_output (a_nino_output)
|
||||
end
|
||||
|
||||
feature {GW_NINO_APPLICATION} -- Nino
|
||||
|
||||
set_nino_output (o: like nino_output)
|
||||
do
|
||||
nino_output := o
|
||||
end
|
||||
|
||||
nino_output: HTTP_OUTPUT_STREAM
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
put_string (s: STRING_8)
|
||||
-- Send `s' to http client
|
||||
do
|
||||
debug ("nino")
|
||||
print (s)
|
||||
end
|
||||
nino_output.put_string (s)
|
||||
end
|
||||
|
||||
flush
|
||||
-- Flush the output stream
|
||||
do
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -11,10 +11,8 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<cluster name="interface" location="src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>GW_REQUEST_CONTEXT_IMP</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<library name="error" location="..\..\error\error-safe.ecf"/>
|
||||
<library name="http" location="..\..\protocol\http\http-safe.ecf"/>
|
||||
<cluster name="interface" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
18
library/server/ewsgi/ewsgi.ecf
Normal file
18
library/server/ewsgi/ewsgi.ecf
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="ewsgi" uuid="D924DBE1-1231-434A-80EF-234BA09D1E30" library_target="ewsgi">
|
||||
<target name="ewsgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="false" void_safety="none" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="error" location="..\..\error\error-safe.ecf"/>
|
||||
<library name="http" location="..\..\protocol\http\http.ecf"/>
|
||||
<cluster name="interface" location="src\" recursive="true" />
|
||||
</target>
|
||||
</system>
|
||||
19
library/server/ewsgi/examples/hello_world/hello-safe.ecf
Normal file
19
library/server/ewsgi/examples/hello_world/hello-safe.ecf
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="hello_world" uuid="734385F1-0D17-4B5F-9138-24DC8D4F06C6">
|
||||
<target name="hello_world">
|
||||
<root class="HELLO_WORLD" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="connector_cgi" location="..\..\connectors\cgi\cgi-safe.ecf" readonly="false"/>
|
||||
<library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_libfcgi" location="..\..\connectors\libfcgi\libfcgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
58
library/server/ewsgi/examples/hello_world/src/hello_world.e
Normal file
58
library/server/ewsgi/examples/hello_world/src/hello_world.e
Normal file
@@ -0,0 +1,58 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
HELLO_WORLD
|
||||
|
||||
inherit
|
||||
GW_APPLICATION_IMP
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
conn: detachable GW_CONNECTOR
|
||||
nino_conn: GW_NINO_CONNECTOR
|
||||
do
|
||||
if is_nino then
|
||||
create nino_conn.make_with_base (Current, "/hello_world")
|
||||
if attached nino_conn.server.server_configuration as cfg then
|
||||
cfg.http_server_port := 8080
|
||||
cfg.force_single_threaded := True
|
||||
end
|
||||
conn := nino_conn
|
||||
elseif is_cgi then
|
||||
create {GW_CGI_CONNECTOR} conn.make (Current)
|
||||
elseif is_libfcgi then
|
||||
create {GW_LIBFCGI_CONNECTOR} conn.make (Current)
|
||||
else
|
||||
io.error.put_string ("Unsupported connector")
|
||||
end
|
||||
if conn /= Void then
|
||||
conn.launch
|
||||
end
|
||||
end
|
||||
|
||||
is_nino: BOOLEAN = True
|
||||
is_cgi: BOOLEAN = False
|
||||
is_libfcgi: BOOLEAN = False
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (ctx: GW_REQUEST_CONTEXT)
|
||||
-- Execute the request
|
||||
do
|
||||
ctx.output.put_string ("Hello World!%N")
|
||||
if attached ctx.execution_variable ("REQUEST_COUNT") as rq_count then
|
||||
ctx.output.put_string ("Request #" + rq_count + "%N")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -258,7 +258,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
||||
deferred
|
||||
end
|
||||
|
||||
path_info: STRING
|
||||
path_info: STRING assign update_path_info
|
||||
-- The PATH_INFO metavariable specifies a path to be interpreted
|
||||
-- by the CGI script. It identifies the resource or sub-resource
|
||||
-- to be returned by the CGI script, and it is derived from the
|
||||
@@ -581,6 +581,31 @@ feature -- Extra
|
||||
deferred
|
||||
end
|
||||
|
||||
feature {GW_REQUEST_CONTEXT} -- Element change
|
||||
|
||||
set_orig_path_info (s: STRING)
|
||||
-- Set ORIG_PATH_INFO to `s'
|
||||
require
|
||||
s_attached: s /= Void
|
||||
deferred
|
||||
ensure
|
||||
same_orig_path_info: orig_path_info ~ variable ({GW_ENVIRONMENT_NAMES}.orig_path_info)
|
||||
end
|
||||
|
||||
unset_orig_path_info
|
||||
-- Unset ORIG_PATH_INFO
|
||||
deferred
|
||||
ensure
|
||||
unset: not has_variable ({GW_ENVIRONMENT_NAMES}.orig_path_info)
|
||||
end
|
||||
|
||||
update_path_info (a_path_info: like path_info)
|
||||
-- Updated PATH_INFO
|
||||
deferred
|
||||
ensure
|
||||
same_path_info: path_info ~ variable ({GW_ENVIRONMENT_NAMES}.path_info)
|
||||
end
|
||||
|
||||
invariant
|
||||
server_name_not_empty: not server_name.is_empty
|
||||
server_port_set: server_port /= 0
|
||||
@@ -589,6 +614,8 @@ invariant
|
||||
query_string_attached: query_string /= Void
|
||||
remote_addr_attached: remote_addr /= Void
|
||||
|
||||
path_info_identical: path_info ~ variable ({GW_ENVIRONMENT_NAMES}.path_info)
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
292
library/server/ewsgi/src/context/gw_environment_variables.e
Normal file
292
library/server/ewsgi/src/context/gw_environment_variables.e
Normal file
@@ -0,0 +1,292 @@
|
||||
note
|
||||
description: "Summary description for {GW_ENVIRONMENT_VARIABLES}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_ENVIRONMENT_VARIABLES
|
||||
|
||||
inherit
|
||||
GW_ENVIRONMENT
|
||||
redefine
|
||||
update_path_info
|
||||
end
|
||||
|
||||
create
|
||||
make_with_variables
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_variables (a_vars: HASH_TABLE [STRING, STRING])
|
||||
-- Fill with variable from `a_vars'
|
||||
local
|
||||
s: detachable STRING
|
||||
do
|
||||
create empty_string.make_empty
|
||||
|
||||
create table.make (a_vars.count)
|
||||
from
|
||||
a_vars.start
|
||||
until
|
||||
a_vars.after
|
||||
loop
|
||||
table.force (a_vars.item_for_iteration, a_vars.key_for_iteration)
|
||||
a_vars.forth
|
||||
end
|
||||
|
||||
--| QUERY_STRING
|
||||
query_string := variable_or_default ({GW_ENVIRONMENT_NAMES}.query_string, empty_string, False)
|
||||
|
||||
--| REQUEST_METHOD
|
||||
request_method := variable_or_default ({GW_ENVIRONMENT_NAMES}.request_method, empty_string, False)
|
||||
|
||||
--| CONTENT_TYPE
|
||||
s := variable ({GW_ENVIRONMENT_NAMES}.content_type)
|
||||
if s /= Void and then not s.is_empty then
|
||||
content_type := s
|
||||
else
|
||||
content_type := Void
|
||||
end
|
||||
|
||||
--| CONTENT_LENGTH
|
||||
s := variable ({GW_ENVIRONMENT_NAMES}.content_length)
|
||||
content_length := s
|
||||
if s /= Void and then s.is_integer then
|
||||
content_length_value := s.to_integer
|
||||
else
|
||||
--| content_length := 0
|
||||
end
|
||||
|
||||
--| PATH_INFO
|
||||
path_info := variable_or_default ({GW_ENVIRONMENT_NAMES}.path_info, empty_string, False)
|
||||
|
||||
--| SERVER_NAME
|
||||
server_name := variable_or_default ({GW_ENVIRONMENT_NAMES}.server_name, empty_string, False)
|
||||
|
||||
--| SERVER_PORT
|
||||
s := variable ({GW_ENVIRONMENT_NAMES}.server_port)
|
||||
if s /= Void and then s.is_integer then
|
||||
server_port := s.to_integer
|
||||
else
|
||||
server_port := 80
|
||||
end
|
||||
|
||||
--| SCRIPT_NAME
|
||||
script_name := variable_or_default ({GW_ENVIRONMENT_NAMES}.script_name, empty_string, False)
|
||||
|
||||
--| REMOTE_ADDR
|
||||
remote_addr := variable_or_default ({GW_ENVIRONMENT_NAMES}.remote_addr, empty_string, False)
|
||||
|
||||
--| REMOTE_HOST
|
||||
remote_host := variable_or_default ({GW_ENVIRONMENT_NAMES}.remote_host, empty_string, False)
|
||||
|
||||
--| REQUEST_URI
|
||||
request_uri := variable_or_default ({GW_ENVIRONMENT_NAMES}.request_uri, empty_string, False)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
table: HASH_TABLE [STRING, STRING]
|
||||
|
||||
feature -- Access
|
||||
|
||||
variable (a_name: STRING): detachable STRING
|
||||
do
|
||||
Result := table.item (a_name)
|
||||
end
|
||||
|
||||
has_variable (a_name: STRING): BOOLEAN
|
||||
do
|
||||
Result := table.has_key (a_name)
|
||||
end
|
||||
|
||||
feature {GW_REQUEST_CONTEXT, GW_APPLICATION, GW_CONNECTOR} -- Element change
|
||||
|
||||
set_variable (a_name: STRING; a_value: STRING)
|
||||
do
|
||||
table.force (a_value, a_name)
|
||||
end
|
||||
|
||||
unset_variable (a_name: STRING)
|
||||
do
|
||||
table.remove (a_name)
|
||||
end
|
||||
|
||||
feature -- Common Gateway Interface - 1.1 8 January 1996
|
||||
|
||||
auth_type: detachable STRING
|
||||
|
||||
content_length: detachable STRING
|
||||
|
||||
content_length_value: INTEGER
|
||||
|
||||
content_type: detachable STRING
|
||||
|
||||
gateway_interface: STRING
|
||||
do
|
||||
Result := variable_or_default ({GW_ENVIRONMENT_NAMES}.gateway_interface, "", False)
|
||||
end
|
||||
|
||||
path_info: STRING
|
||||
-- <Precursor/>
|
||||
--
|
||||
--| For instance, if the current script was accessed via the URL
|
||||
--| http://www.example.com/eiffel/path_info.exe/some/stuff?foo=bar, then $_SERVER['PATH_INFO'] would contain /some/stuff.
|
||||
--|
|
||||
--| Note that is the PATH_INFO variable does not exists, the `path_info' value will be empty
|
||||
|
||||
path_translated: detachable STRING
|
||||
do
|
||||
Result := variable ({GW_ENVIRONMENT_NAMES}.path_translated)
|
||||
end
|
||||
|
||||
query_string: STRING
|
||||
|
||||
remote_addr: STRING
|
||||
|
||||
remote_host: STRING
|
||||
|
||||
remote_ident: detachable STRING
|
||||
do
|
||||
Result := variable ({GW_ENVIRONMENT_NAMES}.remote_ident)
|
||||
end
|
||||
|
||||
remote_user: detachable STRING
|
||||
do
|
||||
Result := variable ({GW_ENVIRONMENT_NAMES}.remote_user)
|
||||
end
|
||||
|
||||
request_method: STRING
|
||||
|
||||
script_name: STRING
|
||||
|
||||
server_name: STRING
|
||||
|
||||
server_port: INTEGER
|
||||
|
||||
server_protocol: STRING
|
||||
do
|
||||
Result := variable_or_default ({GW_ENVIRONMENT_NAMES}.server_protocol, "HTTP/1.0", True)
|
||||
end
|
||||
|
||||
server_software: STRING
|
||||
do
|
||||
Result := variable_or_default ({GW_ENVIRONMENT_NAMES}.server_software, "Unknown Server", True)
|
||||
end
|
||||
|
||||
feature -- HTTP_*
|
||||
|
||||
http_accept: detachable STRING
|
||||
-- Contents of the Accept: header from the current request, if there is one.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_accept)
|
||||
end
|
||||
|
||||
http_accept_charset: detachable STRING
|
||||
-- Contents of the Accept-Charset: header from the current request, if there is one.
|
||||
-- Example: 'iso-8859-1,*,utf-8'.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_accept_charset)
|
||||
end
|
||||
|
||||
http_accept_encoding: detachable STRING
|
||||
-- Contents of the Accept-Encoding: header from the current request, if there is one.
|
||||
-- Example: 'gzip'.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_accept_encoding)
|
||||
end
|
||||
|
||||
http_accept_language: detachable STRING
|
||||
-- Contents of the Accept-Language: header from the current request, if there is one.
|
||||
-- Example: 'en'.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_accept_language)
|
||||
end
|
||||
|
||||
http_connection: detachable STRING
|
||||
-- Contents of the Connection: header from the current request, if there is one.
|
||||
-- Example: 'Keep-Alive'.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_connection)
|
||||
end
|
||||
|
||||
http_host: detachable STRING
|
||||
-- Contents of the Host: header from the current request, if there is one.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_host)
|
||||
end
|
||||
|
||||
http_referer: detachable STRING
|
||||
-- The address of the page (if any) which referred the user agent to the current page.
|
||||
-- This is set by the user agent.
|
||||
-- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature.
|
||||
-- In short, it cannot really be trusted.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_referer)
|
||||
end
|
||||
|
||||
http_user_agent: detachable STRING
|
||||
-- Contents of the User-Agent: header from the current request, if there is one.
|
||||
-- This is a string denoting the user agent being which is accessing the page.
|
||||
-- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).
|
||||
-- Among other things, you can use this value to tailor your page's
|
||||
-- output to the capabilities of the user agent.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_user_agent)
|
||||
end
|
||||
|
||||
http_authorization: detachable STRING
|
||||
-- Contents of the Authorization: header from the current request, if there is one.
|
||||
do
|
||||
Result := table.item ({GW_ENVIRONMENT_NAMES}.http_authorization)
|
||||
end
|
||||
|
||||
feature -- Extra
|
||||
|
||||
request_uri: STRING
|
||||
-- The URI which was given in order to access this page; for instance, '/index.html'.
|
||||
|
||||
orig_path_info: detachable STRING
|
||||
-- Original version of `path_info' before processed by Current environment
|
||||
|
||||
feature {GW_REQUEST_CONTEXT} -- Update
|
||||
|
||||
set_orig_path_info (s: STRING)
|
||||
do
|
||||
orig_path_info := s
|
||||
set_variable ({GW_ENVIRONMENT_NAMES}.orig_path_info, s)
|
||||
end
|
||||
|
||||
unset_orig_path_info
|
||||
do
|
||||
orig_path_info := Void
|
||||
unset_variable ({GW_ENVIRONMENT_NAMES}.orig_path_info)
|
||||
end
|
||||
|
||||
update_path_info (a_path_info: like path_info)
|
||||
do
|
||||
path_info := a_path_info
|
||||
set_variable ({GW_ENVIRONMENT_NAMES}.path_info, a_path_info)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
empty_string: STRING
|
||||
-- Reusable empty string
|
||||
|
||||
invariant
|
||||
empty_string_unchanged: empty_string.is_empty
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -31,29 +31,16 @@ feature -- Status report
|
||||
Result := has (a_name)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
feature {GW_REQUEST_CONTEXT, GW_APPLICATION, GW_CONNECTOR} -- Element change
|
||||
|
||||
replace_variable (v: STRING; k: STRING)
|
||||
-- Replace variable `k'
|
||||
set_variable (a_name: STRING; a_value: STRING_32)
|
||||
do
|
||||
force (v, k)
|
||||
force (a_value, a_name)
|
||||
end
|
||||
|
||||
add_variable (v: STRING; k: STRING)
|
||||
-- Add variable `k' with value `v'
|
||||
require
|
||||
k_attached: k /= Void
|
||||
v_attached: k /= Void
|
||||
unset_variable (a_name: STRING)
|
||||
do
|
||||
force (v, k)
|
||||
end
|
||||
|
||||
delete_variable (k: STRING)
|
||||
-- Remove variable `k'
|
||||
require
|
||||
k_attached: k /= Void
|
||||
do
|
||||
remove (k)
|
||||
remove (a_name)
|
||||
end
|
||||
|
||||
note
|
||||
@@ -17,13 +17,13 @@ deferred class
|
||||
|
||||
feature -- Access: Input/Output
|
||||
|
||||
output: GW_OUTPUT_STREAM
|
||||
-- Server output channel
|
||||
input: GW_INPUT_STREAM
|
||||
-- Server input channel
|
||||
deferred
|
||||
end
|
||||
|
||||
input: GW_INPUT_STREAM
|
||||
-- Server input channel
|
||||
output: GW_OUTPUT_STREAM
|
||||
-- Server output channel
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -31,8 +31,8 @@ feature -- Access: global variable
|
||||
|
||||
variables: HASH_TABLE [STRING_32, STRING_32]
|
||||
-- Table containing all the various variables
|
||||
-- Warning: this is computed each time, if you change this content of other container
|
||||
-- this won't update this Result's content.
|
||||
-- Warning: this is computed each time, if you change the content of other containers
|
||||
-- this won't update this Result's content, unless you query it again
|
||||
local
|
||||
vars: HASH_TABLE [STRING_GENERAL, STRING_GENERAL]
|
||||
do
|
||||
@@ -100,11 +100,11 @@ feature -- Access: global variable
|
||||
if s = Void then
|
||||
s := environment_variable (n8)
|
||||
if s = Void then
|
||||
s := parameters.variable (n8)
|
||||
s := parameter (n8)
|
||||
if s = Void then
|
||||
s := form_fields.variable (n8)
|
||||
s := form_field (n8)
|
||||
if s = Void then
|
||||
s := cookies_variables.item (n8)
|
||||
s := cookies_variable (n8)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -114,6 +114,13 @@ feature -- Access: global variable
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: environment extra values
|
||||
|
||||
request_time: detachable DATE_TIME
|
||||
-- Request time (UTC)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: environment variables
|
||||
|
||||
environment: GW_ENVIRONMENT
|
||||
@@ -144,13 +151,27 @@ feature -- Access: execution variables
|
||||
Result := execution_variables.variable (a_name)
|
||||
end
|
||||
|
||||
feature -- Queries
|
||||
feature -- URL Parameters
|
||||
|
||||
parameter (n: STRING): detachable STRING_32
|
||||
-- Parameter for name `n'.
|
||||
do
|
||||
Result := parameters.variable (n)
|
||||
end
|
||||
|
||||
parameters: GW_REQUEST_VARIABLES
|
||||
-- Variables extracted from QUERY_STRING
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Form fields and related
|
||||
|
||||
form_field (n: STRING): detachable STRING_32
|
||||
-- Field for name `n'.
|
||||
do
|
||||
Result := form_fields.variable (n)
|
||||
end
|
||||
|
||||
form_fields: GW_REQUEST_VARIABLES
|
||||
-- Variables sent by POST request
|
||||
deferred
|
||||
@@ -164,6 +185,16 @@ feature -- Queries
|
||||
--| tmp_base_name: basename of `tmp_name'
|
||||
--| error: if /= 0 , there was an error : TODO ...
|
||||
--| size: size of the file given by the http request
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Cookies
|
||||
|
||||
cookies_variable (n: STRING): detachable STRING
|
||||
-- Field for name `n'.
|
||||
do
|
||||
Result := cookies_variables.item (n)
|
||||
end
|
||||
|
||||
cookies_variables: HASH_TABLE [STRING, STRING]
|
||||
-- Expanded cookies variable
|
||||
@@ -16,8 +16,8 @@ inherit
|
||||
ITERABLE [STRING_32]
|
||||
|
||||
create
|
||||
make--,
|
||||
-- make_from_urlencoded
|
||||
make,
|
||||
make_from_urlencoded
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
@@ -27,11 +27,11 @@ feature -- Initialization
|
||||
table.compare_objects
|
||||
end
|
||||
|
||||
-- make_from_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
||||
-- do
|
||||
-- make (a_content.occurrences ('&') + 1)
|
||||
-- import_urlencoded (a_content, decoding)
|
||||
-- end
|
||||
make_from_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
||||
do
|
||||
make (a_content.occurrences ('&') + 1)
|
||||
import_urlencoded (a_content, decoding)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
@@ -51,15 +51,28 @@ feature -- Status report
|
||||
Result := table.has (a_name)
|
||||
end
|
||||
|
||||
feature {GW_REQUEST_CONTEXT, GW_APPLICATION, GW_CONNECTOR} -- Element change
|
||||
|
||||
set_variable (a_name: STRING; a_value: STRING_32)
|
||||
do
|
||||
table.force (a_value, a_name)
|
||||
end
|
||||
|
||||
unset_variable (a_name: STRING)
|
||||
do
|
||||
table.remove (a_name)
|
||||
end
|
||||
|
||||
feature -- Import urlencoded
|
||||
|
||||
-- import_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
||||
-- -- Import `a_content'
|
||||
-- local
|
||||
import_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
||||
-- Import `a_content'
|
||||
local
|
||||
-- n, p, i, j: INTEGER
|
||||
-- s: STRING
|
||||
-- l_name,l_value: STRING_32
|
||||
-- do
|
||||
do
|
||||
-- FIXME
|
||||
-- n := a_content.count
|
||||
-- if n > 0 then
|
||||
-- from
|
||||
@@ -89,7 +102,7 @@ feature -- Import urlencoded
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
|
||||
feature -- Access: table
|
||||
|
||||
@@ -46,6 +46,24 @@ feature -- Access
|
||||
end
|
||||
end
|
||||
|
||||
feature {GW_REQUEST_CONTEXT, GW_APPLICATION, GW_CONNECTOR} -- Element change
|
||||
|
||||
set_variable (a_name: STRING; a_value: G)
|
||||
require
|
||||
a_name_not_empty: a_name /= Void and then not a_name.is_empty
|
||||
deferred
|
||||
ensure
|
||||
variable_set: has_variable (a_name) and then variable (a_name) ~ a_value
|
||||
end
|
||||
|
||||
unset_variable (a_name: STRING)
|
||||
require
|
||||
a_name_not_empty: a_name /= Void and then not a_name.is_empty
|
||||
deferred
|
||||
ensure
|
||||
variable_unset: not has_variable (a_name)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
@@ -11,6 +11,7 @@ deferred class
|
||||
feature -- Execution
|
||||
|
||||
process (env: GW_ENVIRONMENT; a_input: GW_INPUT_STREAM; a_output: GW_OUTPUT_STREAM)
|
||||
-- Process request with environment `env', and i/o streams `a_input' and `a_output'
|
||||
do
|
||||
execute (new_request_context (env, a_input, a_output))
|
||||
end
|
||||
44
library/server/ewsgi/src/gw_connector.e
Normal file
44
library/server/ewsgi/src/gw_connector.e
Normal file
@@ -0,0 +1,44 @@
|
||||
note
|
||||
description: "Summary description for {GW_CONNECTOR}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
GW_CONNECTOR
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_app: like application)
|
||||
do
|
||||
application := a_app
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize connector
|
||||
do
|
||||
end
|
||||
|
||||
feature {NONE} -- Access
|
||||
|
||||
application: GW_APPLICATION
|
||||
-- Gateway Application
|
||||
|
||||
feature -- Server
|
||||
|
||||
launch
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
66
library/server/ewsgi/src/gw_error.e
Normal file
66
library/server/ewsgi/src/gw_error.e
Normal file
@@ -0,0 +1,66 @@
|
||||
note
|
||||
description: "Summary description for {GW_ERROR}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_ERROR
|
||||
|
||||
inherit
|
||||
ERROR
|
||||
|
||||
HTTP_STATUS_CODE_MESSAGES
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_code: INTEGER)
|
||||
do
|
||||
code := a_code
|
||||
name := "HTTP Error"
|
||||
if attached http_status_code_message (a_code) as m then
|
||||
name := m
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
code: INTEGER
|
||||
|
||||
name: STRING
|
||||
|
||||
message: detachable STRING_32
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_message (m: like message)
|
||||
-- Set `message' to `m'
|
||||
require
|
||||
m_attached: m /= Void
|
||||
do
|
||||
message := m
|
||||
end
|
||||
|
||||
feature -- Visitor
|
||||
|
||||
process (a_visitor: ERROR_VISITOR)
|
||||
-- Process Current using `a_visitor'.
|
||||
do
|
||||
a_visitor.process_error (Current)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
50
library/server/ewsgi/src/implementation/gw_application_imp.e
Normal file
50
library/server/ewsgi/src/implementation/gw_application_imp.e
Normal file
@@ -0,0 +1,50 @@
|
||||
note
|
||||
description: "Summary description for {GW_APPLICATION_IMP} "
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
GW_APPLICATION_IMP
|
||||
|
||||
inherit
|
||||
GW_APPLICATION
|
||||
redefine
|
||||
process
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
request_count: INTEGER
|
||||
-- Request count
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process (env: GW_ENVIRONMENT; a_input: GW_INPUT_STREAM; a_output: GW_OUTPUT_STREAM)
|
||||
-- Process request with environment `env', and i/o streams `a_input' and `a_output'
|
||||
do
|
||||
request_count := request_count + 1
|
||||
Precursor (env, a_input, a_output)
|
||||
end
|
||||
|
||||
feature -- Factory
|
||||
|
||||
new_request_context (env: GW_ENVIRONMENT; a_input: GW_INPUT_STREAM; a_output: GW_OUTPUT_STREAM): GW_REQUEST_CONTEXT
|
||||
do
|
||||
create {GW_REQUEST_CONTEXT_IMP} Result.make (env, a_input, a_output)
|
||||
Result.execution_variables.set_variable (request_count.out, "REQUEST_COUNT")
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
818
library/server/ewsgi/src/implementation/gw_request_context_imp.e
Normal file
818
library/server/ewsgi/src/implementation/gw_request_context_imp.e
Normal file
@@ -0,0 +1,818 @@
|
||||
note
|
||||
description: "[
|
||||
Server request context of the httpd request
|
||||
|
||||
You can create your own descendant of this class to
|
||||
add/remove specific value or processing
|
||||
|
||||
This object is created by {GW_APPLICATION}.new_request_context
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_REQUEST_CONTEXT_IMP
|
||||
|
||||
inherit
|
||||
GW_REQUEST_CONTEXT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (env: GW_ENVIRONMENT; a_input: like input; a_output: like output)
|
||||
require
|
||||
env_attached: env /= Void
|
||||
do
|
||||
create error_handler.make
|
||||
input := a_input
|
||||
output := a_output
|
||||
environment := env
|
||||
content_length := env.content_length_value
|
||||
create execution_variables.make (10)
|
||||
create uploaded_files.make (0)
|
||||
|
||||
raw_post_data_recorded := True
|
||||
|
||||
initialize
|
||||
analyze
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Specific initialization
|
||||
local
|
||||
p: INTEGER
|
||||
dt: DATE_TIME
|
||||
env: like environment
|
||||
do
|
||||
env := environment
|
||||
--| Here one can set its own environment entries if needed
|
||||
|
||||
--| do not use `force', to avoid overwriting existing variable
|
||||
if attached env.request_uri as rq_uri then
|
||||
p := rq_uri.index_of ('?', 1)
|
||||
if p > 0 then
|
||||
env.set_variable (rq_uri.substring (1, p-1), {GW_ENVIRONMENT_NAMES}.self)
|
||||
else
|
||||
env.set_variable (rq_uri, {GW_ENVIRONMENT_NAMES}.self)
|
||||
end
|
||||
end
|
||||
if env.variable ({GW_ENVIRONMENT_NAMES}.request_time) = Void then
|
||||
env.set_variable (date_time_utilities.unix_time_stamp (Void).out, {GW_ENVIRONMENT_NAMES}.request_time)
|
||||
end
|
||||
end
|
||||
|
||||
analyze
|
||||
-- Analyze context, set various attributes and validate values
|
||||
do
|
||||
extract_variables
|
||||
end
|
||||
|
||||
feature -- Access: Input/Output
|
||||
|
||||
output: GW_OUTPUT_STREAM
|
||||
-- Server output channel
|
||||
|
||||
input: GW_INPUT_STREAM
|
||||
-- Server input channel
|
||||
|
||||
feature -- Status
|
||||
|
||||
raw_post_data_recorded: BOOLEAN assign set_raw_post_data_recorded
|
||||
-- Record RAW POST DATA in environment variables
|
||||
-- otherwise just forget about it
|
||||
-- Default: true
|
||||
--| warning: you might keep in memory big amount of memory ...
|
||||
|
||||
feature -- Error handling
|
||||
|
||||
has_error: BOOLEAN
|
||||
do
|
||||
Result := error_handler.has_error
|
||||
end
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler
|
||||
-- By default initialized to new handler
|
||||
|
||||
feature -- Access: environment variables
|
||||
|
||||
environment: GW_ENVIRONMENT
|
||||
-- Environment variables
|
||||
|
||||
content_length: INTEGER
|
||||
-- Extracted Content-Length value
|
||||
|
||||
feature -- Access: execution variables
|
||||
|
||||
execution_variables: GW_EXECUTION_VARIABLES
|
||||
-- Execution variables set by the application
|
||||
|
||||
feature -- URL parameters
|
||||
|
||||
parameters: GW_REQUEST_VARIABLES
|
||||
local
|
||||
vars: like internal_parameters
|
||||
p,e: INTEGER
|
||||
rq_uri: like environment.request_uri
|
||||
s: detachable STRING
|
||||
do
|
||||
vars := internal_parameters
|
||||
if vars = Void then
|
||||
s := environment.query_string
|
||||
if s = Void then
|
||||
rq_uri := environment.request_uri
|
||||
p := rq_uri.index_of ('?', 1)
|
||||
if p > 0 then
|
||||
e := rq_uri.index_of ('#', p + 1)
|
||||
if e = 0 then
|
||||
e := rq_uri.count
|
||||
else
|
||||
e := e - 1
|
||||
end
|
||||
s := rq_uri.substring (p+1, e)
|
||||
end
|
||||
end
|
||||
if s /= Void and then not s.is_empty then
|
||||
create vars.make_from_urlencoded (s, True)
|
||||
else
|
||||
create vars.make (0)
|
||||
end
|
||||
internal_parameters := vars
|
||||
end
|
||||
Result := vars
|
||||
end
|
||||
|
||||
feature -- Form fields and related
|
||||
|
||||
form_fields: GW_REQUEST_VARIABLES
|
||||
local
|
||||
vars: like internal_form_fields
|
||||
s: STRING
|
||||
n: INTEGER
|
||||
l_type: detachable STRING
|
||||
do
|
||||
vars := internal_form_fields
|
||||
if vars = Void then
|
||||
n := content_length
|
||||
if n > 0 then
|
||||
l_type := environment.content_type
|
||||
if
|
||||
l_type /= Void and then
|
||||
l_type.starts_with ({HTTP_CONSTANTS}.multipart_form)
|
||||
then
|
||||
create vars.make (5)
|
||||
--| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ...
|
||||
s := form_input_data (n)
|
||||
analyze_multipart_form (l_type, s, vars)
|
||||
else
|
||||
s := form_input_data (n)
|
||||
create vars.make_from_urlencoded (s, True)
|
||||
end
|
||||
if raw_post_data_recorded then
|
||||
vars.add_variable (s, "RAW_POST_DATA")
|
||||
end
|
||||
else
|
||||
create vars.make (0)
|
||||
end
|
||||
internal_form_fields := vars
|
||||
end
|
||||
Result := vars
|
||||
end
|
||||
|
||||
uploaded_files: HASH_TABLE [TUPLE [name: STRING; type: STRING; tmp_name: STRING; tmp_basename: STRING; error: INTEGER; size: INTEGER], STRING]
|
||||
-- Table of uploaded files information
|
||||
--| name: original path from the user
|
||||
--| type: content type
|
||||
--| tmp_name: path to temp file that resides on server
|
||||
--| tmp_base_name: basename of `tmp_name'
|
||||
--| error: if /= 0 , there was an error : TODO ...
|
||||
--| size: size of the file given by the http request
|
||||
|
||||
feature -- Cookies
|
||||
|
||||
cookies_variables: HASH_TABLE [STRING, STRING]
|
||||
-- Expanded cookies variable
|
||||
local
|
||||
l_cookies: like cookies
|
||||
do
|
||||
l_cookies := cookies
|
||||
create Result.make (l_cookies.count)
|
||||
from
|
||||
l_cookies.start
|
||||
until
|
||||
l_cookies.after
|
||||
loop
|
||||
if attached l_cookies.item_for_iteration.variables as vars then
|
||||
from
|
||||
vars.start
|
||||
until
|
||||
vars.after
|
||||
loop
|
||||
Result.force (vars.item_for_iteration, vars.key_for_iteration)
|
||||
vars.forth
|
||||
end
|
||||
else
|
||||
check same_name: l_cookies.key_for_iteration.same_string (l_cookies.item_for_iteration.name) end
|
||||
Result.force (l_cookies.item_for_iteration.value, l_cookies.key_for_iteration)
|
||||
end
|
||||
l_cookies.forth
|
||||
end
|
||||
end
|
||||
|
||||
cookies: HASH_TABLE [GW_COOKIE, STRING]
|
||||
-- Cookies Information
|
||||
local
|
||||
i,j,p,n: INTEGER
|
||||
l_cookies: like internal_cookies
|
||||
k,v: STRING
|
||||
do
|
||||
l_cookies := internal_cookies
|
||||
if l_cookies = Void then
|
||||
if attached environment_variable ({GW_ENVIRONMENT_NAMES}.http_cookie) as s then
|
||||
create l_cookies.make (5)
|
||||
from
|
||||
n := s.count
|
||||
p := 1
|
||||
i := 1
|
||||
until
|
||||
p < 1
|
||||
loop
|
||||
i := s.index_of ('=', p)
|
||||
if i > 0 then
|
||||
j := s.index_of (';', i)
|
||||
if j = 0 then
|
||||
j := n + 1
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, n)
|
||||
|
||||
p := 0 -- force termination
|
||||
else
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, j - 1)
|
||||
p := j + 1
|
||||
end
|
||||
l_cookies.put (create {GW_COOKIE}.make (k,v), k)
|
||||
end
|
||||
end
|
||||
else
|
||||
create l_cookies.make (0)
|
||||
end
|
||||
internal_cookies := l_cookies
|
||||
end
|
||||
Result := l_cookies
|
||||
end
|
||||
|
||||
feature -- Query
|
||||
|
||||
-- script_absolute_url (a_path: STRING): STRING
|
||||
-- -- Absolute Url for the script if any, extended by `a_path'
|
||||
-- do
|
||||
-- Result := script_url (a_path)
|
||||
-- if attached http_host as h then
|
||||
-- Result.prepend (h)
|
||||
-- else
|
||||
-- --| Issue ??
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- script_url (a_path: STRING): STRING
|
||||
-- -- Url relative to script name if any, extended by `a_path'
|
||||
-- require
|
||||
-- a_path_attached: a_path /= Void
|
||||
-- local
|
||||
-- l_base_url: like script_url_base
|
||||
-- i,m,n: INTEGER
|
||||
-- l_rq_uri: like request_uri
|
||||
-- do
|
||||
-- l_base_url := script_url_base
|
||||
-- if l_base_url = Void then
|
||||
-- if attached environment.script_name as l_script_name then
|
||||
-- l_rq_uri := request_uri
|
||||
-- if l_rq_uri.starts_with (l_script_name) then
|
||||
-- l_base_url := l_script_name
|
||||
-- else
|
||||
-- --| Handle Rewrite url engine, to have clean path
|
||||
-- from
|
||||
-- i := 1
|
||||
-- m := l_rq_uri.count
|
||||
-- n := l_script_name.count
|
||||
-- until
|
||||
-- i > m or i > n or l_rq_uri[i] /= l_script_name[i]
|
||||
-- loop
|
||||
-- i := i + 1
|
||||
-- end
|
||||
-- if i > 1 then
|
||||
-- if l_rq_uri[i-1] = '/' then
|
||||
-- i := i -1
|
||||
-- end
|
||||
-- l_base_url := l_rq_uri.substring (1, i - 1)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- if l_base_url = Void then
|
||||
-- create l_base_url.make_empty
|
||||
-- end
|
||||
-- script_url_base := l_base_url
|
||||
-- end
|
||||
-- Result := l_base_url + a_path
|
||||
-- end
|
||||
|
||||
-- script_url_base: detachable STRING
|
||||
-- -- URL base of potential script
|
||||
|
||||
feature -- Access environment information
|
||||
|
||||
request_time: detachable DATE_TIME
|
||||
-- Request time (UTC)
|
||||
do
|
||||
if
|
||||
attached environment.variable ({GW_ENVIRONMENT_NAMES}.request_time) as t and then
|
||||
t.is_integer_64
|
||||
then
|
||||
Result := date_time_utilities.unix_time_stamp_to_date_time (t.to_integer_64)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_raw_post_data_recorded (b: BOOLEAN)
|
||||
-- Set `raw_post_data_recorded' to `b'
|
||||
do
|
||||
raw_post_data_recorded := b
|
||||
end
|
||||
|
||||
set_error_handler (ehdl: like error_handler)
|
||||
-- Set `error_handler' to `ehdl'
|
||||
do
|
||||
error_handler := ehdl
|
||||
end
|
||||
|
||||
update_path_info (env: GW_ENVIRONMENT)
|
||||
-- Fix and update PATH_INFO value if needed
|
||||
local
|
||||
l_path_info: STRING
|
||||
do
|
||||
l_path_info := env.path_info
|
||||
--| Warning
|
||||
--| on IIS: we might have PATH_INFO = /sample.exe/foo/bar
|
||||
--| on apache: PATH_INFO = /foo/bar
|
||||
--| So, we might need to check with SCRIPT_NAME and remove it on IIS
|
||||
--| store original PATH_INFO in ORIG_PATH_INFO
|
||||
if l_path_info.is_empty then
|
||||
env.unset_orig_path_info
|
||||
else
|
||||
env.set_orig_path_info (l_path_info)
|
||||
if attached env.script_name as l_script_name then
|
||||
if l_path_info.starts_with (l_script_name) then
|
||||
env.path_info := l_path_info.substring (l_script_name.count + 1 , l_path_info.count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Uploaded File Handling
|
||||
|
||||
move_uploaded_file (a_filename: STRING; a_destination: STRING): BOOLEAN
|
||||
-- Move uploaded file `a_filename' to `a_destination'
|
||||
--| if this is not an uploaded file, do not move it.
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
if is_uploaded_file (a_filename) then
|
||||
create f.make (a_filename)
|
||||
if f.exists then
|
||||
f.change_name (a_destination)
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_uploaded_file (a_filename: STRING): BOOLEAN
|
||||
-- Is `a_filename' a file uploaded via HTTP Form
|
||||
local
|
||||
l_files: like uploaded_files
|
||||
do
|
||||
l_files := uploaded_files
|
||||
if not l_files.is_empty then
|
||||
from
|
||||
l_files.start
|
||||
until
|
||||
l_files.after or Result
|
||||
loop
|
||||
if l_files.item_for_iteration.tmp_name.same_string (a_filename) then
|
||||
Result := True
|
||||
end
|
||||
l_files.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Temporary File handling
|
||||
|
||||
delete_uploaded_file (a_filename: STRING)
|
||||
-- Delete file `a_filename'
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
if is_uploaded_file (a_filename) then
|
||||
create f.make (a_filename)
|
||||
if f.exists and then f.is_writable then
|
||||
f.delete
|
||||
else
|
||||
error_handler.add_custom_error (0, "Can not delete file", "Can not delete file %""+ a_filename +"%"")
|
||||
end
|
||||
else
|
||||
error_handler.add_custom_error (0, "Not uploaded file", "This file %""+ a_filename +"%" is not an uploaded file.")
|
||||
end
|
||||
end
|
||||
|
||||
save_uploaded_file (a_content: STRING; a_filename: STRING): detachable TUPLE [name: STRING; basename: STRING]
|
||||
-- Save uploaded file content to `a_filename'
|
||||
local
|
||||
bn: STRING
|
||||
l_safe_name: STRING
|
||||
f: RAW_FILE
|
||||
dn: STRING
|
||||
fn: FILE_NAME
|
||||
d: DIRECTORY
|
||||
n: INTEGER
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
dn := (create {EXECUTION_ENVIRONMENT}).current_working_directory
|
||||
create d.make (dn)
|
||||
if d.exists and then d.is_writable then
|
||||
l_safe_name := safe_filename (a_filename)
|
||||
from
|
||||
create fn.make_from_string (dn)
|
||||
bn := "tmp-" + l_safe_name
|
||||
fn.set_file_name (bn)
|
||||
create f.make (fn.string)
|
||||
n := 0
|
||||
until
|
||||
not f.exists
|
||||
or else n > 1_000
|
||||
loop
|
||||
n := n + 1
|
||||
fn.make_from_string (dn)
|
||||
bn := "tmp-" + n.out + "-" + l_safe_name
|
||||
fn.set_file_name (bn)
|
||||
f.make (fn.string)
|
||||
end
|
||||
|
||||
if not f.exists or else f.is_writable then
|
||||
f.open_write
|
||||
f.put_string (a_content)
|
||||
f.close
|
||||
Result := [f.name, bn]
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
else
|
||||
error_handler.add_custom_error (0, "Directory not writable", "Can not create file in directory %""+ dn +"%"")
|
||||
end
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
rescue
|
||||
rescued := True
|
||||
retry
|
||||
end
|
||||
|
||||
safe_filename (fn: STRING): STRING
|
||||
local
|
||||
c: CHARACTER
|
||||
i, n, p: INTEGER
|
||||
l_accentued, l_non_accentued: STRING
|
||||
do
|
||||
l_accentued := "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||
l_non_accentued := "AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy"
|
||||
|
||||
--| Compute safe filename, to avoid creating impossible filename, or dangerous one
|
||||
from
|
||||
i := 1
|
||||
n := fn.count
|
||||
create Result.make (n)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := fn[i]
|
||||
inspect c
|
||||
when '.', '-', '_' then
|
||||
Result.extend (c)
|
||||
when 'A' .. 'Z', 'a' .. 'z', '0' .. '9' then
|
||||
Result.extend (c)
|
||||
else
|
||||
p := l_accentued.index_of (c, 1)
|
||||
if p > 0 then
|
||||
Result.extend (l_non_accentued[p])
|
||||
else
|
||||
Result.extend ('-')
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: Form analyzer
|
||||
|
||||
analyze_multipart_form (t: STRING; s: STRING; vars: like form_fields)
|
||||
-- Analyze multipart form content
|
||||
--| FIXME[2011-06-21]: integrate eMIME parser library
|
||||
require
|
||||
t_attached: t /= Void
|
||||
s_attached: s /= Void
|
||||
vars_attached: vars /= Void
|
||||
local
|
||||
p,i,next_b: INTEGER
|
||||
l_boundary_prefix: STRING
|
||||
l_boundary: STRING
|
||||
l_boundary_len: INTEGER
|
||||
m: STRING
|
||||
is_crlf: BOOLEAN
|
||||
do
|
||||
p := t.substring_index ("boundary=", 1)
|
||||
if p > 0 then
|
||||
l_boundary := t.substring (p + 9, t.count)
|
||||
p := s.substring_index (l_boundary, 1)
|
||||
if p > 1 then
|
||||
l_boundary_prefix := s.substring (1, p - 1)
|
||||
l_boundary := l_boundary_prefix + l_boundary
|
||||
else
|
||||
create l_boundary_prefix.make_empty
|
||||
end
|
||||
l_boundary_len := l_boundary.count
|
||||
--| Let's support either %R%N and %N ...
|
||||
--| Since both cases might occurs (for instance, our implementation of CGI does not have %R%N)
|
||||
--| then let's be as flexible as possible on this.
|
||||
is_crlf := s[l_boundary_len + 1] = '%R'
|
||||
from
|
||||
i := 1 + l_boundary_len + 1
|
||||
if is_crlf then
|
||||
i := i + 1 --| +1 = CR = %R
|
||||
end
|
||||
next_b := i
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
next_b := s.substring_index (l_boundary, i)
|
||||
if next_b > 0 then
|
||||
if is_crlf then
|
||||
m := s.substring (i, next_b - 1 - 2) --| 2 = CR LF = %R %N
|
||||
else
|
||||
m := s.substring (i, next_b - 1 - 1) --| 1 = LF = %N
|
||||
end
|
||||
analyze_multipart_form_input (m, vars)
|
||||
i := next_b + l_boundary_len + 1
|
||||
if is_crlf then
|
||||
i := i + 1 --| +1 = CR = %R
|
||||
end
|
||||
else
|
||||
if is_crlf then
|
||||
i := i + 1
|
||||
end
|
||||
m := s.substring (i - 1, s.count)
|
||||
m.right_adjust
|
||||
if not l_boundary_prefix.same_string (m) then
|
||||
error_handler.add_custom_error (0, "Invalid form data", "Invalid ending for form data from input")
|
||||
end
|
||||
i := next_b
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
analyze_multipart_form_input (s: STRING; vars_post: like form_fields)
|
||||
-- Analyze multipart entry
|
||||
require
|
||||
s_not_empty: s /= Void and then not s.is_empty
|
||||
local
|
||||
n, i,p, b,e: INTEGER
|
||||
l_name, l_filename, l_content_type: detachable STRING
|
||||
l_header: detachable STRING
|
||||
l_content: detachable STRING
|
||||
l_line: detachable STRING
|
||||
do
|
||||
from
|
||||
p := 1
|
||||
n := s.count
|
||||
until
|
||||
p > n or l_header /= Void
|
||||
loop
|
||||
inspect s[p]
|
||||
when '%R' then -- CR
|
||||
if
|
||||
n >= p + 3 and then
|
||||
s[p+1] = '%N' and then -- LF
|
||||
s[p+2] = '%R' and then -- CR
|
||||
s[p+3] = '%N' -- LF
|
||||
then
|
||||
l_header := s.substring (1, p + 1)
|
||||
l_content := s.substring (p + 4, n)
|
||||
end
|
||||
when '%N' then
|
||||
if
|
||||
n >= p + 1 and then
|
||||
s[p+1] = '%N'
|
||||
then
|
||||
l_header := s.substring (1, p)
|
||||
l_content := s.substring (p + 2, n)
|
||||
end
|
||||
else
|
||||
end
|
||||
p := p + 1
|
||||
end
|
||||
if l_header /= Void and l_content /= Void then
|
||||
from
|
||||
i := 1
|
||||
n := l_header.count
|
||||
until
|
||||
i = 0 or i > n
|
||||
loop
|
||||
l_line := Void
|
||||
b := i
|
||||
p := l_header.index_of ('%N', b)
|
||||
if p > 0 then
|
||||
if l_header[p - 1] = '%R' then
|
||||
p := p - 1
|
||||
i := p + 2
|
||||
else
|
||||
i := p + 1
|
||||
end
|
||||
end
|
||||
if p > 0 then
|
||||
l_line := l_header.substring (b, p - 1)
|
||||
if l_line.starts_with ("Content-Disposition: form-data") then
|
||||
p := l_line.substring_index ("name=", 1)
|
||||
if p > 0 then
|
||||
p := p + 4 --| 4 = ("name=").count - 1
|
||||
if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then
|
||||
p := p + 1
|
||||
e := l_line.index_of ('"', p + 1)
|
||||
else
|
||||
e := l_line.index_of (';', p + 1)
|
||||
if e = 0 then
|
||||
e := l_line.count
|
||||
end
|
||||
end
|
||||
l_name := l_header.substring (p + 1, e - 1)
|
||||
end
|
||||
|
||||
p := l_line.substring_index ("filename=", 1)
|
||||
if p > 0 then
|
||||
p := p + 8 --| 8 = ("filename=").count - 1
|
||||
if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then
|
||||
p := p + 1
|
||||
e := l_line.index_of ('"', p + 1)
|
||||
else
|
||||
e := l_line.index_of (';', p + 1)
|
||||
if e = 0 then
|
||||
e := l_line.count
|
||||
end
|
||||
end
|
||||
l_filename := l_header.substring (p + 1, e - 1)
|
||||
end
|
||||
elseif l_line.starts_with ("Content-Type: ") then
|
||||
l_content_type := l_line.substring (15, l_line.count)
|
||||
end
|
||||
else
|
||||
i := 0
|
||||
end
|
||||
end
|
||||
if l_name /= Void then
|
||||
if l_filename /= Void then
|
||||
if l_content_type = Void then
|
||||
l_content_type := default_content_type
|
||||
end
|
||||
if attached save_uploaded_file (l_content, l_filename) as l_saved_fn_info then
|
||||
uploaded_files.force ([l_filename, l_content_type, l_saved_fn_info.name, l_saved_fn_info.basename, 0, l_content.count], l_name)
|
||||
else
|
||||
uploaded_files.force ([l_filename, l_content_type, "", "", -1, l_content.count], l_name)
|
||||
end
|
||||
else
|
||||
vars_post.add_variable (l_content, l_name)
|
||||
end
|
||||
else
|
||||
error_handler.add_custom_error (0, "unamed multipart entry", Void)
|
||||
end
|
||||
else
|
||||
error_handler.add_custom_error (0, "missformed multipart entry", Void)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Internal value
|
||||
|
||||
default_content_type: STRING = "text/plain"
|
||||
-- Default content type
|
||||
|
||||
form_input_data (nb: INTEGER): STRING
|
||||
-- data from input form
|
||||
local
|
||||
n: INTEGER
|
||||
t: STRING
|
||||
do
|
||||
from
|
||||
n := nb
|
||||
create Result.make (n)
|
||||
if n > 1_024 then
|
||||
n := 1_024
|
||||
end
|
||||
until
|
||||
n <= 0
|
||||
loop
|
||||
read_input (n)
|
||||
t := last_input_string
|
||||
Result.append_string (t)
|
||||
if t.count < n then
|
||||
n := 0
|
||||
end
|
||||
n := nb - t.count
|
||||
end
|
||||
end
|
||||
|
||||
internal_parameters: detachable like parameters
|
||||
-- cached value for `parameters'
|
||||
|
||||
internal_form_fields: detachable like form_fields
|
||||
-- cached value for `form_fields'
|
||||
|
||||
internal_cookies: detachable like cookies
|
||||
-- cached value for `cookies'
|
||||
|
||||
feature {NONE} -- I/O: implementation
|
||||
|
||||
read_input (nb: INTEGER)
|
||||
-- Read `nb' bytes from `input'
|
||||
do
|
||||
input.read_stream (nb)
|
||||
end
|
||||
|
||||
last_input_string: STRING
|
||||
-- Last string read from `input'
|
||||
do
|
||||
Result := input.last_string
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
report_bad_request_error (a_message: detachable STRING)
|
||||
-- Report error
|
||||
local
|
||||
e: GW_ERROR
|
||||
do
|
||||
create e.make ({HTTP_STATUS_CODE}.bad_request)
|
||||
if a_message /= Void then
|
||||
e.set_message (a_message)
|
||||
end
|
||||
error_handler.add_error (e)
|
||||
end
|
||||
|
||||
extract_variables
|
||||
-- Extract relevant environment variables
|
||||
local
|
||||
s: detachable STRING
|
||||
do
|
||||
s := environment.request_uri
|
||||
if s.is_empty then
|
||||
report_bad_request_error ("Missing URI")
|
||||
end
|
||||
if not has_error then
|
||||
s := environment.request_method
|
||||
if s.is_empty then
|
||||
report_bad_request_error ("Missing request method")
|
||||
end
|
||||
end
|
||||
if not has_error then
|
||||
s := environment.http_host
|
||||
if s = Void or else s.is_empty then
|
||||
report_bad_request_error ("Missing host header")
|
||||
end
|
||||
end
|
||||
if not has_error then
|
||||
update_path_info (environment)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: utilities
|
||||
|
||||
date_time_utilities: HTTP_DATE_TIME_UTILITIES
|
||||
-- Utilities classes related to date and time.
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
7
library/server/libfcgi/README.txt
Normal file
7
library/server/libfcgi/README.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
To compile your own binaries .lib and .dll on Windows
|
||||
please get the source from
|
||||
|
||||
https://github.com/EiffelSoftware/libfcgi
|
||||
|
||||
git repository:
|
||||
git clone https://github.com/EiffelSoftware/libfcgi.git
|
||||
50
library/server/libfcgi/doc/Configuration_examples.txt
Normal file
50
library/server/libfcgi/doc/Configuration_examples.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
= How to configure FCGI =
|
||||
== Apache2/Windows ==
|
||||
* in apache2/conf/httpd.conf add
|
||||
LoadModule fcgid_module modules/mod_fcgid.so
|
||||
|
||||
* and for instance, you can put the following code to test the tests/eiffelweb example
|
||||
|
||||
<IfModule mod_fcgid.c>
|
||||
FcgidIdleTimeout 60
|
||||
FcgidBusyScanInterval 120
|
||||
FcgidProcessLifeTime 1600
|
||||
#7200
|
||||
FcgidMaxProcesses 5
|
||||
FcgidMaxProcessesPerClass 100
|
||||
FcgidMinProcessesPerClass 100
|
||||
FcgidConnectTimeout 8
|
||||
FcgidIOTimeout 3000
|
||||
FcgidBusyTimeout 3200
|
||||
FcgidPassHeader Authorization
|
||||
|
||||
|
||||
alias /eiffelweb/ "c:/_dev/EiffelWebReloaded/library/fcgi/tests/EIFGENs/eiffelweb/W_code/"
|
||||
<Location /eiffelweb/>
|
||||
AddHandler fcgid-script .exe
|
||||
Options Indexes FollowSymLinks ExecCGI
|
||||
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Location>
|
||||
</IfModule>
|
||||
|
||||
|
||||
== IIS/Windows ==
|
||||
* When you install IIS on Windows 7, you just need to enable to CGI module which also include the FastCGI module
|
||||
* otherwise, have a look at http://www.iis.net/download/FastCGI and also http://learn.iis.net/page.aspx/375/set-up-fastcgi-for-php/
|
||||
* Then open the IIS Manager
|
||||
Modules: to check you really have FastCGIModule
|
||||
Handler Mappings and then "Add Module Mapping"
|
||||
Request path: *.exe
|
||||
Module: FastCgiModule
|
||||
Executable (optional): c:\_dev\EiffelWebReloaded\library\fcgi\tests\EIFGENs\eiffelweb\W_code\eiffelweb.exe
|
||||
Name: Eiffel Web Solution using FastCGI on IIS
|
||||
|
||||
|
||||
= Notes =
|
||||
* The notes in this readme are very basic, mainly to test your executable.
|
||||
* You will need to configure more precisely your httpd server to fulfill your needs
|
||||
|
||||
== for execution ==
|
||||
* On Windows, be sure to have the libfcgi.dll in your path (or in same folder as executable)
|
||||
52
library/server/libfcgi/fcgi.ecf
Normal file
52
library/server/libfcgi/fcgi.ecf
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-6-0 http://www.eiffel.com/developers/xml/configuration-1-6-0.xsd" name="fcgi" uuid="3F4BCF74-3503-4533-9D74-5A65EC4CA3C4" library_target="fcgi">
|
||||
<target name="fcgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" >
|
||||
</option>
|
||||
<external_include location="$ECF_CONFIG_PATH/spec/include/libfcgi">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_include location="$ECF_CONFIG_PATH\spec\include\libfcgi">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_library location="$ECF_CONFIG_PATH\spec\lib\$ISE_PLATFORM\$ISE_C_COMPILER\libfcgi.lib">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<external_library location="/usr/local/lib/libfcgi.so">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<cluster name="interface" location="interface" recursive="true"/>
|
||||
<cluster name="implementation" location="implementation" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/linux$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<file_rule>
|
||||
<exclude>/windows$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
104
library/server/libfcgi/implementation/fake/fcgi_imp.e
Normal file
104
library/server/libfcgi/implementation/fake/fcgi_imp.e
Normal file
@@ -0,0 +1,104 @@
|
||||
note
|
||||
description: "Implementation for the FCGI_I interface"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class FCGI_IMP
|
||||
|
||||
inherit
|
||||
FCGI_I
|
||||
|
||||
feature -- Access
|
||||
|
||||
environ: POINTER
|
||||
-- Get the (char**) environ variable from the DLL.
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"return (char**) environ;"
|
||||
end
|
||||
|
||||
feature -- FCGI connection
|
||||
|
||||
fcgi_listen: INTEGER
|
||||
-- Listen to the FCGI input stream
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
do
|
||||
-- Set state on first call to prevent looping indefinitely
|
||||
if fcgi_has_run then
|
||||
Result := -1
|
||||
else --if not is_interactive then
|
||||
fcgi_has_run := True
|
||||
end
|
||||
end
|
||||
|
||||
fcgi_has_run: BOOLEAN
|
||||
-- For emulation only; Has fcgi_listen been called?
|
||||
|
||||
fcgi_finish
|
||||
-- Finish current request from HTTP server started from
|
||||
-- the most recent call to `fcgi_accept'.
|
||||
do
|
||||
end
|
||||
|
||||
set_fcgi_exit_status (v: INTEGER)
|
||||
do
|
||||
end
|
||||
|
||||
feature -- FCGI output
|
||||
|
||||
put_string (a_str: STRING)
|
||||
-- Put `a_str' on the FastCGI stdout.
|
||||
do
|
||||
io.put_string (a_str)
|
||||
end
|
||||
|
||||
-- fcgi_printf (fmt: STRING; args: FINITE[ANY])
|
||||
-- -- Put args, formatted per 'fmt' on the FastCGI stdout.
|
||||
-- do
|
||||
-- apf.printf (fmt, args)
|
||||
-- end
|
||||
|
||||
feature -- FCGI Input
|
||||
|
||||
read_from_stdin (n: INTEGER)
|
||||
-- Read up to n bytes from stdin and store in input buffer
|
||||
do
|
||||
end
|
||||
|
||||
copy_from_stdin (n: INTEGER; tf: FILE)
|
||||
-- Read up to n bytes from stdin and write to given file
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
buffer_contents: STRING
|
||||
do
|
||||
if attached private_input_buffer as buf then
|
||||
Result := buf
|
||||
else
|
||||
Result := ""
|
||||
end
|
||||
end
|
||||
|
||||
buffer_capacity: INTEGER
|
||||
do
|
||||
if attached private_input_buffer as bug then
|
||||
Result := buf.capacity
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
97
library/server/libfcgi/implementation/linux/fcgi_c_api.e
Normal file
97
library/server/libfcgi/implementation/linux/fcgi_c_api.e
Normal file
@@ -0,0 +1,97 @@
|
||||
note
|
||||
description: "Wrappers around FastCGI C API."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
FCGI_C_API
|
||||
|
||||
feature -- Connection
|
||||
|
||||
accept: INTEGER
|
||||
-- Accept a Fast CGI connection.
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"return FCGI_Accept();"
|
||||
end
|
||||
|
||||
environ: POINTER
|
||||
-- Get the (char**) environ variable from the DLL.
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"return (char**) environ;"
|
||||
end
|
||||
|
||||
finish
|
||||
-- Finished current request from HTTP server started from
|
||||
-- the most recent call to `fcgi_accept'.
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"FCGI_Finish();"
|
||||
end
|
||||
|
||||
set_exit_status (v: INTEGER)
|
||||
-- Set the exit status for the most recent request
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"FCGI_SetExitStatus($v);"
|
||||
end
|
||||
|
||||
feature -- Input
|
||||
|
||||
read_content_into (a_buffer: POINTER; a_length: INTEGER): INTEGER
|
||||
-- Read content stream into `a_buffer' but no more than `a_length' character.
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"[
|
||||
{
|
||||
size_t n;
|
||||
if (! FCGI_feof(FCGI_stdin)) {
|
||||
n = FCGI_fread($a_buffer, 1, $a_length, FCGI_stdin);
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
]"
|
||||
end
|
||||
|
||||
gets (s: POINTER): POINTER
|
||||
-- gets() reads a line from stdin into the buffer pointed to
|
||||
-- by s until either a terminating newline or EOF, which it
|
||||
-- replaces with '\0'
|
||||
-- No check for buffer overrun is performed
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"return FCGI_gets($s);"
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_string (v: POINTER; n: INTEGER)
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"FCGI_fwrite($v, 1, $n, FCGI_stdout);"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
183
library/server/libfcgi/implementation/linux/fcgi_imp.e
Normal file
183
library/server/libfcgi/implementation/linux/fcgi_imp.e
Normal file
@@ -0,0 +1,183 @@
|
||||
note
|
||||
description: "Implementation for the FCGI_I interface"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class FCGI_IMP
|
||||
|
||||
inherit
|
||||
FCGI_I
|
||||
STRING_HANDLER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize FCGI interface
|
||||
do
|
||||
create fcgi
|
||||
end
|
||||
|
||||
fcgi: FCGI_C_API
|
||||
-- FastCGI C API primitives
|
||||
|
||||
|
||||
feature -- Access
|
||||
|
||||
fcgi_environ: POINTER
|
||||
do
|
||||
Result := fcgi.environ
|
||||
end
|
||||
|
||||
feature -- FCGI Connection
|
||||
|
||||
fcgi_listen: INTEGER
|
||||
-- Listen to the FCGI input stream
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
do
|
||||
Result := {FCGI_C_API}.accept
|
||||
end
|
||||
|
||||
update_eif_environ
|
||||
external
|
||||
"C inline use <string.h>"
|
||||
alias
|
||||
"[
|
||||
eif_environ = (char**) environ;
|
||||
]"
|
||||
end
|
||||
|
||||
fcgi_finish
|
||||
-- Finish current request from HTTP server started from
|
||||
-- the most recent call to `fcgi_accept'.
|
||||
do
|
||||
{FCGI_C_API}.finish
|
||||
end
|
||||
|
||||
set_fcgi_exit_status (v: INTEGER)
|
||||
do
|
||||
{FCGI_C_API}.set_exit_status (-2)
|
||||
end
|
||||
|
||||
feature -- FCGI output
|
||||
|
||||
put_string (a_str: STRING)
|
||||
-- Put `a_str' on the FastCGI stdout.
|
||||
local
|
||||
l_c_str: C_STRING
|
||||
do
|
||||
l_c_str := c_buffer
|
||||
l_c_str.set_string (a_str)
|
||||
{FCGI_C_API}.put_string (l_c_str.item, l_c_str.count)
|
||||
end
|
||||
|
||||
-- fcgi_printf (fmt: STRING; args: FINITE[ANY])
|
||||
-- -- Put args, formatted per 'fmt' on the FastCGI stdout.
|
||||
-- local
|
||||
-- l_c_str: C_STRING
|
||||
-- do
|
||||
-- create l_c_str.make (apf.aprintf (fmt, args))
|
||||
-- {FCGI_C_API}.put_string (l_c_str.item, l_c_str.count)
|
||||
-- end
|
||||
|
||||
feature -- FCGI Input
|
||||
|
||||
copy_from_stdin (n: INTEGER; tf: FILE)
|
||||
-- Read up to n bytes from stdin and write to given file
|
||||
local
|
||||
l_c_str: C_STRING
|
||||
num, readsize, writecount: INTEGER
|
||||
done: BOOLEAN
|
||||
do
|
||||
--put_trace ("copy_from_stdin, n=" +n.out)
|
||||
readsize := n.min (K_input_bufsize)
|
||||
--put_trace ("copy_from_stdin, readsize=" +readsize.out)
|
||||
l_c_str := c_buffer
|
||||
from
|
||||
until done or writecount >= n
|
||||
loop
|
||||
num := {FCGI_C_API}.read_content_into (l_c_str.item, readsize)
|
||||
--put_trace ("copy_from_stdin, num=" +num.out)
|
||||
if num = 0 then
|
||||
-- EOF
|
||||
done := True
|
||||
else
|
||||
tf.put_managed_pointer (c_buffer.managed_data, 0, num)
|
||||
writecount := writecount + num
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: FCGI Input
|
||||
|
||||
fill_pointer_from_stdin (p: POINTER; n: INTEGER): INTEGER
|
||||
-- Read up to `n' bytes from stdin and store in pointer `p'
|
||||
-- and return number of bytes read.
|
||||
do
|
||||
Result := {FCGI_C_API}.read_content_into (p, n)
|
||||
end
|
||||
|
||||
feature -- I/O Routines
|
||||
|
||||
--RFO read_stdin_into (a_str: STRING)
|
||||
--RFO -- Read a string from the `stdin' into `a_str'.
|
||||
--RFO require
|
||||
--RFO a_str_not_void: a_str /= Void
|
||||
--RFO local
|
||||
--RFO l_c_str: C_STRING
|
||||
--RFO n: INTEGER
|
||||
--RFO do
|
||||
--RFO l_c_str := c_buffer
|
||||
--RFO n := {FCGI_C_API}.read_content_into (l_c_str.item, l_c_str.capacity)
|
||||
--RFO a_str.set_count (n)
|
||||
--RFO l_c_str.read_substring_into (a_str, 1, n)
|
||||
--RFO end
|
||||
|
||||
--RFO read_string_into (a_str: STRING)
|
||||
--RFO require
|
||||
--RFO exists: a_str /= Void
|
||||
--RFO local
|
||||
--RFO l_c_str: C_STRING
|
||||
--RFO p: POINTER
|
||||
--RFO do
|
||||
--RFO create l_c_str.make_empty (1024)
|
||||
--RFO p := {FCGI_C_API}.gets (l_c_str.item)
|
||||
--RFO-- if p /= default_pointer and p = l_c_str.item then
|
||||
--RFO a_str.resize (l_c_str.count)
|
||||
--RFO l_c_str.read_string_into (a_str)
|
||||
--RFO-- else
|
||||
--RFO-- put_error_line ("Bad pointer from gets")
|
||||
--RFO-- end
|
||||
--RFO end
|
||||
|
||||
--RFO read_line
|
||||
--RFO -- Read up to the next end of line, or end of input
|
||||
--RFO -- Leave result in last_string
|
||||
--RFO -- Newline character is absent from result
|
||||
--RFO do
|
||||
--RFO if last_string = Void then
|
||||
--RFO create Result.make (K_input_bufsize)
|
||||
--RFO else
|
||||
--RFO last_string.wipe_out
|
||||
--RFO end
|
||||
--RFO-- if input_filename /= Void then
|
||||
--RFO-- io.read_line
|
||||
--RFO-- last_string.append (io.last_string)
|
||||
--RFO-- else
|
||||
--RFO read_string_into (last_string)
|
||||
--RFO-- end
|
||||
--RFO end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
136
library/server/libfcgi/implementation/windows/fcgi_c_api.e
Normal file
136
library/server/libfcgi/implementation/windows/fcgi_c_api.e
Normal file
@@ -0,0 +1,136 @@
|
||||
note
|
||||
description: "Wrappers around FastCGI C API."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
FCGI_C_API
|
||||
|
||||
feature -- Connections
|
||||
|
||||
accept: INTEGER
|
||||
-- Accept a Fast CGI connection.
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
external
|
||||
"dll libfcgi.dll signature (): EIF_INTEGER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_Accept"
|
||||
end
|
||||
|
||||
environ: POINTER
|
||||
-- Get the (char**) environ variable from the DLL.
|
||||
external
|
||||
"dll libfcgi.dll signature (): EIF_POINTER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_Environ"
|
||||
end
|
||||
|
||||
finish
|
||||
-- Finished current request from HTTP server started from
|
||||
-- the most recent call to `accept'.
|
||||
external
|
||||
"dll libfcgi.dll signature () use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_Finish"
|
||||
end
|
||||
|
||||
set_exit_status (v: INTEGER)
|
||||
-- Set the exit status for the most recent request
|
||||
external
|
||||
"dll libfcgi.dll signature (EIF_INTEGER) use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_SetExitStatus"
|
||||
end
|
||||
|
||||
feature -- Input
|
||||
|
||||
fread (v: POINTER; a_size: INTEGER; n: INTEGER; fp: POINTER): INTEGER
|
||||
-- FCGI_fread() read from input `fp' and put into `v'
|
||||
external
|
||||
"dll libfcgi.dll signature (EIF_POINTER, EIF_INTEGER, EIF_INTEGER, EIF_POINTER): EIF_INTEGER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_fread"
|
||||
end
|
||||
|
||||
feof (v: POINTER): INTEGER
|
||||
-- FCGI_feof()
|
||||
external
|
||||
"dll libfcgi.dll signature (EIF_POINTER): EIF_INTEGER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_feof"
|
||||
end
|
||||
|
||||
read_content_into (a_buffer: POINTER; a_length: INTEGER): INTEGER
|
||||
-- Read content stream into `a_buffer' but no more than `a_length' character.
|
||||
local
|
||||
i: INTEGER
|
||||
l_stdin: POINTER
|
||||
do
|
||||
l_stdin := stdin
|
||||
i := feof (l_stdin)
|
||||
if i /= 0 then
|
||||
Result := 0
|
||||
else
|
||||
Result := fread(a_buffer, 1, a_length, l_stdin)
|
||||
end
|
||||
end
|
||||
|
||||
gets (s: POINTER): POINTER
|
||||
-- gets() reads a line from stdin into the buffer pointed to
|
||||
-- by `s' until either a terminating newline or EOF, which it
|
||||
-- replaces with '\0'
|
||||
-- No check for buffer overrun is performed
|
||||
external
|
||||
"dll libfcgi.dll signature (EIF_POINTER): EIF_POINTER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_gets"
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_string (v: POINTER; n: INTEGER)
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
i := fwrite (v, 1, n, stdout)
|
||||
end
|
||||
|
||||
fwrite (v: POINTER; a_size: INTEGER; n: INTEGER; fp: POINTER): INTEGER
|
||||
-- FCGI_fwrite() ouput `v' to `fp'
|
||||
external
|
||||
"dll libfcgi.dll signature (EIF_POINTER, EIF_INTEGER, EIF_INTEGER, EIF_POINTER): EIF_INTEGER use fcgi_stdio.h "
|
||||
alias
|
||||
"FCGI_fwrite"
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
stdout: POINTER
|
||||
-- FCGI_stdout() return pointer on output FCGI_FILE
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"FCGI_stdout"
|
||||
end
|
||||
|
||||
stdin: POINTER
|
||||
-- FCGI_stdin() return pointer on input FCGI_FILE
|
||||
external
|
||||
"C inline use %"fcgi_stdio.h%""
|
||||
alias
|
||||
"FCGI_stdin"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
267
library/server/libfcgi/implementation/windows/fcgi_imp.e
Normal file
267
library/server/libfcgi/implementation/windows/fcgi_imp.e
Normal file
@@ -0,0 +1,267 @@
|
||||
note
|
||||
description: "Implementation for the FCGI_I interface"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class FCGI_IMP
|
||||
|
||||
inherit
|
||||
FCGI_I
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize FCGI interface
|
||||
do
|
||||
create fcgi
|
||||
end
|
||||
|
||||
fcgi: FCGI_C_API
|
||||
-- FastCGI C API primitives
|
||||
|
||||
feature -- Access
|
||||
|
||||
fcgi_environ: POINTER
|
||||
do
|
||||
Result := fcgi.environ
|
||||
end
|
||||
|
||||
-- updated_environ_variables: HASH_TABLE [STRING, STRING]
|
||||
-- local
|
||||
---- n, l_size,
|
||||
-- i: INTEGER
|
||||
-- p, v, null: POINTER
|
||||
-- do
|
||||
---- update_eif_environ
|
||||
---- Result := starting_environment_variables
|
||||
--
|
||||
---- p := environ_strings_pointer ($n)
|
||||
---- from
|
||||
---- i := 1
|
||||
---- l_size := 0
|
||||
---- create Result.make (n)
|
||||
---- until
|
||||
---- i > n
|
||||
---- loop
|
||||
---- create s.make_from_c (p.plus (l_size))
|
||||
---- l_size := l_size + s.count + 1
|
||||
---- if attached separated_variables (s) as t then
|
||||
---- Result.force (t.value, t.key)
|
||||
---- end
|
||||
---- i := i + 1
|
||||
---- end
|
||||
--
|
||||
-- p := fcgi.environ
|
||||
-- create Result.make (50)
|
||||
-- if p /= null then
|
||||
-- from
|
||||
-- i := 0
|
||||
-- v := fcgi_i_th_environ (i,p)
|
||||
-- until
|
||||
-- v = null
|
||||
-- loop
|
||||
-- if attached separated_variables (create {STRING}.make_from_c (v)) as t then
|
||||
-- Result.force (t.value, t.key)
|
||||
-- end
|
||||
-- i := i + 1
|
||||
-- v := fcgi_i_th_environ (i,p)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- fcgi_i_th_environ (i: INTEGER; p: POINTER): POINTER
|
||||
-- -- Environment variable at `i'-th position of `p'.
|
||||
-- require
|
||||
-- i_valid: i >=0
|
||||
-- external
|
||||
-- "C inline use <string.h>"
|
||||
-- alias
|
||||
-- "[
|
||||
-- return ((char **)$p)[$i];
|
||||
-- ]"
|
||||
-- end
|
||||
|
||||
feature -- FCGI connection
|
||||
|
||||
fcgi_listen: INTEGER
|
||||
-- Listen to the FCGI input stream
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
do
|
||||
Result := fcgi.accept
|
||||
end
|
||||
|
||||
-- update_eif_environ
|
||||
-- external
|
||||
-- "C inline use <string.h>"
|
||||
-- alias
|
||||
-- "[
|
||||
-- #ifdef EIF_WINDOWS
|
||||
-- #ifndef GetEnvironmentStringsA
|
||||
-- extern LPVOID WINAPI GetEnvironmentStringsA(void);
|
||||
-- #endif
|
||||
--
|
||||
-- eif_environ = (char**) GetEnvironmentStringsA();
|
||||
-- #endif
|
||||
-- ]"
|
||||
-- end
|
||||
|
||||
fcgi_finish
|
||||
-- Finish current request from HTTP server started from
|
||||
-- the most recent call to `fcgi_accept'.
|
||||
do
|
||||
fcgi.finish
|
||||
end
|
||||
|
||||
set_fcgi_exit_status (v: INTEGER)
|
||||
do
|
||||
fcgi.set_exit_status (-2)
|
||||
end
|
||||
|
||||
feature -- FCGI output
|
||||
|
||||
put_string (a_str: STRING)
|
||||
-- Put `a_str' on the FastCGI stdout.
|
||||
local
|
||||
l_c_str: C_STRING
|
||||
do
|
||||
l_c_str := c_buffer
|
||||
l_c_str.set_string (a_str)
|
||||
fcgi.put_string (l_c_str.item, l_c_str.count)
|
||||
end
|
||||
|
||||
feature -- FCGI input
|
||||
|
||||
copy_from_stdin (n: INTEGER; f: FILE)
|
||||
-- Read up to n bytes from stdin and write to given file
|
||||
local
|
||||
l_c_str: C_STRING
|
||||
num, readsize, writecount: INTEGER
|
||||
done: BOOLEAN
|
||||
l_fcgi: like fcgi
|
||||
do
|
||||
--put_trace ("copy_from_stdin, n=" +n.out)
|
||||
readsize := n.min (K_input_bufsize)
|
||||
--put_trace ("copy_from_stdin, readsize=" +readsize.out)
|
||||
l_c_str := c_buffer
|
||||
from
|
||||
l_fcgi := fcgi
|
||||
until done or writecount >= n
|
||||
loop
|
||||
num := l_fcgi.read_content_into (l_c_str.item, readsize)
|
||||
--put_trace ("copy_from_stdin, num=" +num.out)
|
||||
if num = 0 then
|
||||
-- EOF
|
||||
done := True
|
||||
else
|
||||
f.put_managed_pointer (c_buffer.managed_data, 0, num)
|
||||
writecount := writecount + num
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: FCGI Input
|
||||
|
||||
fill_pointer_from_stdin (p: POINTER; n: INTEGER): INTEGER
|
||||
-- Read up to `n' bytes from stdin and store in pointer `p'
|
||||
-- and return number of bytes read.
|
||||
do
|
||||
Result := fcgi.read_content_into (p, n)
|
||||
end
|
||||
|
||||
feature -- I/O Routines
|
||||
|
||||
--RFO read_stdin_into (a_str: STRING)
|
||||
--RFO -- Read a string from the `stdin' into `a_str'.
|
||||
--RFO require
|
||||
--RFO a_str_not_void: a_str /= Void
|
||||
--RFO local
|
||||
--RFO l_c_str: C_STRING
|
||||
--RFO n: INTEGER
|
||||
--RFO do
|
||||
--RFO l_c_str := c_buffer
|
||||
--RFO n := fcgi.read_content_into (l_c_str.item, l_c_str.capacity)
|
||||
--RFO a_str.set_count (n)
|
||||
--RFO l_c_str.read_substring_into (a_str, 1, n)
|
||||
--RFO end
|
||||
|
||||
--RFO read_string_into (a_str: STRING)
|
||||
--RFO require
|
||||
--RFO exists: a_str /= Void
|
||||
--RFO local
|
||||
--RFO l_c_str: C_STRING
|
||||
--RFO p: POINTER
|
||||
--RFO do
|
||||
--RFO create l_c_str.make_empty (1024)
|
||||
--RFO p := fcgi.gets (l_c_str.item)
|
||||
--RFO-- if p /= default_pointer and p = l_c_str.item then
|
||||
--RFO a_str.resize (l_c_str.count)
|
||||
--RFO l_c_str.read_string_into (a_str)
|
||||
--RFO-- else
|
||||
--RFO-- put_error_line ("Bad pointer from gets")
|
||||
--RFO-- end
|
||||
--RFO end
|
||||
|
||||
|
||||
--RFO read_line
|
||||
--RFO -- Read up to the next end of line, or end of input
|
||||
--RFO -- Leave result in last_string
|
||||
--RFO -- Newline character is absent from result
|
||||
--RFO do
|
||||
--RFO if last_string = Void then
|
||||
--RFO create Result.make (K_input_bufsize)
|
||||
--RFO else
|
||||
--RFO last_string.wipe_out
|
||||
--RFO end
|
||||
--RFO-- if input_filename /= Void then
|
||||
--RFO-- io.read_line
|
||||
--RFO-- last_string.append (io.last_string)
|
||||
--RFO-- else
|
||||
--RFO read_string_into (last_string)
|
||||
--RFO-- end
|
||||
--RFO end
|
||||
|
||||
|
||||
|
||||
feature {NONE} -- Implementation: environment
|
||||
|
||||
-- environ_strings_pointer (p_nb: TYPED_POINTER [INTEGER]): POINTER
|
||||
-- -- Environment variable strings returned by `GetEnvironmentStringsA'
|
||||
-- -- `p_nb' return the count of environment variables.
|
||||
-- external
|
||||
-- "C inline use <string.h>"
|
||||
-- alias
|
||||
-- "[
|
||||
-- #ifdef EIF_WINDOWS
|
||||
-- #ifndef GetEnvironmentStringsA
|
||||
-- extern LPVOID WINAPI GetEnvironmentStringsA(void);
|
||||
-- #endif
|
||||
--
|
||||
-- int cnt = 0;
|
||||
-- LPSTR vars = GetEnvironmentStringsA();
|
||||
-- char** p = (char**) vars;
|
||||
--
|
||||
-- for (; *vars; vars++) {
|
||||
-- while (*vars) { vars++; }
|
||||
-- cnt++;
|
||||
-- }
|
||||
--
|
||||
-- *$p_nb = cnt;
|
||||
-- return (EIF_POINTER) p;
|
||||
-- #endif
|
||||
-- ]"
|
||||
-- end
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
26
library/server/libfcgi/interface/fcgi.e
Normal file
26
library/server/libfcgi/interface/fcgi.e
Normal file
@@ -0,0 +1,26 @@
|
||||
note
|
||||
description: "Interface to FCGI C library"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class FCGI
|
||||
|
||||
inherit
|
||||
FCGI_IMP
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
236
library/server/libfcgi/interface/fcgi_i.e
Normal file
236
library/server/libfcgi/interface/fcgi_i.e
Normal file
@@ -0,0 +1,236 @@
|
||||
note
|
||||
description: "Abstract interface to FCGI C library"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class FCGI_I
|
||||
|
||||
inherit
|
||||
STRING_HANDLER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize FCGI interface
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
updated_environ_variables: HASH_TABLE [STRING, STRING]
|
||||
local
|
||||
i: INTEGER
|
||||
p, v, null: POINTER
|
||||
do
|
||||
p := fcgi_environ
|
||||
create Result.make (50)
|
||||
if p /= null then
|
||||
from
|
||||
i := 0
|
||||
v := fcgi_i_th_environ (i,p)
|
||||
until
|
||||
v = null
|
||||
loop
|
||||
if attached separated_variables (create {STRING}.make_from_c (v)) as t then
|
||||
Result.force (t.value, t.key)
|
||||
end
|
||||
i := i + 1
|
||||
v := fcgi_i_th_environ (i,p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- FCGI interface
|
||||
|
||||
fcgi_listen: INTEGER
|
||||
-- Listen to the FCGI input stream
|
||||
-- Return 0 for successful calls, -1 otherwise.
|
||||
deferred
|
||||
end
|
||||
|
||||
fcgi_environ: POINTER
|
||||
-- Get the (char**) environ variable from the DLL.
|
||||
deferred
|
||||
end
|
||||
|
||||
fcgi_finish
|
||||
-- Finish current request from HTTP server started from
|
||||
-- the most recent call to `fcgi_accept'.
|
||||
deferred
|
||||
end
|
||||
|
||||
set_fcgi_exit_status (v: INTEGER)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
is_interactive: BOOLEAN
|
||||
-- Is execution interactive? (for debugging)
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Input
|
||||
|
||||
fill_string_from_stdin (s: STRING; n: INTEGER)
|
||||
-- Read up to `n' bytes from stdin and store in string `s'
|
||||
local
|
||||
new_count: INTEGER
|
||||
str_area: ANY
|
||||
do
|
||||
s.grow (n)
|
||||
str_area := s.area
|
||||
new_count := fill_pointer_from_stdin ($str_area, n)
|
||||
s.set_count (new_count)
|
||||
end
|
||||
|
||||
read_from_stdin (n: INTEGER)
|
||||
-- Read up to n bytes from stdin and store in input buffer
|
||||
require
|
||||
small_enough: n <= buffer_capacity
|
||||
local
|
||||
l_c_str: C_STRING
|
||||
l_count: INTEGER
|
||||
do
|
||||
last_read_is_empty_ref.set_item (False)
|
||||
l_c_str := c_buffer
|
||||
l_count := fill_pointer_from_stdin (l_c_str.item, n)
|
||||
last_read_count_ref.set_item (l_count)
|
||||
if l_count <= 0 then
|
||||
last_read_is_empty_ref.set_item (True)
|
||||
end
|
||||
end
|
||||
|
||||
fill_pointer_from_stdin (p: POINTER; n: INTEGER): INTEGER
|
||||
-- Read up to `n' bytes from stdin and store in pointer `p'
|
||||
-- and return number of bytes read.
|
||||
deferred
|
||||
end
|
||||
|
||||
copy_from_stdin (n: INTEGER; f: FILE)
|
||||
-- Read up to n bytes from stdin and write to given file
|
||||
require
|
||||
-- small_enough: n <= buffer_capacity
|
||||
file_exists: f /= Void
|
||||
file_open: f.is_open_write or f.is_open_append
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_string (a_str: STRING)
|
||||
-- Put `a_str' on the FastCGI stdout.
|
||||
require
|
||||
a_str_not_void: a_str /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
buffer_contents: STRING
|
||||
local
|
||||
n: like last_read_count
|
||||
do
|
||||
n := last_read_count
|
||||
create Result.make (n)
|
||||
Result.set_count (n)
|
||||
c_buffer.read_substring_into (Result, 1, n)
|
||||
end
|
||||
|
||||
buffer_capacity: INTEGER
|
||||
do
|
||||
Result := c_buffer.capacity
|
||||
end
|
||||
|
||||
--RFO last_string: STRING
|
||||
--RFO once
|
||||
--RFO create Result.make (K_input_bufsize)
|
||||
--RFO end
|
||||
|
||||
last_read_count: INTEGER
|
||||
do
|
||||
Result := last_read_count_ref.item
|
||||
end
|
||||
|
||||
last_read_is_empty: BOOLEAN
|
||||
do
|
||||
Result := last_read_is_empty_ref.item
|
||||
end
|
||||
|
||||
feature {NONE} -- Shared buffer
|
||||
|
||||
c_buffer: C_STRING
|
||||
-- Buffer for Eiffel to C and C to Eiffel string conversions.
|
||||
once
|
||||
create Result.make_empty (K_input_bufsize)
|
||||
ensure
|
||||
c_buffer_not_void: Result /= Void
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Constants
|
||||
|
||||
last_read_count_ref: INTEGER_REF
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
last_read_is_empty_ref: BOOLEAN_REF
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
K_input_bufsize: INTEGER = 1024_000
|
||||
|
||||
feature {NONE} -- Implementation: Environment
|
||||
|
||||
fcgi_i_th_environ (i: INTEGER; p: POINTER): POINTER
|
||||
-- Environment variable at `i'-th position of `p'.
|
||||
require
|
||||
i_valid: i >=0
|
||||
external
|
||||
"C inline use <string.h>"
|
||||
alias
|
||||
"return ((char **)$p)[$i];"
|
||||
end
|
||||
|
||||
separated_variables (a_var: STRING): detachable TUPLE [value: STRING; key: STRING]
|
||||
-- Given an environment variable `a_var' in form of "key=value",
|
||||
-- return separated key and value.
|
||||
-- Return Void if `a_var' is in incorrect format.
|
||||
require
|
||||
a_var_attached: a_var /= Void
|
||||
local
|
||||
i, j: INTEGER
|
||||
done: BOOLEAN
|
||||
do
|
||||
j := a_var.count
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > j or done
|
||||
loop
|
||||
if a_var.item (i) = '=' then
|
||||
done := True
|
||||
else
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
if i > 1 and then i < j then
|
||||
Result := [a_var.substring (i + 1, j), a_var.substring (1, i - 1)]
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
52
library/server/libfcgi/libfcgi-safe.ecf
Normal file
52
library/server/libfcgi/libfcgi-safe.ecf
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-6-0 http://www.eiffel.com/developers/xml/configuration-1-6-0.xsd" name="libfcgi" uuid="3F4BCF74-3503-4533-9D74-5A65EC4CA3C4" library_target="libfcgi">
|
||||
<target name="libfcgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" >
|
||||
</option>
|
||||
<external_include location="$ECF_CONFIG_PATH/spec/include/libfcgi">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_include location="$ECF_CONFIG_PATH\spec\include\libfcgi">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_library location="$ECF_CONFIG_PATH\spec\lib\$ISE_PLATFORM\$ISE_C_COMPILER\libfcgi.lib">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<external_library location="/usr/local/lib/libfcgi.so">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<cluster name="interface" location="interface" recursive="true"/>
|
||||
<cluster name="implementation" location="implementation" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/linux$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<file_rule>
|
||||
<exclude>/windows$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
52
library/server/libfcgi/libfcgi.ecf
Normal file
52
library/server/libfcgi/libfcgi.ecf
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-6-0 http://www.eiffel.com/developers/xml/configuration-1-6-0.xsd" name="libfcgi" uuid="3F4BCF74-3503-4533-9D74-5A65EC4CA3C4" library_target="libfcgi">
|
||||
<target name="libfcgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
<option warning="true" full_class_checking="true">
|
||||
</option>
|
||||
<external_include location="$ECF_CONFIG_PATH/spec/include/libfcgi">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_include location="$ECF_CONFIG_PATH\spec\include\libfcgi">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_library location="$ECF_CONFIG_PATH\spec\lib\$ISE_PLATFORM\$ISE_C_COMPILER\libfcgi.lib">
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<external_library location="/usr/local/lib/libfcgi.so">
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</external_library>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<cluster name="interface" location="interface" recursive="true"/>
|
||||
<cluster name="implementation" location="implementation" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/linux$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<file_rule>
|
||||
<exclude>/windows$</exclude>
|
||||
<exclude>/fake$</exclude>
|
||||
<condition>
|
||||
<platform excluded_value="windows"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
1
library/server/libfcgi/license.lic
Normal file
1
library/server/libfcgi/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
136
library/server/libfcgi/spec/include/libfcgi/fastcgi.h
Normal file
136
library/server/libfcgi/spec/include/libfcgi/fastcgi.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* fastcgi.h --
|
||||
*
|
||||
* Defines for the FastCGI protocol.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995-1996 Open Market, Inc.
|
||||
*
|
||||
* See the file "LICENSE.TERMS" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*
|
||||
* $Id: fastcgi.h,v 1.1.1.1 1997/09/16 15:36:32 stanleyg Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FASTCGI_H
|
||||
#define _FASTCGI_H
|
||||
|
||||
/*
|
||||
* Listening socket file number
|
||||
*/
|
||||
#define FCGI_LISTENSOCK_FILENO 0
|
||||
|
||||
typedef struct {
|
||||
unsigned char version;
|
||||
unsigned char type;
|
||||
unsigned char requestIdB1;
|
||||
unsigned char requestIdB0;
|
||||
unsigned char contentLengthB1;
|
||||
unsigned char contentLengthB0;
|
||||
unsigned char paddingLength;
|
||||
unsigned char reserved;
|
||||
} FCGI_Header;
|
||||
|
||||
#define FCGI_MAX_LENGTH 0xffff
|
||||
|
||||
/*
|
||||
* Number of bytes in a FCGI_Header. Future versions of the protocol
|
||||
* will not reduce this number.
|
||||
*/
|
||||
#define FCGI_HEADER_LEN 8
|
||||
|
||||
/*
|
||||
* Value for version component of FCGI_Header
|
||||
*/
|
||||
#define FCGI_VERSION_1 1
|
||||
|
||||
/*
|
||||
* Values for type component of FCGI_Header
|
||||
*/
|
||||
#define FCGI_BEGIN_REQUEST 1
|
||||
#define FCGI_ABORT_REQUEST 2
|
||||
#define FCGI_END_REQUEST 3
|
||||
#define FCGI_PARAMS 4
|
||||
#define FCGI_STDIN 5
|
||||
#define FCGI_STDOUT 6
|
||||
#define FCGI_STDERR 7
|
||||
#define FCGI_DATA 8
|
||||
#define FCGI_GET_VALUES 9
|
||||
#define FCGI_GET_VALUES_RESULT 10
|
||||
#define FCGI_UNKNOWN_TYPE 11
|
||||
#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
|
||||
|
||||
/*
|
||||
* Value for requestId component of FCGI_Header
|
||||
*/
|
||||
#define FCGI_NULL_REQUEST_ID 0
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char roleB1;
|
||||
unsigned char roleB0;
|
||||
unsigned char flags;
|
||||
unsigned char reserved[5];
|
||||
} FCGI_BeginRequestBody;
|
||||
|
||||
typedef struct {
|
||||
FCGI_Header header;
|
||||
FCGI_BeginRequestBody body;
|
||||
} FCGI_BeginRequestRecord;
|
||||
|
||||
/*
|
||||
* Mask for flags component of FCGI_BeginRequestBody
|
||||
*/
|
||||
#define FCGI_KEEP_CONN 1
|
||||
|
||||
/*
|
||||
* Values for role component of FCGI_BeginRequestBody
|
||||
*/
|
||||
#define FCGI_RESPONDER 1
|
||||
#define FCGI_AUTHORIZER 2
|
||||
#define FCGI_FILTER 3
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char appStatusB3;
|
||||
unsigned char appStatusB2;
|
||||
unsigned char appStatusB1;
|
||||
unsigned char appStatusB0;
|
||||
unsigned char protocolStatus;
|
||||
unsigned char reserved[3];
|
||||
} FCGI_EndRequestBody;
|
||||
|
||||
typedef struct {
|
||||
FCGI_Header header;
|
||||
FCGI_EndRequestBody body;
|
||||
} FCGI_EndRequestRecord;
|
||||
|
||||
/*
|
||||
* Values for protocolStatus component of FCGI_EndRequestBody
|
||||
*/
|
||||
#define FCGI_REQUEST_COMPLETE 0
|
||||
#define FCGI_CANT_MPX_CONN 1
|
||||
#define FCGI_OVERLOADED 2
|
||||
#define FCGI_UNKNOWN_ROLE 3
|
||||
|
||||
|
||||
/*
|
||||
* Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
|
||||
*/
|
||||
#define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
|
||||
#define FCGI_MAX_REQS "FCGI_MAX_REQS"
|
||||
#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char type;
|
||||
unsigned char reserved[7];
|
||||
} FCGI_UnknownTypeBody;
|
||||
|
||||
typedef struct {
|
||||
FCGI_Header header;
|
||||
FCGI_UnknownTypeBody body;
|
||||
} FCGI_UnknownTypeRecord;
|
||||
|
||||
#endif /* _FASTCGI_H */
|
||||
|
||||
39
library/server/libfcgi/spec/include/libfcgi/fcgi_config.h
Normal file
39
library/server/libfcgi/spec/include/libfcgi/fcgi_config.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copied to fcgi_config.h when building on WinNT without cygwin,
|
||||
* i.e. configure is not run. See fcgi_config.h.in for details.
|
||||
*/
|
||||
|
||||
#define HAVE_FPOS 1
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_STREAMBUF_CHAR_TYPE 1
|
||||
#define HAVE_STRERROR 1
|
||||
#undef HAVE_ARPA_INET_H
|
||||
#undef HAVE_DLFCN_H
|
||||
#undef HAVE_FILENO_PROTO
|
||||
#undef HAVE_INTTYPES_H
|
||||
#undef HAVE_IOSTREAM_WITHASSIGN_STREAMBUF
|
||||
#undef HAVE_LIBNSL
|
||||
#undef HAVE_LIBSOCKET
|
||||
#undef HAVE_MEMORY_H
|
||||
#undef HAVE_NETDB_H
|
||||
#undef HAVE_NETINET_IN_H
|
||||
#undef HAVE_PTHREAD
|
||||
#undef HAVE_SOCKADDR_UN_SUN_LEN
|
||||
#undef HAVE_SOCKLEN
|
||||
#undef HAVE_STDINT_H
|
||||
#undef HAVE_STDLIB_H
|
||||
#undef HAVE_STRING_H
|
||||
#undef HAVE_STRINGS_H
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
#undef HAVE_SYS_STAT_H
|
||||
#undef HAVE_SYS_TIME_H
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
#undef HAVE_UNISTD_H
|
||||
#undef HAVE_VA_ARG_LONG_DOUBLE_BUG
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
#undef STDC_HEADERS
|
||||
#undef USE_LOCKING
|
||||
#undef const
|
||||
#undef inline
|
||||
#undef ssize_t
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copied to fcgi_config.h when building on WinNT without cygwin,
|
||||
* i.e. configure is not run. See fcgi_config.h.in for details.
|
||||
*/
|
||||
|
||||
#define HAVE_FPOS 1
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_STREAMBUF_CHAR_TYPE 1
|
||||
#define HAVE_STRERROR 1
|
||||
#undef HAVE_ARPA_INET_H
|
||||
#undef HAVE_DLFCN_H
|
||||
#undef HAVE_FILENO_PROTO
|
||||
#undef HAVE_INTTYPES_H
|
||||
#undef HAVE_IOSTREAM_WITHASSIGN_STREAMBUF
|
||||
#undef HAVE_LIBNSL
|
||||
#undef HAVE_LIBSOCKET
|
||||
#undef HAVE_MEMORY_H
|
||||
#undef HAVE_NETDB_H
|
||||
#undef HAVE_NETINET_IN_H
|
||||
#undef HAVE_PTHREAD
|
||||
#undef HAVE_SOCKADDR_UN_SUN_LEN
|
||||
#undef HAVE_SOCKLEN
|
||||
#undef HAVE_STDINT_H
|
||||
#undef HAVE_STDLIB_H
|
||||
#undef HAVE_STRING_H
|
||||
#undef HAVE_STRINGS_H
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
#undef HAVE_SYS_STAT_H
|
||||
#undef HAVE_SYS_TIME_H
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
#undef HAVE_UNISTD_H
|
||||
#undef HAVE_VA_ARG_LONG_DOUBLE_BUG
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
#undef STDC_HEADERS
|
||||
#undef USE_LOCKING
|
||||
#undef const
|
||||
#undef inline
|
||||
#undef ssize_t
|
||||
246
library/server/libfcgi/spec/include/libfcgi/fcgi_stdio.h
Normal file
246
library/server/libfcgi/spec/include/libfcgi/fcgi_stdio.h
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* fcgi_stdio.h --
|
||||
*
|
||||
* FastCGI-stdio compatibility package
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996 Open Market, Inc.
|
||||
*
|
||||
* See the file "LICENSE.TERMS" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*
|
||||
* $Id: fcgi_stdio.h,v 1.5 2001/06/22 13:21:15 robs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FCGI_STDIO
|
||||
#define _FCGI_STDIO 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "fcgiapp.h"
|
||||
|
||||
#if defined (c_plusplus) || defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DLLAPI
|
||||
#ifdef _WIN32
|
||||
#define DLLAPI __declspec(dllimport)
|
||||
#else
|
||||
#define DLLAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wrapper type for FILE
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
FILE *stdio_stream;
|
||||
FCGX_Stream *fcgx_stream;
|
||||
} FCGI_FILE;
|
||||
|
||||
/*
|
||||
* The four new functions and two new macros
|
||||
*/
|
||||
|
||||
DLLAPI int FCGI_Accept(void);
|
||||
DLLAPI char** FCGI_Environ(void);
|
||||
DLLAPI void FCGI_Finish(void);
|
||||
DLLAPI int FCGI_StartFilterData(void);
|
||||
DLLAPI void FCGI_SetExitStatus(int status);
|
||||
|
||||
#define FCGI_ToFILE(fcgi_file) (fcgi_file->stdio_stream)
|
||||
#define FCGI_ToFcgiStream(fcgi_file) (fcgi_file->fcgx_stream)
|
||||
|
||||
/*
|
||||
* Wrapper stdin, stdout, and stderr variables, set up by FCGI_Accept()
|
||||
*/
|
||||
|
||||
DLLAPI extern FCGI_FILE _fcgi_sF[];
|
||||
#define FCGI_stdin (&_fcgi_sF[0])
|
||||
#define FCGI_stdout (&_fcgi_sF[1])
|
||||
#define FCGI_stderr (&_fcgi_sF[2])
|
||||
|
||||
/*
|
||||
* Wrapper function prototypes, grouped according to sections
|
||||
* of Harbison & Steele, "C: A Reference Manual," fourth edition,
|
||||
* Prentice-Hall, 1995.
|
||||
*/
|
||||
|
||||
DLLAPI void FCGI_perror(const char *str);
|
||||
|
||||
DLLAPI FCGI_FILE *FCGI_fopen(const char *path, const char *mode);
|
||||
DLLAPI int FCGI_fclose(FCGI_FILE *fp);
|
||||
DLLAPI int FCGI_fflush(FCGI_FILE *fp);
|
||||
DLLAPI FCGI_FILE *FCGI_freopen(const char *path, const char *mode, FCGI_FILE *fp);
|
||||
|
||||
DLLAPI int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size);
|
||||
DLLAPI void FCGI_setbuf(FCGI_FILE *fp, char *buf);
|
||||
|
||||
DLLAPI int FCGI_fseek(FCGI_FILE *fp, long offset, int whence);
|
||||
DLLAPI int FCGI_ftell(FCGI_FILE *fp);
|
||||
DLLAPI void FCGI_rewind(FCGI_FILE *fp);
|
||||
#ifdef HAVE_FPOS
|
||||
DLLAPI int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos);
|
||||
DLLAPI int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos);
|
||||
#endif
|
||||
DLLAPI int FCGI_fgetc(FCGI_FILE *fp);
|
||||
DLLAPI int FCGI_getchar(void);
|
||||
DLLAPI int FCGI_ungetc(int c, FCGI_FILE *fp);
|
||||
|
||||
DLLAPI char *FCGI_fgets(char *str, int size, FCGI_FILE *fp);
|
||||
DLLAPI char *FCGI_gets(char *str);
|
||||
|
||||
/*
|
||||
* Not yet implemented
|
||||
*
|
||||
* int FCGI_fscanf(FCGI_FILE *fp, const char *format, ...);
|
||||
* int FCGI_scanf(const char *format, ...);
|
||||
*
|
||||
*/
|
||||
|
||||
DLLAPI int FCGI_fputc(int c, FCGI_FILE *fp);
|
||||
DLLAPI int FCGI_putchar(int c);
|
||||
|
||||
DLLAPI int FCGI_fputs(const char *str, FCGI_FILE *fp);
|
||||
DLLAPI int FCGI_puts(const char *str);
|
||||
|
||||
DLLAPI int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...);
|
||||
DLLAPI int FCGI_printf(const char *format, ...);
|
||||
|
||||
DLLAPI int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap);
|
||||
DLLAPI int FCGI_vprintf(const char *format, va_list ap);
|
||||
|
||||
DLLAPI size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp);
|
||||
DLLAPI size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp);
|
||||
|
||||
DLLAPI int FCGI_feof(FCGI_FILE *fp);
|
||||
DLLAPI int FCGI_ferror(FCGI_FILE *fp);
|
||||
DLLAPI void FCGI_clearerr(FCGI_FILE *fp);
|
||||
|
||||
DLLAPI FCGI_FILE *FCGI_tmpfile(void);
|
||||
|
||||
DLLAPI int FCGI_fileno(FCGI_FILE *fp);
|
||||
DLLAPI FCGI_FILE *FCGI_fdopen(int fd, const char *mode);
|
||||
DLLAPI FCGI_FILE *FCGI_popen(const char *cmd, const char *type);
|
||||
DLLAPI int FCGI_pclose(FCGI_FILE *);
|
||||
|
||||
/*
|
||||
* The remaining definitions are for application programs,
|
||||
* not for fcgi_stdio.c
|
||||
*/
|
||||
|
||||
#ifndef NO_FCGI_DEFINES
|
||||
|
||||
/*
|
||||
* Replace standard types, variables, and functions with FastCGI wrappers.
|
||||
* Use undef in case a macro is already defined.
|
||||
*/
|
||||
|
||||
#undef FILE
|
||||
#define FILE FCGI_FILE
|
||||
|
||||
#undef stdin
|
||||
#define stdin FCGI_stdin
|
||||
#undef stdout
|
||||
#define stdout FCGI_stdout
|
||||
#undef stderr
|
||||
#define stderr FCGI_stderr
|
||||
|
||||
#undef perror
|
||||
#define perror FCGI_perror
|
||||
|
||||
#undef fopen
|
||||
#define fopen FCGI_fopen
|
||||
#undef fclose
|
||||
#define fclose FCGI_fclose
|
||||
#undef fflush
|
||||
#define fflush FCGI_fflush
|
||||
#undef freopen
|
||||
#define freopen FCGI_freopen
|
||||
|
||||
#undef setvbuf
|
||||
#define setvbuf FCGI_setvbuf
|
||||
#undef setbuf
|
||||
#define setbuf FCGI_setbuf
|
||||
|
||||
#undef fseek
|
||||
#define fseek FCGI_fseek
|
||||
#undef ftell
|
||||
#define ftell FCGI_ftell
|
||||
#undef rewind
|
||||
#define rewind FCGI_rewind
|
||||
#undef fgetpos
|
||||
#define fgetpos FCGI_fgetpos
|
||||
#undef fsetpos
|
||||
#define fsetpos FCGI_fsetpos
|
||||
|
||||
#undef fgetc
|
||||
#define fgetc FCGI_fgetc
|
||||
#undef getc
|
||||
#define getc FCGI_fgetc
|
||||
#undef getchar
|
||||
#define getchar FCGI_getchar
|
||||
#undef ungetc
|
||||
#define ungetc FCGI_ungetc
|
||||
|
||||
#undef fgets
|
||||
#define fgets FCGI_fgets
|
||||
#undef gets
|
||||
#define gets FCGI_gets
|
||||
|
||||
#undef fputc
|
||||
#define fputc FCGI_fputc
|
||||
#undef putc
|
||||
#define putc FCGI_fputc
|
||||
#undef putchar
|
||||
#define putchar FCGI_putchar
|
||||
|
||||
#undef fputs
|
||||
#define fputs FCGI_fputs
|
||||
#undef puts
|
||||
#define puts FCGI_puts
|
||||
|
||||
#undef fprintf
|
||||
#define fprintf FCGI_fprintf
|
||||
#undef printf
|
||||
#define printf FCGI_printf
|
||||
|
||||
#undef vfprintf
|
||||
#define vfprintf FCGI_vfprintf
|
||||
#undef vprintf
|
||||
#define vprintf FCGI_vprintf
|
||||
|
||||
#undef fread
|
||||
#define fread FCGI_fread
|
||||
#undef fwrite
|
||||
#define fwrite FCGI_fwrite
|
||||
|
||||
#undef feof
|
||||
#define feof FCGI_feof
|
||||
#undef ferror
|
||||
#define ferror FCGI_ferror
|
||||
#undef clearerr
|
||||
#define clearerr FCGI_clearerr
|
||||
|
||||
#undef tmpfile
|
||||
#define tmpfile FCGI_tmpfile
|
||||
|
||||
#undef fileno
|
||||
#define fileno FCGI_fileno
|
||||
#undef fdopen
|
||||
#define fdopen FCGI_fdopen
|
||||
#undef popen
|
||||
#define popen FCGI_popen
|
||||
#undef pclose
|
||||
#define pclose FCGI_pclose
|
||||
|
||||
#endif /* NO_FCGI_DEFINES */
|
||||
|
||||
#if defined (__cplusplus) || defined (c_plusplus)
|
||||
} /* terminate extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* _FCGI_STDIO */
|
||||
|
||||
622
library/server/libfcgi/spec/include/libfcgi/fcgiapp.h
Normal file
622
library/server/libfcgi/spec/include/libfcgi/fcgiapp.h
Normal file
@@ -0,0 +1,622 @@
|
||||
/*
|
||||
* fcgiapp.h --
|
||||
*
|
||||
* Definitions for FastCGI application server programs
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996 Open Market, Inc.
|
||||
*
|
||||
* See the file "LICENSE.TERMS" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*
|
||||
* $Id: fcgiapp.h,v 1.12 2001/11/21 21:10:11 robs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FCGIAPP_H
|
||||
#define _FCGIAPP_H
|
||||
|
||||
/* Hack to see if we are building TCL - TCL needs varargs not stdarg */
|
||||
#ifndef TCL_LIBRARY
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#ifndef DLLAPI
|
||||
#ifdef _WIN32
|
||||
#define DLLAPI __declspec(dllimport)
|
||||
#else
|
||||
#define DLLAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (c_plusplus) || defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Error codes. Assigned to avoid conflict with EOF and errno(2).
|
||||
*/
|
||||
#define FCGX_UNSUPPORTED_VERSION -2
|
||||
#define FCGX_PROTOCOL_ERROR -3
|
||||
#define FCGX_PARAMS_ERROR -4
|
||||
#define FCGX_CALL_SEQ_ERROR -5
|
||||
|
||||
/*
|
||||
* This structure defines the state of a FastCGI stream.
|
||||
* Streams are modeled after the FILE type defined in stdio.h.
|
||||
* (We wouldn't need our own if platform vendors provided a
|
||||
* standard way to subclass theirs.)
|
||||
* The state of a stream is private and should only be accessed
|
||||
* by the procedures defined below.
|
||||
*/
|
||||
typedef struct FCGX_Stream {
|
||||
unsigned char *rdNext; /* reader: first valid byte
|
||||
* writer: equals stop */
|
||||
unsigned char *wrNext; /* writer: first free byte
|
||||
* reader: equals stop */
|
||||
unsigned char *stop; /* reader: last valid byte + 1
|
||||
* writer: last free byte + 1 */
|
||||
unsigned char *stopUnget; /* reader: first byte of current buffer
|
||||
* fragment, for ungetc
|
||||
* writer: undefined */
|
||||
int isReader;
|
||||
int isClosed;
|
||||
int wasFCloseCalled;
|
||||
int FCGI_errno; /* error status */
|
||||
void (*fillBuffProc) (struct FCGX_Stream *stream);
|
||||
void (*emptyBuffProc) (struct FCGX_Stream *stream, int doClose);
|
||||
void *data;
|
||||
} FCGX_Stream;
|
||||
|
||||
/*
|
||||
* An environment (as defined by environ(7)): A NULL-terminated array
|
||||
* of strings, each string having the form name=value.
|
||||
*/
|
||||
typedef char **FCGX_ParamArray;
|
||||
|
||||
/*
|
||||
* FCGX_Request Flags
|
||||
*
|
||||
* Setting FCGI_FAIL_ACCEPT_ON_INTR prevents FCGX_Accept() from
|
||||
* restarting upon being interrupted.
|
||||
*/
|
||||
#define FCGI_FAIL_ACCEPT_ON_INTR 1
|
||||
|
||||
/*
|
||||
* FCGX_Request -- State associated with a request.
|
||||
*
|
||||
* Its exposed for API simplicity, I expect parts of it to change!
|
||||
*/
|
||||
typedef struct FCGX_Request {
|
||||
int requestId; /* valid if isBeginProcessed */
|
||||
int role;
|
||||
FCGX_Stream *in;
|
||||
FCGX_Stream *out;
|
||||
FCGX_Stream *err;
|
||||
char **envp;
|
||||
|
||||
/* Don't use anything below here */
|
||||
|
||||
struct Params *paramsPtr;
|
||||
int ipcFd; /* < 0 means no connection */
|
||||
int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */
|
||||
int keepConnection; /* don't close ipcFd at end of request */
|
||||
int appStatus;
|
||||
int nWriters; /* number of open writers (0..2) */
|
||||
int flags;
|
||||
int listen_sock;
|
||||
} FCGX_Request;
|
||||
|
||||
|
||||
/*
|
||||
*======================================================================
|
||||
* Control
|
||||
*======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_IsCGI --
|
||||
*
|
||||
* Returns TRUE iff this process appears to be a CGI process
|
||||
* rather than a FastCGI process.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_IsCGI(void);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Init --
|
||||
*
|
||||
* Initialize the FCGX library. Call in multi-threaded apps
|
||||
* before calling FCGX_Accept_r().
|
||||
*
|
||||
* Returns 0 upon success.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_Init(void);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_OpenSocket --
|
||||
*
|
||||
* Create a FastCGI listen socket.
|
||||
*
|
||||
* path is the Unix domain socket (named pipe for WinNT), or a colon
|
||||
* followed by a port number. e.g. "/tmp/fastcgi/mysocket", ":5000"
|
||||
*
|
||||
* backlog is the listen queue depth used in the listen() call.
|
||||
*
|
||||
* Returns the socket's file descriptor or -1 on error.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_OpenSocket(const char *path, int backlog);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_InitRequest --
|
||||
*
|
||||
* Initialize a FCGX_Request for use with FCGX_Accept_r().
|
||||
*
|
||||
* sock is a file descriptor returned by FCGX_OpenSocket() or 0 (default).
|
||||
* The only supported flag at this time is FCGI_FAIL_ON_INTR.
|
||||
*
|
||||
* Returns 0 upon success.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_InitRequest(FCGX_Request *request, int sock, int flags);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Accept_r --
|
||||
*
|
||||
* Accept a new request (multi-thread safe). Be sure to call
|
||||
* FCGX_Init() first.
|
||||
*
|
||||
* Results:
|
||||
* 0 for successful call, -1 for error.
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Finishes the request accepted by (and frees any
|
||||
* storage allocated by) the previous call to FCGX_Accept.
|
||||
* Creates input, output, and error streams and
|
||||
* assigns them to *in, *out, and *err respectively.
|
||||
* Creates a parameters data structure to be accessed
|
||||
* via getenv(3) (if assigned to environ) or by FCGX_GetParam
|
||||
* and assigns it to *envp.
|
||||
*
|
||||
* DO NOT retain pointers to the envp array or any strings
|
||||
* contained in it (e.g. to the result of calling FCGX_GetParam),
|
||||
* since these will be freed by the next call to FCGX_Finish
|
||||
* or FCGX_Accept.
|
||||
*
|
||||
* DON'T use the FCGX_Request, its structure WILL change.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_Accept_r(FCGX_Request *request);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Finish_r --
|
||||
*
|
||||
* Finish the request (multi-thread safe).
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Finishes the request accepted by (and frees any
|
||||
* storage allocated by) the previous call to FCGX_Accept.
|
||||
*
|
||||
* DO NOT retain pointers to the envp array or any strings
|
||||
* contained in it (e.g. to the result of calling FCGX_GetParam),
|
||||
* since these will be freed by the next call to FCGX_Finish
|
||||
* or FCGX_Accept.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_Finish_r(FCGX_Request *request);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Free --
|
||||
*
|
||||
* Free the memory and, if close is true,
|
||||
* IPC FD associated with the request (multi-thread safe).
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_Free(FCGX_Request * request, int close);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Accept --
|
||||
*
|
||||
* Accept a new request (NOT multi-thread safe).
|
||||
*
|
||||
* Results:
|
||||
* 0 for successful call, -1 for error.
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Finishes the request accepted by (and frees any
|
||||
* storage allocated by) the previous call to FCGX_Accept.
|
||||
* Creates input, output, and error streams and
|
||||
* assigns them to *in, *out, and *err respectively.
|
||||
* Creates a parameters data structure to be accessed
|
||||
* via getenv(3) (if assigned to environ) or by FCGX_GetParam
|
||||
* and assigns it to *envp.
|
||||
*
|
||||
* DO NOT retain pointers to the envp array or any strings
|
||||
* contained in it (e.g. to the result of calling FCGX_GetParam),
|
||||
* since these will be freed by the next call to FCGX_Finish
|
||||
* or FCGX_Accept.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_Accept(
|
||||
FCGX_Stream **in,
|
||||
FCGX_Stream **out,
|
||||
FCGX_Stream **err,
|
||||
FCGX_ParamArray *envp);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_Finish --
|
||||
*
|
||||
* Finish the current request (NOT multi-thread safe).
|
||||
*
|
||||
* Side effects:
|
||||
*
|
||||
* Finishes the request accepted by (and frees any
|
||||
* storage allocated by) the previous call to FCGX_Accept.
|
||||
*
|
||||
* DO NOT retain pointers to the envp array or any strings
|
||||
* contained in it (e.g. to the result of calling FCGX_GetParam),
|
||||
* since these will be freed by the next call to FCGX_Finish
|
||||
* or FCGX_Accept.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_Finish(void);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_StartFilterData --
|
||||
*
|
||||
* stream is an input stream for a FCGI_FILTER request.
|
||||
* stream is positioned at EOF on FCGI_STDIN.
|
||||
* Repositions stream to the start of FCGI_DATA.
|
||||
* If the preconditions are not met (e.g. FCGI_STDIN has not
|
||||
* been read to EOF) sets the stream error code to
|
||||
* FCGX_CALL_SEQ_ERROR.
|
||||
*
|
||||
* Results:
|
||||
* 0 for a normal return, < 0 for error
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_StartFilterData(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_SetExitStatus --
|
||||
*
|
||||
* Sets the exit status for stream's request. The exit status
|
||||
* is the status code the request would have exited with, had
|
||||
* the request been run as a CGI program. You can call
|
||||
* SetExitStatus several times during a request; the last call
|
||||
* before the request ends determines the value.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_SetExitStatus(int status, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*======================================================================
|
||||
* Parameters
|
||||
*======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_GetParam -- obtain value of FCGI parameter in environment
|
||||
*
|
||||
*
|
||||
* Results:
|
||||
* Value bound to name, NULL if name not present in the
|
||||
* environment envp. Caller must not mutate the result
|
||||
* or retain it past the end of this request.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI char *FCGX_GetParam(const char *name, FCGX_ParamArray envp);
|
||||
|
||||
/*
|
||||
*======================================================================
|
||||
* Readers
|
||||
*======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_GetChar --
|
||||
*
|
||||
* Reads a byte from the input stream and returns it.
|
||||
*
|
||||
* Results:
|
||||
* The byte, or EOF (-1) if the end of input has been reached.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_GetChar(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_UnGetChar --
|
||||
*
|
||||
* Pushes back the character c onto the input stream. One
|
||||
* character of pushback is guaranteed once a character
|
||||
* has been read. No pushback is possible for EOF.
|
||||
*
|
||||
* Results:
|
||||
* Returns c if the pushback succeeded, EOF if not.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_UnGetChar(int c, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_GetStr --
|
||||
*
|
||||
* Reads up to n consecutive bytes from the input stream
|
||||
* into the character array str. Performs no interpretation
|
||||
* of the input bytes.
|
||||
*
|
||||
* Results:
|
||||
* Number of bytes read. If result is smaller than n,
|
||||
* the end of input has been reached.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_GetStr(char *str, int n, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_GetLine --
|
||||
*
|
||||
* Reads up to n-1 consecutive bytes from the input stream
|
||||
* into the character array str. Stops before n-1 bytes
|
||||
* have been read if '\n' or EOF is read. The terminating '\n'
|
||||
* is copied to str. After copying the last byte into str,
|
||||
* stores a '\0' terminator.
|
||||
*
|
||||
* Results:
|
||||
* NULL if EOF is the first thing read from the input stream,
|
||||
* str otherwise.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_HasSeenEOF --
|
||||
*
|
||||
* Returns EOF if end-of-file has been detected while reading
|
||||
* from stream; otherwise returns 0.
|
||||
*
|
||||
* Note that FCGX_HasSeenEOF(s) may return 0, yet an immediately
|
||||
* following FCGX_GetChar(s) may return EOF. This function, like
|
||||
* the standard C stdio function feof, does not provide the
|
||||
* ability to peek ahead.
|
||||
*
|
||||
* Results:
|
||||
* EOF if end-of-file has been detected, 0 if not.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
DLLAPI int FCGX_HasSeenEOF(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*======================================================================
|
||||
* Writers
|
||||
*======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_PutChar --
|
||||
*
|
||||
* Writes a byte to the output stream.
|
||||
*
|
||||
* Results:
|
||||
* The byte, or EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_PutChar(int c, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_PutStr --
|
||||
*
|
||||
* Writes n consecutive bytes from the character array str
|
||||
* into the output stream. Performs no interpretation
|
||||
* of the output bytes.
|
||||
*
|
||||
* Results:
|
||||
* Number of bytes written (n) for normal return,
|
||||
* EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_PutS --
|
||||
*
|
||||
* Writes a null-terminated character string to the output stream.
|
||||
*
|
||||
* Results:
|
||||
* number of bytes written for normal return,
|
||||
* EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_PutS(const char *str, FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_FPrintF, FCGX_VFPrintF --
|
||||
*
|
||||
* Performs printf-style output formatting and writes the results
|
||||
* to the output stream.
|
||||
*
|
||||
* Results:
|
||||
* number of bytes written for normal return,
|
||||
* EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...);
|
||||
|
||||
DLLAPI int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_FFlush --
|
||||
*
|
||||
* Flushes any buffered output.
|
||||
*
|
||||
* Server-push is a legitimate application of FCGX_FFlush.
|
||||
* Otherwise, FCGX_FFlush is not very useful, since FCGX_Accept
|
||||
* does it implicitly. Calling FCGX_FFlush in non-push applications
|
||||
* results in extra writes and therefore reduces performance.
|
||||
*
|
||||
* Results:
|
||||
* EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_FFlush(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*======================================================================
|
||||
* Both Readers and Writers
|
||||
*======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_FClose --
|
||||
*
|
||||
* Closes the stream. For writers, flushes any buffered
|
||||
* output.
|
||||
*
|
||||
* Close is not a very useful operation since FCGX_Accept
|
||||
* does it implicitly. Closing the out stream before the
|
||||
* err stream results in an extra write if there's nothing
|
||||
* in the err stream, and therefore reduces performance.
|
||||
*
|
||||
* Results:
|
||||
* EOF (-1) if an error occurred.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_FClose(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_GetError --
|
||||
*
|
||||
* Return the stream error code. 0 means no error, > 0
|
||||
* is an errno(2) error, < 0 is an FastCGI error.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI int FCGX_GetError(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_ClearError --
|
||||
*
|
||||
* Clear the stream error code and end-of-file indication.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_ClearError(FCGX_Stream *stream);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_CreateWriter --
|
||||
*
|
||||
* Create a FCGX_Stream (used by cgi-fcgi). This shouldn't
|
||||
* be needed by a FastCGI applictaion.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI FCGX_Stream *FCGX_CreateWriter(
|
||||
int socket,
|
||||
int requestId,
|
||||
int bufflen,
|
||||
int streamType);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FCGX_FreeStream --
|
||||
*
|
||||
* Free a FCGX_Stream (used by cgi-fcgi). This shouldn't
|
||||
* be needed by a FastCGI applictaion.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_FreeStream(FCGX_Stream **stream);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
*
|
||||
* Prevent the lib from accepting any new requests. Signal handler safe.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
DLLAPI void FCGX_ShutdownPending(void);
|
||||
|
||||
#if defined (__cplusplus) || defined (c_plusplus)
|
||||
} /* terminate extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* _FCGIAPP_H */
|
||||
38
library/server/libfcgi/spec/include/libfcgi/fcgimisc.h
Normal file
38
library/server/libfcgi/spec/include/libfcgi/fcgimisc.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* fcgimisc.h --
|
||||
*
|
||||
* Miscellaneous definitions
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996 Open Market, Inc.
|
||||
*
|
||||
* See the file "LICENSE.TERMS" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*
|
||||
* $Id: fcgimisc.h,v 1.3 2001/06/18 14:25:47 robs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FCGIMISC_H
|
||||
#define _FCGIMISC_H
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(assertion) assert(assertion)
|
||||
#endif
|
||||
|
||||
#endif /* _FCGIMISC_H */
|
||||
151
library/server/libfcgi/spec/include/libfcgi/fcgio.h
Normal file
151
library/server/libfcgi/spec/include/libfcgi/fcgio.h
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// Provides support for FastCGI via C++ iostreams.
|
||||
//
|
||||
// $Id: fcgio.h,v 1.15 2002/02/25 13:16:11 robs Exp $
|
||||
//
|
||||
// This work is based on routines written by George Feinberg. They
|
||||
// have been mostly re-written and extensively changed by
|
||||
// Michael Richards.
|
||||
//
|
||||
// Rewritten again with bug fixes and numerous enhancements by
|
||||
// Michael Shell.
|
||||
//
|
||||
// And rewritten again by Rob Saccoccio.
|
||||
//
|
||||
// Special Thanks to Dietmar Kuehl for his help and the numerous custom
|
||||
// streambuf examples on his web site.
|
||||
//
|
||||
// Copyright (c) 2000 Tux the Linux Penguin
|
||||
// Copyright (c) 2001 Rob Saccoccio and Chelsea Networks
|
||||
//
|
||||
// You are free to use this software without charge or royalty
|
||||
// as long as this notice is not removed or altered, and recognition
|
||||
// is given to the author(s)
|
||||
//
|
||||
// This code is offered as-is without any warranty either expressed or
|
||||
// implied; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. If it breaks, you get to keep
|
||||
// both halves.
|
||||
|
||||
#ifndef FCGIO_H
|
||||
#define FCGIO_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "fcgiapp.h"
|
||||
|
||||
#ifndef DLLAPI
|
||||
#ifdef _WIN32
|
||||
#define DLLAPI __declspec(dllimport)
|
||||
#else
|
||||
#define DLLAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ! HAVE_STREAMBUF_CHAR_TYPE
|
||||
typedef char char_type;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fcgi_streambuf
|
||||
*/
|
||||
class DLLAPI fcgi_streambuf : public std::streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
// Note that if no buf is assigned (the default), iostream methods
|
||||
// such as peek(), unget() and putback() will fail. If a buf is
|
||||
// assigned, I/O is a bit less effecient and output streams will
|
||||
// have to be flushed (or the streambuf destroyed) before the next
|
||||
// call to "accept".
|
||||
fcgi_streambuf(FCGX_Stream * fcgx, char * buf, int len);
|
||||
|
||||
fcgi_streambuf(char_type * buf, std::streamsize len);
|
||||
|
||||
fcgi_streambuf(FCGX_Stream * fcgx = 0);
|
||||
|
||||
~fcgi_streambuf(void);
|
||||
|
||||
int attach(FCGX_Stream * fcgx);
|
||||
|
||||
protected:
|
||||
|
||||
// Consume the put area (if buffered) and c (if c is not EOF).
|
||||
virtual int overflow(int);
|
||||
|
||||
// Flush the put area (if buffered) and the FCGX buffer to the client.
|
||||
virtual int sync();
|
||||
|
||||
// Remove and return the current character.
|
||||
virtual int uflow();
|
||||
|
||||
// Fill the get area (if buffered) and return the current character.
|
||||
virtual int underflow();
|
||||
|
||||
// Use a buffer. The only reasons that a buffer would be useful is
|
||||
// to support the use of the unget()/putback() or seek() methods. Using
|
||||
// a buffer will result in less efficient I/O. Note: the underlying
|
||||
// FastCGI library (FCGX) maintains its own input and output buffers.
|
||||
virtual std::streambuf * setbuf(char_type * buf, std::streamsize len);
|
||||
|
||||
virtual std::streamsize xsgetn(char_type * s, std::streamsize n);
|
||||
virtual std::streamsize xsputn(const char_type * s, std::streamsize n);
|
||||
|
||||
private:
|
||||
|
||||
FCGX_Stream * fcgx;
|
||||
|
||||
// buf is just handy to have around
|
||||
char_type * buf;
|
||||
|
||||
// this isn't kept by the base class
|
||||
std::streamsize bufsize;
|
||||
|
||||
void init(FCGX_Stream * fcgx, char_type * buf, std::streamsize bufsize);
|
||||
|
||||
void reset(void);
|
||||
};
|
||||
|
||||
/*
|
||||
* fcgi_istream - deprecated
|
||||
*/
|
||||
class DLLAPI fcgi_istream : public std::istream
|
||||
{
|
||||
public:
|
||||
|
||||
// deprecated
|
||||
fcgi_istream(FCGX_Stream * fcgx = 0);
|
||||
|
||||
// deprecated
|
||||
~fcgi_istream(void) {}
|
||||
|
||||
// deprecated
|
||||
virtual void attach(FCGX_Stream * fcgx);
|
||||
|
||||
private:
|
||||
|
||||
fcgi_streambuf fcgi_strmbuf;
|
||||
};
|
||||
|
||||
/*
|
||||
* fcgi_ostream - deprecated
|
||||
*/
|
||||
class DLLAPI fcgi_ostream : public std::ostream
|
||||
{
|
||||
public:
|
||||
|
||||
// deprecated
|
||||
fcgi_ostream(FCGX_Stream * fcgx = 0);
|
||||
|
||||
// deprecated
|
||||
~fcgi_ostream(void) {}
|
||||
|
||||
// deprecated
|
||||
virtual void attach(FCGX_Stream *fcgx);
|
||||
|
||||
private:
|
||||
|
||||
fcgi_streambuf fcgi_strmbuf;
|
||||
};
|
||||
|
||||
#endif /* FCGIO_H */
|
||||
130
library/server/libfcgi/spec/include/libfcgi/fcgios.h
Normal file
130
library/server/libfcgi/spec/include/libfcgi/fcgios.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* fcgios.h --
|
||||
*
|
||||
* Description of file.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996 Open Market, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file contains proprietary and confidential information and
|
||||
* remains the unpublished property of Open Market, Inc. Use,
|
||||
* disclosure, or reproduction is prohibited except as permitted by
|
||||
* express written license agreement with Open Market, Inc.
|
||||
*
|
||||
* Bill Snapper
|
||||
* snapper@openmarket.com
|
||||
*/
|
||||
#ifndef _FCGIOS_H
|
||||
#define _FCGIOS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "fcgi_config.h"
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined (c_plusplus) || defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define OS_Errno GetLastError()
|
||||
#define OS_SetErrno(err) SetLastError(err)
|
||||
#ifndef O_NONBLOCK
|
||||
#define O_NONBLOCK 0x0004 /* no delay */
|
||||
#endif
|
||||
#else /* !_WIN32 */
|
||||
#define OS_Errno errno
|
||||
#define OS_SetErrno(err) errno = (err)
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
#ifndef DLLAPI
|
||||
#ifdef _WIN32
|
||||
#define DLLAPI __declspec(dllimport)
|
||||
#else
|
||||
#define DLLAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the initializer for a "struct timeval" used in a select() call
|
||||
* right after a new request is accept()ed to determine readablity. Its
|
||||
* a drop-dead timer. Its only used for AF_UNIX sockets (not TCP sockets).
|
||||
* Its a workaround for a kernel bug in Linux 2.0.x and SCO Unixware.
|
||||
* Making this as small as possible, yet remain reliable would be best.
|
||||
* 2 seconds is very conservative. 0,0 is not reliable. The shorter the
|
||||
* timeout, the faster request processing will recover. The longer the
|
||||
* timeout, the more likely this application being "busy" will cause other
|
||||
* requests to abort and cause more dead sockets that need this timeout. */
|
||||
#define READABLE_UNIX_FD_DROP_DEAD_TIMEVAL 2,0
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
|
||||
#ifndef STDERR_FILENO
|
||||
#define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
#define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
#ifndef X_OK
|
||||
#define X_OK 0x01
|
||||
#endif
|
||||
|
||||
#ifndef _CLIENTDATA
|
||||
# if defined(__STDC__) || defined(__cplusplus)
|
||||
typedef void *ClientData;
|
||||
# else
|
||||
typedef int *ClientData;
|
||||
# endif /* __STDC__ */
|
||||
#define _CLIENTDATA
|
||||
#endif
|
||||
|
||||
typedef void (*OS_AsyncProc) (ClientData clientData, int len);
|
||||
|
||||
DLLAPI int OS_LibInit(int stdioFds[3]);
|
||||
DLLAPI void OS_LibShutdown(void);
|
||||
DLLAPI int OS_CreateLocalIpcFd(const char *bindPath, int backlog);
|
||||
DLLAPI int OS_FcgiConnect(char *bindPath);
|
||||
DLLAPI int OS_Read(int fd, char * buf, size_t len);
|
||||
DLLAPI int OS_Write(int fd, char * buf, size_t len);
|
||||
DLLAPI int OS_SpawnChild(char *execPath, int listenFd);
|
||||
DLLAPI int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
|
||||
ClientData clientData);
|
||||
DLLAPI int OS_AsyncRead(int fd, int offset, void *buf, int len,
|
||||
OS_AsyncProc procPtr, ClientData clientData);
|
||||
DLLAPI int OS_AsyncWrite(int fd, int offset, void *buf, int len,
|
||||
OS_AsyncProc procPtr, ClientData clientData);
|
||||
DLLAPI int OS_Close(int fd);
|
||||
DLLAPI int OS_CloseRead(int fd);
|
||||
DLLAPI int OS_DoIo(struct timeval *tmo);
|
||||
DLLAPI int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs);
|
||||
DLLAPI int OS_IpcClose(int ipcFd);
|
||||
DLLAPI int OS_IsFcgi(int sock);
|
||||
DLLAPI void OS_SetFlags(int fd, int flags);
|
||||
|
||||
DLLAPI void OS_ShutdownPending(void);
|
||||
|
||||
#if defined (__cplusplus) || defined (c_plusplus)
|
||||
} /* terminate extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* _FCGIOS_H */
|
||||
BIN
library/server/libfcgi/spec/lib/win64/msc/libfcgi.dll
Normal file
BIN
library/server/libfcgi/spec/lib/win64/msc/libfcgi.dll
Normal file
Binary file not shown.
BIN
library/server/libfcgi/spec/lib/win64/msc/libfcgi.lib
Normal file
BIN
library/server/libfcgi/spec/lib/win64/msc/libfcgi.lib
Normal file
Binary file not shown.
BIN
library/server/libfcgi/spec/lib/windows/msc/libfcgi.dll
Normal file
BIN
library/server/libfcgi/spec/lib/windows/msc/libfcgi.dll
Normal file
Binary file not shown.
BIN
library/server/libfcgi/spec/lib/windows/msc/libfcgi.lib
Normal file
BIN
library/server/libfcgi/spec/lib/windows/msc/libfcgi.lib
Normal file
Binary file not shown.
64
library/server/libfcgi/tests/apache2.conf
Normal file
64
library/server/libfcgi/tests/apache2.conf
Normal file
@@ -0,0 +1,64 @@
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin webmaster@localhost
|
||||
|
||||
DocumentRoot /var/www
|
||||
<Directory />
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
</Directory>
|
||||
<Directory /var/www/>
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
|
||||
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||
<Directory "/usr/lib/cgi-bin">
|
||||
AllowOverride None
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
|
||||
# Possible values include: debug, info, notice, warn, error, crit,
|
||||
# alert, emerg.
|
||||
LogLevel warn
|
||||
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
Alias /doc/ "/usr/share/doc/"
|
||||
<Directory "/usr/share/doc/">
|
||||
Options Indexes MultiViews FollowSymLinks
|
||||
AllowOverride None
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
Allow from 127.0.0.0/255.0.0.0 ::1/128
|
||||
</Directory>
|
||||
|
||||
<IfModule mod_fcgid.c>
|
||||
# FcgidIdleTimeout 600
|
||||
# FcgidBusyScanInterval 120
|
||||
# FcgidProcessLifeTime 0
|
||||
# #7200
|
||||
# FcgidMaxProcesses 1000
|
||||
# FcgidMaxProcessesPerClass 100
|
||||
# FcgidMinProcessesPerClass 100
|
||||
# FcgidConnectTimeout 8
|
||||
# FcgidIOTimeout 60
|
||||
# FcgidBusyTimeout 1200
|
||||
|
||||
alias /eiffelweb/ "/home/jfiat/_dev/EiffelWebReloaded/library/fcgi/tests/EIFGENs/eiffelweb/W_code/"
|
||||
<Location /eiffelweb/>
|
||||
AddHandler fcgid-script .ews
|
||||
Options Indexes FollowSymLinks ExecCGI
|
||||
# Customize the next two directives for your requirements.
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
|
||||
</Location>
|
||||
</IfModule>
|
||||
|
||||
</VirtualHost>
|
||||
80
library/server/libfcgi/tests/application_root.e
Normal file
80
library/server/libfcgi/tests/application_root.e
Normal file
@@ -0,0 +1,80 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_ROOT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
res: INTEGER
|
||||
nb: INTEGER
|
||||
do
|
||||
initialize
|
||||
from
|
||||
res := fcgi.fcgi_listen
|
||||
until
|
||||
res < 0
|
||||
loop
|
||||
nb := nb + 1
|
||||
fcgi.put_string (header ("FCGI Eiffel Application"))
|
||||
|
||||
fcgi.put_string ("<h1>Hello FCGI Eiffel Application</h1>%N")
|
||||
fcgi.put_string ("Request number " + nb.out + "<br/>%N")
|
||||
|
||||
fcgi.put_string ("<ul>Environment variables%N")
|
||||
print_environment_variables (fcgi.updated_environ_variables)
|
||||
fcgi.put_string ("</ul>")
|
||||
fcgi.put_string (footer)
|
||||
|
||||
res := fcgi.fcgi_listen
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
header (a_title: STRING): STRING
|
||||
do
|
||||
Result := "Content-type: text/html%R%N"
|
||||
Result.append ("%R%N")
|
||||
Result.append ("<html>%N")
|
||||
Result.append ("<head><title>" + a_title + "</title></head>")
|
||||
Result.append ("<body>%N")
|
||||
end
|
||||
|
||||
footer: STRING
|
||||
do
|
||||
Result := "</body>%N</html>%N"
|
||||
end
|
||||
|
||||
print_environment_variables (vars: HASH_TABLE [STRING, STRING])
|
||||
local
|
||||
do
|
||||
from
|
||||
vars.start
|
||||
until
|
||||
vars.after
|
||||
loop
|
||||
fcgi.put_string ("<li><strong>" + vars.key_for_iteration + "</strong> = " + vars.item_for_iteration + "</li>%N")
|
||||
vars.forth
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
initialize
|
||||
do
|
||||
create fcgi.make
|
||||
end
|
||||
|
||||
fcgi: FCGI
|
||||
|
||||
end
|
||||
16
library/server/libfcgi/tests/eiffelweb.ecf
Normal file
16
library/server/libfcgi/tests/eiffelweb.ecf
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="eiffelweb" uuid="6A03BC65-BD03-4B68-B51E-2543F9471D42">
|
||||
<target name="eiffelweb">
|
||||
<root cluster="application" class="APPLICATION_ROOT" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<setting name="console_application" value="true"/>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="fcgi" location="..\fcgi.ecf" readonly="false"/>
|
||||
<cluster name="application" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
35
library/text/encoder/encoder-safe.ecf
Normal file
35
library/text/encoder/encoder-safe.ecf
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="encoder" uuid="EE80E648-C64D-4802-8868-C57AAFEACC55" library_target="encoder">
|
||||
<target name="encoder">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/tests$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
|
||||
<target name="tests" extends="encoder" >
|
||||
<root class="ANY" feature="default_create"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||
<tests name="tests" location="./tests"/>
|
||||
</target>
|
||||
|
||||
</system>
|
||||
35
library/text/encoder/encoder.ecf
Normal file
35
library/text/encoder/encoder.ecf
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="encoder" uuid="EE80E648-C64D-4802-8868-C57AAFEACC55" library_target="encoder">
|
||||
<target name="encoder">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/tests$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
|
||||
<target name="tests" extends="encoder" >
|
||||
<root class="ANY" feature="default_create"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<tests name="tests" location="./tests"/>
|
||||
</target>
|
||||
|
||||
</system>
|
||||
1
library/text/encoder/license.lic
Normal file
1
library/text/encoder/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
218
library/text/encoder/src/base64.e
Normal file
218
library/text/encoder/src/base64.e
Normal file
@@ -0,0 +1,218 @@
|
||||
note
|
||||
description: "Summary description for {BASE64}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASE64
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_8, STRING_8]
|
||||
redefine
|
||||
valid_encoded_string
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "base64"
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
valid_encoded_string (v: STRING): BOOLEAN
|
||||
do
|
||||
Result := Precursor (v) and then
|
||||
(v.is_empty or v.count >= 4)
|
||||
end
|
||||
|
||||
feature -- base64 encoder
|
||||
|
||||
encoded_string (s: STRING): STRING_8
|
||||
-- base64 encoded value of `s'.
|
||||
local
|
||||
i,n: INTEGER
|
||||
c: INTEGER
|
||||
f: SPECIAL [BOOLEAN]
|
||||
base64chars: STRING_8
|
||||
do
|
||||
has_error := False
|
||||
base64chars := character_map
|
||||
from
|
||||
n := s.count
|
||||
i := (8 * n) \\ 6
|
||||
if i > 0 then
|
||||
create f.make_filled (False, 8 * n + (6 - i))
|
||||
else
|
||||
create f.make_filled (False, 8 * n)
|
||||
end
|
||||
i := 0
|
||||
until
|
||||
i > n - 1
|
||||
loop
|
||||
c := s.item (i + 1).code
|
||||
f[8 * i + 0] := c.bit_test(7)
|
||||
f[8 * i + 1] := c.bit_test(6)
|
||||
f[8 * i + 2] := c.bit_test(5)
|
||||
f[8 * i + 3] := c.bit_test(4)
|
||||
f[8 * i + 4] := c.bit_test(3)
|
||||
f[8 * i + 5] := c.bit_test(2)
|
||||
f[8 * i + 6] := c.bit_test(1)
|
||||
f[8 * i + 7] := c.bit_test(0)
|
||||
i := i + 1
|
||||
end
|
||||
from
|
||||
i := 0
|
||||
n := f.count
|
||||
create Result.make (n // 6)
|
||||
until
|
||||
i > n - 1
|
||||
loop
|
||||
c := 0
|
||||
if f[i + 0] then c := c + 0x20 end
|
||||
if f[i + 1] then c := c + 0x10 end
|
||||
if f[i + 2] then c := c + 0x8 end
|
||||
if f[i + 3] then c := c + 0x4 end
|
||||
if f[i + 4] then c := c + 0x2 end
|
||||
if f[i + 5] then c := c + 0x1 end
|
||||
Result.extend (base64chars.item (c + 1))
|
||||
i := i + 6
|
||||
end
|
||||
|
||||
i := s.count \\ 3
|
||||
if i > 0 then
|
||||
from until i > 2 loop
|
||||
Result.extend ('=')
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING): STRING
|
||||
-- base64 decoded value of `s'.
|
||||
local
|
||||
byte_count: INTEGER
|
||||
pos, n: INTEGER
|
||||
byte1, byte2, byte3, byte4, tmp1, tmp2: INTEGER
|
||||
done: BOOLEAN
|
||||
base64chars: STRING_8
|
||||
c: CHARACTER
|
||||
do
|
||||
has_error := False
|
||||
base64chars := character_map
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
|
||||
from
|
||||
pos := 0
|
||||
invariant
|
||||
n = v.count
|
||||
until
|
||||
(pos >= n) or done
|
||||
loop
|
||||
byte_count := 0
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
byte1 := base64chars.index_of (v[pos], 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
byte2 := base64chars.index_of (v[pos], 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
c := v[pos]
|
||||
if c /= '=' then
|
||||
byte3 := base64chars.index_of (c, 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
end
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
c := v[pos]
|
||||
if c /= '=' then
|
||||
byte4 := base64chars.index_of (c, 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- pos := pos + byte_count
|
||||
|
||||
done := byte_count < 4
|
||||
|
||||
if byte_count > 1 then
|
||||
tmp1 := byte1.bit_shift_left (2) & 0xff
|
||||
tmp2 := byte2.bit_shift_right (4) & 0x03
|
||||
Result.extend ((tmp1 | tmp2).to_character_8)
|
||||
if byte_count > 2 then
|
||||
tmp1 := byte2.bit_shift_left (4) & 0xff
|
||||
tmp2 := byte3.bit_shift_right (2) & 0x0f
|
||||
Result.extend ((tmp1 | tmp2).to_character_8)
|
||||
if byte_count > 3 then
|
||||
Result.extend(
|
||||
((byte4 | byte3.bit_shift_left(6))& 0xff).to_character_8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
next_encoded_character_position (v: STRING; from_pos: INTEGER): INTEGER
|
||||
-- Next encoded character position from `v' starting after `from_pos' index.
|
||||
-- Result over `v.count' denodes no remaining decodable position
|
||||
--| Mainly to handle base64 encoded text on multiple line
|
||||
--| thus we just skip %N, %R and eventually all blanks
|
||||
require
|
||||
v_attached: v /= Void
|
||||
valid_from_pos: v.valid_index (from_pos + 1)
|
||||
local
|
||||
n: INTEGER
|
||||
l_map: like character_map
|
||||
do
|
||||
l_map := character_map
|
||||
from
|
||||
Result := from_pos + 1
|
||||
n := v.count
|
||||
until
|
||||
in_character_map (v[Result]) or Result > n
|
||||
loop
|
||||
Result := Result + 1
|
||||
end
|
||||
ensure
|
||||
result_after_from_pos: Result > from_pos
|
||||
end
|
||||
|
||||
in_character_map (c: CHARACTER): BOOLEAN
|
||||
-- Is a character map element?
|
||||
do
|
||||
inspect c
|
||||
when 'A' .. 'Z', 'a' .. 'z', '0'..'9', '+', '/', '=' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Constants
|
||||
|
||||
character_map: STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
73
library/text/encoder/src/encoder.e
Normal file
73
library/text/encoder/src/encoder.e
Normal file
@@ -0,0 +1,73 @@
|
||||
note
|
||||
description: "Summary description for {ENCODER}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
ENCODER [U -> STRING_GENERAL, E -> STRING_GENERAL] --| U:unencoded type, E:encoded type
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING
|
||||
-- Encoding name.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Error occurred
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Assertion helpers
|
||||
|
||||
valid_unencoded_string (s: U): BOOLEAN
|
||||
-- Is `s' a valid unencoded string ?
|
||||
do
|
||||
Result := s /= Void
|
||||
end
|
||||
|
||||
valid_encoded_string (v: E): BOOLEAN
|
||||
-- Is `v' a valid encoded string ?
|
||||
do
|
||||
Result := v /= Void
|
||||
end
|
||||
|
||||
feature -- Encoder
|
||||
|
||||
encoded_string (s: U): E
|
||||
-- Encoded value of `s'.
|
||||
require
|
||||
valid_unencoded_string: valid_unencoded_string (s)
|
||||
deferred
|
||||
ensure
|
||||
unchanged: s ~ (old s)
|
||||
valid_encoded_string: valid_encoded_string (Result)
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: E): U
|
||||
-- Decoded value of `v'.
|
||||
require
|
||||
valid_encoded_string: valid_encoded_string (v)
|
||||
deferred
|
||||
ensure
|
||||
unchanged: v ~ (old v)
|
||||
valid_unencoded_string: valid_unencoded_string (Result)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
267
library/text/encoder/src/html_encoder.e
Normal file
267
library/text/encoder/src/html_encoder.e
Normal file
@@ -0,0 +1,267 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {HTML_ENCODER}.
|
||||
|
||||
see: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTML_ENCODER
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_32, STRING_8]
|
||||
|
||||
PLATFORM
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "HTML-encoded"
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
feature -- Encoder
|
||||
|
||||
encoded_string (s: STRING_32): STRING_8
|
||||
-- HTML-encoded value of `s'.
|
||||
local
|
||||
i, n: INTEGER
|
||||
uc: CHARACTER_32
|
||||
c: CHARACTER_8
|
||||
do
|
||||
has_error := False
|
||||
create Result.make (s.count + s.count // 10)
|
||||
n := s.count
|
||||
from i := 1 until i > n loop
|
||||
uc := s.item (i)
|
||||
if uc.is_character_8 then
|
||||
c := uc.to_character_8
|
||||
inspect c
|
||||
when '%"' then Result.append_string (""")
|
||||
when '&' then Result.append_string ("&")
|
||||
when '%'' then Result.append_string ("'")
|
||||
when '<' then Result.append_string ("<")
|
||||
when '>' then Result.append_string (">")
|
||||
else
|
||||
Result.extend (c)
|
||||
end
|
||||
else
|
||||
Result.append ("&#")
|
||||
Result.append (uc.code.out)
|
||||
Result.extend (';')
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING_8): STRING_32
|
||||
-- The HTML-encoded equivalent of the given string
|
||||
local
|
||||
i, n: INTEGER
|
||||
c: CHARACTER
|
||||
cl_i: CELL [INTEGER]
|
||||
do
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
create cl_i.put (0)
|
||||
from i := 1 until i > n loop
|
||||
c := v.item (i)
|
||||
if c = '&' then
|
||||
cl_i.replace (i)
|
||||
Result.append_string (next_entity (v, cl_i))
|
||||
i := cl_i.item
|
||||
else
|
||||
Result.append_character (c.to_character_32)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: decoder
|
||||
|
||||
next_entity (v: STRING_8; cl_i: CELL [INTEGER]): STRING_32
|
||||
-- Return next entity value
|
||||
-- move index
|
||||
local
|
||||
i: INTEGER
|
||||
c: CHARACTER
|
||||
is_char: BOOLEAN
|
||||
is_hexa: BOOLEAN
|
||||
s: STRING_32
|
||||
do
|
||||
i := cl_i.item
|
||||
create s.make_empty
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
if c = '#' then
|
||||
is_char := True
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
if c = 'x' then
|
||||
is_hexa := True
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
if is_char then
|
||||
if is_hexa then
|
||||
from
|
||||
until
|
||||
not c.is_hexa_digit or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
else
|
||||
from
|
||||
until
|
||||
not c.is_digit or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
else
|
||||
from
|
||||
until
|
||||
not valid_entity_character (c) or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
if c = ';' then
|
||||
if is_char then
|
||||
if is_hexa then
|
||||
-- not yet implemented
|
||||
s.prepend_character ('x')
|
||||
s.prepend_character ('#')
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
Result := s
|
||||
elseif s.is_integer then
|
||||
create Result.make (1)
|
||||
Result.append_code (s.to_natural_32)
|
||||
else
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
Result := s
|
||||
end
|
||||
else
|
||||
resolve_entity (s)
|
||||
Result := s
|
||||
end
|
||||
cl_i.replace (i + 1)
|
||||
else
|
||||
cl_i.replace (cl_i.item + 1)
|
||||
s.prepend_character ('&')
|
||||
has_error := True -- ("Invalid entity syntax " + s)
|
||||
Result := s
|
||||
end
|
||||
end
|
||||
|
||||
resolve_entity (s: STRING_32)
|
||||
-- Resolve `s' as an entity
|
||||
--| Hardcoding the xml entities " & ' < and >
|
||||
require
|
||||
s_attached: s /= Void
|
||||
local
|
||||
l_resolved: BOOLEAN
|
||||
do
|
||||
inspect s[1].as_lower
|
||||
when 'a' then
|
||||
if
|
||||
s.count = 3 and then
|
||||
s[2].as_lower = 'm' and then
|
||||
s[3].as_lower = 'p'
|
||||
then -- &
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('&')
|
||||
elseif -- '
|
||||
s.count = 4 and then
|
||||
s[2].as_lower = 'p' and then
|
||||
s[3].as_lower = 'o' and then
|
||||
s[4].as_lower = 's'
|
||||
then
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('%'')
|
||||
end
|
||||
when 'q' then
|
||||
if
|
||||
s.count = 4 and then
|
||||
s[2].as_lower = 'u' and then
|
||||
s[3].as_lower = 'o' and then
|
||||
s[4].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('%"')
|
||||
end
|
||||
when 'l' then
|
||||
if
|
||||
s.count = 2 and then
|
||||
s[2].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('<')
|
||||
end
|
||||
when 'g' then
|
||||
if
|
||||
s.count = 2 and then
|
||||
s[2].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('>')
|
||||
end
|
||||
else
|
||||
end
|
||||
if not l_resolved then
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
end
|
||||
end
|
||||
|
||||
valid_entity_character (c: CHARACTER): BOOLEAN
|
||||
-- Is `c' a valid character in html entity value?
|
||||
--| such as &
|
||||
do
|
||||
inspect
|
||||
c
|
||||
when 'a'..'z' then
|
||||
Result := True
|
||||
when 'A'..'Z' then
|
||||
Result := True
|
||||
when '0'..'9' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
321
library/text/encoder/src/url_encoder.e
Normal file
321
library/text/encoder/src/url_encoder.e
Normal file
@@ -0,0 +1,321 @@
|
||||
note
|
||||
description: "Summary description for {URL_ENCODER}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
URL_ENCODER
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_32, STRING_8]
|
||||
|
||||
PLATFORM
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "URL-encoded"
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
feature -- Encoder
|
||||
|
||||
encoded_string (s: STRING_32): STRING_8
|
||||
-- URL-encoded value of `s'.
|
||||
local
|
||||
i, n: INTEGER
|
||||
uc: CHARACTER_32
|
||||
c: CHARACTER_8
|
||||
do
|
||||
has_error := False
|
||||
create Result.make (s.count + s.count // 10)
|
||||
n := s.count
|
||||
from i := 1 until i > n loop
|
||||
uc := s.item (i)
|
||||
if uc.is_character_8 then
|
||||
c := uc.to_character_8
|
||||
inspect c
|
||||
when
|
||||
'A' .. 'Z',
|
||||
'a' .. 'z', '0' .. '9',
|
||||
'.', '-', '~', '_'
|
||||
then
|
||||
Result.extend (c)
|
||||
when ' ' then
|
||||
Result.extend ('+')
|
||||
else
|
||||
Result.append (url_encoded_char (uc))
|
||||
end
|
||||
else
|
||||
Result.append (url_encoded_char (uc))
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- encoder character
|
||||
|
||||
url_encoded_char (uc: CHARACTER_32): STRING_8
|
||||
do
|
||||
create Result.make (3)
|
||||
if uc.is_character_8 then
|
||||
Result.extend ('%%')
|
||||
Result.append (uc.code.to_hex_string)
|
||||
from
|
||||
until
|
||||
Result.count < 2 or else Result[2] /= '0'
|
||||
loop
|
||||
Result.remove (2)
|
||||
end
|
||||
else
|
||||
has_error := True --| Non-ascii escape not currently supported
|
||||
end
|
||||
ensure
|
||||
exists: Result /= Void
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING_8): STRING_32
|
||||
-- The URL-encoded equivalent of the given string
|
||||
local
|
||||
i, n: INTEGER
|
||||
c: CHARACTER
|
||||
pr: CELL [INTEGER]
|
||||
do
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
from i := 1
|
||||
until i > n
|
||||
loop
|
||||
c := v.item (i)
|
||||
inspect c
|
||||
when '+' then
|
||||
Result.append_character ({CHARACTER_32}' ')
|
||||
when '%%' then
|
||||
-- An escaped character ?
|
||||
if i = n then
|
||||
Result.append_character (c.to_character_32)
|
||||
else
|
||||
create pr.put (i)
|
||||
Result.append (url_decoded_char (v, pr))
|
||||
i := pr.item
|
||||
end
|
||||
else
|
||||
Result.append_character (c.to_character_32)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- decoded character
|
||||
|
||||
url_decoded_char (buf: STRING_8; posr: CELL [INTEGER]): STRING_32
|
||||
-- Character(s) resulting from decoding the URL-encoded string
|
||||
require
|
||||
stream_exists: buf /= Void
|
||||
posr_exists: posr /= Void
|
||||
valid_start: posr.item <= buf.count
|
||||
local
|
||||
c: CHARACTER
|
||||
i, n, nb: INTEGER
|
||||
not_a_digit: BOOLEAN
|
||||
ascii_pos, ival: INTEGER
|
||||
pos: INTEGER
|
||||
do
|
||||
--| pos is index in stream of escape character ('%')
|
||||
pos := posr.item
|
||||
create Result.make (4)
|
||||
if buf.item (pos + 1) = 'u' then
|
||||
-- An escaped Unicode (ucs2) value, from ECMA scripts
|
||||
-- Has the form: %u<n> where <n> is the UCS value
|
||||
-- of the character (two byte integer, one to 4 chars
|
||||
-- after escape sequence).
|
||||
-- UTF-8 result can be 1 to 4 characters
|
||||
n := buf.count
|
||||
from i := pos + 2
|
||||
until (i > n) or not_a_digit
|
||||
loop
|
||||
c := buf.item (i)
|
||||
if c.is_hexa_digit then
|
||||
ival := ival * 16
|
||||
if c.is_digit then
|
||||
ival := ival + (c |-| '0')
|
||||
else
|
||||
ival := ival + (c.upper |-| 'A') + 10
|
||||
end
|
||||
i := i + 1
|
||||
else
|
||||
not_a_digit := True
|
||||
end
|
||||
end
|
||||
posr.replace (i)
|
||||
-- ival is now UCS2 value; needs conversion to UTF8
|
||||
Result.append_code (ival.as_natural_32)
|
||||
nb := utf8_bytes_in_sequence (buf, pos)
|
||||
else
|
||||
-- ASCII char?
|
||||
ascii_pos := hex_to_integer_32 (buf.substring (pos+1, pos+2))
|
||||
if ascii_pos >= 0x80 and ascii_pos <= 0xff then
|
||||
-- Might be improperly escaped
|
||||
Result.append_code (ascii_pos.as_natural_32)
|
||||
posr.replace (pos + 2)
|
||||
else
|
||||
Result.append_code (ascii_pos.as_natural_32)
|
||||
posr.replace (pos + 2)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
exists: Result /= Void
|
||||
end
|
||||
|
||||
feature {NONE} -- UTF8
|
||||
|
||||
utf8_bytes_in_sequence (s: STRING_8; spos: INTEGER): INTEGER
|
||||
-- If the given character is a legal first byte element in a
|
||||
-- utf8 byte sequence (aka character), then return the number
|
||||
-- of bytes in that sequence
|
||||
-- Result of zero means it's not a utf8 first byte
|
||||
require
|
||||
exists: s /= Void
|
||||
long_enough: s.count >= spos
|
||||
do
|
||||
Result := bytes_in_utf8_char (s.item (spos))
|
||||
end
|
||||
|
||||
bytes_in_utf8_char (v: CHARACTER_8): INTEGER
|
||||
-- If the given byte a legal first byte element in a utf8 sequence,
|
||||
-- then the number of bytes in that character
|
||||
-- Zero denotes an error, i.e. not a legal UTF8 char
|
||||
--
|
||||
-- The first byte of a UTF8 encodes the length
|
||||
local
|
||||
c: NATURAL_8
|
||||
do
|
||||
c := v.code.to_natural_8
|
||||
Result := 1 -- 7 bit ASCII
|
||||
if (c & 0x80) /= 0 then
|
||||
-- Hi bit means not ASCII
|
||||
Result := 0
|
||||
if (c & 0xe0) = 0xc0 then
|
||||
-- If we see a first byte as b110xxxxx
|
||||
-- then we expect a two-byte character
|
||||
Result := 2
|
||||
elseif (c & 0xf0) = 0xe0 then
|
||||
-- If we see a first byte as b1110xxxx
|
||||
-- then we expect a three-byte character
|
||||
Result := 3
|
||||
elseif (c & 0xf8) = 0xf0 then
|
||||
-- If we see a first byte as b11110xxx
|
||||
-- then we expect a four-byte character
|
||||
Result := 4
|
||||
elseif (c & 0xfc) = 0xf8 then
|
||||
-- If we see a first byte as b111110xx
|
||||
-- then we expect a five-byte character
|
||||
Result := 5
|
||||
elseif (c & 0xfe) = 0xfc then
|
||||
-- If we see a first byte as b1111110x
|
||||
-- then we expect a six-byte character
|
||||
Result := 6
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Hexadecimal and strings
|
||||
|
||||
hex_to_integer_32 (s: STRING): INTEGER_32
|
||||
-- Hexadecimal string `s' converted to INTEGER_32 value
|
||||
require
|
||||
s_not_void: s /= Void
|
||||
local
|
||||
i, nb: INTEGER;
|
||||
char: CHARACTER
|
||||
do
|
||||
nb := s.count
|
||||
|
||||
if nb >= 2 and then s.item (2) = 'x' then
|
||||
i := 3
|
||||
else
|
||||
i := 1
|
||||
end
|
||||
|
||||
from
|
||||
until
|
||||
i > nb
|
||||
loop
|
||||
Result := Result * 16
|
||||
char := s.item (i)
|
||||
if char >= '0' and then char <= '9' then
|
||||
Result := Result + (char |-| '0')
|
||||
else
|
||||
Result := Result + (char.lower |-| 'a' + 10)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
hex_to_integer_64 (s: STRING): INTEGER_64
|
||||
-- Hexadecimal string `s' converted to INTEGER_64 value
|
||||
require
|
||||
s_not_void: s /= Void
|
||||
local
|
||||
i, nb: INTEGER;
|
||||
char: CHARACTER
|
||||
do
|
||||
nb := s.count
|
||||
|
||||
if nb >= 2 and then s.item (2) = 'x' then
|
||||
i := 3
|
||||
else
|
||||
i := 1
|
||||
end
|
||||
|
||||
from
|
||||
until
|
||||
i > nb
|
||||
loop
|
||||
Result := Result * 16
|
||||
char := s.item (i)
|
||||
if char >= '0' and then char <= '9' then
|
||||
Result := Result + (char |-| '0')
|
||||
else
|
||||
Result := Result + (char.lower |-| 'a' + 10)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
hex_to_pointer (s: STRING): POINTER
|
||||
-- Hexadecimal string `s' converted to POINTER value
|
||||
require
|
||||
s_not_void: s /= Void
|
||||
local
|
||||
val_32: INTEGER_32
|
||||
val_64: INTEGER_64
|
||||
do
|
||||
if Pointer_bytes = Integer_64_bytes then
|
||||
val_64 := hex_to_integer_64 (s)
|
||||
($Result).memory_copy ($val_64, Pointer_bytes)
|
||||
else
|
||||
val_32 := hex_to_integer_32 (s)
|
||||
($Result).memory_copy ($val_32, Pointer_bytes)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
267
library/text/encoder/src/xml_encoder.e
Normal file
267
library/text/encoder/src/xml_encoder.e
Normal file
@@ -0,0 +1,267 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {XML_ENCODER}.
|
||||
|
||||
see: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
XML_ENCODER
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_32, STRING_8]
|
||||
|
||||
PLATFORM
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "XML-encoded"
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
feature -- Encoder
|
||||
|
||||
encoded_string (s: STRING_32): STRING_8
|
||||
-- XML-encoded value of `s'.
|
||||
local
|
||||
i, n: INTEGER
|
||||
uc: CHARACTER_32
|
||||
c: CHARACTER_8
|
||||
do
|
||||
has_error := False
|
||||
create Result.make (s.count + s.count // 10)
|
||||
n := s.count
|
||||
from i := 1 until i > n loop
|
||||
uc := s.item (i)
|
||||
if uc.is_character_8 then
|
||||
c := uc.to_character_8
|
||||
inspect c
|
||||
when '%"' then Result.append_string (""")
|
||||
when '&' then Result.append_string ("&")
|
||||
when '%'' then Result.append_string ("'")
|
||||
when '<' then Result.append_string ("<")
|
||||
when '>' then Result.append_string (">")
|
||||
else
|
||||
Result.extend (c)
|
||||
end
|
||||
else
|
||||
Result.append ("&#")
|
||||
Result.append (uc.code.out)
|
||||
Result.extend (';')
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING_8): STRING_32
|
||||
-- The XML-encoded equivalent of the given string
|
||||
local
|
||||
i, n: INTEGER
|
||||
c: CHARACTER
|
||||
cl_i: CELL [INTEGER]
|
||||
do
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
create cl_i.put (0)
|
||||
from i := 1 until i > n loop
|
||||
c := v.item (i)
|
||||
if c = '&' then
|
||||
cl_i.replace (i)
|
||||
Result.append_string (next_entity (v, cl_i))
|
||||
i := cl_i.item
|
||||
else
|
||||
Result.append_character (c.to_character_32)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: decoder
|
||||
|
||||
next_entity (v: STRING_8; cl_i: CELL [INTEGER]): STRING_32
|
||||
-- Return next entity value
|
||||
-- move index
|
||||
local
|
||||
i: INTEGER
|
||||
c: CHARACTER
|
||||
is_char: BOOLEAN
|
||||
is_hexa: BOOLEAN
|
||||
s: STRING_32
|
||||
do
|
||||
i := cl_i.item
|
||||
create s.make_empty
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
if c = '#' then
|
||||
is_char := True
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
if c = 'x' then
|
||||
is_hexa := True
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
if is_char then
|
||||
if is_hexa then
|
||||
from
|
||||
until
|
||||
not c.is_hexa_digit or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
else
|
||||
from
|
||||
until
|
||||
not c.is_digit or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
else
|
||||
from
|
||||
until
|
||||
not valid_entity_character (c) or c = ';'
|
||||
loop
|
||||
s.append_character (c)
|
||||
i := i + 1
|
||||
c := v[i]
|
||||
end
|
||||
end
|
||||
if c = ';' then
|
||||
if is_char then
|
||||
if is_hexa then
|
||||
-- not yet implemented
|
||||
s.prepend_character ('x')
|
||||
s.prepend_character ('#')
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
Result := s
|
||||
elseif s.is_integer then
|
||||
create Result.make (1)
|
||||
Result.append_code (s.to_natural_32)
|
||||
else
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
Result := s
|
||||
end
|
||||
else
|
||||
resolve_entity (s)
|
||||
Result := s
|
||||
end
|
||||
cl_i.replace (i + 1)
|
||||
else
|
||||
cl_i.replace (cl_i.item + 1)
|
||||
s.prepend_character ('&')
|
||||
has_error := True -- ("Invalid entity syntax " + s)
|
||||
Result := s
|
||||
end
|
||||
end
|
||||
|
||||
resolve_entity (s: STRING_32)
|
||||
-- Resolve `s' as an entity
|
||||
--| Hardcoding the xml entities " & ' < and >
|
||||
require
|
||||
s_attached: s /= Void
|
||||
local
|
||||
l_resolved: BOOLEAN
|
||||
do
|
||||
inspect s[1].as_lower
|
||||
when 'a' then
|
||||
if
|
||||
s.count = 3 and then
|
||||
s[2].as_lower = 'm' and then
|
||||
s[3].as_lower = 'p'
|
||||
then -- &
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('&')
|
||||
elseif -- '
|
||||
s.count = 4 and then
|
||||
s[2].as_lower = 'p' and then
|
||||
s[3].as_lower = 'o' and then
|
||||
s[4].as_lower = 's'
|
||||
then
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('%'')
|
||||
end
|
||||
when 'q' then
|
||||
if
|
||||
s.count = 4 and then
|
||||
s[2].as_lower = 'u' and then
|
||||
s[3].as_lower = 'o' and then
|
||||
s[4].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('%"')
|
||||
end
|
||||
when 'l' then
|
||||
if
|
||||
s.count = 2 and then
|
||||
s[2].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('<')
|
||||
end
|
||||
when 'g' then
|
||||
if
|
||||
s.count = 2 and then
|
||||
s[2].as_lower = 't'
|
||||
then -- "
|
||||
l_resolved := True
|
||||
s.wipe_out
|
||||
s.append_character ('>')
|
||||
end
|
||||
else
|
||||
end
|
||||
if not l_resolved then
|
||||
s.prepend_character ('&')
|
||||
s.append_character (';')
|
||||
end
|
||||
end
|
||||
|
||||
valid_entity_character (c: CHARACTER): BOOLEAN
|
||||
-- Is `c' a valid character in html entity value?
|
||||
--| such as &
|
||||
do
|
||||
inspect
|
||||
c
|
||||
when 'a'..'z' then
|
||||
Result := True
|
||||
when 'A'..'Z' then
|
||||
Result := True
|
||||
when '0'..'9' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
49
library/text/encoder/tests/test_base64.e
Normal file
49
library/text/encoder/tests/test_base64.e
Normal file
@@ -0,0 +1,49 @@
|
||||
note
|
||||
description: "[
|
||||
Eiffel tests that can be executed by testing tool.
|
||||
]"
|
||||
author: "EiffelStudio test wizard"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
testing: "type/manual"
|
||||
|
||||
class
|
||||
TEST_BASE64
|
||||
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
|
||||
feature -- Test routines
|
||||
|
||||
test_base64_encoder
|
||||
note
|
||||
testing: "base64"
|
||||
do
|
||||
test_base64_encoding ("Il <20>tait une fois !")
|
||||
end
|
||||
|
||||
test_base64_encoding (s: STRING_8)
|
||||
local
|
||||
u: STRING_8
|
||||
e: STRING_8
|
||||
b: BASE64
|
||||
do
|
||||
create b
|
||||
e := b.encoded_string (s)
|
||||
u := b.decoded_string (e)
|
||||
assert ("decoded encoded string is same", u ~ s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
49
library/text/encoder/tests/test_url_encoder.e
Normal file
49
library/text/encoder/tests/test_url_encoder.e
Normal file
@@ -0,0 +1,49 @@
|
||||
note
|
||||
description: "[
|
||||
Eiffel tests that can be executed by testing tool.
|
||||
]"
|
||||
author: "EiffelStudio test wizard"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
testing: "type/manual"
|
||||
|
||||
class
|
||||
TEST_URL_ENCODER
|
||||
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
|
||||
feature -- Test routines
|
||||
|
||||
test_url_encoded_encoder
|
||||
note
|
||||
testing: "url-encoded"
|
||||
do
|
||||
test_url_encoded_encoding ("http://domain.tld/foo/bar/script.php?test='toto'&foo=bar&title=il <20>tait une fois")
|
||||
end
|
||||
|
||||
test_url_encoded_encoding (s: STRING_32)
|
||||
local
|
||||
u: STRING_32
|
||||
e: STRING_8
|
||||
b: URL_ENCODER
|
||||
do
|
||||
create b
|
||||
e := b.encoded_string (s)
|
||||
u := b.decoded_string (e)
|
||||
assert ("decoded encoded string is same", u ~ s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user