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
|
||||
-- Server input channel
|
||||
require
|
||||
is_not_chunked_input: not is_chunked_input
|
||||
--| Could also be Chunked input, but this is transparent
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -87,13 +86,6 @@ feature -- Access: Input
|
||||
deferred
|
||||
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
|
||||
|
||||
meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
note
|
||||
description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_CHUNKED_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
WGI_INPUT_STREAM
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
@@ -14,90 +16,177 @@ feature {NONE} -- Implementation
|
||||
|
||||
make (an_input: like input)
|
||||
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
|
||||
input := an_input
|
||||
end
|
||||
|
||||
feature -- Input
|
||||
|
||||
data: STRING_8
|
||||
local
|
||||
d: like internal_data
|
||||
read_character
|
||||
-- Read the next character in input stream.
|
||||
-- Make the result available in `last_character'
|
||||
do
|
||||
d := internal_data
|
||||
if d = Void then
|
||||
d := fetched_data
|
||||
internal_data := d
|
||||
index := index + 1
|
||||
if index > chunk_upper then
|
||||
read_chunk
|
||||
if last_chunk = Void then
|
||||
read_trailer
|
||||
end
|
||||
end
|
||||
Result := d
|
||||
last_character := last_chunk.item (index)
|
||||
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
|
||||
|
||||
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
|
||||
last_chunk_size: INTEGER
|
||||
last_chunk: detachable STRING_8
|
||||
|
||||
fetched_data: STRING_8
|
||||
-- Read all the data in a chunked stream.
|
||||
-- Make the result available in `last_chunked'.
|
||||
-- Chunked-Body = *chunk
|
||||
-- last-chunk
|
||||
-- trailer
|
||||
-- CRLF
|
||||
-- chunk = chunk-size [ chunk-extension ] CRLF
|
||||
-- chunk-data CRLF
|
||||
-- chunk-size = 1*HEX
|
||||
-- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||
-- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||
-- chunk-ext-name = token
|
||||
-- chunk-ext-val = token | quoted-string
|
||||
-- chunk-data = chunk-size(OCTET)
|
||||
-- trailer = *(entity-header CRLF)
|
||||
local
|
||||
eoc: BOOLEAN
|
||||
s: STRING_8
|
||||
do
|
||||
from
|
||||
create s.make (1024)
|
||||
until
|
||||
eoc
|
||||
loop
|
||||
read_chunk
|
||||
if attached last_chunk as l_last_chunk then
|
||||
s.append (l_last_chunk)
|
||||
else
|
||||
eoc := True
|
||||
end
|
||||
if last_chunk_size = 0 then
|
||||
eoc := True
|
||||
end
|
||||
end
|
||||
-- fetched_data: STRING_8
|
||||
-- -- Read all the data in a chunked stream.
|
||||
-- -- Make the result available in `last_chunked'.
|
||||
-- -- Chunked-Body = *chunk
|
||||
-- -- last-chunk
|
||||
-- -- trailer
|
||||
-- -- CRLF
|
||||
-- -- chunk = chunk-size [ chunk-extension ] CRLF
|
||||
-- -- chunk-data CRLF
|
||||
-- -- chunk-size = 1*HEX
|
||||
-- -- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||
-- -- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||
-- -- chunk-ext-name = token
|
||||
-- -- chunk-ext-val = token | quoted-string
|
||||
-- -- chunk-data = chunk-size(OCTET)
|
||||
-- -- trailer = *(entity-header CRLF)
|
||||
-- local
|
||||
-- eoc: BOOLEAN
|
||||
-- s: STRING_8
|
||||
-- do
|
||||
-- from
|
||||
-- create s.make (1024)
|
||||
-- until
|
||||
-- eoc
|
||||
-- loop
|
||||
-- read_chunk
|
||||
-- if attached last_chunk as l_last_chunk then
|
||||
-- s.append (l_last_chunk)
|
||||
-- else
|
||||
-- eoc := True
|
||||
-- end
|
||||
-- if last_chunk_size = 0 then
|
||||
-- eoc := True
|
||||
-- end
|
||||
-- end
|
||||
|
||||
read_trailer
|
||||
-- read_trailer
|
||||
|
||||
Result := s
|
||||
end
|
||||
|
||||
reset_chunk
|
||||
do
|
||||
last_chunk := Void
|
||||
last_chunk_size := 0
|
||||
end
|
||||
-- Result := s
|
||||
-- end
|
||||
|
||||
read_chunk
|
||||
do
|
||||
reset_chunk
|
||||
chunk_lower := chunk_upper + 1
|
||||
last_chunk.wipe_out
|
||||
last_chunk_size := 0
|
||||
read_chunk_size
|
||||
if last_chunk_size > 0 then
|
||||
chunk_upper := chunk_upper + last_chunk_size
|
||||
read_chunk_data
|
||||
end
|
||||
ensure
|
||||
attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower
|
||||
end
|
||||
|
||||
read_chunk_data
|
||||
require
|
||||
last_chunk.is_empty
|
||||
last_chunk_size > 0
|
||||
local
|
||||
l_input: like input
|
||||
@@ -105,12 +194,6 @@ feature {NONE} -- Parser
|
||||
l_input := input
|
||||
l_input.read_string (last_chunk_size)
|
||||
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
|
||||
last_chunk_attached: attached last_chunk as el_last_chunk
|
||||
last_chunk_size_ok: el_last_chunk.count = last_chunk_size
|
||||
|
||||
@@ -27,9 +27,18 @@ feature {NONE} -- Initialization
|
||||
input := a_input
|
||||
set_meta_variables (a_vars)
|
||||
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
|
||||
create chunked_input.make (a_input)
|
||||
create {WGI_CHUNKED_INPUT_STREAM} input.make (input)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,9 +49,7 @@ feature -- Access: Input
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Server input channel
|
||||
|
||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
||||
-- Chunked server input channel
|
||||
--| Could be a chunked input as well
|
||||
|
||||
feature -- EWSGI access
|
||||
|
||||
|
||||
@@ -11,44 +11,30 @@ feature {NONE} -- Implementation
|
||||
|
||||
full_input_data (req: WSF_REQUEST): READABLE_STRING_8
|
||||
do
|
||||
if req.is_chunked_input then
|
||||
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
|
||||
Result := read_input_data (req.input)
|
||||
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
|
||||
local
|
||||
nb32: INTEGER
|
||||
n64: NATURAL_64
|
||||
n: INTEGER
|
||||
t: STRING
|
||||
do
|
||||
from
|
||||
n64 := nb
|
||||
nb32 := n64.to_integer_32
|
||||
create Result.make (nb32)
|
||||
n := nb32
|
||||
if n > 1_024 then
|
||||
n := 1_024
|
||||
end
|
||||
n := 1_024
|
||||
create Result.make (n)
|
||||
until
|
||||
n64 <= 0
|
||||
n = 0
|
||||
loop
|
||||
a_input.read_string (n)
|
||||
t := a_input.last_string
|
||||
Result.append_string (t)
|
||||
if t.count < n then
|
||||
n64 := 0
|
||||
if t.count = 0 then
|
||||
n := 0
|
||||
else
|
||||
n64 := n64 - t.count.as_natural_64
|
||||
if t.count < n then
|
||||
n := 0
|
||||
end
|
||||
Result.append_string (t)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -157,26 +157,17 @@ feature -- Access: Input
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Server input channel
|
||||
require
|
||||
is_not_chunked_input: not is_chunked_input
|
||||
do
|
||||
Result := wgi_request.input
|
||||
end
|
||||
|
||||
is_chunked_input: BOOLEAN
|
||||
-- Is request using chunked transfer-encoding?
|
||||
-- If True, the Content-Length has no meaning
|
||||
do
|
||||
Result := wgi_request.is_chunked_input
|
||||
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
|
||||
|
||||
is_request_method (m: READABLE_STRING_8): BOOLEAN
|
||||
|
||||
Reference in New Issue
Block a user