Commit b5f08a36efb7578a0910a2abde4a63f208d206e7
1 parent
e91d9dd5
add Content_Disposition for send file. This allow to determine how the file is p…
…rocess by the browser inline (to be displayed) or attachment (to be downloaded)
Showing
2 changed files
with
83 additions
and
56 deletions
Show diff stats
web/CXM_making_a_web_site.anubis
| ... | ... | @@ -341,7 +341,8 @@ public type WEB_Controller_Result: |
| 341 | 341 | String additional_script |
| 342 | 342 | ), |
| 343 | 343 | send_file( |
| 344 | - String full_path //full path with file name of the file to send | |
| 344 | + String full_path, //full path with file name of the file to send | |
| 345 | + Content_Disposition content_disposition //in which form the file must consider by the client (inline: try to display to user, attachment: save as file) | |
| 345 | 346 | ), |
| 346 | 347 | renderer_content( |
| 347 | 348 | Maybe(WEB_Session) mb_session, //modified session if success else failure |
| ... | ... | @@ -2248,15 +2249,15 @@ public define HTML_Off_Form |
| 2248 | 2249 | |
| 2249 | 2250 | |
| 2250 | 2251 | public define HTML_Off_Form |
| 2251 | - private_download | |
| 2252 | - ( | |
| 2253 | - String abs_path, | |
| 2254 | - String name, | |
| 2255 | - String extra_ext, | |
| 2256 | - String action_name, | |
| 2257 | - List((String,String)) args | |
| 2258 | - ) = | |
| 2259 | - private_download(abs_path,name,extra_ext,success((action_name,args))). | |
| 2252 | + private_download | |
| 2253 | + ( | |
| 2254 | + String abs_path, | |
| 2255 | + String name, | |
| 2256 | + String extra_ext, | |
| 2257 | + String action_name, | |
| 2258 | + List((String,String)) args | |
| 2259 | + ) = | |
| 2260 | + private_download(abs_path,name,extra_ext,success((action_name,args))). | |
| 2260 | 2261 | |
| 2261 | 2262 | . |
| 2262 | 2263 | |
| ... | ... | @@ -2501,7 +2502,8 @@ public type HTTP_Answer: |
| 2501 | 2502 | Printable_tree /*content*/), |
| 2502 | 2503 | json (HTTP_Status, /*http_status*/ |
| 2503 | 2504 | JsonValue), /*json value*/ |
| 2504 | - send_file (String file_path), //file to send to client. //TODO add call back for before, during, after send | |
| 2505 | + send_file ( String file_path, //file to send to client. //TODO add call back for before, during, after send | |
| 2506 | + Content_Disposition c_disposition), | |
| 2505 | 2507 | http_raw (Printable_tree), |
| 2506 | 2508 | html_content (HTTP_Status /*http_status*/, |
| 2507 | 2509 | HTML_Off_Form), |
| ... | ... | @@ -3655,7 +3657,7 @@ define (Maybe(WEB_Session), HTTP_Answer) |
| 3655 | 3657 | ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))), |
| 3656 | 3658 | //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, additional_script))), |
| 3657 | 3659 | ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, additional_script))), |
| 3658 | - send_file(file_path) then (failure, send_file(file_path)), | |
| 3660 | + send_file(file_path, c_disposition) then (failure, send_file(file_path, c_disposition)), | |
| 3659 | 3661 | renderer_content(session, title, content) then |
| 3660 | 3662 | with the_session = if session is {failure then _session, success(__session) then __session}, |
| 3661 | 3663 | with page_renderer = get_page_renderer(the_session, _current_page_renderer, page_renderers), |
| ... | ... | @@ -6375,8 +6377,8 @@ public define AWP_Handler_Answer //Printable_tree |
| 6375 | 6377 | content |
| 6376 | 6378 | ]) |
| 6377 | 6379 | , |
| 6378 | - send_file(file_path) then | |
| 6379 | - send_file(file_path), | |
| 6380 | + send_file(file_path, c_disposition) then | |
| 6381 | + send_file(file_path, c_disposition), | |
| 6380 | 6382 | |
| 6381 | 6383 | http_raw(Printable_tree content) then |
| 6382 | 6384 | printable_tree(content), | ... | ... |
web/CXM_multihost_http_server.anubis
| ... | ... | @@ -187,10 +187,25 @@ read web/mime.anubis |
| 187 | 187 | |
| 188 | 188 | Each site is described by a 'web site description', which is a datum of type |
| 189 | 189 | 'Web_Site_Description'. |
| 190 | +public type Content_Disposition: | |
| 191 | + inline, | |
| 192 | + attachment. | |
| 193 | + | |
| 194 | +public define String | |
| 195 | + to_String | |
| 196 | + ( | |
| 197 | + Content_Disposition c_disposition | |
| 198 | + )= | |
| 199 | + if c_disposition is | |
| 200 | + { | |
| 201 | + inline then "inline", | |
| 202 | + attachment then "attachment" | |
| 203 | + } | |
| 204 | +. | |
| 190 | 205 | |
| 191 | 206 | public type AWP_Handler_Answer: |
| 192 | 207 | printable_tree(Printable_tree p_tree), |
| 193 | - send_file(String full_path) | |
| 208 | + send_file(String full_path, Content_Disposition c_disposition) | |
| 194 | 209 | . |
| 195 | 210 | |
| 196 | 211 | public type Web_Site_Description: |
| ... | ... | @@ -2145,21 +2160,24 @@ public define String |
| 2145 | 2160 | |
| 2146 | 2161 | We send 2 headers 'Content-Type' and 'Content-Length'. |
| 2147 | 2162 | |
| 2163 | + | |
| 2164 | + | |
| 2148 | 2165 | define List(HTTP_header) |
| 2149 | 2166 | headers_for_send_file |
| 2150 | 2167 | ( |
| 2151 | - MIME mime_type, | |
| 2152 | - String filename, | |
| 2153 | - Int size, | |
| 2154 | - String etag, | |
| 2155 | - Maybe(FileTimes) mb_ftimes, | |
| 2168 | + MIME mime_type, | |
| 2169 | + String filename, | |
| 2170 | + Int size, | |
| 2171 | + String etag, | |
| 2172 | + Maybe(FileTimes) mb_ftimes, | |
| 2173 | + Content_Disposition c_disposition | |
| 2156 | 2174 | )= |
| 2157 | 2175 | with headers = (List(HTTP_header)) |
| 2158 | 2176 | [ |
| 2159 | 2177 | http_header("Content-Type", to_String(mime_type)), |
| 2160 | 2178 | http_header("Etag", "\""+etag+"\""), |
| 2161 | 2179 | http_header("Content-Length",to_decimal(size)), |
| 2162 | - http_header("Content-Disposition", "attachment; filename=\"" + filename +"\"") | |
| 2180 | + http_header("Content-Disposition", to_String(c_disposition)+"; filename=\"" + filename +"\"") | |
| 2163 | 2181 | |
| 2164 | 2182 | ], |
| 2165 | 2183 | if mb_ftimes is |
| ... | ... | @@ -2241,6 +2259,7 @@ define One |
| 2241 | 2259 | String filename, // name of file |
| 2242 | 2260 | String full_path, // full path to the file (filename included) |
| 2243 | 2261 | MIME mime_type, // mime type of the file |
| 2262 | + Content_Disposition c_disposition, // content disposition (inline, attachment) | |
| 2244 | 2263 | One -> One action_before_send_file //call to execute before sending file |
| 2245 | 2264 | ) = |
| 2246 | 2265 | action_before_send_file(unique); |
| ... | ... | @@ -2252,7 +2271,7 @@ define One |
| 2252 | 2271 | { |
| 2253 | 2272 | false then |
| 2254 | 2273 | forget(reliable_write(connection,to_byte_array("HTTP/1.1 200 OK"+crlf))); |
| 2255 | - forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, filename, size, current_etag, mb_ftimes)) , crlf])); | |
| 2274 | + forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, filename, size, current_etag, mb_ftimes, c_disposition)) , crlf])); | |
| 2256 | 2275 | //forget(copy_file_to_Connection(file, connection, size)), |
| 2257 | 2276 | send_file_body(desc,connection,file,size,0,filename), |
| 2258 | 2277 | true then |
| ... | ... | @@ -2285,33 +2304,34 @@ define Bool |
| 2285 | 2304 | except if there is a valid authorization for private download. |
| 2286 | 2305 | |
| 2287 | 2306 | define One |
| 2288 | - send_file | |
| 2289 | - ( | |
| 2290 | - Web_Site_Description desc, | |
| 2291 | - Connection connection, | |
| 2292 | - String uri, | |
| 2293 | - List(HTTP_header) input_headers, | |
| 2294 | - List(HTTP_header) output_headers, | |
| 2295 | - Maybe(String) mbauthorization, | |
| 2296 | - One -> One action_before_send_file | |
| 2297 | - ) = | |
| 2298 | - if mbauthorization is | |
| 2299 | - { | |
| 2300 | - //--- file without authorization: take it from public --- | |
| 2301 | - failure then if recognize_mime_type_from_uri(desc,uri) is | |
| 2302 | - { | |
| 2303 | - failure then log_journal_msg(desc,"No MIME type found for '"+uri+"'.\n"), | |
| 2304 | - success(mime_type) then | |
| 2305 | - with path = site_directory(desc)+"/public"+uri, | |
| 2306 | - if (Maybe(RStream))file(path, read) is | |
| 2307 | - { | |
| 2308 | - failure then | |
| 2309 | - println("HTTP/1.1 404 Not Found"+path); | |
| 2310 | - forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ | |
| 2307 | + send_file | |
| 2308 | + ( | |
| 2309 | + Web_Site_Description desc, | |
| 2310 | + Connection connection, | |
| 2311 | + String uri, | |
| 2312 | + List(HTTP_header) input_headers, | |
| 2313 | + List(HTTP_header) output_headers, | |
| 2314 | + Maybe(String) mbauthorization, | |
| 2315 | + Content_Disposition c_disposition, | |
| 2316 | + One -> One action_before_send_file | |
| 2317 | + )= | |
| 2318 | + if mbauthorization is | |
| 2319 | + { | |
| 2320 | + //--- file without authorization: take it from public --- | |
| 2321 | + failure then if recognize_mime_type_from_uri(desc,uri) is | |
| 2322 | + { | |
| 2323 | + failure then log_journal_msg(desc,"No MIME type found for '"+uri+"'.\n"), | |
| 2324 | + success(mime_type) then | |
| 2325 | + with path = site_directory(desc)+"/public"+uri, | |
| 2326 | + if (Maybe(RStream))file(path, read) is | |
| 2327 | + { | |
| 2328 | + failure then | |
| 2329 | + println("HTTP/1.1 404 Not Found"+path); | |
| 2330 | + forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ | |
| 2311 | 2331 | "Content-Length: 0"+crlf+crlf |
| 2312 | 2332 | /*+"Connection: close"+crlf+crlf*/))); |
| 2313 | - log_journal_msg(desc,"Cannot find file '"+path+"'.\n"), | |
| 2314 | - success(f) then with size = file_size(f), | |
| 2333 | + log_journal_msg(desc,"Cannot find file '"+path+"'.\n"), | |
| 2334 | + success(f) then with size = file_size(f), | |
| 2315 | 2335 | send_file(desc, |
| 2316 | 2336 | connection, |
| 2317 | 2337 | input_headers, |
| ... | ... | @@ -2321,6 +2341,7 @@ define One |
| 2321 | 2341 | uri, |
| 2322 | 2342 | path, |
| 2323 | 2343 | mime_type, |
| 2344 | + c_disposition, | |
| 2324 | 2345 | action_before_send_file) |
| 2325 | 2346 | } |
| 2326 | 2347 | }, |
| ... | ... | @@ -2336,10 +2357,10 @@ define One |
| 2336 | 2357 | if (Maybe(RStream))file(absolute_path, read) is |
| 2337 | 2358 | { |
| 2338 | 2359 | failure then |
| 2339 | - println("HTTP/1.1 404 Not Found"+absolute_path); | |
| 2340 | - forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ | |
| 2360 | + println("HTTP/1.1 404 Not Found"+absolute_path); | |
| 2361 | + forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ | |
| 2341 | 2362 | "Content-Length: 0"+crlf+crlf |
| 2342 | - /*+"Connection: close"+crlf+crlf*/))); | |
| 2363 | + ))); | |
| 2343 | 2364 | log_journal_msg(desc,"Cannot find file '"+absolute_path+"'.\n"), |
| 2344 | 2365 | success(f) then with size = file_size(f), |
| 2345 | 2366 | mime_type = if recognize_mime_type_from_uri(desc,uri) is |
| ... | ... | @@ -2356,6 +2377,7 @@ define One |
| 2356 | 2377 | uri, |
| 2357 | 2378 | absolute_path, |
| 2358 | 2379 | mime_type, |
| 2380 | + c_disposition, | |
| 2359 | 2381 | action_before_send_file) |
| 2360 | 2382 | } |
| 2361 | 2383 | ) |
| ... | ... | @@ -2369,6 +2391,7 @@ define One |
| 2369 | 2391 | Connection connection, |
| 2370 | 2392 | String uri, |
| 2371 | 2393 | String absolute_path, |
| 2394 | + Content_Disposition c_disposition, | |
| 2372 | 2395 | List(HTTP_header) input_headers, |
| 2373 | 2396 | List(HTTP_header) output_headers, |
| 2374 | 2397 | One -> One action_before_send_file |
| ... | ... | @@ -2396,6 +2419,7 @@ define One |
| 2396 | 2419 | filename+"."+extension, |
| 2397 | 2420 | absolute_path, |
| 2398 | 2421 | mime_type, |
| 2422 | + c_disposition, | |
| 2399 | 2423 | action_before_send_file |
| 2400 | 2424 | ) |
| 2401 | 2425 | } |
| ... | ... | @@ -2410,7 +2434,7 @@ public define List(HTTP_header) |
| 2410 | 2434 | = |
| 2411 | 2435 | [ |
| 2412 | 2436 | http_header("Date", format_http_date(now)), |
| 2413 | - http_header("Server", "Anubis Embedded Server v" + major_version_number + "." + minor_version_number), | |
| 2437 | + http_header("Server", "Anubis Calexium Embedded Server v" + major_version_number + "." + minor_version_number), | |
| 2414 | 2438 | /*http_header("Connection", "close"), */ |
| 2415 | 2439 | ]. |
| 2416 | 2440 | |
| ... | ... | @@ -2463,10 +2487,10 @@ define One |
| 2463 | 2487 | then |
| 2464 | 2488 | if awp_handler(desc)(host_name, http_inf, all_web_args, is_SSL(connection)) is |
| 2465 | 2489 | { |
| 2466 | - printable_tree(answer_headers_body) then | |
| 2490 | + printable_tree(answer_headers_body) then | |
| 2467 | 2491 | forget(reliable_write(connection, answer_headers_body)), |
| 2468 | - send_file(file_path) then | |
| 2469 | - send_file_answer(desc, connection, uri, file_path, headers, standard_headers, | |
| 2492 | + send_file(file_path, content_disposition) then | |
| 2493 | + send_file_answer(desc, connection, uri, file_path, content_disposition, headers, standard_headers, | |
| 2470 | 2494 | (One u) |-> before_send_file(desc)(http_inf, all_web_args)) |
| 2471 | 2495 | } |
| 2472 | 2496 | else (send_file(desc, |
| ... | ... | @@ -2479,6 +2503,7 @@ define One |
| 2479 | 2503 | not_found then failure, |
| 2480 | 2504 | found(v) then success(v) |
| 2481 | 2505 | }, |
| 2506 | + inline, | |
| 2482 | 2507 | (One u) |-> before_send_file(desc)(http_inf, all_web_args)) |
| 2483 | 2508 | //print_delta("After sending file") |
| 2484 | 2509 | )). |
| ... | ... | @@ -2980,8 +3005,8 @@ define One |
| 2980 | 3005 | { |
| 2981 | 3006 | printable_tree(answer_headers_body) then |
| 2982 | 3007 | forget(reliable_write(connection, answer_headers_body)), |
| 2983 | - send_file(file_path) then | |
| 2984 | - send_file_answer(desc, connection, uri, file_path, headers, standard_headers, | |
| 3008 | + send_file(file_path, c_disposition) then | |
| 3009 | + send_file_answer(desc, connection, uri, file_path, c_disposition, headers, standard_headers, | |
| 2985 | 3010 | (One u) |-> before_send_file(desc)(http_inf, all_web_args)) |
| 2986 | 3011 | } |
| 2987 | 3012 | ... | ... |