Commit d17b1121d7da446b0d15cd91bd303693cdc010bf

Authored by Cédric RICARD
1 parent aa11d0af

Several great optimizations for HTTP server:

- headers are now read using a buffer and no more bytes per bytes
- adding headers 'Date' and 'Last-Modified' allowing to improve efficiency of browser cache
- adding header 'Server' just for decoration.
Showing 1 changed file with 215 additions and 48 deletions   Show diff stats
calexium_lib/web/CXM_multihost_http_server.anubis
@@ -592,7 +592,10 @@ type EncodingType: @@ -592,7 +592,10 @@ type EncodingType:
592 www_url, 592 www_url,
593 multipart_form_data. 593 multipart_form_data.
594 594
595 - 595 +type BufferedConnection:
  596 + buffered_connection(Connection conn,
  597 + Var(ByteArray) buffer,
  598 + Var(Int32) read_pos).
596 599
597 600
598 601
@@ -687,12 +690,55 @@ define Result(Error,Word8) @@ -687,12 +690,55 @@ define Result(Error,Word8)
687 " as dubious after "+(dead_line-*sttm)+" seconds. Total: "+ 690 " as dubious after "+(dead_line-*sttm)+" seconds. Total: "+
688 length(*list_of_dubious(dos))+"\n"); 691 length(*list_of_dubious(dos))+"\n");
689 error(timeout(dead_line)). 692 error(timeout(dead_line)).
690 - 693 +
  694 +define String
  695 + pid
  696 + =
  697 + "[" + virtual_machine_id + "] ".
  698 +
  699 +define ReadResult
  700 + read
  701 + (
  702 + BufferedConnection connection,
  703 + Int32 size,
  704 + Int32 time_out
  705 + ) =
  706 + //println(pid + "read(" + size + ")");
  707 +
  708 + if *connection.read_pos < length(*connection.buffer) then
  709 + //println(pid + " reading from buffer (size = " + length(*connection.buffer) + ", pos = " + *connection.read_pos);
  710 + with result = extract(*connection.buffer, *connection.read_pos, *connection.read_pos + size),
  711 + size_read = length(result),
  712 + connection.read_pos <- *connection.read_pos + size_read;
  713 + if size > size_read
  714 + then
  715 + //println("Wanted " + size + ", read only " + size_read);
  716 + if read(connection, size - size_read, time_out) is
  717 + {
  718 + error then error,
  719 + timeout then ok(result),
  720 + ok(ba) then ok(result + ba)
  721 + }
  722 + else ok(result)
  723 + else
  724 + //if now > dead_line then record_dubious_connection(connection,dead_line,dos) else
  725 + if read(connection.conn, 16384, time_out) is // the connection is closed after 10 minutes of inactivity
  726 + {
  727 + error then println(pid + "read failed)"); error,
  728 + timeout then timeout,
  729 + ok(ba) then
  730 +// println(pid + "ba = " + length(ba));
  731 + connection.buffer <- ba;
  732 + connection.read_pos <- 0;
  733 + //println(pid + "rb = " + length(*read_buffer));
  734 + read(connection, size, time_out)
  735 + }.
  736 +
