note description: "Implementation for the FCGI_I interface" legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" deferred class FCGI_IMP inherit FCGI_I feature {NONE} -- Initialization make -- Initialize FCGI interface do create fcgi end fcgi: FCGI_C_API -- FastCGI C API primitives feature -- Access fcgi_environ: POINTER do Result := fcgi.environ end fcgi_end_of_input: BOOLEAN do Result := fcgi.feof (fcgi.stdin) /= 0 --| in fact, True if feof (..) = EOF end fcgi_clearerr do fcgi.clearerr (fcgi.stdin) end -- updated_environ_variables: HASH_TABLE [STRING, STRING] -- local ---- n, l_size, -- i: INTEGER -- p, v, null: POINTER -- do ---- update_eif_environ ---- Result := starting_environment_variables -- ---- p := environ_strings_pointer ($n) ---- from ---- i := 1 ---- l_size := 0 ---- create Result.make (n) ---- until ---- i > n ---- loop ---- create s.make_from_c (p.plus (l_size)) ---- l_size := l_size + s.count + 1 ---- if attached separated_variables (s) as t then ---- Result.force (t.value, t.key) ---- end ---- i := i + 1 ---- end -- -- p := fcgi.environ -- create Result.make (50) -- if p /= null then -- from -- i := 0 -- v := fcgi_i_th_environ (i,p) -- until -- v = null -- loop -- if attached separated_variables (create {STRING}.make_from_c (v)) as t then -- Result.force (t.value, t.key) -- end -- i := i + 1 -- v := fcgi_i_th_environ (i,p) -- end -- end -- end -- -- fcgi_i_th_environ (i: INTEGER; p: POINTER): POINTER -- -- Environment variable at `i'-th position of `p'. -- require -- i_valid: i >=0 -- external -- "C inline use " -- alias -- "[ -- return ((char **)$p)[$i]; -- ]" -- end feature -- FCGI connection fcgi_listen: INTEGER -- Listen to the FCGI input stream -- Return 0 for successful calls, -1 otherwise. do Result := fcgi.accept end -- update_eif_environ -- external -- "C inline use " -- alias -- "[ -- #ifdef EIF_WINDOWS -- #ifndef GetEnvironmentStringsA -- extern LPVOID WINAPI GetEnvironmentStringsA(void); -- #endif -- -- eif_environ = (char**) GetEnvironmentStringsA(); -- #endif -- ]" -- end fcgi_finish -- Finish current request from HTTP server started from -- the most recent call to `fcgi_accept'. do fcgi.finish end set_fcgi_exit_status (v: INTEGER) do fcgi.set_exit_status (-2) end feature -- FCGI output put_string (a_str: READABLE_STRING_8) -- Put `a_str' on the FastCGI stdout. local l_c_str: C_STRING do l_c_str := c_buffer l_c_str.set_string (a_str) fcgi.put_string (l_c_str.item, l_c_str.count) end feature -- Error put_error (a_message: READABLE_STRING_8) -- Put error message `a_message' on the FastCGI stderr local l_c_str: C_STRING do l_c_str := c_buffer l_c_str.set_string (a_message) fcgi.put_error (l_c_str.item, l_c_str.count) end feature -- FCGI input copy_from_stdin (n: INTEGER; f: FILE) -- Read up to n bytes from stdin and write to given file local l_c_str: C_STRING num, readsize, writecount: INTEGER done: BOOLEAN l_fcgi: like fcgi do --put_trace ("copy_from_stdin, n=" +n.out) readsize := n.min (K_input_bufsize) --put_trace ("copy_from_stdin, readsize=" +readsize.out) l_c_str := c_buffer from l_fcgi := fcgi until done or writecount >= n loop num := l_fcgi.read_content_into (l_c_str.item, readsize) --put_trace ("copy_from_stdin, num=" +num.out) if num = 0 then -- EOF done := True else f.put_managed_pointer (c_buffer.managed_data, 0, num) writecount := writecount + num end end end feature {NONE} -- Implementation: FCGI Input fill_pointer_from_stdin (p: POINTER; n: INTEGER): INTEGER -- Read up to `n' bytes from stdin and store in pointer `p' -- and return number of bytes read. do Result := fcgi.read_content_into (p, n) end feature -- I/O Routines --RFO read_stdin_into (a_str: STRING) --RFO -- Read a string from the `stdin' into `a_str'. --RFO require --RFO a_str_not_void: a_str /= Void --RFO local --RFO l_c_str: C_STRING --RFO n: INTEGER --RFO do --RFO l_c_str := c_buffer --RFO n := fcgi.read_content_into (l_c_str.item, l_c_str.capacity) --RFO a_str.set_count (n) --RFO l_c_str.read_substring_into (a_str, 1, n) --RFO end --RFO read_string_into (a_str: STRING) --RFO require --RFO exists: a_str /= Void --RFO local --RFO l_c_str: C_STRING --RFO p: POINTER --RFO do --RFO create l_c_str.make_empty (1024) --RFO p := fcgi.gets (l_c_str.item) --RFO-- if p /= default_pointer and p = l_c_str.item then --RFO a_str.resize (l_c_str.count) --RFO l_c_str.read_string_into (a_str) --RFO-- else --RFO-- put_error_line ("Bad pointer from gets") --RFO-- end --RFO end --RFO read_line --RFO -- Read up to the next end of line, or end of input --RFO -- Leave result in last_string --RFO -- Newline character is absent from result --RFO do --RFO if last_string = Void then --RFO create Result.make (K_input_bufsize) --RFO else --RFO last_string.wipe_out --RFO end --RFO-- if input_filename /= Void then --RFO-- io.read_line --RFO-- last_string.append (io.last_string) --RFO-- else --RFO read_string_into (last_string) --RFO-- end --RFO end feature {NONE} -- Implementation: environment -- environ_strings_pointer (p_nb: TYPED_POINTER [INTEGER]): POINTER -- -- Environment variable strings returned by `GetEnvironmentStringsA' -- -- `p_nb' return the count of environment variables. -- external -- "C inline use " -- alias -- "[ -- #ifdef EIF_WINDOWS -- #ifndef GetEnvironmentStringsA -- extern LPVOID WINAPI GetEnvironmentStringsA(void); -- #endif -- -- int cnt = 0; -- LPSTR vars = GetEnvironmentStringsA(); -- char** p = (char**) vars; -- -- for (; *vars; vars++) { -- while (*vars) { vars++; } -- cnt++; -- } -- -- *$p_nb = cnt; -- return (EIF_POINTER) p; -- #endif -- ]" -- end note copyright: "Copyright (c) 1984-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