Added a version of ISE Library URI modified to be compilable with compiler < 7.2
Fixed openid when redirection is involved Fixed Openid Attribute Exchange implementation (AX) Added WSF_REQUEST.items_as_string_items: ... for convenience, and ease integration with other components (such as the new openid)
This commit is contained in:
1
contrib/ise_library/text/uri/license.lic
Normal file
1
contrib/ise_library/text/uri/license.lic
Normal file
@@ -0,0 +1 @@
|
|||||||
|
reference:forum2
|
||||||
@@ -0,0 +1,508 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Component to handle percent encoding
|
||||||
|
]"
|
||||||
|
date: "$Date: 2013-01-26 01:40:46 +0100 (sam., 26 janv. 2013) $"
|
||||||
|
revision: "$Revision: 90880 $"
|
||||||
|
EIS: "name=Percent-encoding", "protocol=URI", "src=http://en.wikipedia.org/wiki/Percent-encoding"
|
||||||
|
|
||||||
|
class
|
||||||
|
PERCENT_ENCODER
|
||||||
|
|
||||||
|
feature -- Percent encoding
|
||||||
|
|
||||||
|
append_percent_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||||
|
-- Append `a_string' as percent-encoded value to `a_result'
|
||||||
|
local
|
||||||
|
c: NATURAL_32
|
||||||
|
i,n: INTEGER
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
c := s.code (i)
|
||||||
|
if
|
||||||
|
--| unreserved ALPHA / DIGIT
|
||||||
|
(48 <= c and c <= 57) -- DIGIT: 0 .. 9
|
||||||
|
or (65 <= c and c <= 90) -- ALPHA: A .. Z
|
||||||
|
or (97 <= c and c <= 122) -- ALPHA: a .. z
|
||||||
|
then
|
||||||
|
a_result.append_code (c)
|
||||||
|
else
|
||||||
|
inspect c
|
||||||
|
when
|
||||||
|
45, 46, 95, 126 -- unreserved characters: -._~
|
||||||
|
then
|
||||||
|
a_result.append_code (c)
|
||||||
|
when
|
||||||
|
58, 64, -- reserved =+ gen-delims: :@
|
||||||
|
33, 36, 38, 39, 40, 41, 42, -- reserved =+ sub-delims: !$&'()*
|
||||||
|
43, 44, 59, 61, -- reserved = sub-delims: +,;=
|
||||||
|
37 -- percent encoding: %
|
||||||
|
then
|
||||||
|
append_percent_encoded_character_code_to (c, a_result)
|
||||||
|
else
|
||||||
|
append_percent_encoded_character_code_to (c, a_result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Percent encoding: character
|
||||||
|
|
||||||
|
append_percent_encoded_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||||
|
-- Append character code `a_code' as percent-encoded content into `a_result'
|
||||||
|
do
|
||||||
|
if a_code > 0xFF then
|
||||||
|
-- Unicode
|
||||||
|
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||||
|
elseif a_code > 0x7F then
|
||||||
|
-- Extended ASCII
|
||||||
|
-- This requires percent-encoding on UTF-8 converted character.
|
||||||
|
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||||
|
else
|
||||||
|
-- ASCII
|
||||||
|
append_percent_encoded_ascii_character_code_to (a_code, a_result)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
appended: a_result.count > old a_result.count
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: character encoding
|
||||||
|
|
||||||
|
append_percent_encoded_ascii_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||||
|
-- Append extended ascii character code `a_code' as percent-encoded content into `a_result'
|
||||||
|
-- Note: it does not UTF-8 convert this extended ASCII.
|
||||||
|
require
|
||||||
|
is_extended_ascii: a_code <= 0xFF
|
||||||
|
local
|
||||||
|
c: INTEGER
|
||||||
|
do
|
||||||
|
if a_code > 0xFF then
|
||||||
|
-- Unicode
|
||||||
|
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||||
|
else
|
||||||
|
-- Extended ASCII
|
||||||
|
c := a_code.to_integer_32
|
||||||
|
a_result.append_code (37) -- 37 '%%'
|
||||||
|
a_result.append_code (hex_digit [c |>> 4])
|
||||||
|
a_result.append_code (hex_digit [c & 0xF])
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
appended: a_result.count > old a_result.count
|
||||||
|
end
|
||||||
|
|
||||||
|
append_percent_encoded_unicode_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||||
|
-- Append Unicode character code `a_code' as UTF-8 and percent-encoded content into `a_result'
|
||||||
|
-- Note: it does include UTF-8 conversion of extended ASCII and Unicode.
|
||||||
|
do
|
||||||
|
if a_code <= 0x7F then
|
||||||
|
-- 0xxxxxxx
|
||||||
|
append_percent_encoded_ascii_character_code_to (a_code, a_result)
|
||||||
|
elseif a_code <= 0x7FF then
|
||||||
|
-- 110xxxxx 10xxxxxx
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code |>> 6) | 0xC0, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||||
|
elseif a_code <= 0xFFFF then
|
||||||
|
-- 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code |>> 12) | 0xE0, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to (((a_code |>> 6) & 0x3F) | 0x80, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||||
|
else
|
||||||
|
-- c <= 1FFFFF - there are no higher code points
|
||||||
|
-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code |>> 18) | 0xF0, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to (((a_code |>> 12) & 0x3F) | 0x80, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to (((a_code |>> 6) & 0x3F) | 0x80, a_result)
|
||||||
|
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
appended: a_result.count > old a_result.count
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Percent decoding
|
||||||
|
|
||||||
|
append_percent_decoded_string_to (v: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||||
|
-- Append to `a_result' a string equivalent to the percent-encoded string `v'
|
||||||
|
--| Note that is `a_result' is a STRING_8, any Unicode character will be kept as UTF-8
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: NATURAL_32
|
||||||
|
pr: CELL [INTEGER]
|
||||||
|
a_result_is_string_32: BOOLEAN
|
||||||
|
do
|
||||||
|
a_result_is_string_32 := attached {STRING_32} a_result
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
create pr.put (i)
|
||||||
|
n := v.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
c := v.code (i)
|
||||||
|
inspect c
|
||||||
|
when 43 then -- 43 '+'
|
||||||
|
-- Some implementation are replacing spaces with "+" instead of "%20"
|
||||||
|
a_result.append_code (32) -- 32 ' '
|
||||||
|
when 37 then -- 37 '%%'
|
||||||
|
-- An escaped character ?
|
||||||
|
if i = n then -- Error?
|
||||||
|
a_result.append_code (c)
|
||||||
|
else
|
||||||
|
if a_result_is_string_32 then
|
||||||
|
-- Convert UTF-8 to UTF-32
|
||||||
|
pr.replace (i)
|
||||||
|
c := next_percent_decoded_unicode_character_code (v, pr)
|
||||||
|
a_result.append_code (c)
|
||||||
|
i := pr.item
|
||||||
|
else
|
||||||
|
-- Keep UTF-8
|
||||||
|
pr.replace (i)
|
||||||
|
c := next_percent_decoded_character_code (v, pr)
|
||||||
|
a_result.append_code (c)
|
||||||
|
i := pr.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if c <= 0x7F then
|
||||||
|
a_result.append_code (c)
|
||||||
|
else
|
||||||
|
if a_result_is_string_32 then
|
||||||
|
a_result.append_code (c)
|
||||||
|
else
|
||||||
|
append_percent_encoded_character_code_to (c, a_result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: decoding
|
||||||
|
|
||||||
|
next_percent_decoded_character_code (v: READABLE_STRING_GENERAL; a_position: CELL [INTEGER]): NATURAL_32
|
||||||
|
-- Character decoded from string `v' starting from index `a_position.item'
|
||||||
|
-- note: it also updates `a_position.item' to indicate the new index position.
|
||||||
|
require
|
||||||
|
valid_start: a_position.item <= v.count
|
||||||
|
is_percent_char: v.code (a_position.item) = 37 -- 37 '%%'
|
||||||
|
local
|
||||||
|
c: NATURAL_32
|
||||||
|
i, n: INTEGER
|
||||||
|
not_a_digit: BOOLEAN
|
||||||
|
ascii_pos: NATURAL_32
|
||||||
|
ival: NATURAL_32
|
||||||
|
pos: INTEGER
|
||||||
|
c_is_digit: BOOLEAN
|
||||||
|
do
|
||||||
|
--| pos is index in stream of escape character ('%')
|
||||||
|
pos := a_position.item
|
||||||
|
c := v.code (pos + 1)
|
||||||
|
if c = 85 or c = 117 then -- 117 'u' 85 'U'
|
||||||
|
-- NOTE: this is not a standard, but it can occur, so use this for decoding only
|
||||||
|
-- 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).
|
||||||
|
-- See: http://en.wikipedia.org/wiki/Percent-encoding#Non-standard_implementations
|
||||||
|
-- UTF-8 result can be 1 to 4 characters.
|
||||||
|
from
|
||||||
|
i := pos + 2
|
||||||
|
n := v.count
|
||||||
|
until
|
||||||
|
(i > n) or not_a_digit
|
||||||
|
loop
|
||||||
|
c := v.code (i)
|
||||||
|
c_is_digit := (48 <= c and c <= 57) -- DIGIT: 0 .. 9
|
||||||
|
if
|
||||||
|
c_is_digit
|
||||||
|
or (97 <= c and c <= 102) -- ALPHA: a..f
|
||||||
|
or (65 <= c and c <= 70) -- ALPHA: A..F
|
||||||
|
then
|
||||||
|
ival := ival * 16
|
||||||
|
if c_is_digit then
|
||||||
|
ival := ival + (c - 48) -- 48 '0'
|
||||||
|
else
|
||||||
|
if c > 70 then -- a..f
|
||||||
|
ival := ival + (c - 97) + 10 -- 97 'a'
|
||||||
|
else -- A..F
|
||||||
|
ival := ival + (c - 65) + 10 -- 65 'A'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
else
|
||||||
|
not_a_digit := True
|
||||||
|
i := i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
a_position.replace (i)
|
||||||
|
Result := ival
|
||||||
|
else
|
||||||
|
-- ASCII char?
|
||||||
|
ascii_pos := hexadecimal_string_to_natural_32 (v.substring (pos + 1, pos + 2))
|
||||||
|
Result := ascii_pos
|
||||||
|
a_position.replace (pos + 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
next_percent_decoded_unicode_character_code (v: READABLE_STRING_GENERAL; a_position: CELL [INTEGER]): NATURAL_32
|
||||||
|
-- Next decoded character from `v' at position `a_position.item'
|
||||||
|
-- note: it also updates `a_position' to indicate the new index position.
|
||||||
|
require
|
||||||
|
valid_start: a_position.item <= v.count
|
||||||
|
is_percent_char: v.code (a_position.item) = 37 -- 37 '%%'
|
||||||
|
local
|
||||||
|
n, j: INTEGER
|
||||||
|
c: NATURAL_32
|
||||||
|
c1, c2, c3, c4: NATURAL_32
|
||||||
|
pr: CELL [INTEGER]
|
||||||
|
do
|
||||||
|
create pr.put (a_position.item)
|
||||||
|
c1 := next_percent_decoded_character_code (v, pr)
|
||||||
|
|
||||||
|
j := pr.item
|
||||||
|
n := v.count
|
||||||
|
|
||||||
|
Result := c1
|
||||||
|
a_position.replace (j)
|
||||||
|
|
||||||
|
if c1 <= 0x7F then
|
||||||
|
-- 0xxxxxxx
|
||||||
|
Result := c1
|
||||||
|
elseif c1 <= 0xDF then
|
||||||
|
-- 110xxxxx 10xxxxxx
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c2 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
Result := (
|
||||||
|
((c1 & 0x1F) |<< 6) |
|
||||||
|
( c2 & 0x3F )
|
||||||
|
)
|
||||||
|
a_position.replace (j)
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif c1 <= 0xEF then
|
||||||
|
-- 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c2 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c3 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
|
||||||
|
Result := (
|
||||||
|
((c1 & 0xF) |<< 12) |
|
||||||
|
((c2 & 0x3F) |<< 6) |
|
||||||
|
( c3 & 0x3F )
|
||||||
|
)
|
||||||
|
a_position.replace (j)
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif c1 <= 0xF7 then
|
||||||
|
-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c2 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c3 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
if j + 2 <= n then
|
||||||
|
c := v.code (j + 1)
|
||||||
|
if c = 37 then -- 37 '%%'
|
||||||
|
pr.replace (j + 1)
|
||||||
|
c4 := next_percent_decoded_character_code (v, pr)
|
||||||
|
j := pr.item
|
||||||
|
|
||||||
|
a_position.replace (j)
|
||||||
|
|
||||||
|
Result := (
|
||||||
|
((c1 & 0x7) |<< 18 ) |
|
||||||
|
((c2 & 0x3F) |<< 12) |
|
||||||
|
((c3 & 0x3F) |<< 6) |
|
||||||
|
( c4 & 0x3F )
|
||||||
|
)
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Do not try to decode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := c1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- RFC and characters
|
||||||
|
|
||||||
|
is_hexa_decimal_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- Is hexadecimal character ?
|
||||||
|
do
|
||||||
|
Result := ('a' <= c and c <= 'f') or ('A' <= c and c <= 'F') -- HEXA
|
||||||
|
or ('0' <= c and c <= '9') -- DIGIT
|
||||||
|
end
|
||||||
|
|
||||||
|
is_alpha_or_digit_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- Is ALPHA or DIGIT character ?
|
||||||
|
do
|
||||||
|
Result := ('a' <= c and c <= 'z') or ('A' <= c and c <= 'Z') -- ALPHA
|
||||||
|
or ('0' <= c and c <= '9') -- DIGIT
|
||||||
|
end
|
||||||
|
|
||||||
|
is_alpha_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- Is ALPHA character ?
|
||||||
|
do
|
||||||
|
Result := ('a' <= c and c <= 'z') or ('A' <= c and c <= 'Z')
|
||||||
|
end
|
||||||
|
|
||||||
|
is_digit_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- Is DIGIT character ?
|
||||||
|
do
|
||||||
|
Result := ('0' <= c and c <= '9')
|
||||||
|
end
|
||||||
|
|
||||||
|
is_unreserved_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||||
|
do
|
||||||
|
if
|
||||||
|
('a' <= c and c <= 'z') -- ALPHA
|
||||||
|
or ('A' <= c and c <= 'Z') -- ALPHA
|
||||||
|
or ('0' <= c and c <= '9') -- DIGIT
|
||||||
|
then
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
inspect c
|
||||||
|
when '-', '_', '.', '~' then -- unreserved
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_reserved_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- reserved = gen-delims / sub-delims
|
||||||
|
do
|
||||||
|
Result := is_gen_delims_character (c) or is_sub_delims_character (c)
|
||||||
|
end
|
||||||
|
|
||||||
|
is_gen_delims_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||||
|
do
|
||||||
|
inspect c
|
||||||
|
when ':' , '/', '?' , '#' , '[' , ']' , '@' then
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_sub_delims_character (c: CHARACTER_32): BOOLEAN
|
||||||
|
-- sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
-- / "*" / "+" / "," / ";" / "="
|
||||||
|
do
|
||||||
|
inspect c
|
||||||
|
when '!' , '$' , '&' , '%'' , '(' , ')' , '*' , '+' , ',' , ';' , '=' then -- sub-delims
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
hex_digit: SPECIAL [NATURAL_32]
|
||||||
|
-- Hexadecimal digits.
|
||||||
|
once
|
||||||
|
create Result.make_filled (0, 16)
|
||||||
|
Result [0] := {NATURAL_32} 48 -- 48 '0'
|
||||||
|
Result [1] := {NATURAL_32} 49 -- 49 '1'
|
||||||
|
Result [2] := {NATURAL_32} 50 -- 50 '2'
|
||||||
|
Result [3] := {NATURAL_32} 51 -- 51 '3'
|
||||||
|
Result [4] := {NATURAL_32} 52 -- 52 '4'
|
||||||
|
Result [5] := {NATURAL_32} 53 -- 53 '5'
|
||||||
|
Result [6] := {NATURAL_32} 54 -- 54 '6'
|
||||||
|
Result [7] := {NATURAL_32} 55 -- 55 '7'
|
||||||
|
Result [8] := {NATURAL_32} 56 -- 56 '8'
|
||||||
|
Result [9] := {NATURAL_32} 57 -- 57 '9'
|
||||||
|
Result [10] := {NATURAL_32} 65 -- 65 'A'
|
||||||
|
Result [11] := {NATURAL_32} 66 -- 66 'B'
|
||||||
|
Result [12] := {NATURAL_32} 67 -- 67 'C'
|
||||||
|
Result [13] := {NATURAL_32} 68 -- 68 'D'
|
||||||
|
Result [14] := {NATURAL_32} 69 -- 69 'E'
|
||||||
|
Result [15] := {NATURAL_32} 70 -- 70 'F'
|
||||||
|
end
|
||||||
|
|
||||||
|
is_hexa_decimal (a_string: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Is `a_string' a valid hexadecimal sequence?
|
||||||
|
local
|
||||||
|
l_convertor: like ctoi_convertor
|
||||||
|
do
|
||||||
|
l_convertor := ctoi_convertor
|
||||||
|
l_convertor.parse_string_with_type (a_string, {NUMERIC_INFORMATION}.type_natural_32)
|
||||||
|
Result := l_convertor.is_integral_integer
|
||||||
|
end
|
||||||
|
|
||||||
|
hexadecimal_string_to_natural_32 (a_hex_string: READABLE_STRING_GENERAL): NATURAL_32
|
||||||
|
-- Convert hexadecimal value `a_hex_string' to its corresponding NATURAL_32 value.
|
||||||
|
require
|
||||||
|
is_hexa: is_hexa_decimal (a_hex_string)
|
||||||
|
local
|
||||||
|
l_convertor: like ctoi_convertor
|
||||||
|
do
|
||||||
|
l_convertor := ctoi_convertor
|
||||||
|
l_convertor.parse_string_with_type (a_hex_string, {NUMERIC_INFORMATION}.type_no_limitation)
|
||||||
|
Result := l_convertor.parsed_natural_32
|
||||||
|
end
|
||||||
|
|
||||||
|
ctoi_convertor: HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
||||||
|
-- Converter used to convert string to integer or natural.
|
||||||
|
once
|
||||||
|
create Result.make
|
||||||
|
Result.set_leading_separators_acceptable (False)
|
||||||
|
Result.set_trailing_separators_acceptable (False)
|
||||||
|
ensure
|
||||||
|
ctoi_convertor_not_void: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "Copyright (c) 1984-2013, 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
|
||||||
352
contrib/ise_library/text/uri/src/iri.e
Normal file
352
contrib/ise_library/text/uri/src/iri.e
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
note
|
||||||
|
description : "[
|
||||||
|
Object that represents an IRI Scheme
|
||||||
|
|
||||||
|
See http://en.wikipedia.org/wiki/Internationalized_Resource_Identifier
|
||||||
|
See http://tools.ietf.org/html/rfc3987 (IRI)
|
||||||
|
|
||||||
|
]"
|
||||||
|
author: "$Author: manus $"
|
||||||
|
date: "$Date: 2013-01-26 01:40:46 +0100 (sam., 26 janv. 2013) $"
|
||||||
|
revision: "$Revision: 90880 $"
|
||||||
|
EIS: "name=IRI-RFC3987", "protocol=URI", "src=http://tools.ietf.org/html/rfc3987"
|
||||||
|
EIS: "name=IRI-Wikipedia", "protocol=URI", "src=http://en.wikipedia.org/wiki/Internationalized_Resource_Identifier"
|
||||||
|
|
||||||
|
class
|
||||||
|
IRI
|
||||||
|
|
||||||
|
inherit
|
||||||
|
URI
|
||||||
|
rename
|
||||||
|
make_from_string as make_from_uri_string,
|
||||||
|
userinfo as uri_userinfo,
|
||||||
|
path as uri_path, path_segments as uri_path_segments,
|
||||||
|
query as uri_query, query_items as uri_query_items,
|
||||||
|
fragment as uri_fragment,
|
||||||
|
username_password as uri_username_password,
|
||||||
|
username as uri_username, password as uri_password,
|
||||||
|
hier as uri_hier,
|
||||||
|
authority as uri_authority,
|
||||||
|
string as uri_string
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_string,
|
||||||
|
make_from_uri
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_from_string (a_string: READABLE_STRING_GENERAL)
|
||||||
|
-- Make from Internationalized resource identifier text `a_string'
|
||||||
|
note
|
||||||
|
EIS: "name=IRI-RFC3987", "protocol=URI", "src=http://tools.ietf.org/html/rfc3987"
|
||||||
|
EIS: "name=IRI-Wikipedia", "protocol=URI", "src=http://en.wikipedia.org/wiki/Internationalized_Resource_Identifier"
|
||||||
|
local
|
||||||
|
l_uri_string: STRING_8
|
||||||
|
do
|
||||||
|
create l_uri_string.make (a_string.count)
|
||||||
|
iri_into_uri (a_string, l_uri_string)
|
||||||
|
make_from_uri_string (l_uri_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_uri (a_uri: URI)
|
||||||
|
-- Make Current Internationalized resource identifier from `uri' object
|
||||||
|
do
|
||||||
|
make_from_uri_string (a_uri.string)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
userinfo: detachable READABLE_STRING_32
|
||||||
|
-- User information.
|
||||||
|
--| username:password
|
||||||
|
--| RFC3986: userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||||
|
do
|
||||||
|
Result := to_internationalized_percent_encoded_string (uri_userinfo)
|
||||||
|
end
|
||||||
|
|
||||||
|
path: READABLE_STRING_32
|
||||||
|
-- Path component containing data, usually organized in hierarchical form.
|
||||||
|
do
|
||||||
|
Result := to_attached_internationalized_percent_encoded_string (uri_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
query: detachable READABLE_STRING_32
|
||||||
|
-- Query string.
|
||||||
|
do
|
||||||
|
Result := to_internationalized_percent_encoded_string (uri_query)
|
||||||
|
end
|
||||||
|
|
||||||
|
fragment: detachable READABLE_STRING_32
|
||||||
|
-- The fragment identifier component of a URI allows indirect
|
||||||
|
-- identification of a secondary resource by reference to a primary
|
||||||
|
-- resource and additional identifying information.
|
||||||
|
do
|
||||||
|
Result := to_internationalized_percent_encoded_string (uri_fragment)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
path_segments: LIST [READABLE_STRING_32]
|
||||||
|
-- Segments composing `path'.
|
||||||
|
do
|
||||||
|
Result := path.split ('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
query_items: detachable LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]]
|
||||||
|
-- Query items composing the `query'.
|
||||||
|
local
|
||||||
|
lst: LIST [READABLE_STRING_32]
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
if attached query as q then
|
||||||
|
lst := q.split ('&')
|
||||||
|
create {ARRAYED_LIST [like query_items.item]} Result.make (lst.count)
|
||||||
|
across
|
||||||
|
lst as e
|
||||||
|
loop
|
||||||
|
i := e.item.index_of ('=', 1)
|
||||||
|
if i > 0 then
|
||||||
|
Result.force ([e.item.substring (1, i - 1), e.item.substring (i + 1, e.item.count)])
|
||||||
|
else
|
||||||
|
Result.force ([e.item, Void])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
hier: READABLE_STRING_32
|
||||||
|
-- Hier part.
|
||||||
|
-- hier-part = "//" authority path-abempty
|
||||||
|
-- / path-absolute
|
||||||
|
-- / path-rootless
|
||||||
|
-- / path-empty
|
||||||
|
local
|
||||||
|
s: STRING_32
|
||||||
|
do
|
||||||
|
create s.make (10)
|
||||||
|
if attached authority as l_authority then
|
||||||
|
s.append_character ('/')
|
||||||
|
s.append_character ('/')
|
||||||
|
s.append (l_authority)
|
||||||
|
end
|
||||||
|
s.append (path)
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
username_password: detachable TUPLE [username: READABLE_STRING_32; password: detachable READABLE_STRING_32]
|
||||||
|
-- Username and password value extrated from `userinfo'.
|
||||||
|
--| userinfo = username:password
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
u,p: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
if attached userinfo as t then
|
||||||
|
i := t.index_of (':', 1)
|
||||||
|
if i > 0 then
|
||||||
|
p := t.substring (i + 1, t.count)
|
||||||
|
u := t.substring (1, i - 1)
|
||||||
|
else
|
||||||
|
u := t
|
||||||
|
p := Void
|
||||||
|
end
|
||||||
|
Result := [u, p]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
username: detachable READABLE_STRING_32
|
||||||
|
-- Eventual username.
|
||||||
|
do
|
||||||
|
if attached username_password as up then
|
||||||
|
Result := up.username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
password: detachable READABLE_STRING_32
|
||||||
|
-- Eventual password.
|
||||||
|
do
|
||||||
|
if attached username_password as up then
|
||||||
|
Result := up.password
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
authority: detachable READABLE_STRING_32
|
||||||
|
-- Hierarchical element for naming authority.
|
||||||
|
--| RFC3986: authority = [ userinfo "@" ] host [ ":" port ]
|
||||||
|
local
|
||||||
|
s: STRING_32
|
||||||
|
do
|
||||||
|
if attached host as h then
|
||||||
|
if attached userinfo as u then
|
||||||
|
create s.make_from_string (u)
|
||||||
|
s.append_character ('@')
|
||||||
|
s.append_string_general (h)
|
||||||
|
else
|
||||||
|
create s.make (h.count)
|
||||||
|
s.append_string_general (h)
|
||||||
|
end
|
||||||
|
if port /= 0 then
|
||||||
|
s.append_character (':')
|
||||||
|
s.append_integer (port)
|
||||||
|
end
|
||||||
|
Result := s
|
||||||
|
else
|
||||||
|
check not is_valid or else (userinfo = Void and port = 0) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
string: READABLE_STRING_32
|
||||||
|
-- String representation.
|
||||||
|
-- scheme://username:password@hostname/path?query#fragment
|
||||||
|
local
|
||||||
|
s: STRING_32
|
||||||
|
do
|
||||||
|
if attached scheme as l_scheme and then not l_scheme.is_empty then
|
||||||
|
create s.make (l_scheme.count)
|
||||||
|
s.append_string_general (l_scheme)
|
||||||
|
s.append_character (':')
|
||||||
|
else
|
||||||
|
create s.make_empty
|
||||||
|
end
|
||||||
|
s.append (hier)
|
||||||
|
if attached query as q then
|
||||||
|
s.append_character ('?')
|
||||||
|
s.append (q)
|
||||||
|
end
|
||||||
|
if attached fragment as f then
|
||||||
|
s.append_character ('#')
|
||||||
|
s.append (f)
|
||||||
|
end
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
to_uri: URI
|
||||||
|
do
|
||||||
|
create Result.make_from_string (uri_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: Internationalization
|
||||||
|
|
||||||
|
iri_into_uri (a_string: READABLE_STRING_GENERAL; a_result: STRING_8)
|
||||||
|
require
|
||||||
|
is_valid_iri: True
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: NATURAL_32
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := a_string.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
c := a_string.code (i)
|
||||||
|
if c > 0x7F then
|
||||||
|
-- extended ASCII and/or Unicode
|
||||||
|
append_percent_encoded_character_code_to (c, a_result)
|
||||||
|
-- elseif c = 37 then -- '%'
|
||||||
|
-- -- Check for %u + code
|
||||||
|
-- if i + 1 <= n then
|
||||||
|
-- c := a_string.code (i + 1)
|
||||||
|
-- if c = 85 or c = 117 then -- 85 'U' 117 'u'
|
||||||
|
-- TODO: Convert it to standard percent-encoding without %U...
|
||||||
|
-- end
|
||||||
|
-- else
|
||||||
|
-- a_result.append_code (c)
|
||||||
|
-- end
|
||||||
|
else
|
||||||
|
-- keep as it is
|
||||||
|
a_result.append_code (c)
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
to_internationalized_percent_encoded_string (s: detachable READABLE_STRING_8): detachable STRING_32
|
||||||
|
-- Convert string `s' to Internationalized Resource Identifier string
|
||||||
|
-- Result is Void if `s' is Void.
|
||||||
|
do
|
||||||
|
if s /= Void then
|
||||||
|
create Result.make (s.count)
|
||||||
|
append_percent_encoded_string_into_internationalized_percent_encoded_string (s, Result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
to_attached_internationalized_percent_encoded_string (s: READABLE_STRING_8): STRING_32
|
||||||
|
-- Convert string `s' to Internationalized Resource Identifier string
|
||||||
|
do
|
||||||
|
create Result.make (s.count)
|
||||||
|
append_percent_encoded_string_into_internationalized_percent_encoded_string (s, Result)
|
||||||
|
end
|
||||||
|
|
||||||
|
append_percent_encoded_string_into_internationalized_percent_encoded_string (v: READABLE_STRING_GENERAL; a_result: STRING_32)
|
||||||
|
-- Append to `a_result' the Internationalized URL-decoded equivalent of the given percent-encoded string `v'
|
||||||
|
-- It simply decode any percent-encoded Unicode character and kept the rest untouched
|
||||||
|
-- "http://example.com/summer/%C3%A9t%C3%A9" will be converted to IRI "http://example.com/summer/<2F>t<EFBFBD>"
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c1,
|
||||||
|
c: NATURAL_32
|
||||||
|
pr: CELL [INTEGER]
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
create pr.put (i)
|
||||||
|
n := v.count
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
c := v.code (i)
|
||||||
|
inspect c
|
||||||
|
when 43 then -- 43 '+'
|
||||||
|
-- Some implementation are replacing spaces with "+" instead of "%20"
|
||||||
|
-- Here fix this bad behavior
|
||||||
|
a_result.append_code (37) -- 37 '%'
|
||||||
|
a_result.append_code (50) -- 50 '2'
|
||||||
|
a_result.append_code (48) -- 48 '0'
|
||||||
|
when 37 then -- 37 '%%'
|
||||||
|
-- An escaped character ?
|
||||||
|
if i = n then -- Error?
|
||||||
|
a_result.append_code (c)
|
||||||
|
elseif i + 1 <= n then
|
||||||
|
c1 := v.code (i + 1)
|
||||||
|
if c1 = 85 or c1 = 117 then -- 117 'u' 85 'U'
|
||||||
|
-- %u + UTF-32 code
|
||||||
|
pr.replace (i)
|
||||||
|
c1 := next_percent_decoded_character_code (v, pr)
|
||||||
|
i := pr.item
|
||||||
|
a_result.append_code (c1)
|
||||||
|
else
|
||||||
|
pr.replace (i)
|
||||||
|
c1 := next_percent_decoded_unicode_character_code (v, pr)
|
||||||
|
if c1 > 0x7F then
|
||||||
|
a_result.append_code (c1)
|
||||||
|
i := pr.item
|
||||||
|
else
|
||||||
|
a_result.append_code (c)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
a_result.append_code (c)
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
;note
|
||||||
|
copyright: "Copyright (c) 1984-2013, 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
|
||||||
971
contrib/ise_library/text/uri/src/uri.e
Normal file
971
contrib/ise_library/text/uri/src/uri.e
Normal file
@@ -0,0 +1,971 @@
|
|||||||
|
note
|
||||||
|
description : "[
|
||||||
|
Object that represent a URI Scheme
|
||||||
|
|
||||||
|
See http://en.wikipedia.org/wiki/URI_scheme
|
||||||
|
See http://en.wikipedia.org/wiki/Uniform_resource_identifier
|
||||||
|
See http://en.wikipedia.org/wiki/Uniform_resource_locator
|
||||||
|
See http://tools.ietf.org/html/rfc3986 (URI)
|
||||||
|
|
||||||
|
Global syntax element:
|
||||||
|
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
|
pct-encoded = "%" HEXDIG HEXDIG
|
||||||
|
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||||
|
reserved = gen-delims / sub-delims
|
||||||
|
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||||
|
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
/ "*" / "+" / "," / ";" / "="
|
||||||
|
]"
|
||||||
|
date: "$Date: 2013-01-21 10:25:01 +0100 (lun., 21 janv. 2013) $"
|
||||||
|
revision: "$Revision: 90748 $"
|
||||||
|
EIS: "name=URI-RFC3986 Generic syntax", "protocol=URI", "src=http://tools.ietf.org/html/rfc3986"
|
||||||
|
EIS: "name=URI-Wikipedia", "protocol=URI", "src=http://en.wikipedia.org/wiki/URI_scheme"
|
||||||
|
EIS: "name=IRI-RFC3987", "protocol=URI", "src=http://tools.ietf.org/html/rfc3987"
|
||||||
|
EIS: "name=IRI-Wikipedia", "protocol=URI", "src=http://en.wikipedia.org/wiki/Internationalized_Resource_Identifier"
|
||||||
|
EIS: "name=Percent-encoding", "protocol=URI", "src=http://en.wikipedia.org/wiki/Percent-encoding"
|
||||||
|
|
||||||
|
EIS: "name=url-RFC1738", "protocol=URI", "src=http://tools.ietf.org/html/rfc1738"
|
||||||
|
EIS: "name=mailto-RFC2368", "protocol=URI", "src=http://tools.ietf.org/html/rfc2368"
|
||||||
|
EIS: "name=ipv6-RFC2373", "protocol=URI", "src=http://tools.ietf.org/html/rfc2373"
|
||||||
|
EIS: "name=ipv6-RFC2373 in URL", "protocol=URI", "src=http://tools.ietf.org/html/rfc2732"
|
||||||
|
|
||||||
|
class
|
||||||
|
URI
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
|
||||||
|
PERCENT_ENCODER
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_string
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_from_string (a_string: READABLE_STRING_8)
|
||||||
|
-- Parse `a_string' as a URI as specified by RFC3986
|
||||||
|
--| Note: for now the result of the parsing does not check the strict validity of each part.
|
||||||
|
--| URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
||||||
|
note
|
||||||
|
EIS: "name=Syntax Components", "protocol=URI", "src=http://tools.ietf.org/html/rfc3986#section-3"
|
||||||
|
local
|
||||||
|
p,q: INTEGER
|
||||||
|
s, t: STRING_8
|
||||||
|
do
|
||||||
|
is_valid := True
|
||||||
|
p := a_string.index_of (':', 1)
|
||||||
|
if p > 0 then
|
||||||
|
set_scheme (a_string.substring (1, p - 1))
|
||||||
|
if a_string.count > p + 1 and then a_string[p+1] = '/' and then a_string[p+2] = '/' then
|
||||||
|
--| Starts by scheme://
|
||||||
|
--| waiting for hierarchical part username:password@hostname:port
|
||||||
|
p := p + 2
|
||||||
|
q := a_string.index_of ('@', p + 1)
|
||||||
|
if q > 0 then
|
||||||
|
--| found user:passwd
|
||||||
|
t := a_string.substring (p + 1, q - 1)
|
||||||
|
set_userinfo (t)
|
||||||
|
p := q
|
||||||
|
end
|
||||||
|
q := a_string.index_of ('/', p + 1)
|
||||||
|
if q > 0 then
|
||||||
|
t := a_string.substring (p + 1, q - 1)
|
||||||
|
else
|
||||||
|
q := a_string.count
|
||||||
|
t := a_string.substring (p + 1, q)
|
||||||
|
q := 0 --| end of processing
|
||||||
|
end
|
||||||
|
if not t.is_empty and then t[1] = '[' then
|
||||||
|
p := t.index_of (']', 2)
|
||||||
|
if p > 0 then
|
||||||
|
p := t.index_of (':', p + 1)
|
||||||
|
else
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
else
|
||||||
|
p := t.index_of (':', 1)
|
||||||
|
end
|
||||||
|
if p > 0 then
|
||||||
|
set_hostname (t.substring (1, p - 1))
|
||||||
|
t.remove_head (p)
|
||||||
|
if t.is_integer then
|
||||||
|
set_port (t.to_integer)
|
||||||
|
else
|
||||||
|
set_port (0)
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set_hostname (t)
|
||||||
|
set_port (0)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--| Keep eventual '/' as part of the path
|
||||||
|
q := p + 1
|
||||||
|
set_hostname (Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
if q > 0 and q <= a_string.count then
|
||||||
|
--| found query
|
||||||
|
t := a_string.substring (q, a_string.count)
|
||||||
|
q := t.index_of ('?', 1)
|
||||||
|
if q > 0 then
|
||||||
|
s := t.substring (1, q - 1)
|
||||||
|
if is_valid_in_uri_string (s) then
|
||||||
|
set_path (s)
|
||||||
|
else
|
||||||
|
set_path ("")
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
t.remove_head (q)
|
||||||
|
q := t.index_of ('#', 1)
|
||||||
|
if q > 0 then
|
||||||
|
set_query (t.substring (1, q - 1))
|
||||||
|
t.remove_head (q)
|
||||||
|
set_fragment (t)
|
||||||
|
else
|
||||||
|
set_query (t)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if is_valid_in_uri_string (t) then
|
||||||
|
set_path (t)
|
||||||
|
else
|
||||||
|
set_path ("")
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set_path ("")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set_scheme ("")
|
||||||
|
set_hostname (Void)
|
||||||
|
set_path ("")
|
||||||
|
end
|
||||||
|
if is_valid then
|
||||||
|
check_validity (True)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
same_if_valid: is_valid and not is_corrected implies a_string.starts_with (string)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Basic operation
|
||||||
|
|
||||||
|
check_validity (a_fixing: BOOLEAN)
|
||||||
|
-- Check validity of URI
|
||||||
|
-- If `a_fixing' is True, attempt to correct input URI.
|
||||||
|
local
|
||||||
|
s: STRING_8
|
||||||
|
do
|
||||||
|
-- check scheme
|
||||||
|
-- TODO: RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||||
|
if not is_valid_scheme (scheme) then
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check userinfo
|
||||||
|
-- TODO: RFC3986: userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||||
|
if not is_valid_userinfo (userinfo) then
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check host
|
||||||
|
-- TODO: RFC3986: host = IP-literal / IPv4address / reg-name
|
||||||
|
if not is_valid_host (host) then
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check path
|
||||||
|
-- TODO: no space, all character well escaped, ...
|
||||||
|
if path.has (' ') then
|
||||||
|
-- Fix bad URI
|
||||||
|
if a_fixing then
|
||||||
|
create s.make_from_string (path)
|
||||||
|
s.replace_substring_all (" ", "%%20")
|
||||||
|
set_path (s)
|
||||||
|
is_corrected := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not is_valid_path (path) then
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check query
|
||||||
|
-- TODO: no space, all character well escaped, ...
|
||||||
|
if attached query as q then
|
||||||
|
if q.has (' ') then
|
||||||
|
-- Fix bad URI
|
||||||
|
if a_fixing then
|
||||||
|
create s.make_from_string (q)
|
||||||
|
s.replace_substring_all (" ", "%%20")
|
||||||
|
set_query (s)
|
||||||
|
is_corrected := True
|
||||||
|
else
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not is_valid_query (query) then
|
||||||
|
is_valid := True
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check fragment
|
||||||
|
if not is_valid_fragment (fragment) then
|
||||||
|
is_valid := False
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status
|
||||||
|
|
||||||
|
is_valid: BOOLEAN
|
||||||
|
-- Is Current valid?
|
||||||
|
|
||||||
|
is_corrected: BOOLEAN
|
||||||
|
-- Is Current valid after eventual correction?
|
||||||
|
|
||||||
|
has_authority: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := host /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
has_query: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := query /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
has_path: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := not path.is_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
has_fragment: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := fragment /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
scheme: IMMUTABLE_STRING_8
|
||||||
|
-- Scheme name.
|
||||||
|
--| scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||||
|
|
||||||
|
userinfo: detachable IMMUTABLE_STRING_8
|
||||||
|
-- User information.
|
||||||
|
--| username:password
|
||||||
|
--| RFC3986: userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||||
|
|
||||||
|
host: detachable IMMUTABLE_STRING_8
|
||||||
|
-- Host name.
|
||||||
|
--| RFC3986: host = IP-literal / IPv4address / reg-name
|
||||||
|
|
||||||
|
port: INTEGER
|
||||||
|
-- Associated port, if `0' this is not defined.
|
||||||
|
-- RFC3986: port = *DIGIT
|
||||||
|
|
||||||
|
path: IMMUTABLE_STRING_8
|
||||||
|
-- Path component containing data, usually organized in hierarchical form.
|
||||||
|
|
||||||
|
query: detachable IMMUTABLE_STRING_8
|
||||||
|
-- Query string.
|
||||||
|
|
||||||
|
fragment: detachable IMMUTABLE_STRING_8
|
||||||
|
-- The fragment identifier component of a URI allows indirect
|
||||||
|
-- identification of a secondary resource by reference to a primary
|
||||||
|
-- resource and additional identifying information.
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
decoded_path: READABLE_STRING_32
|
||||||
|
-- Decoded `path'
|
||||||
|
local
|
||||||
|
s: STRING_32
|
||||||
|
do
|
||||||
|
create s.make (path.count)
|
||||||
|
append_decoded_www_form_urlencoded_string_to (path, s)
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
path_segments: LIST [READABLE_STRING_8]
|
||||||
|
-- Segments composing `path'.
|
||||||
|
do
|
||||||
|
Result := path.split ('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
decoded_path_segments: LIST [READABLE_STRING_32]
|
||||||
|
-- Decoded Segments composing `path'.
|
||||||
|
local
|
||||||
|
lst: like path_segments
|
||||||
|
do
|
||||||
|
lst := path_segments
|
||||||
|
create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (lst.count)
|
||||||
|
across
|
||||||
|
lst as e
|
||||||
|
loop
|
||||||
|
Result.force (decoded_www_form_urlencoded_string (e.item))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
query_items: detachable LIST [TUPLE [name: READABLE_STRING_8; value: detachable READABLE_STRING_8]]
|
||||||
|
-- Query items composing the `query'.
|
||||||
|
local
|
||||||
|
lst: LIST [READABLE_STRING_8]
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
if attached query as q then
|
||||||
|
lst := q.split ('&')
|
||||||
|
create {ARRAYED_LIST [like query_items.item]} Result.make (lst.count)
|
||||||
|
across
|
||||||
|
lst as e
|
||||||
|
loop
|
||||||
|
i := e.item.index_of ('=', 1)
|
||||||
|
if i > 0 then
|
||||||
|
Result.force ([e.item.substring (1, i - 1), e.item.substring (i + 1, e.item.count)])
|
||||||
|
else
|
||||||
|
Result.force ([e.item, Void])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
decoded_query_items: detachable LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]]
|
||||||
|
-- Decoded query items composing the `query'.
|
||||||
|
do
|
||||||
|
if attached query_items as lst then
|
||||||
|
create {ARRAYED_LIST [like decoded_query_items.item]} Result.make (lst.count)
|
||||||
|
across
|
||||||
|
lst as e
|
||||||
|
loop
|
||||||
|
if attached e.item.value as l_val then
|
||||||
|
Result.force ([decoded_www_form_urlencoded_string (e.item.name), decoded_www_form_urlencoded_string (l_val)])
|
||||||
|
else
|
||||||
|
Result.force ([decoded_www_form_urlencoded_string (e.item.name), Void])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
hier: READABLE_STRING_8
|
||||||
|
-- Hier part.
|
||||||
|
-- hier-part = "//" authority path-abempty
|
||||||
|
-- / path-absolute
|
||||||
|
-- / path-rootless
|
||||||
|
-- / path-empty
|
||||||
|
local
|
||||||
|
s: STRING_8
|
||||||
|
do
|
||||||
|
create s.make (10)
|
||||||
|
if attached authority as l_authority then
|
||||||
|
s.append_character ('/')
|
||||||
|
s.append_character ('/')
|
||||||
|
s.append (l_authority)
|
||||||
|
end
|
||||||
|
s.append (path)
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
username_password: detachable TUPLE [username: READABLE_STRING_8; password: detachable READABLE_STRING_8]
|
||||||
|
-- Username and password value extrated from `userinfo'.
|
||||||
|
--| userinfo = username:password
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
u,p: detachable READABLE_STRING_8
|
||||||
|
do
|
||||||
|
if attached userinfo as t then
|
||||||
|
i := t.index_of (':', 1)
|
||||||
|
if i > 0 then
|
||||||
|
p := t.substring (i + 1, t.count)
|
||||||
|
u := t.substring (1, i - 1)
|
||||||
|
else
|
||||||
|
u := t
|
||||||
|
p := Void
|
||||||
|
end
|
||||||
|
Result := [u, p]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
username: detachable READABLE_STRING_8
|
||||||
|
-- Eventual username.
|
||||||
|
do
|
||||||
|
if attached username_password as up then
|
||||||
|
Result := up.username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
password: detachable READABLE_STRING_8
|
||||||
|
-- Eventual password.
|
||||||
|
do
|
||||||
|
if attached username_password as up then
|
||||||
|
Result := up.password
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
authority: detachable READABLE_STRING_8
|
||||||
|
-- Hierarchical element for naming authority.
|
||||||
|
--| RFC3986: authority = [ userinfo "@" ] host [ ":" port ]
|
||||||
|
local
|
||||||
|
s: STRING_8
|
||||||
|
do
|
||||||
|
if attached host as h then
|
||||||
|
if attached userinfo as u then
|
||||||
|
create s.make_from_string (u)
|
||||||
|
s.append_character ('@')
|
||||||
|
s.append (h)
|
||||||
|
else
|
||||||
|
create s.make_from_string (h)
|
||||||
|
end
|
||||||
|
if port /= 0 then
|
||||||
|
s.append_character (':')
|
||||||
|
s.append_integer (port)
|
||||||
|
end
|
||||||
|
Result := s
|
||||||
|
else
|
||||||
|
check not is_valid or else (userinfo = Void and port = 0) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
string: READABLE_STRING_8
|
||||||
|
-- String representation.
|
||||||
|
-- scheme://username:password@hostname/path?query#fragment
|
||||||
|
local
|
||||||
|
s: STRING_8
|
||||||
|
do
|
||||||
|
if attached scheme as l_scheme and then not l_scheme.is_empty then
|
||||||
|
create s.make_from_string (l_scheme)
|
||||||
|
s.append_character (':')
|
||||||
|
else
|
||||||
|
create s.make_empty
|
||||||
|
end
|
||||||
|
s.append (hier)
|
||||||
|
if attached query as q then
|
||||||
|
s.append_character ('?')
|
||||||
|
s.append (q)
|
||||||
|
end
|
||||||
|
if attached fragment as f then
|
||||||
|
s.append_character ('#')
|
||||||
|
s.append (f)
|
||||||
|
end
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
resolved_uri: URI
|
||||||
|
-- Resolved URI, i.e remove segment-component from `path'
|
||||||
|
local
|
||||||
|
p: STRING_8
|
||||||
|
lst: like path_segments
|
||||||
|
l_first: BOOLEAN
|
||||||
|
do
|
||||||
|
from
|
||||||
|
lst := path_segments
|
||||||
|
lst.start
|
||||||
|
until
|
||||||
|
lst.off
|
||||||
|
loop
|
||||||
|
if lst.item.same_string (".") then
|
||||||
|
lst.remove
|
||||||
|
elseif lst.item.same_string ("..") then
|
||||||
|
lst.back
|
||||||
|
if not lst.before then
|
||||||
|
lst.remove
|
||||||
|
lst.remove
|
||||||
|
else
|
||||||
|
lst.forth
|
||||||
|
lst.remove
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lst.forth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
create p.make (path.count)
|
||||||
|
l_first := True
|
||||||
|
across
|
||||||
|
lst as c
|
||||||
|
loop
|
||||||
|
if l_first then
|
||||||
|
l_first := False
|
||||||
|
else
|
||||||
|
p.append_character ('/')
|
||||||
|
end
|
||||||
|
p.append (c.item)
|
||||||
|
end
|
||||||
|
if p.is_empty then
|
||||||
|
else
|
||||||
|
if p.item (1) /= '/' then
|
||||||
|
if not path.is_empty and then path.item (1) = '/' then
|
||||||
|
p.prepend_character ('/')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
create Result.make_from_string (string)
|
||||||
|
Result.set_path (p)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Comparison
|
||||||
|
|
||||||
|
is_same_uri (a_uri: URI): BOOLEAN
|
||||||
|
-- Is `a_uri' same as Current ?
|
||||||
|
--| See http://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_unreserved_characters
|
||||||
|
do
|
||||||
|
Result := decoded_www_form_urlencoded_string (string).same_string (decoded_www_form_urlencoded_string (a_uri.string))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element Change
|
||||||
|
|
||||||
|
set_scheme (v: READABLE_STRING_8)
|
||||||
|
-- Set `scheme' to `v'
|
||||||
|
require
|
||||||
|
is_valid_scheme (v)
|
||||||
|
do
|
||||||
|
create scheme.make_from_string (v)
|
||||||
|
ensure
|
||||||
|
scheme_set: scheme.same_string (v)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_userinfo (v: detachable READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
is_valid_userinfo (v)
|
||||||
|
do
|
||||||
|
if v = Void then
|
||||||
|
userinfo := Void
|
||||||
|
else
|
||||||
|
create userinfo.make_from_string (v.as_string_8)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
userinfo_set: is_same_string (v, userinfo)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_hostname (v: detachable READABLE_STRING_8)
|
||||||
|
-- Set `host' to `v'
|
||||||
|
require
|
||||||
|
is_valid_host (v)
|
||||||
|
do
|
||||||
|
if v = Void then
|
||||||
|
host := Void
|
||||||
|
else
|
||||||
|
create host.make_from_string (v)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
hostname_set: is_same_string (v, host)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_port (v: like port)
|
||||||
|
-- Set `port' to `v'
|
||||||
|
do
|
||||||
|
port := v
|
||||||
|
ensure
|
||||||
|
port_set: port = v
|
||||||
|
end
|
||||||
|
|
||||||
|
set_path (a_path: READABLE_STRING_8)
|
||||||
|
-- Set `path' to `a_path'
|
||||||
|
require
|
||||||
|
is_valid_path (a_path)
|
||||||
|
do
|
||||||
|
create path.make_from_string (a_path)
|
||||||
|
ensure
|
||||||
|
path_set: path.same_string_general (a_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_query (v: detachable READABLE_STRING_8)
|
||||||
|
-- Set `query' to `v'
|
||||||
|
require
|
||||||
|
is_valid_query (v)
|
||||||
|
do
|
||||||
|
if v = Void then
|
||||||
|
query := Void
|
||||||
|
else
|
||||||
|
create query.make_from_string (v)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
query_set: is_same_string (v, query)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_fragment (v: detachable READABLE_STRING_8)
|
||||||
|
-- Set `fragment' to `v'
|
||||||
|
require
|
||||||
|
is_valid_fragment (v)
|
||||||
|
do
|
||||||
|
if v = Void then
|
||||||
|
fragment := Void
|
||||||
|
else
|
||||||
|
create fragment.make_from_string (v)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
fragment_set: is_same_string (v, fragment)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change: query
|
||||||
|
|
||||||
|
remove_query
|
||||||
|
-- Remove query from Current URI
|
||||||
|
do
|
||||||
|
query := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
add_query_parameter (a_name: READABLE_STRING_GENERAL; a_value: detachable READABLE_STRING_GENERAL)
|
||||||
|
-- Add non percent-encoded parameters
|
||||||
|
local
|
||||||
|
q: detachable STRING
|
||||||
|
do
|
||||||
|
if attached query as l_query then
|
||||||
|
create q.make_from_string (l_query)
|
||||||
|
else
|
||||||
|
create q.make_empty
|
||||||
|
end
|
||||||
|
if not q.is_empty then
|
||||||
|
q.append_character ('&')
|
||||||
|
end
|
||||||
|
|
||||||
|
q.append (www_form_urlencoded_string (a_name))
|
||||||
|
if a_value /= Void then
|
||||||
|
q.append_character ('=')
|
||||||
|
q.append (www_form_urlencoded_string (a_value))
|
||||||
|
end
|
||||||
|
create query.make_from_string (q)
|
||||||
|
end
|
||||||
|
|
||||||
|
add_query_parameters (lst: ITERABLE [TUPLE [name: READABLE_STRING_GENERAL; value: detachable READABLE_STRING_GENERAL]])
|
||||||
|
-- Add non percent-encoded parameters from manifest
|
||||||
|
do
|
||||||
|
across
|
||||||
|
lst as c
|
||||||
|
loop
|
||||||
|
add_query_parameter (c.item.name, c.item.value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
add_query_parameters_from_table (tb: TABLE_ITERABLE [detachable READABLE_STRING_GENERAL, READABLE_STRING_GENERAL])
|
||||||
|
-- Add non percent-encoded parameters from table
|
||||||
|
do
|
||||||
|
across
|
||||||
|
tb as c
|
||||||
|
loop
|
||||||
|
add_query_parameter (c.key, c.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_valid_scheme (s: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: CHARACTER_32
|
||||||
|
do
|
||||||
|
if s.is_empty then
|
||||||
|
Result := False -- Check for URI-reference ..
|
||||||
|
else
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
Result := is_alpha_character (string_item (s, i))
|
||||||
|
i := 2
|
||||||
|
until
|
||||||
|
not Result or i > n
|
||||||
|
loop
|
||||||
|
c := string_item (s, i)
|
||||||
|
Result := is_alpha_or_digit_character (c) or c = '+' or c = '-' or c = '.'
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_userinfo (s: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: CHARACTER_32
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
if s /= Void then
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
not Result or i > n
|
||||||
|
loop
|
||||||
|
c := string_item (s, i)
|
||||||
|
-- unreserved
|
||||||
|
if is_unreserved_character (c)
|
||||||
|
or is_sub_delims_character (c)
|
||||||
|
or c = ':'
|
||||||
|
then
|
||||||
|
-- True
|
||||||
|
elseif c = '%%' then
|
||||||
|
if
|
||||||
|
i + 2 <= n and then
|
||||||
|
is_hexa_decimal_character (string_item (s, i+ 1)) and is_hexa_decimal_character (string_item (s, i + 2))
|
||||||
|
then
|
||||||
|
-- True
|
||||||
|
i := i + 2
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_host (s: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- host = IP-literal / IPv4address / reg-name
|
||||||
|
-- IP-literal = "[" ( IPv6address / IPvFuture ) "]"
|
||||||
|
-- IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
|
||||||
|
-- IPv6address = 6( h16 ":" ) ls32
|
||||||
|
-- / "::" 5( h16 ":" ) ls32
|
||||||
|
-- / [ h16 ] "::" 4( h16 ":" ) ls32
|
||||||
|
-- / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
|
||||||
|
-- / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
|
||||||
|
-- / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
|
||||||
|
-- / [ *4( h16 ":" ) h16 ] "::" ls32
|
||||||
|
-- / [ *5( h16 ":" ) h16 ] "::" h16
|
||||||
|
-- / [ *6( h16 ":" ) h16 ] "::"
|
||||||
|
--
|
||||||
|
-- ls32 = ( h16 ":" h16 ) / IPv4address
|
||||||
|
-- ; least-significant 32 bits of address
|
||||||
|
--
|
||||||
|
-- h16 = 1*4HEXDIG
|
||||||
|
-- ; 16 bits of address represented in hexadecimal
|
||||||
|
--
|
||||||
|
-- IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
|
||||||
|
--
|
||||||
|
-- dec-octet = DIGIT ; 0-9
|
||||||
|
-- / %x31-39 DIGIT ; 10-99
|
||||||
|
-- / "1" 2DIGIT ; 100-199
|
||||||
|
-- / "2" %x30-34 DIGIT ; 200-249
|
||||||
|
-- / "25" %x30-35 ; 250-255
|
||||||
|
--
|
||||||
|
-- reg-name = *( unreserved / pct-encoded / sub-delims )
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
if s /= Void and then not s.is_empty then
|
||||||
|
if string_item (s, 1) = '[' and string_item (s, s.count) = ']' then
|
||||||
|
Result := True -- IPV6 : to complete
|
||||||
|
else
|
||||||
|
Result := is_hexa_decimal_character (string_item (s, 1)) -- IPV4 or reg-name : to complete
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_path (s: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- path = path-abempty ; begins with "/" or is empty
|
||||||
|
-- / path-absolute ; begins with "/" but not "//"
|
||||||
|
-- / path-noscheme ; begins with a non-colon segment
|
||||||
|
-- / path-rootless ; begins with a segment
|
||||||
|
-- / path-empty ; zero characters
|
||||||
|
--
|
||||||
|
-- path-abempty = *( "/" segment )
|
||||||
|
-- path-absolute = "/" [ segment-nz *( "/" segment ) ]
|
||||||
|
-- path-noscheme = segment-nz-nc *( "/" segment )
|
||||||
|
-- path-rootless = segment-nz *( "/" segment )
|
||||||
|
-- path-empty = 0<pchar>
|
||||||
|
-- segment = *pchar
|
||||||
|
-- segment-nz = 1*pchar
|
||||||
|
-- segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
|
||||||
|
-- ; non-zero-length segment without any colon ":"
|
||||||
|
--
|
||||||
|
-- pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
|
do
|
||||||
|
if s.is_empty or string_item (s, 1) = '/' then
|
||||||
|
Result := is_valid_in_uri_string (s)
|
||||||
|
elseif has_authority then
|
||||||
|
if string_item (s, 1) = '/' and (s.count > 1 implies string_item (s, 2) /= '/') then
|
||||||
|
Result := is_valid_in_uri_string (s)
|
||||||
|
end
|
||||||
|
elseif s.is_empty then
|
||||||
|
Result := True
|
||||||
|
else
|
||||||
|
Result := is_valid_in_uri_string (s)
|
||||||
|
end
|
||||||
|
-- TO COMPLETE
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_query (s: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- query = *( pchar / "/" / "?" )
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: CHARACTER_32
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
if s /= Void then
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
not Result or i > n
|
||||||
|
loop
|
||||||
|
c := string_item (s, i)
|
||||||
|
-- pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
|
if -- pchar
|
||||||
|
is_unreserved_character (c)
|
||||||
|
or is_sub_delims_character (c)
|
||||||
|
or c = ':' or c = '@'
|
||||||
|
then
|
||||||
|
Result := True
|
||||||
|
elseif c = '/' or c = '?' then
|
||||||
|
Result := True
|
||||||
|
elseif c = '%%' then
|
||||||
|
if
|
||||||
|
i + 2 <= n and then
|
||||||
|
is_hexa_decimal_character (string_item (s, i + 1)) and is_hexa_decimal_character (string_item (s, i + 2))
|
||||||
|
then
|
||||||
|
-- True
|
||||||
|
i := i + 2
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_valid_fragment (s: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
--fragment = *( pchar / "/" / "?" )
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
c: CHARACTER_32
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
if s /= Void then
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
not Result or i > n
|
||||||
|
loop
|
||||||
|
c := string_item (s, i)
|
||||||
|
-- pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||||
|
if -- pchar
|
||||||
|
is_unreserved_character (c)
|
||||||
|
or is_sub_delims_character (c)
|
||||||
|
or c = ':' or c = '@'
|
||||||
|
then
|
||||||
|
Result := True
|
||||||
|
elseif c = '/' or c = '?' then
|
||||||
|
Result := True
|
||||||
|
elseif c = '%%' then
|
||||||
|
if
|
||||||
|
i + 2 <= n and then
|
||||||
|
is_alpha_or_digit_character (string_item (s, i + 1)) and is_alpha_or_digit_character (string_item (s, i + 2))
|
||||||
|
then
|
||||||
|
i := i + 2
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Helper
|
||||||
|
|
||||||
|
string_item (s: READABLE_STRING_GENERAL; i: INTEGER): CHARACTER_32
|
||||||
|
do
|
||||||
|
Result := s.code (i).to_character_32
|
||||||
|
end
|
||||||
|
|
||||||
|
append_www_form_urlencoded_string_to (a_string: READABLE_STRING_GENERAL; a_target: STRING_GENERAL)
|
||||||
|
-- The application/x-www-form-urlencoded encoded string for `a_string'.
|
||||||
|
-- character encoding is UTF-8.
|
||||||
|
-- See http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
||||||
|
do
|
||||||
|
append_percent_encoded_string_to (a_string, a_target)
|
||||||
|
end
|
||||||
|
|
||||||
|
www_form_urlencoded_string (a_string: READABLE_STRING_GENERAL): STRING_8
|
||||||
|
-- The application/x-www-form-urlencoded encoded string for `a_string'.
|
||||||
|
-- character encoding is UTF-8.
|
||||||
|
-- See http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
||||||
|
do
|
||||||
|
create Result.make (a_string.count)
|
||||||
|
append_percent_encoded_string_to (a_string, Result)
|
||||||
|
end
|
||||||
|
|
||||||
|
append_decoded_www_form_urlencoded_string_to (a_string: READABLE_STRING_GENERAL; a_target: STRING_GENERAL)
|
||||||
|
-- The string decoded from application/x-www-form-urlencoded encoded string `a_string'.
|
||||||
|
-- character encoding is UTF-8.
|
||||||
|
-- See http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
||||||
|
do
|
||||||
|
append_percent_decoded_string_to (a_string, a_target)
|
||||||
|
end
|
||||||
|
|
||||||
|
decoded_www_form_urlencoded_string (a_string: READABLE_STRING_GENERAL): STRING_32
|
||||||
|
-- The string decoded from application/x-www-form-urlencoded encoded string `a_string'.
|
||||||
|
-- character encoding is UTF-8.
|
||||||
|
-- See http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
||||||
|
do
|
||||||
|
create Result.make (a_string.count)
|
||||||
|
append_percent_decoded_string_to (a_string, Result)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Assertion helper
|
||||||
|
|
||||||
|
is_valid_in_uri_string (s: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- Is `s' composed only of ASCII character?
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
do
|
||||||
|
from
|
||||||
|
Result := True
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
not Result or i > n
|
||||||
|
loop
|
||||||
|
if s.code (i) > 0x7F then
|
||||||
|
Result := False
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_same_string (s1, s2: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
-- `s1' and `s2' have same string content?
|
||||||
|
do
|
||||||
|
if s1 = Void then
|
||||||
|
Result := s2 = Void
|
||||||
|
elseif s2 = Void then
|
||||||
|
Result := False
|
||||||
|
else
|
||||||
|
Result := s1.same_string (s2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
debug_output: STRING
|
||||||
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
|
local
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
create s.make_empty
|
||||||
|
s.append (string)
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
|
||||||
|
;note
|
||||||
|
copyright: "Copyright (c) 1984-2013, 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
contrib/ise_library/text/uri/uri-safe.ecf
Normal file
17
contrib/ise_library/text/uri/uri-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-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="uri" uuid="C83EA64A-F823-4A1C-A38E-138EDB142F52" library_target="uri">
|
||||||
|
<target name="uri">
|
||||||
|
<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" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<cluster name="src" location=".\src\">
|
||||||
|
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
17
contrib/ise_library/text/uri/uri.ecf
Normal file
17
contrib/ise_library/text/uri/uri.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="uri" uuid="C83EA64A-F823-4A1C-A38E-138EDB142F52" library_target="uri">
|
||||||
|
<target name="uri">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/.git$</exclude>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
|
||||||
|
<cluster name="src" location=".\src\">
|
||||||
|
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||||
|
</cluster>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -86,13 +86,13 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
if l_openid_mode.same_string ("id_res") then
|
if l_openid_mode.same_string ("id_res") then
|
||||||
o := new_openid_consumer (req)
|
o := new_openid_consumer (req)
|
||||||
create v.make_from_string (o, req.absolute_script_url (req.request_uri))
|
create v.make_from_items (o, req.items_as_string_items)
|
||||||
v.validate
|
v.validate
|
||||||
if v.is_valid then
|
if v.is_valid then
|
||||||
s.append ("<div>User authenticated</div>")
|
s.append ("<div>User authenticated</div>")
|
||||||
s.append ("<ul>Query")
|
s.append ("<ul>Request items")
|
||||||
across
|
across
|
||||||
req.query_parameters as c
|
req.items as c
|
||||||
loop
|
loop
|
||||||
s.append ("<li>" + c.item.url_encoded_name + "=" + c.item.string_representation + "</li>")
|
s.append ("<li>" + c.item.url_encoded_name + "=" + c.item.string_representation + "</li>")
|
||||||
end
|
end
|
||||||
@@ -140,9 +140,10 @@ feature {NONE} -- Initialization
|
|||||||
do
|
do
|
||||||
create Result.make (req.absolute_script_url ("/openid"))
|
create Result.make (req.absolute_script_url ("/openid"))
|
||||||
|
|
||||||
-- Result.ask_email (True)
|
Result.ask_email (True)
|
||||||
Result.ask_nickname (False)
|
Result.ask_all_info (False)
|
||||||
|
-- Result.ask_nickname (False)
|
||||||
-- Result.ask_fullname (False)
|
-- Result.ask_fullname (False)
|
||||||
Result.ask_country (True)
|
-- Result.ask_country (True)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
</option>
|
</option>
|
||||||
<setting name="concurrency" value="thread"/>
|
<setting name="concurrency" value="thread"/>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="http" location="..\..\..\..\..\..\library\network\protocol\http\http-safe.ecf"/>
|
|
||||||
<library name="wsf_nino_connector" location="..\..\..\..\..\..\library\server\wsf\connector\nino-safe.ecf" readonly="false"/>
|
|
||||||
<library name="ewsgi" location="..\..\..\..\..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
<library name="ewsgi" location="..\..\..\..\..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
||||||
<library name="ewsgi_nino_connector" location="..\..\..\..\..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
<library name="ewsgi_nino_connector" location="..\..\..\..\..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||||
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
|
<library name="http" location="..\..\..\..\..\..\library\network\protocol\http\http-safe.ecf"/>
|
||||||
<library name="openid" location="../openid-safe.ecf" readonly="false"/>
|
<library name="openid" location="..\openid-safe.ecf" readonly="false"/>
|
||||||
|
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
|
||||||
|
<library name="wsf_nino_connector" location="..\..\..\..\..\..\library\server\wsf\connector\nino-safe.ecf" readonly="false"/>
|
||||||
<cluster name="src" location=".\" recursive="true"/>
|
<cluster name="src" location=".\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ feature -- Change
|
|||||||
across
|
across
|
||||||
ax_to_sreg_map as c
|
ax_to_sreg_map as c
|
||||||
loop
|
loop
|
||||||
ask_info (c.item, is_required)
|
ask_info (c.key.to_string_32, is_required)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ feature {OPENID_CONSUMER_VALIDATION} -- Implementation
|
|||||||
|
|
||||||
discovering_info (id: READABLE_STRING_8): detachable OPENID_DISCOVER
|
discovering_info (id: READABLE_STRING_8): detachable OPENID_DISCOVER
|
||||||
local
|
local
|
||||||
cl: LIBCURL_HTTP_CLIENT
|
|
||||||
sess: HTTP_CLIENT_SESSION
|
sess: HTTP_CLIENT_SESSION
|
||||||
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
||||||
xrds_location: detachable READABLE_STRING_8
|
xrds_location: detachable READABLE_STRING_8
|
||||||
@@ -148,18 +148,17 @@ feature {OPENID_CONSUMER_VALIDATION} -- Implementation
|
|||||||
r_version: INTEGER
|
r_version: INTEGER
|
||||||
l_xrds_content: detachable READABLE_STRING_8
|
l_xrds_content: detachable READABLE_STRING_8
|
||||||
do
|
do
|
||||||
create cl.make
|
sess := new_session (id)
|
||||||
sess := cl.new_session (id)
|
if attached sess.head ("", ctx) as rep then
|
||||||
sess.set_is_insecure (True)
|
|
||||||
if attached sess.get ("", ctx) as rep then
|
|
||||||
if rep.error_occurred then
|
if rep.error_occurred then
|
||||||
report_error ("Unable get answer from openid provider at " + rep.url)
|
report_error ("Unable get answer from openid provider at " + rep.url)
|
||||||
else
|
else
|
||||||
if
|
if
|
||||||
attached rep.header ("Content-Type") as l_content_type and then
|
attached rep.header ("Content-Type") as l_content_type and then
|
||||||
l_content_type.has_substring ("application/xrds+xml")
|
l_content_type.has_substring ("application/xrds+xml") and then
|
||||||
|
attached sess.get ("", ctx) as l_getres
|
||||||
then
|
then
|
||||||
l_xrds_content := rep.body
|
l_xrds_content := l_getres.body
|
||||||
elseif attached rep.header ("X-XRDS-Location") as loc then
|
elseif attached rep.header ("X-XRDS-Location") as loc then
|
||||||
xrds_location := loc
|
xrds_location := loc
|
||||||
else
|
else
|
||||||
@@ -168,8 +167,7 @@ feature {OPENID_CONSUMER_VALIDATION} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if l_xrds_content = Void and xrds_location /= Void then
|
if l_xrds_content = Void and xrds_location /= Void then
|
||||||
sess := cl.new_session (xrds_location)
|
sess := new_session (xrds_location)
|
||||||
sess.set_is_insecure (True)
|
|
||||||
if attached sess.get ("", ctx) as rep then
|
if attached sess.get ("", ctx) as rep then
|
||||||
if rep.error_occurred then
|
if rep.error_occurred then
|
||||||
r_err := True
|
r_err := True
|
||||||
@@ -256,7 +254,6 @@ feature {OPENID_CONSUMER_VALIDATION} -- Implementation
|
|||||||
Result.sreg_supported := r_sreg_supported
|
Result.sreg_supported := r_sreg_supported
|
||||||
Result.identifier_select := r_identifier_select
|
Result.identifier_select := r_identifier_select
|
||||||
Result.has_error := r_err
|
Result.has_error := r_err
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -457,9 +454,9 @@ feature {NONE} -- Implementation
|
|||||||
Result.force ("language", "pref/language")
|
Result.force ("language", "pref/language")
|
||||||
Result.force ("timezone", "pref/timezone")
|
Result.force ("timezone", "pref/timezone")
|
||||||
|
|
||||||
-- extension
|
-- -- extension
|
||||||
Result.force ("firstname", "namePerson/first")
|
-- Result.force ("firstname", "namePerson/first")
|
||||||
Result.force ("lastname", "namePerson/last")
|
-- Result.force ("lastname", "namePerson/last")
|
||||||
end
|
end
|
||||||
|
|
||||||
ax_to_sreg (n: READABLE_STRING_8): detachable READABLE_STRING_8
|
ax_to_sreg (n: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
@@ -495,6 +492,8 @@ feature {NONE} -- Implementation
|
|||||||
has_error
|
has_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Helper
|
||||||
|
|
||||||
xml_content (e: XML_ELEMENT): STRING_8
|
xml_content (e: XML_ELEMENT): STRING_8
|
||||||
do
|
do
|
||||||
create Result.make_empty
|
create Result.make_empty
|
||||||
@@ -507,4 +506,15 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
new_session (a_uri: READABLE_STRING_8): HTTP_CLIENT_SESSION
|
||||||
|
local
|
||||||
|
cl: LIBCURL_HTTP_CLIENT
|
||||||
|
do
|
||||||
|
create cl.make
|
||||||
|
Result := cl.new_session (a_uri)
|
||||||
|
Result.set_is_insecure (True)
|
||||||
|
Result.set_max_redirects (5)
|
||||||
|
Result.add_header ("Accept", "application/xrds+xml, */*")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,25 +8,19 @@ class
|
|||||||
OPENID_CONSUMER_VALIDATION
|
OPENID_CONSUMER_VALIDATION
|
||||||
|
|
||||||
create
|
create
|
||||||
make_from_uri,
|
make_from_items
|
||||||
make_from_string
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make_from_uri (o: OPENID_CONSUMER; a_uri: URI)
|
make_from_items (o: OPENID_CONSUMER; lst: like values)
|
||||||
do
|
do
|
||||||
openid := o
|
openid := o
|
||||||
uri := a_uri
|
values := lst
|
||||||
return_url := o.return_url
|
return_url := o.return_url
|
||||||
create attributes.make (0)
|
create attributes.make (0)
|
||||||
end
|
end
|
||||||
|
|
||||||
make_from_string (o: OPENID_CONSUMER; a_uri: READABLE_STRING_8)
|
values: detachable ITERABLE [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]]
|
||||||
do
|
|
||||||
make_from_uri (o, create {URI}.make_from_string (a_uri))
|
|
||||||
end
|
|
||||||
|
|
||||||
uri: URI
|
|
||||||
|
|
||||||
return_url: READABLE_STRING_8
|
return_url: READABLE_STRING_8
|
||||||
|
|
||||||
@@ -45,7 +39,6 @@ feature -- Basic operation
|
|||||||
local
|
local
|
||||||
l_claimed_id: detachable READABLE_STRING_8
|
l_claimed_id: detachable READABLE_STRING_8
|
||||||
tb: STRING_TABLE [detachable READABLE_STRING_32]
|
tb: STRING_TABLE [detachable READABLE_STRING_32]
|
||||||
cl: LIBCURL_HTTP_CLIENT
|
|
||||||
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
||||||
ret: URI
|
ret: URI
|
||||||
sess: HTTP_CLIENT_SESSION
|
sess: HTTP_CLIENT_SESSION
|
||||||
@@ -53,7 +46,7 @@ feature -- Basic operation
|
|||||||
is_valid := False
|
is_valid := False
|
||||||
create ret.make_from_string (return_url)
|
create ret.make_from_string (return_url)
|
||||||
create tb.make (5)
|
create tb.make (5)
|
||||||
if attached uri.decoded_query_items as q_lst then
|
if attached values as q_lst then
|
||||||
if attached item_by_name ("openid.claimed_id", q_lst) as q_claimed_id then
|
if attached item_by_name ("openid.claimed_id", q_lst) as q_claimed_id then
|
||||||
l_claimed_id := q_claimed_id.as_string_8
|
l_claimed_id := q_claimed_id.as_string_8
|
||||||
elseif attached item_by_name ("openid.identity", q_lst) as l_id then
|
elseif attached item_by_name ("openid.identity", q_lst) as l_id then
|
||||||
@@ -103,7 +96,6 @@ feature -- Basic operation
|
|||||||
end
|
end
|
||||||
|
|
||||||
tb.force ("check_authentication", "openid.mode")
|
tb.force ("check_authentication", "openid.mode")
|
||||||
create cl.make
|
|
||||||
create ctx.make
|
create ctx.make
|
||||||
across
|
across
|
||||||
tb as c
|
tb as c
|
||||||
@@ -112,8 +104,7 @@ feature -- Basic operation
|
|||||||
ctx.add_form_parameter (c.key.to_string_32, l_value)
|
ctx.add_form_parameter (c.key.to_string_32, l_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
sess := cl.new_session (d_info.server_uri)
|
sess := openid.new_session (d_info.server_uri)
|
||||||
sess.set_is_insecure (True)
|
|
||||||
if attached sess.post ("", ctx, Void) as res then
|
if attached sess.post ("", ctx, Void) as res then
|
||||||
if res.error_occurred then
|
if res.error_occurred then
|
||||||
elseif attached {STRING} res.body as l_body then
|
elseif attached {STRING} res.body as l_body then
|
||||||
@@ -128,7 +119,7 @@ feature -- Basic operation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get_attributes (lst: LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]])
|
get_attributes (lst: like values)
|
||||||
local
|
local
|
||||||
s: READABLE_STRING_32
|
s: READABLE_STRING_32
|
||||||
sreg_keys: ARRAYED_LIST [READABLE_STRING_32]
|
sreg_keys: ARRAYED_LIST [READABLE_STRING_32]
|
||||||
@@ -139,14 +130,14 @@ feature -- Basic operation
|
|||||||
get_ax_attributes (lst)
|
get_ax_attributes (lst)
|
||||||
end
|
end
|
||||||
|
|
||||||
get_sreg_attributes (lst: LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]])
|
get_sreg_attributes (lst: like values)
|
||||||
local
|
local
|
||||||
s: READABLE_STRING_32
|
s: READABLE_STRING_32
|
||||||
sreg_keys: ARRAYED_LIST [READABLE_STRING_32]
|
sreg_keys: ARRAYED_LIST [READABLE_STRING_32]
|
||||||
do
|
do
|
||||||
if attached item_by_name ("openid.signed", lst) as l_signed then
|
if lst /= Void and then attached item_by_name ("openid.signed", lst) as l_signed then
|
||||||
-- sreg attributes
|
-- sreg attributes
|
||||||
create sreg_keys.make (3)
|
create sreg_keys.make (5)
|
||||||
across
|
across
|
||||||
l_signed.split (',') as c
|
l_signed.split (',') as c
|
||||||
loop
|
loop
|
||||||
@@ -166,7 +157,7 @@ feature -- Basic operation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get_ax_attributes (lst: LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]])
|
get_ax_attributes (lst: like values)
|
||||||
local
|
local
|
||||||
s: READABLE_STRING_32
|
s: READABLE_STRING_32
|
||||||
ax_keys: ARRAYED_LIST [READABLE_STRING_32]
|
ax_keys: ARRAYED_LIST [READABLE_STRING_32]
|
||||||
@@ -174,38 +165,47 @@ feature -- Basic operation
|
|||||||
k_value, k_type, k_count, k: STRING
|
k_value, k_type, k_count, k: STRING
|
||||||
i: INTEGER
|
i: INTEGER
|
||||||
do
|
do
|
||||||
if attached item_by_name ("openid.signed", lst) as l_signed then
|
if lst /= Void and then attached item_by_name ("openid.signed", lst) as l_signed then
|
||||||
-- ax attributes
|
-- ax attributes
|
||||||
across
|
across
|
||||||
l_signed.split (',') as c
|
l_signed.split (',') as c
|
||||||
loop
|
loop
|
||||||
|
i := i + 1
|
||||||
s := c.item
|
s := c.item
|
||||||
if s.starts_with ("ns.") then
|
if s.starts_with ("ns.") then
|
||||||
if attached item_by_name (s, lst) as v then
|
if attached item_by_name ("openid." + s, lst) as v then
|
||||||
if s.same_string ("ns.ax") and v.same_string ("http://openid.net/srv/ax/1.0") then
|
if s.same_string ("ns.ax") and v.same_string ("http://openid.net/srv/ax/1.0") then
|
||||||
l_alias := "ax."
|
l_alias := "ax."
|
||||||
else
|
else
|
||||||
if v.same_string ("http://openid.net/srv/ax/1.0") then
|
if v.same_string ("http://openid.net/srv/ax/1.0") then
|
||||||
l_alias := s.substring (("ns.").count, s.count) + "."
|
l_alias := s.substring (("ns.").count + 1, s.count) + "."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if l_alias /= Void then
|
if l_alias /= Void then
|
||||||
create ax_keys.make (lst.count)
|
k_value := l_alias + "value."
|
||||||
|
k_type := l_alias + "type."
|
||||||
|
k_count := l_alias + "count."
|
||||||
|
|
||||||
|
create ax_keys.make (i)
|
||||||
across
|
across
|
||||||
l_signed.split (',') as c
|
l_signed.split (',') as c
|
||||||
loop
|
loop
|
||||||
s := c.item
|
s := c.item
|
||||||
if s.starts_with (l_alias) then
|
if
|
||||||
|
s.starts_with (k_value)
|
||||||
|
or s.starts_with (k_type)
|
||||||
|
then
|
||||||
ax_keys.force ("openid." + s)
|
ax_keys.force ("openid." + s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
k_value := "openid." + l_alias + "value."
|
k_value := "openid." + k_value
|
||||||
k_type := "openid." + l_alias + "type."
|
k_type := "openid." + k_type
|
||||||
k_count := "openid." + l_alias + "count."
|
k_count := "openid." + k_count
|
||||||
|
|
||||||
across
|
across
|
||||||
ax_keys as c
|
ax_keys as c
|
||||||
loop
|
loop
|
||||||
@@ -230,15 +230,15 @@ feature -- Basic operation
|
|||||||
else
|
else
|
||||||
-- no alias !!!
|
-- no alias !!!
|
||||||
end
|
end
|
||||||
|
-- attributes.force (v, k)
|
||||||
end
|
end
|
||||||
attributes.force (v, s.substring (5, s.count))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
item_by_name (a_name: READABLE_STRING_32; lst: like {URI}.decoded_query_items): detachable READABLE_STRING_32
|
item_by_name (a_name: READABLE_STRING_32; lst: like values): detachable READABLE_STRING_32
|
||||||
local
|
local
|
||||||
l_found: BOOLEAN
|
l_found: BOOLEAN
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ feature
|
|||||||
check o.error = Void end
|
check o.error = Void end
|
||||||
get_openid_response_uri (l_url)
|
get_openid_response_uri (l_url)
|
||||||
if attached openid_response_uri as u and then u.is_valid then
|
if attached openid_response_uri as u and then u.is_valid then
|
||||||
create v.make_from_uri (o, u)
|
create v.make_from_items (o, u.decoded_query_items)
|
||||||
v.validate
|
v.validate
|
||||||
if v.is_valid then
|
if v.is_valid then
|
||||||
print ("Succeed ...%N")
|
print ("Succeed ...%N")
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ feature {NONE} -- Access: global variable
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: global variable
|
feature -- Access: global variables
|
||||||
|
|
||||||
items: ITERABLE [WSF_VALUE]
|
items: ITERABLE [WSF_VALUE]
|
||||||
do
|
do
|
||||||
@@ -411,6 +411,43 @@ feature -- Access: global variable
|
|||||||
Result.keep_head (n - 1)
|
Result.keep_head (n - 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Helpers: global variables
|
||||||
|
|
||||||
|
items_as_string_items: ITERABLE [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]]
|
||||||
|
-- `items' as strings items
|
||||||
|
-- i.e: flatten any table or related into multiple string items
|
||||||
|
local
|
||||||
|
res: ARRAYED_LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]]
|
||||||
|
do
|
||||||
|
if attached items_table as tb then
|
||||||
|
create res.make (tb.count)
|
||||||
|
across
|
||||||
|
tb as c
|
||||||
|
loop
|
||||||
|
append_value_as_string_items_to (c.item, res)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
create res.make (0)
|
||||||
|
end
|
||||||
|
Result := res
|
||||||
|
end
|
||||||
|
|
||||||
|
append_value_as_string_items_to (v: WSF_VALUE; a_target: LIST [TUPLE [name: READABLE_STRING_32; value: detachable READABLE_STRING_32]])
|
||||||
|
-- Append value `v' to `a_target' as multiple string items
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} v as s then
|
||||||
|
a_target.force ([s.name, s.value])
|
||||||
|
elseif attached {ITERABLE [WSF_VALUE]} v as lst then
|
||||||
|
across
|
||||||
|
lst as c
|
||||||
|
loop
|
||||||
|
append_value_as_string_items_to (c.item, a_target)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
a_target.force ([v.name, v.string_representation])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Execution variables
|
feature -- Execution variables
|
||||||
|
|
||||||
execution_variable (a_name: READABLE_STRING_GENERAL): detachable ANY
|
execution_variable (a_name: READABLE_STRING_GENERAL): detachable ANY
|
||||||
|
|||||||
Reference in New Issue
Block a user