Redesigned the RESPONSE to remove the output stream from the deferred interface
Redesigned the uploaded file part to be more object oriented Move some implementation from REQUEST to REQUEST_IMP
This commit is contained in:
@@ -85,7 +85,7 @@ feature -- Form fields and related
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
uploaded_files: HASH_TABLE [TUPLE [name: STRING; type: STRING; tmp_name: STRING; tmp_basename: STRING; error: INTEGER; size: INTEGER], STRING]
|
uploaded_files: HASH_TABLE [GW_UPLOADED_FILE_DATA, STRING]
|
||||||
-- Table of uploaded files information
|
-- Table of uploaded files information
|
||||||
--| name: original path from the user
|
--| name: original path from the user
|
||||||
--| type: content type
|
--| type: content type
|
||||||
@@ -203,15 +203,6 @@ feature -- Access: global variable
|
|||||||
|
|
||||||
feature -- Uploaded File Handling
|
feature -- Uploaded File Handling
|
||||||
|
|
||||||
move_uploaded_file (a_filename: STRING; a_destination: STRING): BOOLEAN
|
|
||||||
-- Move uploaded file `a_filename' to `a_destination'
|
|
||||||
--| if this is not an uploaded file, do not move it.
|
|
||||||
require
|
|
||||||
a_filename_valid: a_filename /= Void and then not a_filename.is_empty
|
|
||||||
a_destination_valid: a_destination /= Void and then not a_destination.is_empty
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
is_uploaded_file (a_filename: STRING): BOOLEAN
|
is_uploaded_file (a_filename: STRING): BOOLEAN
|
||||||
-- Is `a_filename' a file uploaded via HTTP POST
|
-- Is `a_filename' a file uploaded via HTTP POST
|
||||||
deferred
|
deferred
|
||||||
@@ -219,10 +210,10 @@ feature -- Uploaded File Handling
|
|||||||
|
|
||||||
feature {NONE} -- Temporary File handling
|
feature {NONE} -- Temporary File handling
|
||||||
|
|
||||||
delete_uploaded_file (a_filename: STRING)
|
delete_uploaded_file (f: GW_UPLOADED_FILE_DATA)
|
||||||
-- Delete file `a_filename'
|
-- Delete file `f'
|
||||||
require
|
require
|
||||||
a_filename_valid: a_filename /= Void and then not a_filename.is_empty
|
f_valid: f /= Void
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -230,66 +221,16 @@ feature -- URL Utility
|
|||||||
|
|
||||||
absolute_script_url (a_path: STRING): STRING
|
absolute_script_url (a_path: STRING): STRING
|
||||||
-- Absolute Url for the script if any, extended by `a_path'
|
-- Absolute Url for the script if any, extended by `a_path'
|
||||||
do
|
deferred
|
||||||
Result := script_url (a_path)
|
|
||||||
if attached environment.http_host as h then
|
|
||||||
Result.prepend (h)
|
|
||||||
else
|
|
||||||
--| Issue ??
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
script_url (a_path: STRING): STRING
|
script_url (a_path: STRING): STRING
|
||||||
-- Url relative to script name if any, extended by `a_path'
|
-- Url relative to script name if any, extended by `a_path'
|
||||||
require
|
require
|
||||||
a_path_attached: a_path /= Void
|
a_path_attached: a_path /= Void
|
||||||
local
|
deferred
|
||||||
l_base_url: like internal_url_base
|
|
||||||
i,m,n: INTEGER
|
|
||||||
l_rq_uri: like environment.request_uri
|
|
||||||
env: like environment
|
|
||||||
do
|
|
||||||
l_base_url := internal_url_base
|
|
||||||
if l_base_url = Void then
|
|
||||||
env := environment
|
|
||||||
if attached env.script_name as l_script_name then
|
|
||||||
l_rq_uri := env.request_uri
|
|
||||||
if l_rq_uri.starts_with (l_script_name) then
|
|
||||||
l_base_url := l_script_name
|
|
||||||
else
|
|
||||||
--| Handle Rewrite url engine, to have clean path
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
m := l_rq_uri.count
|
|
||||||
n := l_script_name.count
|
|
||||||
until
|
|
||||||
i > m or i > n or l_rq_uri[i] /= l_script_name[i]
|
|
||||||
loop
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
if i > 1 then
|
|
||||||
if l_rq_uri[i-1] = '/' then
|
|
||||||
i := i -1
|
|
||||||
end
|
|
||||||
l_base_url := l_rq_uri.substring (1, i - 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if l_base_url = Void then
|
|
||||||
create l_base_url.make_empty
|
|
||||||
end
|
|
||||||
internal_url_base := l_base_url
|
|
||||||
end
|
|
||||||
Result := l_base_url + a_path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation: URL Utility
|
|
||||||
|
|
||||||
internal_url_base: detachable STRING
|
|
||||||
-- URL base of potential script
|
|
||||||
|
|
||||||
invariant
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|||||||
103
library/server/ewsgi/src/context/gw_uploaded_file_data.e
Normal file
103
library/server/ewsgi/src/context/gw_uploaded_file_data.e
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {GW_UPLOADED_FILE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
GW_UPLOADED_FILE_DATA
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (n: like name; t: like content_type; s: like size)
|
||||||
|
do
|
||||||
|
name := n
|
||||||
|
content_type := t
|
||||||
|
size := s
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: STRING
|
||||||
|
-- original filename
|
||||||
|
|
||||||
|
content_type: STRING
|
||||||
|
-- Content type
|
||||||
|
|
||||||
|
size: INTEGER
|
||||||
|
-- Size of uploaded file
|
||||||
|
|
||||||
|
tmp_name: detachable STRING
|
||||||
|
-- Filename of tmp file
|
||||||
|
|
||||||
|
tmp_basename: detachable STRING
|
||||||
|
-- Basename of tmp file
|
||||||
|
|
||||||
|
feature -- Basic operation
|
||||||
|
|
||||||
|
move_to (a_destination: STRING): BOOLEAN
|
||||||
|
-- Move current uploaded file to `a_destination'
|
||||||
|
require
|
||||||
|
has_no_error: not has_error
|
||||||
|
local
|
||||||
|
f: RAW_FILE
|
||||||
|
do
|
||||||
|
if attached tmp_name as n then
|
||||||
|
create f.make (n)
|
||||||
|
if f.exists then
|
||||||
|
f.change_name (a_destination)
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Has error during uploading
|
||||||
|
do
|
||||||
|
Result := error /= 0
|
||||||
|
end
|
||||||
|
|
||||||
|
error: INTEGER
|
||||||
|
-- Eventual error code
|
||||||
|
--| no error => 0
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_error (e: like error)
|
||||||
|
-- Set `error' to `e'
|
||||||
|
do
|
||||||
|
error := e
|
||||||
|
end
|
||||||
|
|
||||||
|
set_tmp_name (n: like tmp_name)
|
||||||
|
-- Set `tmp_name' to `n'
|
||||||
|
do
|
||||||
|
tmp_name := n
|
||||||
|
end
|
||||||
|
|
||||||
|
set_tmp_basename (n: like tmp_basename)
|
||||||
|
-- Set `tmp_basename' to `n'
|
||||||
|
do
|
||||||
|
tmp_basename := n
|
||||||
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
valid_tmp_name: not has_error implies attached tmp_name as n and then not n.is_empty
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
@@ -26,6 +26,9 @@ feature -- Process request
|
|||||||
else
|
else
|
||||||
rescue_execute (req, res, (create {EXCEPTION_MANAGER}).last_exception)
|
rescue_execute (req, res, (create {EXCEPTION_MANAGER}).last_exception)
|
||||||
end
|
end
|
||||||
|
if res /= Void then
|
||||||
|
res.commit (a_output)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Execution
|
feature {NONE} -- Execution
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ feature -- Form fields and related
|
|||||||
Result := vars
|
Result := vars
|
||||||
end
|
end
|
||||||
|
|
||||||
uploaded_files: HASH_TABLE [TUPLE [name: STRING; type: STRING; tmp_name: STRING; tmp_basename: STRING; error: INTEGER; size: INTEGER], STRING]
|
uploaded_files: HASH_TABLE [GW_UPLOADED_FILE_DATA, STRING]
|
||||||
-- Table of uploaded files information
|
-- Table of uploaded files information
|
||||||
--| name: original path from the user
|
--| name: original path from the user
|
||||||
--| type: content type
|
--| type: content type
|
||||||
@@ -274,6 +274,66 @@ feature -- Access extra information
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- URL Utility
|
||||||
|
|
||||||
|
absolute_script_url (a_path: STRING): STRING
|
||||||
|
-- Absolute Url for the script if any, extended by `a_path'
|
||||||
|
do
|
||||||
|
Result := script_url (a_path)
|
||||||
|
if attached environment.http_host as h then
|
||||||
|
Result.prepend (h)
|
||||||
|
else
|
||||||
|
--| Issue ??
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
script_url (a_path: STRING): STRING
|
||||||
|
-- Url relative to script name if any, extended by `a_path'
|
||||||
|
local
|
||||||
|
l_base_url: like internal_url_base
|
||||||
|
i,m,n: INTEGER
|
||||||
|
l_rq_uri: like environment.request_uri
|
||||||
|
env: like environment
|
||||||
|
do
|
||||||
|
l_base_url := internal_url_base
|
||||||
|
if l_base_url = Void then
|
||||||
|
env := environment
|
||||||
|
if attached env.script_name as l_script_name then
|
||||||
|
l_rq_uri := env.request_uri
|
||||||
|
if l_rq_uri.starts_with (l_script_name) then
|
||||||
|
l_base_url := l_script_name
|
||||||
|
else
|
||||||
|
--| Handle Rewrite url engine, to have clean path
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
m := l_rq_uri.count
|
||||||
|
n := l_script_name.count
|
||||||
|
until
|
||||||
|
i > m or i > n or l_rq_uri[i] /= l_script_name[i]
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if i > 1 then
|
||||||
|
if l_rq_uri[i-1] = '/' then
|
||||||
|
i := i -1
|
||||||
|
end
|
||||||
|
l_base_url := l_rq_uri.substring (1, i - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if l_base_url = Void then
|
||||||
|
create l_base_url.make_empty
|
||||||
|
end
|
||||||
|
internal_url_base := l_base_url
|
||||||
|
end
|
||||||
|
Result := l_base_url + a_path
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation: URL Utility
|
||||||
|
|
||||||
|
internal_url_base: detachable STRING
|
||||||
|
-- URL base of potential script
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
set_raw_post_data_recorded (b: BOOLEAN)
|
set_raw_post_data_recorded (b: BOOLEAN)
|
||||||
@@ -313,21 +373,6 @@ feature -- Element change
|
|||||||
|
|
||||||
feature -- Uploaded File Handling
|
feature -- Uploaded File Handling
|
||||||
|
|
||||||
move_uploaded_file (a_filename: STRING; a_destination: STRING): BOOLEAN
|
|
||||||
-- Move uploaded file `a_filename' to `a_destination'
|
|
||||||
--| if this is not an uploaded file, do not move it.
|
|
||||||
local
|
|
||||||
f: RAW_FILE
|
|
||||||
do
|
|
||||||
if is_uploaded_file (a_filename) then
|
|
||||||
create f.make (a_filename)
|
|
||||||
if f.exists then
|
|
||||||
f.change_name (a_destination)
|
|
||||||
Result := True
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
is_uploaded_file (a_filename: STRING): BOOLEAN
|
is_uploaded_file (a_filename: STRING): BOOLEAN
|
||||||
-- Is `a_filename' a file uploaded via HTTP Form
|
-- Is `a_filename' a file uploaded via HTTP Form
|
||||||
local
|
local
|
||||||
@@ -340,7 +385,7 @@ feature -- Uploaded File Handling
|
|||||||
until
|
until
|
||||||
l_files.after or Result
|
l_files.after or Result
|
||||||
loop
|
loop
|
||||||
if l_files.item_for_iteration.tmp_name.same_string (a_filename) then
|
if attached l_files.item_for_iteration.tmp_name as l_tmp_name and then l_tmp_name.same_string (a_filename) then
|
||||||
Result := True
|
Result := True
|
||||||
end
|
end
|
||||||
l_files.forth
|
l_files.forth
|
||||||
@@ -350,24 +395,28 @@ feature -- Uploaded File Handling
|
|||||||
|
|
||||||
feature {NONE} -- Temporary File handling
|
feature {NONE} -- Temporary File handling
|
||||||
|
|
||||||
delete_uploaded_file (a_filename: STRING)
|
delete_uploaded_file (uf: GW_UPLOADED_FILE_DATA)
|
||||||
-- Delete file `a_filename'
|
-- Delete file `a_filename'
|
||||||
local
|
local
|
||||||
f: RAW_FILE
|
f: RAW_FILE
|
||||||
do
|
do
|
||||||
if is_uploaded_file (a_filename) then
|
if uploaded_files.has_item (uf) then
|
||||||
create f.make (a_filename)
|
if attached uf.tmp_name as fn then
|
||||||
if f.exists and then f.is_writable then
|
create f.make (fn)
|
||||||
f.delete
|
if f.exists and then f.is_writable then
|
||||||
|
f.delete
|
||||||
|
else
|
||||||
|
error_handler.add_custom_error (0, "Can not delete uploaded file", "Can not delete file %""+ fn +"%"")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "Can not delete file", "Can not delete file %""+ a_filename +"%"")
|
error_handler.add_custom_error (0, "Can not delete uploaded file", "Can not delete uploaded file %""+ uf.name +"%" Tmp File not found")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "Not uploaded file", "This file %""+ a_filename +"%" is not an uploaded file.")
|
error_handler.add_custom_error (0, "Not an uploaded file", "This file %""+ uf.name +"%" is not an uploaded file.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
save_uploaded_file (a_content: STRING; a_filename: STRING): detachable TUPLE [name: STRING; basename: STRING]
|
save_uploaded_file (a_content: STRING; a_up_fn_info: GW_UPLOADED_FILE_DATA)
|
||||||
-- Save uploaded file content to `a_filename'
|
-- Save uploaded file content to `a_filename'
|
||||||
local
|
local
|
||||||
bn: STRING
|
bn: STRING
|
||||||
@@ -383,7 +432,7 @@ feature {NONE} -- Temporary File handling
|
|||||||
dn := (create {EXECUTION_ENVIRONMENT}).current_working_directory
|
dn := (create {EXECUTION_ENVIRONMENT}).current_working_directory
|
||||||
create d.make (dn)
|
create d.make (dn)
|
||||||
if d.exists and then d.is_writable then
|
if d.exists and then d.is_writable then
|
||||||
l_safe_name := safe_filename (a_filename)
|
l_safe_name := safe_filename (a_up_fn_info.name)
|
||||||
from
|
from
|
||||||
create fn.make_from_string (dn)
|
create fn.make_from_string (dn)
|
||||||
bn := "tmp-" + l_safe_name
|
bn := "tmp-" + l_safe_name
|
||||||
@@ -402,18 +451,19 @@ feature {NONE} -- Temporary File handling
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not f.exists or else f.is_writable then
|
if not f.exists or else f.is_writable then
|
||||||
|
a_up_fn_info.set_tmp_name (f.name)
|
||||||
|
a_up_fn_info.set_tmp_basename (bn)
|
||||||
f.open_write
|
f.open_write
|
||||||
f.put_string (a_content)
|
f.put_string (a_content)
|
||||||
f.close
|
f.close
|
||||||
Result := [f.name, bn]
|
|
||||||
else
|
else
|
||||||
Result := Void
|
a_up_fn_info.set_error (-1)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "Directory not writable", "Can not create file in directory %""+ dn +"%"")
|
error_handler.add_custom_error (0, "Directory not writable", "Can not create file in directory %""+ dn +"%"")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result := Void
|
a_up_fn_info.set_error (-1)
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
rescued := True
|
rescued := True
|
||||||
@@ -533,6 +583,7 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
l_header: detachable STRING
|
l_header: detachable STRING
|
||||||
l_content: detachable STRING
|
l_content: detachable STRING
|
||||||
l_line: detachable STRING
|
l_line: detachable STRING
|
||||||
|
l_up_file_info: GW_UPLOADED_FILE_DATA
|
||||||
do
|
do
|
||||||
from
|
from
|
||||||
p := 1
|
p := 1
|
||||||
@@ -625,11 +676,9 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
if l_content_type = Void then
|
if l_content_type = Void then
|
||||||
l_content_type := default_content_type
|
l_content_type := default_content_type
|
||||||
end
|
end
|
||||||
if attached save_uploaded_file (l_content, l_filename) as l_saved_fn_info then
|
create l_up_file_info.make (l_filename, l_content_type, l_content.count)
|
||||||
uploaded_files.force ([l_filename, l_content_type, l_saved_fn_info.name, l_saved_fn_info.basename, 0, l_content.count], l_name)
|
save_uploaded_file (l_content, l_up_file_info)
|
||||||
else
|
uploaded_files.force (l_up_file_info, l_name)
|
||||||
uploaded_files.force ([l_filename, l_content_type, "", "", -1, l_content.count], l_name)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
vars_post.add_variable (l_content, l_name)
|
vars_post.add_variable (l_content, l_name)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,32 +7,30 @@ note
|
|||||||
deferred class
|
deferred class
|
||||||
GW_RESPONSE
|
GW_RESPONSE
|
||||||
|
|
||||||
feature {NONE} -- Implementation: Output
|
feature {GW_APPLICATION} -- Commit
|
||||||
|
|
||||||
output: GW_OUTPUT_STREAM
|
commit (a_output_stream: GW_OUTPUT_STREAM)
|
||||||
-- Server output channel
|
-- Commit the current response
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Output header
|
|
||||||
|
|
||||||
write_header_object (h: GW_HEADER)
|
|
||||||
-- Send `header' to `output'.
|
|
||||||
do
|
do
|
||||||
h.send_to (output)
|
--| To be redefined as needed, to flush, or what you need...
|
||||||
|
a_output_stream.flush
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Output operation
|
feature -- Output operation
|
||||||
|
|
||||||
write_string (s: STRING)
|
write_string (s: STRING)
|
||||||
do
|
-- Send the content of `s'
|
||||||
output.put_string (s)
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
write_file_content (fn: STRING)
|
write_file_content (fn: STRING)
|
||||||
-- Send the content of file `fn'
|
-- Send the content of file `fn'
|
||||||
do
|
deferred
|
||||||
output.put_file_content (fn)
|
end
|
||||||
|
|
||||||
|
write_header_object (h: GW_HEADER)
|
||||||
|
-- Send `header' to `output'.
|
||||||
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
write_header (a_status: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]])
|
write_header (a_status: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]])
|
||||||
|
|||||||
@@ -20,6 +20,26 @@ feature {NONE} -- Initialization
|
|||||||
output := a_output
|
output := a_output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Output operation
|
||||||
|
|
||||||
|
write_string (s: STRING)
|
||||||
|
-- Send the content of `s'
|
||||||
|
do
|
||||||
|
output.put_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
write_file_content (fn: STRING)
|
||||||
|
-- Send the content of file `fn'
|
||||||
|
do
|
||||||
|
output.put_file_content (fn)
|
||||||
|
end
|
||||||
|
|
||||||
|
write_header_object (h: GW_HEADER)
|
||||||
|
-- Send `header' to `output'.
|
||||||
|
do
|
||||||
|
h.send_to (output)
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation: Access
|
feature {NONE} -- Implementation: Access
|
||||||
|
|
||||||
output: GW_OUTPUT_STREAM
|
output: GW_OUTPUT_STREAM
|
||||||
|
|||||||
Reference in New Issue
Block a user