PageRenderTime 28ms CodeModel.GetById 15ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/library/server/httpd/interface/response/httpd_header.e

http://github.com/jocelyn/EiffelWebReloaded
Specman e | 388 lines | 283 code | 56 blank | 49 comment | 12 complexity | 662ef160cf11b3295c28bca4c991cbcd MD5 | raw file
  1note
  2	description: "Summary description for {HTTPD_HEADER}."
  3	legal: "See notice at end of class."
  4	status: "See notice at end of class."
  5	date: "$Date$"
  6	revision: "$Revision$"
  7
  8class
  9	HTTPD_HEADER
 10
 11inherit
 12	HTTP_STATUS_CODE_MESSAGES
 13
 14create
 15	make
 16
 17feature {NONE} -- Initialization
 18
 19	make
 20			-- Initialize current
 21		do
 22			create {ARRAYED_LIST [STRING]} headers.make (3)
 23			http_version := "HTTP/1.1"
 24		end
 25
 26feature -- Recycle
 27
 28	recycle
 29		do
 30			status_code := 0
 31			status_message := Void
 32			http_version := "HTTP/1.1"
 33			headers.wipe_out
 34		end
 35
 36feature -- Access
 37
 38	headers: LIST [STRING]
 39			-- Header's lines
 40
 41	string: STRING
 42			-- String representation of the headers
 43		local
 44			l_headers: like headers
 45			h: STRING
 46		do
 47			create Result.make (32)
 48			create h.make (16)
 49			h.append_string (http_version)
 50			h.append_character (' ')
 51			h.append_integer (status_code)
 52			h.append_character (' ')
 53			if attached status_message as l_status_message then
 54				h.append_string (l_status_message)
 55			end
 56			append_line_to (h, Result)
 57
 58			l_headers := headers
 59			if l_headers.is_empty then
 60				put_content_type_text_html
 61			else
 62				from
 63					l_headers.start
 64				until
 65					l_headers.after
 66				loop
 67					append_line_to (l_headers.item, Result)
 68					l_headers.forth
 69				end
 70			end
 71			append_end_of_line_to (Result)
 72		end
 73
 74feature -- Header change: general
 75
 76	add_header (h: STRING)
 77		do
 78			headers.force (h)
 79		end
 80
 81	put_header (h: STRING)
 82			-- Add header `h' or replace existing header of same header name
 83		do
 84			force_header_by_name (header_name (h), h)
 85		end
 86
 87feature -- Content related header
 88
 89	put_content_type (t: STRING)
 90		do
 91			put_header (name_content_type + colon_space + t)
 92		end
 93
 94	add_content_type (t: STRING)
 95			-- same as `put_content_type', but allow multiple definition of "Content-Type"
 96		do
 97			put_header (name_content_type + colon_space + t)
 98		end
 99
