From cde771f1f9fbb88fc725550f76edd7b6d527314a Mon Sep 17 00:00:00 2001 From: totoro Date: Tue, 2 Jun 2015 02:15:09 +0200 Subject: [PATCH] [!] improve speed on receiving files under HTTP server --- web/CXM_multihost_http_server.anubis | 754 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 file changed, 437 insertions(+), 317 deletions(-) diff --git a/web/CXM_multihost_http_server.anubis b/web/CXM_multihost_http_server.anubis index fbb035a..fee6835 100644 --- a/web/CXM_multihost_http_server.anubis +++ b/web/CXM_multihost_http_server.anubis @@ -11,8 +11,9 @@ Cédric Ricard - *Revised* July 2007. - + *Revised* + June 2015 : Optimization of the file upload + July 2007 : Initial version in calexium_lib *Overviews* @@ -169,6 +170,7 @@ read tools/printable_tree.anubis read system/string.anubis read system/files.anubis read system/lists.anubis +read system/data_io.anubis read web/mime.anubis @@ -843,7 +845,6 @@ define ReadResult connection.read_pos <- *connection.read_pos + size_read; //accumulate_t1(t1_tmp); if size > size_read then - //println("Wanted " + size + ", read only " + size_read); terminal read_from_connexion(connection, size - size_read, time_out, result_buffer, position+size_read) // { @@ -862,7 +863,6 @@ define ReadResult timeout then timeout, ok(ba) then with size_read = length(ba), - //println("Wanted 32768, read only " + size_read); //the needed read is higher than the if size > size_read then put(ba, result_buffer, position, 0); @@ -934,7 +934,31 @@ define Result(Error,Word8) ok(h) }. - +define ByteArray + get_and_erase_buffer + ( + BufferedConnection connection, + SState s + )= + with head = to_byte_array(implode(*s.unput_chars)), + tail = extract(*connection.buffer, *connection.read_pos, length(*connection.buffer)), +// println("--- get_and_erase_buffer ----"); +// println("unput char length : "+length(to_string(head))); +// println("connection.read_pos : "+*connection.read_pos); +// println("connection.buffer length : "+length(*connection.buffer)); +// println(" tail length : "+length(tail)); +// println(" -- unputchar content "); +// println("["+to_string(head)+"]"); +// println(" -- buffer content "); +// println("["+to_string(*connection.buffer)+"]"); +// println(" -- tail content "); +// println("["+to_string(tail)+"]"); + s.unput_chars <- []; + connection.buffer <- constant_byte_array(0,0); + connection.read_pos <- 0; + head + tail + . + @@ -1632,43 +1656,44 @@ define Bool if ('a' +=< c & c +=< 'z') then true else if ('A' +=< c & c +=< 'Z') then true else if ('0' +=< c & c +=< '9') then true else - if c = '-' then true else + if c = '-' then true else c = '_'. define Result(Error,String) - read_header_name - ( - BufferedConnection connection, - Int dead_line, - List(Word8) so_far, - DenialOfService dos, - SState s - ) = + read_header_name + ( + BufferedConnection connection, + Int dead_line, + List(Word8) so_far, + DenialOfService dos, + SState s + ) = if next_char(connection, dead_line, dos, s) is { error(msg) then error(msg), - ok(c) then + ok(c) then if is_header_name_char(c) - then read_header_name(connection,dead_line,[to_lower(c) . so_far],dos, s) + then read_header_name(connection, dead_line, [to_lower(c) . so_far], dos, s) else unput(c, s); ok(implode(reverse(so_far))) }. define Result(Error,One) - skip_colon - ( - BufferedConnection connection, - Int dead_line, - DenialOfService dos, - SState s - ) = - if skip_http_blanks(connection, dead_line, dos, s) is - { - error(msg) then error(msg), - ok(_) then - if next_char(connection, dead_line, dos, s) is - { - error(msg) then error(msg), - ok(c) then + skip_colon + ( + BufferedConnection connection, + Int dead_line, + DenialOfService dos, + SState s + ) = + //Skip the blank char until ':' + if skip_http_blanks(connection, dead_line, dos, s) is + { + error(msg) then error(msg), + ok(_) then + if next_char(connection, dead_line, dos, s) is + { + error(msg) then error(msg), + ok(c) then if c = ':' then ok(unique) else error(colon_expected) @@ -1718,49 +1743,54 @@ define Result(Error,Maybe(HTTP_header)) DenialOfService dos, SState s ) = - if read_header_name(connection, dead_line, [], dos, s) is - { - error(msg) then error(msg), - ok(name) then - if name = "" then - if read_and_ignore(connection, dead_line, 2, dos, s) /* 13 and 10 */ is - { - error(msg) then error(msg), - ok(_) then // this is the blank line - ok(failure) // end of headers + //Find the name + if read_header_name(connection, dead_line, [], dos, s) is + { + error(msg) then error(msg), + ok(name) then + if name = "" then + if read_and_ignore(connection, dead_line, 2, dos, s) /* 13 and 10 */ is + { + error(msg) then error(msg), + ok(_) then // this is the blank line + ok(failure) // end of headers + } + //skip the ':' and blank before and after it + else if skip_colon(connection, dead_line, dos, s) is + { + error(msg) then error(msg), + ok(_) then + //skip the blank char after the ':' + if skip_http_blanks(connection, dead_line, dos, s) is + { + error(msg) then error(msg), + ok(_) then + //Now read the value + if read_header_value(connection, dead_line, [], dos, s) is + { + error(msg) then error(msg), + ok(value) then ok(success(http_header(name,value))) } - else if skip_colon(connection, dead_line, dos, s) is - { - error(msg) then error(msg), - ok(_) then if skip_http_blanks(connection, dead_line, dos, s) is - { - error(msg) then error(msg), - ok(_) then if read_header_value(connection, dead_line, [], dos, s) is - { - error(msg) then error(msg), - ok(value) then - ok(success(http_header(name,value))) - } - } - } - }. + } + } + }. Reading all the headers. define Result(Error,List(HTTP_header)) - read_http_headers - ( - BufferedConnection connection, - Int dead_line, - DenialOfService dos, - SState s - ) = - if read_header(connection, dead_line, dos, s) is - { - error(msg) then error(msg), - ok(mbh) then if mbh is + read_http_headers + ( + BufferedConnection connection, + Int dead_line, + DenialOfService dos, + SState s + ) = + if read_header(connection, dead_line, dos, s) is + { + error(msg) then error(msg), + ok(mbh) then if mbh is { failure then ok([ ]), success(header) then @@ -1784,21 +1814,21 @@ define Result(Error,List(HTTP_header)) header is not present, the size is assumed to be zero. define Result(Error,Int) - get_body_size - ( - List(HTTP_header) headers - ) = - if headers is - { - [ ] then ok(0), - [h . t] then if h is http_header(name,value) then - if name = "content-length" - then if decimal_scan(value) is - { - failure then error(incorrect_content_length_value), - success(n) then ok(n) - } - else get_body_size(t) + get_body_size + ( + List(HTTP_header) headers + ) = + if headers is + { + [ ] then ok(0), + [h . t] then if h is http_header(name,value) then + if name = "content-length" + then if decimal_scan(value) is + { + failure then error(incorrect_content_length_value), + success(n) then ok(n) + } + else get_body_size(t) }. @@ -1820,17 +1850,18 @@ define Result(Error,Int) required number of bytes. However, if the number of bytes read is zero, the connection may be broken. In that case, we must not try to read indefinitely. On the contrary, we make at most 10 retries, with a small sleeping time between any two of them. - + define Result(Error, ByteArray) read_http_body ( BufferedConnection connection, - Int body_size, - ByteArray so_far, // when calling this function, 'so_far' is the empty byte array - Int retries // this function is called with retries = 10 + Int body_size, + ByteArray so_far, // when calling this function, 'so_far' is the empty byte array + Int retries // this function is called with retries = 10 ) = if body_size = 0 then ok(constant_byte_array(0,0)) else if retries =< 0 then error(cannot_read_from_connection) else + if read_from_connexion(connection,body_size,60,constant_byte_array(body_size,0),0) is { error then error(cannot_read_from_connection), @@ -2016,19 +2047,19 @@ public define Bool define Maybe(MIME) - recognize_mime_type_from_ext - ( - String ext, - List(MIME) l - ) = - if l is - { - [ ] then success(mime("application", "octet-stream", [])), // failure, - [h . t] then if h is mime(type, subtype, extensions) then - if contains_no_case(extensions, ext) - then success(h) - else recognize_mime_type_from_ext(ext,t) - }. + recognize_mime_type_from_ext + ( + String ext, + List(MIME) l + ) = + if l is + { + [ ] then success(mime("application", "octet-stream", [])), // failure, + [h . t] then if h is mime(type, subtype, extensions) then + if contains_no_case(extensions, ext) + then success(h) + else recognize_mime_type_from_ext(ext,t) + }. define Maybe(MIME) recognize_mime_type_from_uri @@ -2038,13 +2069,8 @@ define Maybe(MIME) ) = recognize_mime_type_from_ext(get_uri_extension(uri),known_mime_types(desc)). - - - - - *** [5.4] Formating HTTP headers. This is the formating for sending to the client (hence, it has nothing to do with the @@ -2187,11 +2213,11 @@ define String Maybe(FileTimes) mb_ftimes, Int size, ) = - if mb_ftimes is - { - failure then println("Warning: no file times for '" + filename + "', etag won't be very accurate."); to_ascii(sha1((filename, size))), - success(ftimes) then to_ascii(md5((filename, ftimes, size))) - }. + if mb_ftimes is + { + failure then println("Warning: no file times for '" + filename + "', etag won't be very accurate."); to_ascii(sha1((filename, size))), + success(ftimes) then to_ascii(md5((filename, ftimes, size))) + }. define Bool are_same_etag @@ -2243,18 +2269,18 @@ define One Checking if a connection is under SSL. define Bool - is_SSL - ( - Connection c - ) = - if c is - { - file_r(_) then false, - file_w(_) then false, - file_rw(_) then false, - tcp(_) then false, - ssl(_) then true - }. + is_SSL + ( + Connection c + ) = + if c is + { + file_r(_) then false, + file_w(_) then false, + file_rw(_) then false, + tcp(_) then false, + ssl(_) then true + }. @@ -2527,10 +2553,10 @@ define Maybe(String) }. define Maybe(String) - get_boundary - ( - List(HTTP_header) headers - ) = + get_boundary + ( + List(HTTP_header) headers + )= if headers is { [ ] then failure, @@ -2586,13 +2612,13 @@ define Maybe(String) argument. define Maybe(Int) - find - ( - String what, - ByteArray where, - Int start, - Int end - ) = + find + ( + String what, + ByteArray where, + Int start, + Int end + ) = if find(to_byte_array(what),where,start) is { failure then failure, @@ -2601,7 +2627,23 @@ define Maybe(Int) then failure else success(n) }. - + +define Maybe(Int) + find + ( + String what, + String where, + Int start, + Int end + ) = + if find_string(where,what,start) is + { + failure then failure, + success(n) then + if n+length(what) >= end + then failure + else success(n) + }. define String read_attribute_value @@ -2642,26 +2684,26 @@ define Maybe(String) define Maybe((String,Maybe(String))) - find_name_and_filename - ( - ByteArray body, - Int start, - Int end - ) = - if find(to_byte_array("Content-Disposition"),body,start) is - { - failure then failure, - success(n) then - if find_attribute("name",body,n+19,end) is - { - failure then failure, - success(name_value) then if find_attribute("filename",body,n+19,end) is - { - failure then success((name_value,failure)), - success(filename_value) then success((name_value,success(filename_value))) - } - } - }. + find_name_and_filename + ( + ByteArray body, + Int start, + Int end + ) = + if find(to_byte_array("Content-Disposition"),body,start) is + { + failure then failure, + success(n) then + if find_attribute("name",body,n+19,end) is + { + failure then failure, + success(name_value) then if find_attribute("filename",body,n+19,end) is + { + failure then success((name_value,failure)), + success(filename_value) then success((name_value,success(filename_value))) + } + } + }. @@ -2697,27 +2739,38 @@ define Maybe((String,Maybe(String))) define Maybe(String) // returns the temporary file name save_uploaded_file ( - Web_Site_Description desc, - ByteArray body, - Int start, - Int end, - SState s + Web_Site_Description desc, + RStream body_fd, +// ByteArray body, + Int start, + Int end, + SState s ) = s.uploaded_file_count <- 1 + *(s.uploaded_file_count); with tfn = "_"+to_decimal(virtual_machine_id)+"_"+to_decimal(*(s.uploaded_file_count)), - if (Maybe(RWStream))file(site_directory(desc)+"/upload_temporary/"+tfn, new) is - { - failure then failure, - success(f) then - if reliable_write(file(f),extract(body,start,end)) is - { - failure then failure, - success(nw) then - if nw = end - start - then success(tfn) - else failure - } - }. +// println("save_uploaded_file to :"+site_directory(desc)+"/upload_temporary/"+tfn); +// println("start offset = "+start+" end offset = "+end); + //make data_io which is the size of the file to extract + if copy_Data_IO_to_file(make_data_io(body_fd, start, end - start), site_directory(desc)+"/upload_temporary/"+tfn) is copy_ok(_) + then success(tfn) + else failure + . + + + +// if (Maybe(RWStream))file(site_directory(desc)+"/upload_temporary/"+tfn, new) is +// { +// failure then failure, +// success(f) then +// if reliable_write(file(f),extract(body,start,end)) is +// { +// failure then failure, +// success(nw) then +// if nw = end - start +// then success(tfn) +// else failure +// } +// }. @@ -2763,94 +2816,114 @@ define String *** [5.7.6] Reading a multipart entity. define Maybe(Web_arg) - get_multipart_entity - ( - Web_Site_Description desc, - ByteArray body, - Int start, - Int end, - SState s - ) = - if find(to_byte_array(crlf+crlf),body,start) is - { - failure then failure, - success(k) then - if k >= end // must be within this entity, not the next one - then failure - else if find_name_and_filename(body,start,k) is - { - failure then failure, - success(n_mbfn) then if n_mbfn is (name,mbfn) then + get_multipart_entity + ( + Web_Site_Description desc, + String body_temp_file, + Int start_offset, //real offset in source file of the part + Int end_offset, //real offset in source file of the part + SState s + )= + //Get header of the part + if find_the_first(body_temp_file, crlf+crlf, start_offset, end_offset) is + { + failure then failure, + success(k) then + if (Maybe(RStream))file(body_temp_file, read) is + { + failure then failure, + success(body_fd) then + if read_bytes(make_data_io(body_fd, start_offset, k), k) is success(header_part) then + + if find_name_and_filename(header_part, 0, k) is + { + failure then failure, + success(n_mbfn) then if n_mbfn is (name, mbfn) then if mbfn is - { + { failure then - success(web_arg(name,to_string(extract(body,k+4,end-2)))), + if read_bytes(make_data_io(body_fd, start_offset+k+4, (end_offset-2)-(start_offset+k+4)), (end_offset-2)-(start_offset+k+4)) is success(attachement) then + success(web_arg(name,to_string(attachement))) // we must substract 2 to end because of crlf just before the boundary + else + failure, success(fn) then - if save_uploaded_file(desc, body, k+4, end-2, s) is - { - failure then failure, - success(tfn) then - success(upload(name,remove_path(fn), - site_directory(desc)+"/upload_temporary/"+tfn)) + if save_uploaded_file(desc, body_fd, start_offset+k+4, end_offset-2, s) is + { + failure then failure, + success(tfn) then success(upload(name, remove_path(fn), site_directory(desc)+"/upload_temporary/"+tfn)) } } } - }. + else + failure + } + }. define List(Web_arg) - read_multipart_form_data_encoded_web_args - ( - Web_Site_Description desc, - ByteArray body, - ByteArray __boundary, - Int i, - SState s - ) = - if find(__boundary,body,i) is - { - failure then [ ], - success(n) then - if find(__boundary,body,n+length(__boundary)) is - { - failure then [ ], - success(m) then - if get_multipart_entity(desc, body, n+length(__boundary), m, s) is - { - failure then [ ], - success(wa) then - [wa . read_multipart_form_data_encoded_web_args(desc, body, __boundary, m, s)] - } - } - }. + read_multipart_form_data_encoded_web_args + ( + Web_Site_Description desc, + String body_temp_file, + String __boundary, + Int file_offset, + SState s + ) = + with boundary_length = length(__boundary), +// println( +//"read_multipart_form_data_encoded_web_args +// boundary["+__boundary+"] +// body_temp_file : "+body_temp_file+" +// file_offset : "+file_offset); + //get the first boundary position + if find_the_first(body_temp_file, __boundary, file_offset) is + { + failure then println("first boundary not found");[ ], + success(first) then + with first = first + file_offset, //adjust the offset to real offset in file + //get the second boundary position + if find_the_first(body_temp_file, __boundary, first + boundary_length) is + { + failure then println("last boundary found");[ ], + success(last) then + with last = last + first + boundary_length, //adjust the offset to real offset in file + //Extract the file content here + if get_multipart_entity(desc, body_temp_file, first+boundary_length, last, s) is + { + failure then [ ], + success(wa) then + [wa . read_multipart_form_data_encoded_web_args(desc, body_temp_file, __boundary, last, s)] + } + } + }. define One multipart_form_data_answer ( - String host_name, - Web_Site_Description desc, - Connection connection, - Word32 ip_addr, - HTTP_RequestLine request_line, - List(HTTP_header) headers, - ByteArray body, - One -> String generate_tt, - SState s + String host_name, + Web_Site_Description desc, + Connection connection, + Word32 ip_addr, + HTTP_RequestLine request_line, + List(HTTP_header) headers, + String body_temp_file, + One -> String generate_tt, + SState s ) = - if get_boundary(headers) is - { - failure then unique, - success(boundary) then - with all_web_args = query_string(request_line) + + if get_boundary(headers) is + { + failure then unique, + success(boundary) then + with all_web_args = query_string(request_line) + read_multipart_form_data_encoded_web_args(desc, - body, - to_byte_array("--"+boundary), + body_temp_file, + "--"+boundary, 0, s), uri = uri(request_line), @@ -2967,47 +3040,46 @@ define String is achieved through the header 'Content-Type'. define EncodingType - get_encoding_type - ( - List(HTTP_header) headers - ) = - if headers is - { - [ ] then www_url, // this is the default - [h . t] then if h is http_header(name,value) then - if name = "content-type" - then if find("multipart/form-data",value,0) is - { - failure then www_url, - success(_) then multipart_form_data - } - else get_encoding_type(t) + get_encoding_type + ( + List(HTTP_header) headers + ) = + if headers is + { + [ ] then www_url, // this is the default + [h . t] then if h is http_header(name, value) then + if name = "content-type" + then if find("multipart/form-data",value,0) is + { + failure then www_url, + success(_) then multipart_form_data + } + else + get_encoding_type(t) //content-type not found, check the next header line }. -define One - send_answer - ( - String host_name, - Web_Site_Description desc, - Connection connection, - HTTP_RequestLine rqline, - List(HTTP_header) headers, - ByteArray body, - One -> String generate_tt, - SState s - ) = - if rqline is request_line(type,uri,qstring) then - with rqline2 = request_line(type,handle_redirection(redirections(desc),uri,headers),qstring), - if remote_IP_address_and_port(connection) is (ip_addr,_) then - if get_encoding_type(headers) is - { - www_url then - www_url_answer(host_name,desc,connection,ip_addr,rqline2,headers,body,generate_tt), - multipart_form_data then - multipart_form_data_answer(host_name,desc,connection,ip_addr,rqline2,headers,body,generate_tt, s) - }. + define One + send_answer + ( + String host_name, + Web_Site_Description desc, + Connection connection, + HTTP_RequestLine rqline, + List(HTTP_header) headers, + ByteArray body, + One -> String generate_tt, + SState s + )= + if rqline is request_line(type, uri, qstring) then + with rqline2 = request_line(type, handle_redirection(redirections(desc), uri, headers), qstring), + if remote_IP_address_and_port(connection) is (ip_addr,_) then + if get_encoding_type(headers) is + { + www_url then www_url_answer(host_name, desc, connection, ip_addr, rqline2, headers, body, generate_tt), + multipart_form_data then multipart_form_data_answer(host_name, desc, connection, ip_addr, rqline2, headers, body, generate_tt, s) + }. @@ -3110,54 +3182,102 @@ define One SState s ) = //t0 <- (UTime)unow; - with start_time = (Int)now, - s.sttm <- start_time; - //println("Request time: " + format_http_date(start_time)); - if dos is denial_of_service(mc_v,rld_v,hd_v,ad_v,ld_v,ra_v) then - if remote_IP_address_and_port(connection.conn) is (ip_addr,port) then - if read_request_line(connection, start_time+*rld_v, dos, s) is - { - error(msg) then print(format(msg)), - ok(request_line) then - //print_delta("read_request_line"); - if read_http_headers(connection, start_time+*hd_v, dos, s) is - { - error(msg) then print(format(msg)), - ok(headers) then //print_delta("read_http_headers"); - if get_site(headers,sites) is - { - failure then unique, - success(p) then if p is (host_name,desc) then - //print_delta("get_site"); - if get_body_size(headers) is - { - error(msg) then log_journal_msg(desc,format(msg)), - ok(body_size) then + with start_time = (Int)now, + s.sttm <- start_time; + //println("Request time: " + format_http_date(start_time)); + if dos is denial_of_service(mc_v,rld_v,hd_v,ad_v,ld_v,ra_v) then + if remote_IP_address_and_port(connection.conn) is (ip_addr,port) then + if read_request_line(connection, start_time+*rld_v, dos, s) is + { + error(msg) then print(format(msg)), + ok(rqline) then //request line + //print_delta("read_request_line"); + if read_http_headers(connection, start_time+*hd_v, dos, s) is + { + error(msg) then print(format(msg)), + ok(headers) then //print_delta("read_http_headers"); + if get_site(headers,sites) is + { + failure then unique, + success(p) then if p is (host_name, desc) then + //Body Size + if get_body_size(headers) is + { + error(msg) then log_journal_msg(desc,format(msg)), + ok(body_size) then + if rqline is request_line(type, uri, qstring) then + with rqline2 = request_line(type, handle_redirection(redirections(desc), uri, headers), qstring), + + //Get the type of encoding which decide if we read the content in ByteArray for www_url or in + //temporary file for multipart. + with generate_tt = make_generate_trust_ticket(dos), + if get_encoding_type(headers) is + { + //WWW_URL + www_url then + if read_http_body(connection,body_size,constant_byte_array(0,0),1000) is + { + error(msg) then log_journal_msg(desc,format(msg)), + ok(body) then + www_url_answer(host_name, desc, connection.conn, ip_addr, rqline2, headers, body, generate_tt); + //it's HTTP 1.1 keep-alive is default + http_https_handler(sites, connection, is_https, dos, s) + } + //MULTIPART_FORM_DATA + multipart_form_data then + + if body_size > 0 then + with t0 = (UTime)unow, + println("read body, size "+body_size); + + if get_socket_from_connection(conn(connection)) is + { + failure then println("can't get socket"), + success(source) then - with t0 = (UTime)unow, - (if body_size > 0 then - println("read body, size "+body_size) - else - unique); - if read_http_body(connection,body_size,constant_byte_array(0,0),1000) is - { - error(msg) then log_journal_msg(desc,format(msg)), - ok(body) then - with duration = (UTime) unow - t0, - (if body_size > 0 then - println("Read body "+body_size+" duration: " + __utime_to_string(duration)) - else - unique); + with tmp_body_file = "/temp/" + virtual_machine_id + "-" + now, + if (Maybe(RWStream))file(desc.site_directory + tmp_body_file, new) is + { + failure then println("can't create target file "+desc.site_directory + tmp_body_file),//nothing to write + success(target) then + + //get the content of the current buffer and unput char list + with buffer = get_and_erase_buffer(connection, s), + buffer_size = length(buffer), + //println("buffer Size = "+buffer_size); + //println("Old body size "+body_size+" New body size request = "+body_size - buffer_size); + if flush(buffer, weaken(target)) is + { + failure then println("Can't flush the buffer"), + success(_) then + if copy_file(weaken(source), weaken(target), body_size - buffer_size) is copy_ok(read_size) then + + with duration = (UTime) unow - t0, + println("Read body "+read_size+" duration: " + __utime_to_string(duration)); + + multipart_form_data_answer(host_name, desc, connection.conn, ip_addr, rqline2, headers, desc.site_directory + tmp_body_file, generate_tt, s); + + //it's HTTP 1.1 keep-alive is default + http_https_handler(sites, connection, is_https, dos, s) + + else + println("Can't copy data from stream to temporary file ") + }}} + else + println("bbody_size = 0 !") + } + //print_delta("before send_answer"); - send_answer(host_name, desc,connection.conn, request_line, headers, body, - make_generate_trust_ticket(dos), s); - //it's HTTP 1.1 keep-alive is default - http_https_handler(sites, connection, is_https, dos, s) +// with body = constant_byte_array(0,0), +// send_answer(host_name, desc,connection.conn, request_line, headers, body, +// make_generate_trust_ticket(dos), s); +// //it's HTTP 1.1 keep-alive is default +// http_https_handler(sites, connection, is_https, dos, s) //with duration = (UTime) unow - *t0, //println("Request duration: " + __utime_to_string(duration)) //println("BufferRead duration: " + __utime_to_string(*t1)); //println("next_char duration: " + __utime_to_string(*t2)) - } + } } } -- libgit2 0.21.4