691 737
692 define Result(Error,Word8) 738 define Result(Error,Word8)
693 read_one_byte 739 read_one_byte
694 ( 740 (
695 - Connection connection, 741 + BufferedConnection connection,
696 Int32 dead_line, 742 Int32 dead_line,
697 DenialOfService dos 743 DenialOfService dos
698 ) = 744 ) =
@@ -705,16 +751,54 @@ define Result(Error,Word8) @@ -705,16 +751,54 @@ define Result(Error,Word8)
705 ok(ba) then if nth(0,ba) is 751 ok(ba) then if nth(0,ba) is
706 { 752 {
707 failure then error(cannot_read_from_connection), 753 failure then error(cannot_read_from_connection),
708 - success(c) then ok(c) 754 + success(c) then
  755 +// println("-" + pid + "read [" + implode([c]) + "]\t");
  756 + ok(c)
709 } 757 }
710 }. 758 }.
  759 +
  760 +
  761 +variable ByteArray read_buffer = constant_byte_array(0, 0).
  762 +variable Int32 read_offset = 0.
  763 +
  764 + define Result(Error,Word8)
  765 + read_one_byte
  766 + (
  767 + BufferedConnection connection,
  768 + Int32 dead_line,
  769 + DenialOfService dos
  770 + ) =
  771 + if *read_offset < length(*read_buffer) then
  772 + if nth(*read_offset, *read_buffer) is
  773 + {
  774 + failure then println(pid + "nth failed)"); error(cannot_read_from_connection),
  775 + success(c) then
  776 + println("-" + pid + "read [" + implode([c]) + "]\tat " + *read_offset);
  777 + read_offset <- *read_offset + 1;
  778 + ok(c)
  779 + }
  780 + else
  781 + //if now > dead_line then record_dubious_connection(connection,dead_line,dos) else
  782 + println(pid + "len = " + length(*read_buffer));
  783 + if read(connection, 16384, 600) is // the connection is closed after 10 minutes of inactivity
  784 + {
  785 + error then println(pid + "read failed)"); error(cannot_read_from_connection),
  786 + timeout then error(timeout(600)),
  787 + //record_dubious_connection(connection,dead_line,dos),
  788 + ok(ba) then
  789 + println(pid + "ba = " + length(ba));
  790 + read_buffer <- ba;
  791 + read_offset <- 0;
  792 + println(pid + "rb = " + length(*read_buffer));
  793 + read_one_byte(connection, dead_line, dos)
  794 + }.