100	put_content_type_with_name (t: STRING; n: STRING)
101		do
102			put_header (name_content_type + colon_space + t + "; name=%"" + n + "%"")
103		end
104
105	add_content_type_with_name (t: STRING; n: STRING)
106			-- same as `put_content_type_with_name', but allow multiple definition of "Content-Type"	
107		do
108			add_header (name_content_type + colon_space + t + "; name=%"" + n + "%"")
109		end
110
111	put_content_type_text_css				do put_content_type ("text/css") end
112	put_content_type_text_csv				do put_content_type ("text/csv") end
113	put_content_type_text_html				do put_content_type ("text/html") end
114	put_content_type_text_javascript		do put_content_type ("text/javascript") end
115	put_content_type_text_json				do put_content_type ("text/json") end
116	put_content_type_text_plain				do put_content_type ("text/plain") end
117	put_content_type_text_xml				do put_content_type ("text/xml") end
118
119	put_content_type_application_json		do put_content_type ("application/json") end
120	put_content_type_application_javascript	do put_content_type ("application/javascript") end
121	put_content_type_application_zip		do put_content_type ("application/zip")	end
122
123	put_content_type_image_gif				do put_content_type ("image/gif") end
124	put_content_type_image_png				do put_content_type ("image/png") end
125	put_content_type_image_jpg				do put_content_type ("image/jpg") end
126	put_content_type_image_svg_xml			do put_content_type ("image/svg+xml") end
127
128	put_content_type_message_http			do put_content_type ("message/http") end
129
130	put_content_type_multipart_mixed		do put_content_type ("multipart/mixed") end
131	put_content_type_multipart_alternative	do put_content_type ("multipart/alternative") end
132	put_content_type_multipart_related		do put_content_type ("multipart/related") end
133	put_content_type_multipart_form_data	do put_content_type ("multipart/form-data") end
134	put_content_type_multipart_signed		do put_content_type ("multipart/signed") end
135	put_content_type_multipart_encrypted	do put_content_type ("multipart/encrypted") end
136
137
138	put_content_length (n: INTEGER)
139		do
140			put_header (name_content_length + colon_space + n.out)
141		end
142
143	put_content_transfer_encoding (a_mechanism: STRING)
144			-- Put "Content-Transfer-Encoding" header with for instance "binary"
145			--|   encoding := "Content-Transfer-Encoding" ":" mechanism
146			--|
147			--|   mechanism :=     "7bit"  ;  case-insensitive
148			--|                  / "quoted-printable"
149			--|                  / "base64"
150			--|                  / "8bit"
151			--|                  / "binary"
152			--|                  / x-token
153
154		do
155			put_header ("Content-Transfer-Encoding: " + a_mechanism)
156		end
157
158	put_content_disposition (a_type: STRING; a_params: detachable STRING)
159			-- Put "Content-Disposition" header
160			--| See RFC2183
161			--|     disposition := "Content-Disposition" ":"
162			--|                    disposition-type
163			--|                    *(";" disposition-parm)
164			--|     disposition-type := "inline"
165			--|                       / "attachment"
166			--|                       / extension-token
167			--|                       ; values are not case-sensitive
168			--|     disposition-parm := filename-parm
169			--|                       / creation-date-parm
170			--|                       / modification-date-parm
171			--|                       / read-date-parm
172			--|                       / size-parm
173			--|                       / parameter
174			--|     filename-parm := "filename" "=" value
175			--|     creation-date-parm := "creation-date" "=" quoted-date-time
176			--|     modification-date-parm := "modification-date" "=" quoted-date-time
177			--|     read-date-parm := "read-date" "=" quoted-date-time
178			--|     size-parm := "size" "=" 1*DIGIT
179			--|     quoted-date-time := quoted-string
180			--|                      ; contents MUST be an RFC 822 `date-time'
181			--|                      ; numeric timezones (+HHMM or -HHMM) MUST be used
182		do
183			if a_params /= Void then
184				put_header ("Content-Disposition: " + a_type + "; " + a_params)
185			else
186				put_header ("Content-Disposition: " + a_type)
187			end
188		end
189
190feature -- Status, ...
191
192	status_code: INTEGER
193			-- Status
194
195	status_message: detachable STRING
196			-- Optional reason
197
198	http_version: STRING
199			-- HTTP version
200
201	put_status (a_code: INTEGER)
202		do
203			status_code := a_code
204			status_message := http_status_code_message (a_code)
205		end
206
207feature -- Others
208
209	put_expires (n: INTEGER)
210		do
211			put_header ("Expires: " + n.out)
212		end
213
214	put_cache_control (s: STRING)
215			-- `s' could be for instance "no-cache, must-revalidate"
216		do
217			put_header ("Cache-Control: " + s)
218		end
219
220	put_pragma (s: STRING)
221		do
222			put_header ("Pragma: " + s)
223		end
224
225	put_pragma_no_cache
226		do
227			put_pragma ("no-cache")
228		end
229
230feature -- Redirection
231
232	put_redirection (a_location: STRING; a_code: INTEGER)
233		do
234			if a_code > 0 then
235				put_status (a_code)
236			else
237				put_status (302) -- Found
238			end
239			put_header ("Location: " + a_location)
240		end
241
242	put_refresh (a_location: STRING; a_timeout: INTEGER; a_code: INTEGER)
243		do
244			if a_code > 0 then
245				put_status (a_code)
246			else
247				put_status (200) -- Ok
248			end
249			put_header ("Refresh: "+ a_timeout.out + "; url=" + a_location)
250		end
251
252feature -- Cookie
253
254	put_cookie (key, value: STRING_8; expiration, path, domain, secure: detachable STRING_8)
255			-- Set a cookie on the client's machine
256			-- with key 'key' and value 'value'.
257		require
258			make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty)
259		local
260			s: STRING
261		do
262			s := "Set-Cookie:" + key + "=" + value
263			if expiration /= Void then
264				s.append (";expires=" + expiration)
265			end
266			if path /= Void then
267				s.append (";path=" + path)
268			end
269			if domain /= Void then
270				s.append (";domain=" + domain)
271			end
272			if secure /= Void then
273				s.append (";secure=" + secure)
274			end
275			add_header (s)
276		end
277
278feature -- Status report
279
280	has_header_named (a_name: STRING): BOOLEAN
281			-- Has header item for `n'?
282		local
283			c: like headers.new_cursor
284			n: INTEGER
285		do
286			from
287				n := a_name.count
288				c := headers.new_cursor
289			until
290				c.after or Result
291			loop
292				Result := c.item.starts_with (a_name) and then c.item [n + 1] = ':'
293				c.forth
294			end
295		end
296
297	has_content_length: BOOLEAN
298			-- Has header "content_length"
299		do
300			Result := has_header_named (name_content_length)
301		end
302
303feature {NONE} -- Implementation: Header
304
305	force_header_by_name (n: detachable STRING; h: STRING)
306			-- Add header `h' or replace existing header of same header name `n'
307		require
308			h_has_name_n: (n /= Void and attached header_name (h) as hn) implies n.same_string (hn)
309		local
310			l_headers: like headers
311		do
312			if n /= Void then
313				from
314					l_headers := headers
315					l_headers.start
316				until
317					l_headers.after or l_headers.item.starts_with (n)
318				loop
319					l_headers.forth
320				end
321				if not l_headers.after then
322					l_headers.replace (h)
323				else
324					add_header (h)
325				end
326			else
327				add_header (h)
328			end
329		end
330
331	header_name (h: STRING): detachable STRING
332			-- If any, header's name with colon
333			--| ex: for "Foo-bar: something", this will return "Foo-bar:"
334		local
335			i,n: INTEGER
336			c: CHARACTER
337		do
338			from
339				i := 1
340				n := h.count
341				create Result.make (10)
342			until
343				i > n or c = ':' or Result = Void
344			loop
345				c := h[i]
346				inspect c
347				when ':' then
348					Result.extend (c)
349				when '-', 'a' .. 'z', 'A' .. 'Z' then
350					Result.extend (c)
351				else
352					Result := Void
353				end
354				i := i + 1
355			end
356		end
357
358feature {NONE} -- Implementation
359
360	append_line_to (s, h: STRING)
361		do
362			h.append_string (s)
363			append_end_of_line_to (h)
364		end
365
366	append_end_of_line_to (h: like string)
367		do
368			h.append_character ('%R')
369			h.append_character ('%N')
370		end
371
372feature {NONE} -- Constants
373
374	colon_space: STRING = ": "
375	name_content_length: STRING = "Content-Length"
376	name_content_type: STRING = "Content-Type"
377
378note
379	copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
380	license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
381	source: "[
382			Eiffel Software
383			5949 Hollister Ave., Goleta, CA 93117 USA
384			Telephone 805-685-1006, Fax 805-685-6869
385			Website http://www.eiffel.com
386			Customer support http://support.eiffel.com
387		]"
388end