Made WGI_CHUNKED_INPUT_STREAM inherits from WGI_INPUT_STREAM
Merged REQUEST.input and REQUEST.chunked_input Now REQUEST.input handles directly the chunked transfer encoding, or the non chunked. Kept REQUEST.is_chunked_input since it matters that Content-Length is 0 even if there are input (chunked) data.
This commit is contained in:
@@ -77,8 +77,7 @@ feature -- Access: Input
|
|||||||
|
|
||||||
input: WGI_INPUT_STREAM
|
input: WGI_INPUT_STREAM
|
||||||
-- Server input channel
|
-- Server input channel
|
||||||
require
|
--| Could also be Chunked input, but this is transparent
|
||||||
is_not_chunked_input: not is_chunked_input
|
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -87,13 +86,6 @@ feature -- Access: Input
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
|
||||||
-- Chunked server input channel
|
|
||||||
require
|
|
||||||
is_chunked_input: is_chunked_input
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: CGI meta variables
|
feature -- Access: CGI meta variables
|
||||||
|
|
||||||
meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
|
meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}."
|
description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}."
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
WGI_CHUNKED_INPUT_STREAM
|
WGI_CHUNKED_INPUT_STREAM
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -14,90 +16,177 @@ feature {NONE} -- Implementation
|
|||||||
|
|
||||||
make (an_input: like input)
|
make (an_input: like input)
|
||||||
do
|
do
|
||||||
|
create last_string.make_empty
|
||||||
|
create last_chunk.make_empty
|
||||||
|
last_chunk_size := 0
|
||||||
|
index := 0
|
||||||
|
chunk_lower := 0
|
||||||
|
chunk_upper := 0
|
||||||
create tmp_hex_chunk_size.make_empty
|
create tmp_hex_chunk_size.make_empty
|
||||||
input := an_input
|
input := an_input
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Input
|
feature -- Input
|
||||||
|
|
||||||
data: STRING_8
|
read_character
|
||||||
local
|
-- Read the next character in input stream.
|
||||||
d: like internal_data
|
-- Make the result available in `last_character'
|
||||||
do
|
do
|
||||||
d := internal_data
|
index := index + 1
|
||||||
if d = Void then
|
if index > chunk_upper then
|
||||||
d := fetched_data
|
read_chunk
|
||||||
internal_data := d
|
if last_chunk = Void then
|
||||||
|
read_trailer
|
||||||
|
end
|
||||||
end
|
end
|
||||||
Result := d
|
last_character := last_chunk.item (index)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
read_string (nb: INTEGER)
|
||||||
|
-- Read the next `nb' characters and
|
||||||
|
-- make the string result available in `last_string'
|
||||||
|
local
|
||||||
|
i: like index
|
||||||
|
do
|
||||||
|
last_string.wipe_out
|
||||||
|
if last_chunk_size = 0 then
|
||||||
|
read_chunk
|
||||||
|
end
|
||||||
|
from
|
||||||
|
index := index + 1
|
||||||
|
i := index
|
||||||
|
until
|
||||||
|
i - index + 1 = nb or last_chunk_size = 0
|
||||||
|
loop
|
||||||
|
if i + nb - 1 <= chunk_upper then
|
||||||
|
last_string.append (last_chunk.substring (i, i + nb - 1))
|
||||||
|
i := i + nb - 1
|
||||||
|
else
|
||||||
|
-- Need to read new chunk
|
||||||
|
-- first get all available data from current chunk
|
||||||
|
if i <= chunk_upper then
|
||||||
|
last_string.append (last_chunk.substring (i, chunk_upper))
|
||||||
|
i := chunk_upper
|
||||||
|
end
|
||||||
|
-- then continue
|
||||||
|
read_chunk
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if last_chunk_size = 0 then
|
||||||
|
read_trailer
|
||||||
|
end
|
||||||
|
index := i
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
last_string: STRING_8
|
||||||
|
-- Last string read.
|
||||||
|
--
|
||||||
|
-- Note: this query *might* return the same object.
|
||||||
|
-- Therefore a clone should be used if the result
|
||||||
|
-- is to be kept beyond the next call to this feature.
|
||||||
|
-- However `last_string' is not shared between file objects.)
|
||||||
|
|
||||||
|
last_character: CHARACTER_8
|
||||||
|
-- Last item read.
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_open_read: BOOLEAN
|
||||||
|
-- Can items be read from input stream?
|
||||||
|
do
|
||||||
|
Result := input.is_open_read
|
||||||
|
end
|
||||||
|
|
||||||
|
end_of_input: BOOLEAN
|
||||||
|
-- Has the end of input stream been reached?
|
||||||
|
do
|
||||||
|
Result := input.end_of_input
|
||||||
|
end
|
||||||
|
|
||||||
|
--feature -- Input
|
||||||
|
|
||||||
|
-- data: STRING_8
|
||||||
|
-- local
|
||||||
|
-- d: like internal_data
|
||||||
|
-- do
|
||||||
|
-- d := internal_data
|
||||||
|
-- if d = Void then
|
||||||
|
-- d := fetched_data
|
||||||
|
-- internal_data := d
|
||||||
|
-- end
|
||||||
|
-- Result := d
|
||||||
|
-- end
|
||||||
|
|
||||||
feature {NONE} -- Parser
|
feature {NONE} -- Parser
|
||||||
|
|
||||||
internal_data: detachable STRING_8
|
index, chunk_lower, chunk_upper: INTEGER
|
||||||
|
last_chunk_size: INTEGER
|
||||||
|
last_chunk: STRING_8
|
||||||
|
|
||||||
|
-- internal_data: detachable STRING_8
|
||||||
|
|
||||||
tmp_hex_chunk_size: STRING_8
|
tmp_hex_chunk_size: STRING_8
|
||||||
last_chunk_size: INTEGER
|
|
||||||
last_chunk: detachable STRING_8
|
|
||||||
|
|
||||||
fetched_data: STRING_8
|
-- fetched_data: STRING_8
|
||||||
-- Read all the data in a chunked stream.
|
-- -- Read all the data in a chunked stream.
|
||||||
-- Make the result available in `last_chunked'.
|
-- -- Make the result available in `last_chunked'.
|
||||||
-- Chunked-Body = *chunk
|
-- -- Chunked-Body = *chunk
|
||||||
-- last-chunk
|
-- -- last-chunk
|
||||||
-- trailer
|
-- -- trailer
|
||||||
-- CRLF
|
-- -- CRLF
|
||||||
-- chunk = chunk-size [ chunk-extension ] CRLF
|
-- -- chunk = chunk-size [ chunk-extension ] CRLF
|
||||||
-- chunk-data CRLF
|
-- -- chunk-data CRLF
|
||||||
-- chunk-size = 1*HEX
|
-- -- chunk-size = 1*HEX
|
||||||
-- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
-- -- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||||
-- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
-- -- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||||
-- chunk-ext-name = token
|
-- -- chunk-ext-name = token
|
||||||
-- chunk-ext-val = token | quoted-string
|
-- -- chunk-ext-val = token | quoted-string
|
||||||
-- chunk-data = chunk-size(OCTET)
|
-- -- chunk-data = chunk-size(OCTET)
|
||||||
-- trailer = *(entity-header CRLF)
|
-- -- trailer = *(entity-header CRLF)
|
||||||
local
|
-- local
|
||||||
eoc: BOOLEAN
|
-- eoc: BOOLEAN
|
||||||
s: STRING_8
|
-- s: STRING_8
|
||||||
do
|
-- do
|
||||||
from
|
-- from
|
||||||
create s.make (1024)
|
-- create s.make (1024)
|
||||||
until
|
-- until
|
||||||
eoc
|
-- eoc
|
||||||
loop
|
-- loop
|
||||||
read_chunk
|
-- read_chunk
|
||||||
if attached last_chunk as l_last_chunk then
|
-- if attached last_chunk as l_last_chunk then
|
||||||
s.append (l_last_chunk)
|
-- s.append (l_last_chunk)
|
||||||
else
|
-- else
|
||||||
eoc := True
|
-- eoc := True
|
||||||
end
|
-- end
|
||||||
if last_chunk_size = 0 then
|
-- if last_chunk_size = 0 then
|
||||||
eoc := True
|
-- eoc := True
|
||||||
end
|
-- end
|
||||||
end
|
-- end
|
||||||
|
|
||||||
read_trailer
|
-- read_trailer
|
||||||
|
|
||||||
Result := s
|
-- Result := s
|
||||||
end
|
-- end
|
||||||
|
|
||||||
reset_chunk
|
|
||||||
do
|
|
||||||
last_chunk := Void
|
|
||||||
last_chunk_size := 0
|
|
||||||
end
|
|
||||||
|
|
||||||
read_chunk
|
read_chunk
|
||||||
do
|
do
|
||||||
reset_chunk
|
chunk_lower := chunk_upper + 1
|
||||||
|
last_chunk.wipe_out
|
||||||
|
last_chunk_size := 0
|
||||||
read_chunk_size
|
read_chunk_size
|
||||||
if last_chunk_size > 0 then
|
if last_chunk_size > 0 then
|
||||||
|
chunk_upper := chunk_upper + last_chunk_size
|
||||||
read_chunk_data
|
read_chunk_data
|
||||||
end
|
end
|
||||||
|
ensure
|
||||||
|
attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower
|
||||||
end
|
end
|
||||||
|
|
||||||
read_chunk_data
|
read_chunk_data
|
||||||
require
|
require
|
||||||
|
last_chunk.is_empty
|
||||||
last_chunk_size > 0
|
last_chunk_size > 0
|
||||||
local
|
local
|
||||||
l_input: like input
|
l_input: like input
|
||||||
@@ -105,12 +194,6 @@ feature {NONE} -- Parser
|
|||||||
l_input := input
|
l_input := input
|
||||||
l_input.read_string (last_chunk_size)
|
l_input.read_string (last_chunk_size)
|
||||||
last_chunk := l_input.last_string
|
last_chunk := l_input.last_string
|
||||||
|
|
||||||
-- read CRLF
|
|
||||||
l_input.read_character
|
|
||||||
if l_input.last_character = '%R' then
|
|
||||||
l_input.read_character
|
|
||||||
end
|
|
||||||
ensure
|
ensure
|
||||||
last_chunk_attached: attached last_chunk as el_last_chunk
|
last_chunk_attached: attached last_chunk as el_last_chunk
|
||||||
last_chunk_size_ok: el_last_chunk.count = last_chunk_size
|
last_chunk_size_ok: el_last_chunk.count = last_chunk_size
|
||||||
|
|||||||
@@ -27,9 +27,18 @@ feature {NONE} -- Initialization
|
|||||||
input := a_input
|
input := a_input
|
||||||
set_meta_variables (a_vars)
|
set_meta_variables (a_vars)
|
||||||
update_path_info
|
update_path_info
|
||||||
if attached http_transfer_encoding as l_transfer_encoding and then l_transfer_encoding.same_string ("chunked") then
|
update_input
|
||||||
|
end
|
||||||
|
|
||||||
|
update_input
|
||||||
|
-- Update input, depending on Transfer-Encoding value.
|
||||||
|
do
|
||||||
|
if
|
||||||
|
attached http_transfer_encoding as l_transfer_encoding and then
|
||||||
|
l_transfer_encoding.same_string (once "chunked")
|
||||||
|
then
|
||||||
is_chunked_input := True
|
is_chunked_input := True
|
||||||
create chunked_input.make (a_input)
|
create {WGI_CHUNKED_INPUT_STREAM} input.make (input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,9 +49,7 @@ feature -- Access: Input
|
|||||||
|
|
||||||
input: WGI_INPUT_STREAM
|
input: WGI_INPUT_STREAM
|
||||||
-- Server input channel
|
-- Server input channel
|
||||||
|
--| Could be a chunked input as well
|
||||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
|
||||||
-- Chunked server input channel
|
|
||||||
|
|
||||||
feature -- EWSGI access
|
feature -- EWSGI access
|
||||||
|
|
||||||
|
|||||||
@@ -11,44 +11,30 @@ feature {NONE} -- Implementation
|
|||||||
|
|
||||||
full_input_data (req: WSF_REQUEST): READABLE_STRING_8
|
full_input_data (req: WSF_REQUEST): READABLE_STRING_8
|
||||||
do
|
do
|
||||||
if req.is_chunked_input then
|
Result := read_input_data (req.input)
|
||||||
if attached req.chunked_input as l_chunked_input then
|
|
||||||
Result := l_chunked_input.data
|
|
||||||
else
|
|
||||||
check has_chunked_input: False end
|
|
||||||
Result := ""
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Result := read_input_data (req.input, req.content_length_value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
read_input_data (a_input: WGI_INPUT_STREAM; nb: NATURAL_64): STRING_8
|
read_input_data (a_input: WGI_INPUT_STREAM): STRING_8
|
||||||
-- All data from input form
|
-- All data from input form
|
||||||
local
|
local
|
||||||
nb32: INTEGER
|
|
||||||
n64: NATURAL_64
|
|
||||||
n: INTEGER
|
n: INTEGER
|
||||||
t: STRING
|
t: STRING
|
||||||
do
|
do
|
||||||
from
|
from
|
||||||
n64 := nb
|
n := 1_024
|
||||||
nb32 := n64.to_integer_32
|
create Result.make (n)
|
||||||
create Result.make (nb32)
|
|
||||||
n := nb32
|
|
||||||
if n > 1_024 then
|
|
||||||
n := 1_024
|
|
||||||
end
|
|
||||||
until
|
until
|
||||||
n64 <= 0
|
n = 0
|
||||||
loop
|
loop
|
||||||
a_input.read_string (n)
|
a_input.read_string (n)
|
||||||
t := a_input.last_string
|
t := a_input.last_string
|
||||||
Result.append_string (t)
|
if t.count = 0 then
|
||||||
if t.count < n then
|
n := 0
|
||||||
n64 := 0
|
|
||||||
else
|
else
|
||||||
n64 := n64 - t.count.as_natural_64
|
if t.count < n then
|
||||||
|
n := 0
|
||||||
|
end
|
||||||
|
Result.append_string (t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -157,26 +157,17 @@ feature -- Access: Input
|
|||||||
|
|
||||||
input: WGI_INPUT_STREAM
|
input: WGI_INPUT_STREAM
|
||||||
-- Server input channel
|
-- Server input channel
|
||||||
require
|
|
||||||
is_not_chunked_input: not is_chunked_input
|
|
||||||
do
|
do
|
||||||
Result := wgi_request.input
|
Result := wgi_request.input
|
||||||
end
|
end
|
||||||
|
|
||||||
is_chunked_input: BOOLEAN
|
is_chunked_input: BOOLEAN
|
||||||
-- Is request using chunked transfer-encoding?
|
-- Is request using chunked transfer-encoding?
|
||||||
|
-- If True, the Content-Length has no meaning
|
||||||
do
|
do
|
||||||
Result := wgi_request.is_chunked_input
|
Result := wgi_request.is_chunked_input
|
||||||
end
|
end
|
||||||
|
|
||||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
|
||||||
-- Server input channel
|
|
||||||
require
|
|
||||||
is_chunked_input: is_chunked_input
|
|
||||||
do
|
|
||||||
Result := wgi_request.chunked_input
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Helper
|
feature -- Helper
|
||||||
|
|
||||||
is_request_method (m: READABLE_STRING_8): BOOLEAN
|
is_request_method (m: READABLE_STRING_8): BOOLEAN
|
||||||
|
|||||||
Reference in New Issue
Block a user