711 795
712 796
713 define Result(Error,Word8) 797 define Result(Error,Word8)
714 next_char // reading a character (check the list first, and read on the connection 798 next_char // reading a character (check the list first, and read on the connection
715 // only when the list is empty). 799 // only when the list is empty).
716 ( 800 (
717 - Connection connection, 801 + BufferedConnection connection,
718 Int32 dead_line, 802 Int32 dead_line,
719 DenialOfService dos 803 DenialOfService dos
720 ) = 804 ) =
@@ -742,13 +826,13 @@ define Result(Error,Word8) @@ -742,13 +826,13 @@ define Result(Error,Word8)
742 define Result(Error,One) 826 define Result(Error,One)
743 read_and_ignore 827 read_and_ignore
744 ( 828 (
745 - Connection connection, // to client 829 + BufferedConnection connection, // to client
746 Int32 dead_line, 830 Int32 dead_line,
747 Int32 number_of_characters, // number of characters to read and ignore 831 Int32 number_of_characters, // number of characters to read and ignore
748 DenialOfService dos 832 DenialOfService dos
749 ) = 833 ) =
750 if number_of_characters =< 0 then ok(unique) else 834 if number_of_characters =< 0 then ok(unique) else
751 - if next_char(connection,dead_line,dos) is 835 + if next_char(connection, dead_line, dos) is
752 { 836 {
753 error(msg) then error(msg), 837 error(msg) then error(msg),
754 ok(c) then read_and_ignore(connection,dead_line,number_of_characters-1,dos) 838 ok(c) then read_and_ignore(connection,dead_line,number_of_characters-1,dos)
@@ -770,12 +854,12 @@ define Result(Error,One) @@ -770,12 +854,12 @@ define Result(Error,One)
770 define Result(Error,String) 854 define Result(Error,String)
771 read_string 855 read_string
772 ( 856 (
773 - Connection connection, // connection with the client 857 + BufferedConnection connection, // connection with the client
774 Int32 dead_line, 858 Int32 dead_line,
775 List(Word8) so_far, // characters read so far (in reverse order) 859 List(Word8) so_far, // characters read so far (in reverse order)
776 DenialOfService dos 860 DenialOfService dos
777 ) = 861 ) =
778 - if next_char(connection,dead_line,dos) is 862 + if next_char(connection, dead_line,dos) is
779 { 863 {
780 error(msg) then error(msg), 864 error(msg) then error(msg),
781 ok(c) then 865 ok(c) then
@@ -1092,7 +1176,7 @@ define Bool @@ -1092,7 +1176,7 @@ define Bool
1092 define Result(Error,One) 1176 define Result(Error,One)
1093 skip_http_blanks 1177 skip_http_blanks
1094 ( 1178 (
1095 - Connection connection, 1179 + BufferedConnection connection,
1096 Int32 dead_line, 1180 Int32 dead_line,
1097 DenialOfService dos 1181 DenialOfService dos
1098 ) = 1182 ) =
@@ -1148,7 +1232,7 @@ define Result(Error,One) @@ -1148,7 +1232,7 @@ define Result(Error,One)
1148 define Result(Error,One) 1232 define Result(Error,One)
1149 read_new_line 1233 read_new_line
1150 ( 1234 (
1151 - Connection connection, 1235 + BufferedConnection connection,
1152 Int32 dead_line, 1236 Int32 dead_line,
1153 DenialOfService dos 1237 DenialOfService dos
1154 ) = 1238 ) =
@@ -1197,7 +1281,7 @@ define Result(Error,One) @@ -1197,7 +1281,7 @@ define Result(Error,One)
1197 define Result(Error,String) 1281 define Result(Error,String)
1198 read_word_aux 1282 read_word_aux
1199 ( 1283 (
1200 - Connection connection, 1284 + BufferedConnection connection,
1201 Int32 dead_line, 1285 Int32 dead_line,
1202 List(Word8) so_far, 1286 List(Word8) so_far,
1203 DenialOfService dos 1287 DenialOfService dos
@@ -1215,7 +1299,7 @@ define Result(Error,String) @@ -1215,7 +1299,7 @@ define Result(Error,String)
1215 define Result(Error,String) 1299 define Result(Error,String)
1216 read_word 1300 read_word
1217 ( 1301 (
1218 - Connection connection, 1302 + BufferedConnection connection,
1219 Int32 dead_line, 1303 Int32 dead_line,
1220 DenialOfService dos 1304 DenialOfService dos
1221 ) = 1305 ) =
@@ -1388,7 +1472,7 @@ define Result(Error,HTTP_RequestType) @@ -1388,7 +1472,7 @@ define Result(Error,HTTP_RequestType)
1388 define Result(Error,HTTP_RequestLine) 1472 define Result(Error,HTTP_RequestLine)
1389 read_request_line 1473 read_request_line
1390 ( 1474 (
1391 - Connection connection, 1475 + BufferedConnection connection,
1392 Int32 dead_line, 1476 Int32 dead_line,
1393 DenialOfService dos 1477 DenialOfService dos
1394 ) = 1478 ) =
@@ -1445,7 +1529,7 @@ define Bool @@ -1445,7 +1529,7 @@ define Bool
1445 define Result(Error,String) 1529 define Result(Error,String)
1446 read_header_name 1530 read_header_name
1447 ( 1531 (
1448 - Connection connection, 1532 + BufferedConnection connection,
1449 Int32 dead_line, 1533 Int32 dead_line,
1450 List(Word8) so_far, 1534 List(Word8) so_far,
1451 DenialOfService dos 1535 DenialOfService dos
@@ -1462,7 +1546,7 @@ define Result(Error,String) @@ -1462,7 +1546,7 @@ define Result(Error,String)
1462 define Result(Error,One) 1546 define Result(Error,One)
1463 skip_colon 1547 skip_colon
1464 ( 1548 (
1465 - Connection connection, 1549 + BufferedConnection connection,
1466 Int32 dead_line, 1550 Int32 dead_line,
1467 DenialOfService dos 1551 DenialOfService dos
1468 ) = 1552 ) =
@@ -1483,7 +1567,7 @@ define Result(Error,One) @@ -1483,7 +1567,7 @@ define Result(Error,One)
1483 define Result(Error,String) 1567 define Result(Error,String)
1484 read_header_value 1568 read_header_value
1485 ( 1569 (
1486 - Connection connection, 1570 + BufferedConnection connection,
1487 Int32 dead_line, 1571 Int32 dead_line,
1488 List(Word8) so_far, 1572 List(Word8) so_far,
1489 DenialOfService dos 1573 DenialOfService dos
@@ -1517,7 +1601,7 @@ define Result(Error,String) @@ -1517,7 +1601,7 @@ define Result(Error,String)
1517 define Result(Error,Maybe(HTTP_header)) 1601 define Result(Error,Maybe(HTTP_header))
1518 read_header 1602 read_header
1519 ( 1603 (
1520 - Connection connection, 1604 + BufferedConnection connection,
1521 Int32 dead_line, 1605 Int32 dead_line,
1522 DenialOfService dos 1606 DenialOfService dos
1523 ) = 1607 ) =
@@ -1555,7 +1639,7 @@ define Result(Error,Maybe(HTTP_header)) @@ -1555,7 +1639,7 @@ define Result(Error,Maybe(HTTP_header))
1555 define Result(Error,List(HTTP_header)) 1639 define Result(Error,List(HTTP_header))
1556 read_http_headers 1640 read_http_headers
1557 ( 1641 (
1558 - Connection connection, 1642 + BufferedConnection connection,
1559 Int32 dead_line, 1643 Int32 dead_line,
1560 DenialOfService dos 1644 DenialOfService dos
1561 ) = 1645 ) =
@@ -1626,7 +1710,7 @@ define Result(Error,Int32) @@ -1626,7 +1710,7 @@ define Result(Error,Int32)
1626 define Result(Error,ByteArray) 1710 define Result(Error,ByteArray)
1627 read_http_body 1711 read_http_body
1628 ( 1712 (
1629 - Connection connection, 1713 + BufferedConnection connection,
1630 Int32 body_size, 1714 Int32 body_size,
1631 ByteArray so_far, // when calling this function, 'so_far' is the empty byte array 1715 ByteArray so_far, // when calling this function, 'so_far' is the empty byte array
1632 Int32 retries // this function is called with retries = 10 1716 Int32 retries // this function is called with retries = 10
@@ -1850,10 +1934,68 @@ define Printable_tree @@ -1850,10 +1934,68 @@ define Printable_tree
1850 }. 1934 }.
1851 1935
1852 1936
  1937 +
  1938 +define String
  1939 + month_abrv
  1940 + (
  1941 + Date_and_Time d
  1942 + ) =
  1943 + if d.month = 1 then "Jan"
  1944 + else if d.month = 2 then "Feb"
  1945 + else if d.month = 3 then "Mar"
  1946 + else if d.month = 4 then "Apr"
  1947 + else if d.month = 5 then "May"
  1948 + else if d.month = 6 then "Jun"
  1949 + else if d.month = 7 then "Jul"
  1950 + else if d.month = 8 then "Aug"
  1951 + else if d.month = 9 then "Sep"
  1952 + else if d.month = 10 then "Oct"
  1953 + else if d.month = 11 then "Nov"
  1954 + else if d.month = 12 then "Dec"
  1955 + else
  1956 + println("Bad month value [" + d.month + "] on Date_and_Time");
  1957 + "XXX".
  1958 +
  1959 +define String
  1960 + weekday_abrv
  1961 + (
  1962 + Date_and_Time d
  1963 + ) =
  1964 + if d.week_day = 0 then "Sun"
  1965 + else if d.week_day = 1 then "Mon"
  1966 + else if d.week_day = 2 then "Tue"
  1967 + else if d.week_day = 3 then "Wed"
  1968 + else if d.week_day = 4 then "Thu"
  1969 + else if d.week_day = 5 then "Fri"
  1970 + else if d.week_day = 6 then "Sat"
  1971 + else
  1972 + println("Bad weekday value [" + d.week_day + "] on Date_and_Time");
  1973 + "XXX".
  1974 +
  1975 +/**
  1976 + * Format a date with the followin format : "Mon, 23 Jul 2007 11:33:43 GMT"
  1977 + * Currently, this function can't output a GMT time, but only local time.
  1978 + * So the final GMT is totally fake, but needed by protocol.
  1979 + */
  1980 +public define String
  1981 + format_http_date
  1982 + (
  1983 + Date_and_Time d
  1984 + ) =
  1985 + weekday_abrv(d) + ", " + zero_pad_n(2,day(d)) + " " + month_abrv(d) + " " + year(d)
  1986 + + " " + zero_pad_n(2,hour(d)) + ":" + zero_pad_n(2,minute(d)) + ":" + zero_pad_n(2,second(d)) + " GMT".
  1987 +
  1988 +/**
  1989 + * Same as previous format_http_date() function, but with seconds count from the UNIX epoch as input.
  1990 + */
  1991 +public define String
  1992 + format_http_date
  1993 + (
  1994 + Int32 date
  1995 + ) =
  1996 + format_http_date(convert_time(date)).
1853 1997
1854 -  
1855 -  
1856 - 1998 +
1857 *** [5.5] Sending a file. 1999 *** [5.5] Sending a file.
1858 2000
1859 We send 2 headers 'Content-Type' and 'Content-Length'. 2001 We send 2 headers 'Content-Type' and 'Content-Length'.
@@ -1864,12 +2006,20 @@ define List(HTTP_header) @@ -1864,12 +2006,20 @@ define List(HTTP_header)
1864 String mime_type, 2006 String mime_type,
1865 Int32 size, 2007 Int32 size,
1866 String etag, 2008 String etag,
1867 - ) =  
1868 - [  
1869 - http_header("Content-Type",mime_type),  
1870 - http_header("Etag", etag),  
1871 - http_header("Content-Length",integer_to_string(size)),  
1872 - ]. 2009 + Maybe(FileTimes) mb_ftimes,
  2010 + ) =
  2011 + with headers = (List(HTTP_header))
  2012 + [
  2013 + http_header("Content-Type",mime_type),
  2014 + http_header("Etag", etag),
  2015 + http_header("Content-Length",integer_to_string(size)),
  2016 + ],
  2017 + if mb_ftimes is
  2018 + {
  2019 + failure then headers,
  2020 + success(ftimes) then [http_header("Last-Modified", format_http_date(ftimes.last_modified)) . headers]
  2021 + }
  2022 + .
1873 2023
1874 2024
1875 2025
@@ -1905,11 +2055,12 @@ define String @@ -1905,11 +2055,12 @@ define String
1905 compute_etag 2055 compute_etag
1906 ( 2056 (
1907 String filename, 2057 String filename,
  2058 + Maybe(FileTimes) mb_ftimes,
1908 Int32 size, 2059 Int32 size,
1909 ) = 2060 ) =
1910 - if get_file_times(filename) is 2061 + if mb_ftimes is
1911 { 2062 {
1912 - failure then println("FAILED to get get_file_times() for file '" + filename + "'"); to_ascii(sha1((filename, size))), 2063 + failure then println("Warning: no file times for '" + filename + "', etag won't be very accurate."); to_ascii(sha1((filename, size))),
1913 success(ftimes) then to_ascii(sha1((filename, ftimes, size))) 2064 success(ftimes) then to_ascii(sha1((filename, ftimes, size)))
1914 }. 2065 }.
1915 2066
@@ -1943,12 +2094,13 @@ define One @@ -1943,12 +2094,13 @@ define One
1943 ) = 2094 ) =
1944 action_before_send_file(unique); 2095 action_before_send_file(unique);
1945 with input_etag = http_header_value(input_headers, "If-None-Match"), 2096 with input_etag = http_header_value(input_headers, "If-None-Match"),
1946 - current_etag = compute_etag(full_path, size), 2097 + mb_ftimes = get_file_times(full_path),
  2098 + current_etag = compute_etag(full_path, mb_ftimes, size),
1947 if are_same_etag(input_etag, current_etag) is 2099 if are_same_etag(input_etag, current_etag) is
1948 { 2100 {
1949 false then 2101 false then
1950 forget(reliable_write(connection,to_byte_array("HTTP/1.1 200 OK"+crlf))); 2102 forget(reliable_write(connection,to_byte_array("HTTP/1.1 200 OK"+crlf)));
1951 - forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, size, current_etag)) , crlf])); 2103 + forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, size, current_etag, mb_ftimes)) , crlf]));
1952 send_file_body(desc,connection,file,size,0,filename), 2104 send_file_body(desc,connection,file,size,0,filename),
1953 true then 2105 true then
1954 forget(reliable_write(connection,to_byte_array("HTTP/1.1 304 Not Modified"+crlf))); 2106 forget(reliable_write(connection,to_byte_array("HTTP/1.1 304 Not Modified"+crlf)));
@@ -1986,6 +2138,7 @@ define One @@ -1986,6 +2138,7 @@ define One
1986 Connection connection, 2138 Connection connection,
1987 String uri, 2139 String uri,
1988 List(HTTP_header) input_headers, 2140 List(HTTP_header) input_headers,
  2141 + List(HTTP_header) output_headers,
