Permalink
Browse files

Input reader now a KL_CHARACTER_INPUT_STREA.

Use eposix MIME handler to read multipart forms.
  • Loading branch information...
1 parent 615af68 commit e28feaa61f1edec250e345efd67c5051d6de3b03 @berenddeboer committed Mar 21, 2012
@@ -29,6 +29,8 @@ inherit
make as make_service,
make_and_launch as make_and_launch_service,
make_and_launch_with_options as make_and_launch_service_with_options
+ redefine
+ wgi_execute
end
inherit {NONE}
@@ -60,7 +62,7 @@ feature {NONE} -- Initialization
launch
end
- make_and_launch_with_options (a_terminate_signal: EPX_KILL_SIGNAL_HANDLER; a_action: like action; a_options: attached like options)
+ make_and_launch_with_options (a_terminate_signal: EPX_KILL_SIGNAL_HANDLER; a_action: like action; a_options: attached like options)
require
signal_handler_attached: a_terminate_signal /= Void
a_options_attached: a_options /= Void
@@ -78,6 +80,7 @@ feature {NONE} -- Initialization
create connector.make (terminate_signal, Current, options)
end
+
feature -- Execution
launch
@@ -87,6 +90,28 @@ feature -- Execution
end
end
+
+feature {WGI_CONNECTOR} -- WGI Execution
+
+ wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE)
+ local
+ w_req: detachable EPX_WSF_REQUEST
+ w_res: detachable WSF_RESPONSE
+ do
+ create w_res.make_from_wgi (res)
+ create w_req.make_from_wgi (req)
+ execute (w_req, w_res)
+ w_req.destroy
+ rescue
+ if w_res /= Void then
+ w_res.flush
+ end
+ if w_req /= Void then
+ w_req.destroy
+ end
+ end
+
+
feature -- Access
terminate_signal: attached EPX_KILL_SIGNAL_HANDLER
@@ -42,10 +42,12 @@ feature {NONE} -- Initialisation
socket.set_continue_on_error
socket.errno.clear_all
create parameters.make (64)
+ parameters.compare_objects
create header_buf.allocate_and_clear (Fcgi_header_len)
create body_buf.allocate_and_clear (Fcgi_max_len)
create output_header_buf.allocate_and_clear (Fcgi_header_len)
output_header_buf.poke_int8 (0, Fcgi_version)
+ create last_string.make (1024)
end
@@ -55,6 +57,8 @@ feature -- Status
-- Set if read or write to webserver has failed;
-- Can be used to abort request processing early
+ end_of_input: BOOLEAN
+
feature -- Access
@@ -67,12 +71,64 @@ feature -- Access
last_character: CHARACTER
-- Last character read by `read_chacter'
+ last_read: INTEGER
+ -- How many characters were read by `read_buffer'
+
+ bytes_read: INTEGER
+ -- Total bytes read;
+ -- Should be less or equal than Content-Length
+
last_string: STRING
-- Last string read by `read_string'
feature -- Reading
+ read_buffer (buf: STDC_BUFFER; offset, nbytes: INTEGER)
+ -- Read data into `buf' at `offset' for `nbytes' bytes.
+ -- Number of bytes actually read are available in `last_read'.
+ require
+ is_open_read: socket.is_open_read
+ not_end_of_input: not end_of_input
+ nbytes_not_negative: nbytes >= 0
+ offset_not_negative: offset >= 0
+ buf_not_void: buf /= Void
+ dont_overflow: buf.capacity >= offset + nbytes
+ local
+ done: BOOLEAN
+ do
+ end_of_input := bytes_read = content_length
+ last_read := 0
+ if not end_of_input then
+ if last_record_type = 0 then
+ read_record_header
+ end
+ from
+ until
+ socket.errno.is_not_ok or else
+ done
+ loop
+ if last_record_type = Fcgi_stdin then
+ -- We will always read an entire block as we don't cache
+ check
+ can_read_entire_block: nbytes >= last_content_length
+ end
+ do_read_record_body (buf, offset, last_content_length)
+ last_read := socket.last_read
+ done := True
+ else
+ read_record_body (last_content_length)
+ action_record_body (last_record_type, last_content_length, body_buf)
+ done := last_record_type = Fcgi_abort_request
+ end
+ end
+ end
+ last_record_type := 0
+ ensure
+ last_record_type_unset: last_record_type = 0
+ consistent: last_read > 0 implies not end_of_input
+ end
+
read_string
do
if last_record_type = 0 then
@@ -101,11 +157,17 @@ feature -- Reading
action_record_body (last_record_type, last_content_length, body_buf)
read_record_header
end
+ if parameters.has_key ({WGI_META_NAMES}.content_length) then
+ content_length := parameters.item ({WGI_META_NAMES}.content_length).to_integer
+ end
end
feature {NONE} -- Record reading
+ content_length: INTEGER
+ -- Max input bytes to read from stdin
+
header_buf: attached EPX_BUFFER
-- Set by `read_record_header'
@@ -119,6 +181,7 @@ feature {NONE} -- Record reading
-- Set by `read_record_header'
last_content_length: INTEGER
+ -- Length of body content;
-- Set by `read_record_header'
read_record_header
@@ -137,7 +200,17 @@ feature {NONE} -- Record reading
require
content_fits: body_buf.capacity >= a_content_length
do
- socket.read_buffer (body_buf, 0, a_content_length)
+ do_read_record_body (body_buf, 0, a_content_length)
+ end
+
+ do_read_record_body (buf: STDC_BUFFER; offset, nbytes: INTEGER)
+ require
+ content_fits: body_buf.capacity >= offset + nbytes
+ do
+ socket.read_buffer (buf, offset, nbytes)
+ if last_record_type = Fcgi_stdin then
+ bytes_read := bytes_read + socket.last_read
+ end
end
action_record_body (a_record_type, a_content_length: INTEGER; a_content: EPX_BUFFER)
@@ -227,7 +300,7 @@ feature {EPX_FAST_CGI} -- Record handlers
-- Most probably the web server just sends a block as soon as
-- it receives new data.
last_string.wipe_out
- a_content.append_to_string (last_string, 0, a_content_length)
+ a_content.append_to_string (last_string, 0, a_content_length - 1)
ensure
correct_string_length: last_string.count = a_content_length
end
@@ -383,5 +456,7 @@ invariant
body_buf_large_enough: body_buf.capacity >= Fcgi_max_len
output_header_buf_not_void: output_header_buf /= Void
output_header_buf_large_enough: output_header_buf.capacity = Fcgi_header_len
+ last_string_not_void: last_string /= Void
+ never_read_too_much_from_stdin: bytes_read <= content_length
end
@@ -58,24 +58,25 @@ feature -- Execution
end
execute_service_default (req: WSF_REQUEST; res: WSF_RESPONSE)
- -- I'm using this method to handle the method not allowed response
- -- in the case that the given uri does not have a corresponding http method
- -- to handle it.
+ -- I'm using this method to handle the method not allowed
+ -- response in the case that the given uri does not have a
+ -- corresponding http method to handle it.
local
h : HTTP_HEADER
l_description : STRING
l_api_doc : STRING
do
+ res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
if req.content_length_value > 0 then
req.input.read_string (req.content_length_value.as_integer_32)
end
create h.make
h.put_content_type_text_plain
- l_api_doc := "%NPlease check the API%NURI:/order METHOD: POST%NURI:/order/{orderid} METHOD: GET, PUT, DELETE%N"
- l_description := req.request_method + req.request_uri + " is not allowed" + "%N" + l_api_doc
+ l_api_doc := "%NPlease check the API%N"
+ l_description := req.request_method + " " +req.request_uri + " is not supported" + "%N" + l_api_doc
h.put_content_length (l_description.count)
h.put_current_date
- res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
+ --h.put_header ({HTTP_HEADER_NAMES}.header_status + ": " + res.status_code.out)
res.put_header_text (h.string)
res.put_string (l_description)
end
@@ -19,6 +19,13 @@ inherit
WGI_INPUT_STREAM
+ EPX_CHARACTER_INPUT_STREAM
+ undefine
+ read_to_string
+ redefine
+ valid_unread_character
+ end
+
create
@@ -50,10 +57,44 @@ feature -- Status report
Result := fcgi.socket.is_open_read
end
+ is_streaming: BOOLEAN
+ do
+ Result := True
+ end
+
end_of_input: BOOLEAN
-- Has the end of input stream been reached?
do
- Result := fcgi.socket.end_of_input
+ Result := fcgi.end_of_input
+ end
+
+ valid_unread_character (a_character: CHARACTER): BOOLEAN
+ -- Can `a_character' be put back in input stream?
+ do
+ Result := False
+ end
+
+
+feature -- Access
+
+ name: STRING
+ -- Name of input stream
+ once
+ Result := "fastcgi"
+ end
+
+ last_string: STRING
+ -- Last string read
+
+ last_character: CHARACTER_8
+ -- Last item read
+
+ last_read: INTEGER is
+ -- Last bytes read by `read_buffer'.
+ -- Can be less than requested for non-blocking input.
+ -- Check `last_blocked' in that case.
+ do
+ Result := fcgi.last_read
end
@@ -102,14 +143,27 @@ feature -- Input
end
end
+ unread_character (an_item: CHARACTER)
+ -- Put `an_item' back in input stream.
+ -- This item will be read first by the next
+ -- call to a read routine.
+ do
+ -- Unsupported
+ end
-feature -- Access
+ read_buffer (buf: STDC_BUFFER; offset, nbytes: INTEGER)
+ -- Read data into `buf' at `offset' for `nbytes' bytes.
+ -- Number of bytes actually read are available in `last_read'.
+ do
+ fcgi.read_buffer (buf, offset, nbytes)
+ end
- last_string: STRING
- -- Last string read
- last_character: CHARACTER_8
- -- Last item read
+feature -- Commands
+
+ close
+ do
+ end
feature {NONE} -- Implementation
Oops, something went wrong.

0 comments on commit e28feaa

Please sign in to comment.