indexing description: "[ A simple implementation of the HTTP protocol supporting GET and POST. ]" date: "$Date$" revision: "$Revision$" class EM_HTTP_PROTOCOL inherit EM_TCP_CLIENT_SOCKET export {NONE} send_string redefine make, handle_data_received end create make, make_from_address create {EM_SOCKETS} make_from_socket_id feature {NONE} -- Initialization make is do Precursor create header_received_event set_port (80) end feature -- Access user_agent: STRING path: STRING -- Path on server feature -- Element change set_user_agent (an_user_agent: like user_agent) is -- Set `user_agent' to `an_user_agent'. do user_agent := an_user_agent ensure user_agent_assigned: user_agent = an_user_agent end set_path (a_path: like path) is -- Set `path' to `a_path'. require path_not_void: a_path /= void do path := a_path ensure path_assigned: path = a_path end feature -- Events header_received_event: EM_EVENT_CHANNEL [TUPLE [STRING]] -- Header received event feature -- Basic operations get is -- Send a HTTP GET request require connected: is_connected path_set: path /= Void do send_string (http_get_command + " " + path + " " + http_version + http_end_of_line) if user_agent /= void then send_string ("User-Agent: " + user_agent + http_end_of_line) end send_string ("Host: " + address.hostname + http_end_of_command) end post (the_parameters: STRING) is -- Send a HTTP POST request require the_parameters /= void connected: is_connected path_set: path /= Void do send_string (http_post_command + " " + path + " " + http_version + http_end_of_line) send_string ("Host: " + address.hostname + http_end_of_line) if user_agent /= void then send_string ("User-Agent: " + user_agent + http_end_of_line) end send_string ("Content-Type: application/x-www-form-urlencoded" + http_end_of_line) send_string ("Content-Length: " + the_parameters.count.out + http_end_of_command) send_string (the_parameters) end reset is -- reset the object do header_received := false create header.make_empty end feature {NONE} -- Implementation handle_data_received is -- Handle data received event. local length: INTEGER a_buffer: STRING header_part: STRING data_part: STRING split: INTEGER tmp: ANY do from length := 1 until length = 0 loop create a_buffer.make (1024) tmp := a_buffer.to_c length := net2_tcpread_external (net2_socket_id, $tmp, a_buffer.capacity-1) if length > 0 then a_buffer.set_count (length) if not header_received then if header = void then create header.make_empty end header.append_string (a_buffer) split := header.substring_index (http_header_end, 1) if split /= 0 then header_part := header.substring (1, split - 1) data_part := header.substring (split + 4, header.count) header_received := true header_received_event.publish ([header_part]) data_received_event.publish ([data_part]) end else data_received_event.publish ([a_buffer]) end end end end header_received: BOOLEAN header: STRING feature {NONE} -- Constants for HTTP Http_get_command: STRING is "GET" Http_post_command: STRING is "POST" Http_version: STRING is "HTTP/1.0" Http_end_of_line: STRING is "%R%N" Http_end_of_command: STRING is "%R%N%R%N" Http_header_end: STRING is "%R%N%R%N" end