1989 Maybe(String) mbauthorization, 2142 Maybe(String) mbauthorization,
1990 One -> One action_before_send_file 2143 One -> One action_before_send_file
1991 ) = 2144 ) =
@@ -2004,7 +2157,7 @@ define One @@ -2004,7 +2157,7 @@ define One
2004 send_file(desc, 2157 send_file(desc,
2005 connection, 2158 connection,
2006 input_headers, 2159 input_headers,
2007 - [], 2160 + output_headers,
2008 size, 2161 size,
2009 file(f), 2162 file(f),
2010 uri, 2163 uri,
@@ -2034,7 +2187,7 @@ define One @@ -2034,7 +2187,7 @@ define One
2034 send_file(desc, 2187 send_file(desc,
2035 connection, 2188 connection,
2036 input_headers, 2189 input_headers,
2037 - [], 2190 + output_headers,
2038 size, 2191 size,
2039 file(f), 2192 file(f),
2040 uri, 2193 uri,
@@ -2059,6 +2212,14 @@ define One @@ -2059,6 +2212,14 @@ define One
2059 2212
2060 define List(HTTP_header) 2213 define List(HTTP_header)
2061 standard_headers 2214 standard_headers
  2215 + =
  2216 + [
  2217 + http_header("Date", format_http_date(now)),
  2218 + http_header("Server", "Anubis Embedded Server v" + major_version_number + "." + minor_version_number)
  2219 + ].
  2220 +
  2221 +define List(HTTP_header)
  2222 + standard_headers_for_html
2062 ( 2223 (
2063 Int32 answer_body_size, 2224 Int32 answer_body_size,
2064 String charset 2225 String charset
@@ -2100,7 +2261,8 @@ define One @@ -2100,7 +2261,8 @@ define One
2100 if answer_headers_body is (additional_headers,answer_body) then 2261 if answer_headers_body is (additional_headers,answer_body) then
2101 forget(reliable_write(connection, 2262 forget(reliable_write(connection,
2102 [ "HTTP/1.1 200 OK", crlf, 2263 [ "HTTP/1.1 200 OK", crlf,
2103 - format_headers(standard_headers(length(answer_body),charset(desc))), 2264 + format_headers(standard_headers),
  2265 + format_headers(standard_headers_for_html(length(answer_body),charset(desc))),
2104 format_headers(additional_headers), 2266 format_headers(additional_headers),
2105 crlf . 2267 crlf .
2106 answer_body]))) 2268 answer_body])))
@@ -2108,6 +2270,7 @@ define One @@ -2108,6 +2270,7 @@ define One
2108 connection, 2270 connection,
2109 uri, 2271 uri,
2110 headers, 2272 headers,
  2273 + standard_headers,
2111 if web_arg_value(all_web_args,"zauth") is 2274 if web_arg_value(all_web_args,"zauth") is
2112 { 2275 {
2113 not_found then failure, 2276 not_found then failure,
@@ -2551,7 +2714,7 @@ define One @@ -2551,7 +2714,7 @@ define One
2551 if answer_headers_body is (additional_headers,answer_body) then 2714 if answer_headers_body is (additional_headers,answer_body) then
2552 forget(reliable_write(connection, 2715 forget(reliable_write(connection,
2553 [ "HTTP/1.1 200 OK",crlf, 2716 [ "HTTP/1.1 200 OK",crlf,
2554 - format_headers(standard_headers(length(answer_body),charset(desc))), 2717 + format_headers(standard_headers_for_html(length(answer_body),charset(desc))),
2555 format_headers(additional_headers), 2718 format_headers(additional_headers),
2556 crlf . 2719 crlf .
2557 answer_body]))) 2720 answer_body])))
@@ -2790,14 +2953,14 @@ define One @@ -2790,14 +2953,14 @@ define One
2790 http_https_handler 2953 http_https_handler
2791 ( 2954 (
2792 List(Web_Site_Description) sites, 2955 List(Web_Site_Description) sites,
2793 - Connection connection, 2956 + BufferedConnection connection,
2794 Bool is_https, 2957 Bool is_https,
2795 DenialOfService dos 2958 DenialOfService dos
2796 ) = 2959 ) =
2797 with start_time = (Int32)now, 2960 with start_time = (Int32)now,
2798 sttm <- start_time; 2961 sttm <- start_time;
2799 if dos is denial_of_service(mc_v,rld_v,hd_v,ad_v,ld_v,ra_v) then 2962 if dos is denial_of_service(mc_v,rld_v,hd_v,ad_v,ld_v,ra_v) then
2800 - if remote_IP_address_and_port(connection) is (ip_addr,port) then 2963 + if remote_IP_address_and_port(connection.conn) is (ip_addr,port) then
2801 if read_request_line(connection,start_time+*rld_v,dos) is 2964 if read_request_line(connection,start_time+*rld_v,dos) is
2802 { 2965 {
2803 error(msg) then print(format(msg)), 2966 error(msg) then print(format(msg)),
@@ -2817,8 +2980,8 @@ define One @@ -2817,8 +2980,8 @@ define One
2817 { 2980 {
2818 error(msg) then log_journal_msg(desc,format(msg)), 2981 error(msg) then log_journal_msg(desc,format(msg)),
2819 ok(body) then 2982 ok(body) then
2820 - send_answer(host_name,desc,connection,request_line,headers,body,  
2821 - make_generate_trust_ticket(dos)) 2983 + send_answer(host_name, desc,connection.conn, request_line, headers, body,
  2984 + make_generate_trust_ticket(dos))
2822 } 2985 }
2823 } 2986 }
2824 } 2987 }
@@ -2837,11 +3000,13 @@ define Server -&gt; ((RWStream) -&gt; One) @@ -2837,11 +3000,13 @@ define Server -&gt; ((RWStream) -&gt; One)
2837 List(Web_Site_Description) sites, 3000 List(Web_Site_Description) sites,
2838 DenialOfService dos 3001 DenialOfService dos
2839 ) = 3002 ) =
2840 - (Server server) |-> (RWStream connection) |->  
2841 - if remote_IP_address_and_port(connection) is (addr,_) then 3003 + (Server server) |-> (RWStream conn) |->
  3004 + if remote_IP_address_and_port(conn) is (addr,_) then
