diff --git a/web/CXM_making_a_web_site.anubis b/web/CXM_making_a_web_site.anubis
index 43d457f..9ac67b5 100644
--- a/web/CXM_making_a_web_site.anubis
+++ b/web/CXM_making_a_web_site.anubis
@@ -350,7 +350,10 @@ public type WEB_Controller_Result:
WEB_Session session, //modified session
Printable_tree content,
String additional_script
- )
+ ),
+ send_file(
+ String full_path //full path with file name of the file to send
+ )
.
public define WEB_Controller_Result
@@ -1277,7 +1280,7 @@ public type JS_File:
public type Script:
script( String script_type,
String content).
-
+
public define JS_File
js_file
(
@@ -1298,6 +1301,13 @@ public type HTML_Head_Tag:
css_inline(String css_styles) /* Note: tags are not necessaries */
.
+public define HTML_Head_Tag
+ js_script
+ (
+ String script_content
+ )=
+ js_inline(script("text/javascript", script_content))
+.
/* Label with help */
@@ -1733,17 +1743,22 @@ public type HTML_Off_Form:
button (List(CoreAttrs), List(HTML_Off_Form) content),
i (List(CoreAttrs), String text),
span (List(CoreAttrs), String text),
+ strong (List(CoreAttrs), List(HTML_Off_Form) content),
hr (List(CoreAttrs)),
h1 (List(CoreAttrs), List(HTML_Off_Form) content),
h2 (List(CoreAttrs), List(HTML_Off_Form) content),
h3 (List(CoreAttrs), List(HTML_Off_Form) content),
h4 (List(CoreAttrs), List(HTML_Off_Form) content),
h5 (List(CoreAttrs), List(HTML_Off_Form) content),
- h6 (List(CoreAttrs), List(HTML_Off_Form) content)
+ h6 (List(CoreAttrs), List(HTML_Off_Form) content)
.
'HTML_Off_Form' defines all the elements you may put outside any form.
+public define HTML_Off_Form strong(HTML_Off_Form content) = strong([], [content]).
+public define HTML_Off_Form strong(List(HTML_Off_Form) content) = strong([], content).
+public define HTML_Off_Form strong(List(CoreAttrs) attrs, HTML_Off_Form content) = strong(attrs, [content]).
+
public define HTML_Off_Form h1(HTML_Off_Form content) = h1([], [content]).
public define HTML_Off_Form h1(List(HTML_Off_Form) content) = h1([], content).
public define HTML_Off_Form h1(List(CoreAttrs) attrs, HTML_Off_Form content) = h1(attrs, [content]).
@@ -2434,6 +2449,7 @@ 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
http_raw (Printable_tree),
html_content (HTTP_Status /*http_status*/,
HTML_Off_Form),
@@ -3160,16 +3176,15 @@ public type CommonInfo:
We need a forward declaration.
-public define Printable_tree
- format
- (
- CommonInfo cinfo,
- //String state_name,
- List(HTTP_header) headers,
- HTTP_Answer page,
- Bool is_https,
- String charset
- ).
+public define AWP_Handler_Answer
+ format
+ (
+ CommonInfo cinfo,
+ List(HTTP_header) headers,
+ HTTP_Answer page,
+ Bool is_https,
+ String charset
+ ).
define Printable_tree
@@ -3218,7 +3233,7 @@ public define Web_Site
List(Web_arg),
Bool is_https) -> $State ticket_lost_state,
List(Web_Action($State)) actions,
- $State -> HTTP_Answer compute_page,
+ $State -> HTTP_Answer compute_page,
$State -> List(HTTP_header) additional_headers,
Int timeout,
Redirections redirections,
@@ -3256,7 +3271,6 @@ public define Web_Site
HTTP_Info http_info,
List(Web_arg) lwa,
Bool is_https) |->
- //(Printable_tree)
//println(dump_web_arg_values(lwa));
since separate_web_args(lwa, http_info) is swa(mb_previous_state, mb_action_name, operands),
with new_state = if mb_previous_state is
@@ -3300,7 +3314,6 @@ public define Web_Site
},
format(info(host_name, http_port, https_port, site_directory, secret),
- //state_name,
additional_headers(new_state) + cookie_headers,
compute_page(new_state),
is_https,
@@ -3324,8 +3337,8 @@ public define Web_Site
journal_headers,
secret,
known_mime_types,
- site_handler(http_port,https_port),
- (HTTP_Info http_info, List(Web_arg) lwa) |-> if separate_web_args(lwa, http_info ) is
+ site_handler(http_port, https_port),
+ (HTTP_Info http_info, List(Web_arg) lwa) |-> if separate_web_args(lwa, http_info ) is
swa(mb_previous_state,mb_action_name,operands) then
if mb_action_name is
{
@@ -3539,7 +3552,7 @@ define (Maybe(WEB_Session), HTTP_Answer)
ajax(session, content, additional_script) then (success(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 (success(session), json(http_ok, to_html_ajax_content(content, additional_script))),
-
+ send_file(file_path) then (failure, send_file(file_path))
}
}
.
@@ -5810,6 +5823,8 @@ define Printable_tree
format(cinfo,ic_v,any_i(opts,t),format_element,is_https, action_count, head_tags),
span(opts,t) then
format(cinfo,ic_v,any_span(opts,t),format_element,is_https, action_count, head_tags),
+ strong(opts, l) then ["",flat(map(format_element,l)),"\n"],
+
hr(opts) then
format(cinfo,ic_v,any_hr(opts),format_element,is_https, action_count, head_tags),
h1(opts, l) then ["
",flat(map(format_element,l)),"
\n"],
@@ -6054,19 +6069,18 @@ public define JsonValue
])
.
-public define Printable_tree
- format
- (
- CommonInfo cinfo,
- //String state_name,
- List(HTTP_header) additional_headers,
- HTTP_Answer page,
- Bool is_https,
- String charset
- ) =
- if cinfo is info(common_name,http_port,https_port,site_directory,secret) then
- with ic_v = var((Int)0),
- p_content_head_tags = var((List(HTML_Head_Tag))[]), //list of heat_tags extracted from partial_content during format of body content
+public define AWP_Handler_Answer //Printable_tree
+ format
+ (
+ CommonInfo cinfo,
+ List(HTTP_header) additional_headers,
+ HTTP_Answer page,
+ Bool is_https,
+ String charset
+ )=
+ if cinfo is info(common_name,http_port,https_port,site_directory,secret) then
+ with ic_v = var((Int)0),
+ p_content_head_tags = var((List(HTML_Head_Tag))[]), //list of heat_tags extracted from partial_content during format of body content
if page is
{
html_page(status, head_tags, body) then
@@ -6085,15 +6099,16 @@ public define Printable_tree
"\n", format_html_head(head_tags + *p_content_head_tags, charset),"\n",
],
- [ "HTTP/1.1 " + status_string, crlf,
- format_headers(standard_headers),
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
+ format_headers(standard_headers),
format_headers(standard_headers_for("text/html", length(answer_body_header) + length(answer_body_body), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf,
answer_body_header .
answer_body_body
- ],
+ ]),
html_page(status, title, metas, css_styles, css_files, js_files, script, body) then
if body is body(options,element) then
@@ -6130,41 +6145,45 @@ public define Printable_tree
format_html_head(*p_content_head_tags, charset),
"\n"
],
-
- [ "HTTP/1.1 " + status_string, crlf,
- format_headers(standard_headers),
- format_headers(standard_headers_for("text/html", length(answer_body_header) + length(answer_body_body), success(charset))),
- format_headers(status_headers),
- format_headers(additional_headers),
- crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
+ format_headers(standard_headers),
+ format_headers(standard_headers_for("text/html", length(answer_body_header) + length(answer_body_body), success(charset))),
+ format_headers(status_headers),
+ format_headers(additional_headers),
+ crlf,
answer_body_header .
answer_body_body
- ],
+ ]),
plain_text (HTTP_Status status, String text) then
if format(status) is (status_string, status_headers) then
- [ "HTTP/1.1 " + status_string, crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(standard_headers),
format_headers(standard_headers_for("text/plain", length(text), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf,
text . (Printable_tree)[]
- ],
+ ]),
custom_text(HTTP_Status status, mime_type, String content) then
if format(status) is (status_string, status_headers) then
- [ "HTTP/1.1 " + status_string, crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(standard_headers),
format_headers(standard_headers_for(to_String(mime_type), length(content), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf,
content . (Printable_tree)[]
- ],
+ ]),
+
custom_binary(HTTP_Status status, mime_type, ByteArray content, List(HTTP_header) other_headers) then
if format(status) is (status_string, status_headers) then
- [ "HTTP/1.1 " + status_string, crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(status_headers),
format_headers(standard_headers_for(to_String(mime_type), length(content), failure)),
format_headers(status_headers),
@@ -6172,44 +6191,53 @@ public define Printable_tree
format_headers(additional_headers),
crlf,
content . (Printable_tree)[]
- ],
+ ]),
custom_tree(HTTP_Status status, mime_type, Printable_tree content) then
- if format(status) is (status_string, status_headers) then
- [ "HTTP/1.1 " + status_string, crlf,
+ if format(status) is (status_string, status_headers) then
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(standard_headers),
format_headers(standard_headers_for(to_String(mime_type), length(content), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf .
content
- ],
+ ]),
+
json(HTTP_Status status, JsonValue json_content) then
//with start = unow,
with content = (Printable_tree)format_json(json_content),
//println(show_duration_string("HTTP json format json object ", start));
if format(status) is (status_string, status_headers) then
- [ "HTTP/1.1 " + status_string, crlf,
- format_headers(standard_headers),
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
+ format_headers(standard_headers),
format_headers(standard_headers_for(to_String(mime_json), length(content), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf .
content
- ],
- http_raw(Printable_tree content) then content,
+ ])
+ ,
+ send_file(file_path) then
+ send_file(file_path),
+
+ http_raw(Printable_tree content) then
+ printable_tree(content),
html_content(HTTP_Status status, HTML_Off_Form content_HTML) then
if format(status) is (status_string, status_headers) then
with content = format(cinfo, ic_v, content_HTML, is_https, var(0), p_content_head_tags),
- [ "HTTP/1.1 " + status_string, crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(standard_headers),
format_headers(standard_headers_for("text/html", length(content), success(charset))),
format_headers(status_headers),
format_headers(additional_headers),
crlf .
content
- ],
+ ]),
//HMTL content with some header
html_partial_content(HTTP_Status status, HTML_Partial_Content p_content) then
@@ -6225,7 +6253,8 @@ public define Printable_tree
// html_header,
format_html_head(head_tags + *p_content_head_tags),
],
- [ "HTTP/1.1 " + status_string, crlf,
+ printable_tree([
+ "HTTP/1.1 " + status_string, crlf,
format_headers(standard_headers),
format_headers(standard_headers_for("text/html", length(answer_header) + length(answer_body), success(charset))),
format_headers(status_headers),
@@ -6233,6 +6262,6 @@ public define Printable_tree
crlf,
answer_header .
answer_body
- ],
+ ]),
}.
diff --git a/web/CXM_multihost_http_server.anubis b/web/CXM_multihost_http_server.anubis
index 113a57a..632e403 100644
--- a/web/CXM_multihost_http_server.anubis
+++ b/web/CXM_multihost_http_server.anubis
@@ -188,6 +188,11 @@ read web/mime.anubis
Each site is described by a 'web site description', which is a datum of type
'Web_Site_Description'.
+public type AWP_Handler_Answer:
+ printable_tree(Printable_tree p_tree),
+ send_file(String full_path)
+.
+
public type Web_Site_Description:
web_site_description(
List(String) common_names,
@@ -201,8 +206,7 @@ public type Web_Site_Description:
(String host_name,
HTTP_Info http_info,
List(Web_arg) lwa,
- Bool is_https) -> (//List(HTTP_header),
- Printable_tree) awp_handler,
+ Bool is_https) -> AWP_Handler_Answer awp_handler,
(HTTP_Info http_info,
List(Web_arg) lwa) -> One before_send_file
//Bool using_state_cookies,
@@ -2176,11 +2180,14 @@ define One
Int sent, // bytes already sent
String filename // name of file
) =
- if sent >= size then unique else
+ if sent >= size then
+ //TODO add call back on success if need
+ unique
+ else
if read(file,min(65536,size-sent),60) is
{
error then log_journal_msg(desc,"Cannot read from file '"+filename+"'.\n"),
- timeout then log_journal_msg(desc,"Cannot read from file timeoput'"+filename+"'.\n"),
+ timeout then log_journal_msg(desc,"Cannot read from file timeout'"+filename+"'.\n"),
ok(ba) then
with nr = length(ba), // get the number of bytes read
if reliable_write(connection, ba) is
@@ -2226,17 +2233,18 @@ define One
Connection connection,
List(HTTP_header) input_headers,
List(HTTP_header) headers,
- Int size,
- Connection file,
- String filename,
- String full_path,
- MIME mime_type,
- One -> One action_before_send_file
+ Int size, // size of the file to send
+ Connection file, // file to be sent already opened
+ String filename, // name of file
+ String full_path, // full path to the file (filename included)
+ MIME mime_type, // mime type of the file
+ One -> One action_before_send_file //call to execute before sending file
) =
action_before_send_file(unique);
with input_etag = http_header_value(input_headers, "If-None-Match"),
mb_ftimes = get_file_times(full_path),
- current_etag = compute_etag(full_path, mb_ftimes, size),
+ current_etag = compute_etag(full_path, mb_ftimes, size),
+
if are_same_etag(input_etag, current_etag) is
{
false then
@@ -2272,7 +2280,7 @@ define Bool
Before opening and sending a file, we check the MIME type. It must be recognized,
except if there is a valid authorization for private download.
-
+
define One
send_file
(
@@ -2350,6 +2358,43 @@ define One
)
else log_journal_msg(desc,"Cannot find or read authorization file.\n")
}.
+
+define One
+ send_file_answer
+ (
+ Web_Site_Description desc,
+ Connection connection,
+ String uri,
+ String absolute_path,
+ List(HTTP_header) input_headers,
+ List(HTTP_header) output_headers,
+ One -> One action_before_send_file
+ )=
+ 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+
+ "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 = mime("application", "octet-stream", []),
+
+ send_file(
+ desc,
+ connection,
+ input_headers,
+ output_headers,
+ size,
+ file(f),
+ uri,
+ absolute_path,
+ mime_type,
+ action_before_send_file)
+ }
+.
*** [5.6] Answering a www-url encoded request.
@@ -2410,14 +2455,15 @@ define One
if is_illegal_uri(uri,0)
then log_journal_msg(desc,"Received illegal URI: "+uri+"\n")
else (if (ext = ".awp" | ext = "")
- then (with answer_headers_body = awp_handler(desc)(host_name,
- http_inf,
- all_web_args,
- is_SSL(connection)),
- //print_delta("After page generation");
- forget(reliable_write(connection, answer_headers_body))
- //print_delta("After sending page")
- )
+ then
+ if awp_handler(desc)(host_name, http_inf, all_web_args, is_SSL(connection)) is
+ {
+ 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,
+ (One u) |-> before_send_file(desc)(http_inf, all_web_args))
+ }
else (send_file(desc,
connection,
uri,
@@ -2916,12 +2962,25 @@ define One
if is_illegal_uri(uri,0)
then log_journal_msg(desc,"Received illegal URI: "+uri+"\n")
else
- if (ext = ".awp" | ext = "") then
- (with answer_headers_body = awp_handler(desc)(host_name,
- http_info(ip_addr, host_name, uri, headers, is_SSL(connection)),
- all_web_args,
- is_SSL(connection)),
- forget(reliable_write(connection, answer_headers_body)))
+// if (ext = ".awp" | ext = "") then
+// (with answer_headers_body = awp_handler(desc)(host_name,
+// http_info(ip_addr, host_name, uri, headers, is_SSL(connection)),
+// all_web_args,
+// is_SSL(connection)),
+// forget(reliable_write(connection, answer_headers_body)))
+
+ if (ext = ".awp" | ext = "") then
+ with http_inf = http_info(ip_addr, host_name, uri, headers, is_SSL(connection)),
+ if awp_handler(desc)(host_name, http_inf, all_web_args, is_SSL(connection)) is
+ {
+ 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,
+ (One u) |-> before_send_file(desc)(http_inf, all_web_args))
+ }
+
+
else unique
}.
diff --git a/web/widgets/button.anubis b/web/widgets/button.anubis
index 88d4ae7..cc50a94 100644
--- a/web/widgets/button.anubis
+++ b/web/widgets/button.anubis
@@ -78,10 +78,18 @@ public define HTML_Partial_Content
img_button
(
String img_path,
- WEB_Action_Name url,
+ WEB_Action_Name web_action,
List((String, String)) extra_ops
)=
- img_button(img_path, [], same, url, extra_ops).
+ img_button(img_path, [], same, web_action, extra_ops).
+
+public define HTML_Partial_Content
+ img_button
+ (
+ String img_path,
+ WEB_Action_Name web_action
+ )=
+ img_button(img_path, [], same, web_action, []).
public define HTML_Partial_Content
img_button
--
libgit2 0.21.4