/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

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