2842 if is_dubious_IP(addr,dos) 3005 if is_dubious_IP(addr,dos)
2843 then print("Rejecting dubious IP address "+ip_addr_to_string(addr)+"\n") 3006 then print("Rejecting dubious IP address "+ip_addr_to_string(addr)+"\n")
2844 - else http_https_handler(sites,tcp(connection),false,dos). 3007 + else
  3008 + with connection = buffered_connection(tcp(conn), var(constant_byte_array(0, 0)), var(0)),
  3009 + http_https_handler(sites, connection, false, dos).
2845 3010
2846 define Server -> (SSL_Connection -> One) 3011 define Server -> (SSL_Connection -> One)
2847 make_https_handler 3012 make_https_handler
@@ -2849,8 +3014,9 @@ define Server -&gt; (SSL_Connection -&gt; One) @@ -2849,8 +3014,9 @@ define Server -&gt; (SSL_Connection -&gt; One)
2849 List(Web_Site_Description) sites, 3014 List(Web_Site_Description) sites,
2850 DenialOfService dos 3015 DenialOfService dos
2851 ) = 3016 ) =
2852 - (Server server) |-> (SSL_Connection connection) |->  
2853 - http_https_handler(sites,ssl(connection),true,dos). 3017 + (Server server) |-> (SSL_Connection conn) |->
  3018 + with connection = buffered_connection(ssl(conn), var(constant_byte_array(0, 0)), var(0)),
  3019 + http_https_handler(sites, connection, true, dos).
