diff --git a/web/CXM_making_a_web_site.anubis b/web/CXM_making_a_web_site.anubis index ab89558..8b18e6b 100644 --- a/web/CXM_making_a_web_site.anubis +++ b/web/CXM_making_a_web_site.anubis @@ -341,7 +341,8 @@ public type WEB_Controller_Result: String additional_script ), send_file( - String full_path //full path with file name of the file to send + String full_path, //full path with file name of the file to send + Content_Disposition content_disposition //in which form the file must consider by the client (inline: try to display to user, attachment: save as file) ), renderer_content( Maybe(WEB_Session) mb_session, //modified session if success else failure @@ -2248,15 +2249,15 @@ public define HTML_Off_Form public define HTML_Off_Form - private_download - ( - String abs_path, - String name, - String extra_ext, - String action_name, - List((String,String)) args - ) = - private_download(abs_path,name,extra_ext,success((action_name,args))). + private_download + ( + String abs_path, + String name, + String extra_ext, + String action_name, + List((String,String)) args + ) = + private_download(abs_path,name,extra_ext,success((action_name,args))). . @@ -2501,7 +2502,8 @@ public type HTTP_Answer: Printable_tree /*content*/), json (HTTP_Status, /*http_status*/ JsonValue), /*json value*/ - send_file (String file_path), //file to send to client. //TODO add call back for before, during, after send + send_file ( String file_path, //file to send to client. //TODO add call back for before, during, after send + Content_Disposition c_disposition), http_raw (Printable_tree), html_content (HTTP_Status /*http_status*/, HTML_Off_Form), @@ -3655,7 +3657,7 @@ define (Maybe(WEB_Session), HTTP_Answer) ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))), //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, additional_script))), ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, additional_script))), - send_file(file_path) then (failure, send_file(file_path)), + send_file(file_path, c_disposition) then (failure, send_file(file_path, c_disposition)), renderer_content(session, title, content) then with the_session = if session is {failure then _session, success(__session) then __session}, with page_renderer = get_page_renderer(the_session, _current_page_renderer, page_renderers), @@ -6375,8 +6377,8 @@ public define AWP_Handler_Answer //Printable_tree content ]) , - send_file(file_path) then - send_file(file_path), + send_file(file_path, c_disposition) then + send_file(file_path, c_disposition), http_raw(Printable_tree content) then printable_tree(content), diff --git a/web/CXM_multihost_http_server.anubis b/web/CXM_multihost_http_server.anubis index afdcf89..aab3d80 100644 --- a/web/CXM_multihost_http_server.anubis +++ b/web/CXM_multihost_http_server.anubis @@ -187,10 +187,25 @@ read web/mime.anubis Each site is described by a 'web site description', which is a datum of type 'Web_Site_Description'. +public type Content_Disposition: + inline, + attachment. + +public define String + to_String + ( + Content_Disposition c_disposition + )= + if c_disposition is + { + inline then "inline", + attachment then "attachment" + } +. public type AWP_Handler_Answer: printable_tree(Printable_tree p_tree), - send_file(String full_path) + send_file(String full_path, Content_Disposition c_disposition) . public type Web_Site_Description: @@ -2145,21 +2160,24 @@ public define String We send 2 headers 'Content-Type' and 'Content-Length'. + + define List(HTTP_header) headers_for_send_file ( - MIME mime_type, - String filename, - Int size, - String etag, - Maybe(FileTimes) mb_ftimes, + MIME mime_type, + String filename, + Int size, + String etag, + Maybe(FileTimes) mb_ftimes, + Content_Disposition c_disposition )= with headers = (List(HTTP_header)) [ http_header("Content-Type", to_String(mime_type)), http_header("Etag", "\""+etag+"\""), http_header("Content-Length",to_decimal(size)), - http_header("Content-Disposition", "attachment; filename=\"" + filename +"\"") + http_header("Content-Disposition", to_String(c_disposition)+"; filename=\"" + filename +"\"") ], if mb_ftimes is @@ -2241,6 +2259,7 @@ define One String filename, // name of file String full_path, // full path to the file (filename included) MIME mime_type, // mime type of the file + Content_Disposition c_disposition, // content disposition (inline, attachment) One -> One action_before_send_file //call to execute before sending file ) = action_before_send_file(unique); @@ -2252,7 +2271,7 @@ define One { false then forget(reliable_write(connection,to_byte_array("HTTP/1.1 200 OK"+crlf))); - forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, filename, size, current_etag, mb_ftimes)) , crlf])); + forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, filename, size, current_etag, mb_ftimes, c_disposition)) , crlf])); //forget(copy_file_to_Connection(file, connection, size)), send_file_body(desc,connection,file,size,0,filename), true then @@ -2285,33 +2304,34 @@ define Bool except if there is a valid authorization for private download. define One - send_file - ( - Web_Site_Description desc, - Connection connection, - String uri, - List(HTTP_header) input_headers, - List(HTTP_header) output_headers, - Maybe(String) mbauthorization, - One -> One action_before_send_file - ) = - if mbauthorization is - { - //--- file without authorization: take it from public --- - failure then if recognize_mime_type_from_uri(desc,uri) is - { - failure then log_journal_msg(desc,"No MIME type found for '"+uri+"'.\n"), - success(mime_type) then - with path = site_directory(desc)+"/public"+uri, - if (Maybe(RStream))file(path, read) is - { - failure then - println("HTTP/1.1 404 Not Found"+path); - forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ + send_file + ( + Web_Site_Description desc, + Connection connection, + String uri, + List(HTTP_header) input_headers, + List(HTTP_header) output_headers, + Maybe(String) mbauthorization, + Content_Disposition c_disposition, + One -> One action_before_send_file + )= + if mbauthorization is + { + //--- file without authorization: take it from public --- + failure then if recognize_mime_type_from_uri(desc,uri) is + { + failure then log_journal_msg(desc,"No MIME type found for '"+uri+"'.\n"), + success(mime_type) then + with path = site_directory(desc)+"/public"+uri, + if (Maybe(RStream))file(path, read) is + { + failure then + println("HTTP/1.1 404 Not Found"+path); + forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ "Content-Length: 0"+crlf+crlf /*+"Connection: close"+crlf+crlf*/))); - log_journal_msg(desc,"Cannot find file '"+path+"'.\n"), - success(f) then with size = file_size(f), + log_journal_msg(desc,"Cannot find file '"+path+"'.\n"), + success(f) then with size = file_size(f), send_file(desc, connection, input_headers, @@ -2321,6 +2341,7 @@ define One uri, path, mime_type, + c_disposition, action_before_send_file) } }, @@ -2336,10 +2357,10 @@ define One if (Maybe(RStream))file(absolute_path, read) is { failure then - println("HTTP/1.1 404 Not Found"+absolute_path); - forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ + println("HTTP/1.1 404 Not Found"+absolute_path); + forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+ "Content-Length: 0"+crlf+crlf - /*+"Connection: close"+crlf+crlf*/))); + ))); log_journal_msg(desc,"Cannot find file '"+absolute_path+"'.\n"), success(f) then with size = file_size(f), mime_type = if recognize_mime_type_from_uri(desc,uri) is @@ -2356,6 +2377,7 @@ define One uri, absolute_path, mime_type, + c_disposition, action_before_send_file) } ) @@ -2369,6 +2391,7 @@ define One Connection connection, String uri, String absolute_path, + Content_Disposition c_disposition, List(HTTP_header) input_headers, List(HTTP_header) output_headers, One -> One action_before_send_file @@ -2396,6 +2419,7 @@ define One filename+"."+extension, absolute_path, mime_type, + c_disposition, action_before_send_file ) } @@ -2410,7 +2434,7 @@ public define List(HTTP_header) = [ http_header("Date", format_http_date(now)), - http_header("Server", "Anubis Embedded Server v" + major_version_number + "." + minor_version_number), + http_header("Server", "Anubis Calexium Embedded Server v" + major_version_number + "." + minor_version_number), /*http_header("Connection", "close"), */ ]. @@ -2463,10 +2487,10 @@ define One then if awp_handler(desc)(host_name, http_inf, all_web_args, is_SSL(connection)) is { - printable_tree(answer_headers_body) then + printable_tree(answer_headers_body) then forget(reliable_write(connection, answer_headers_body)), - send_file(file_path) then - send_file_answer(desc, connection, uri, file_path, headers, standard_headers, + send_file(file_path, content_disposition) then + send_file_answer(desc, connection, uri, file_path, content_disposition, headers, standard_headers, (One u) |-> before_send_file(desc)(http_inf, all_web_args)) } else (send_file(desc, @@ -2479,6 +2503,7 @@ define One not_found then failure, found(v) then success(v) }, + inline, (One u) |-> before_send_file(desc)(http_inf, all_web_args)) //print_delta("After sending file") )). @@ -2980,8 +3005,8 @@ define One { printable_tree(answer_headers_body) then forget(reliable_write(connection, answer_headers_body)), - send_file(file_path) then - send_file_answer(desc, connection, uri, file_path, headers, standard_headers, + send_file(file_path, c_disposition) then + send_file_answer(desc, connection, uri, file_path, c_disposition, headers, standard_headers, (One u) |-> before_send_file(desc)(http_inf, all_web_args)) } -- libgit2 0.21.4