2854 3020
2855 3021
2856 3022
@@ -3240,11 +3406,12 @@ define Server -&gt; ((RWStream) -&gt; One) @@ -3240,11 +3406,12 @@ define Server -&gt; ((RWStream) -&gt; One)
3240 ) = 3406 ) =
3241 (Server server) |-> (RWStream conn) |-> 3407 (Server server) |-> (RWStream conn) |->
3242 with start_time = (Int32)now, 3408 with start_time = (Int32)now,
3243 - if read_request_line(tcp(conn),start_time+*request_line_delay(dos),dos) is 3409 + connection = buffered_connection(tcp(conn), var(constant_byte_array(0, 0)), var(0)),
  3410 + if read_request_line(connection, start_time+*request_line_delay(dos), dos) is
3244 { 3411 {
3245 error(msg) then print(format(msg)), 3412 error(msg) then print(format(msg)),
3246 ok(request_line) then 3413 ok(request_line) then
3247 - if read_http_headers(tcp(conn),start_time+*headers_delay(dos),dos) is 3414 + if read_http_headers(connection, start_time+*headers_delay(dos), dos) is
3248 { 3415 {
3249 error(msg) then print(format(msg)), 3416 error(msg) then print(format(msg)),
3250 ok(headers) then if get_host_header_value(headers) is 3417 ok(headers) then if get_host_header_value(headers) is