mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
BREAKING(http): remove deprecated server
module (#5100)
This commit is contained in:
parent
cf2aeeb3aa
commit
051ab73026
360
.github/dependency_graph.svg
vendored
360
.github/dependency_graph.svg
vendored
@ -4,457 +4,451 @@
|
||||
<!-- Generated by graphviz version 2.44.0 (20200518.1210)
|
||||
-->
|
||||
<!-- Title: std_deps Pages: 1 -->
|
||||
<svg width="2392pt" height="404pt"
|
||||
viewBox="0.00 0.00 2392.00 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg width="2450pt" height="404pt"
|
||||
viewBox="0.00 0.00 2450.00 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)">
|
||||
<title>std_deps</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-400 2388,-400 2388,4 -4,4"/>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-400 2446,-400 2446,4 -4,4"/>
|
||||
<!-- archive -->
|
||||
<g id="node1" class="node">
|
||||
<title>archive</title>
|
||||
<ellipse fill="none" stroke="black" cx="531" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="531" y="-247.8" font-family="Times,serif" font-size="14.00">archive</text>
|
||||
<ellipse fill="none" stroke="black" cx="216" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="216" y="-247.8" font-family="Times,serif" font-size="14.00">archive</text>
|
||||
</g>
|
||||
<!-- io -->
|
||||
<g id="node2" class="node">
|
||||
<title>io</title>
|
||||
<ellipse fill="none" stroke="black" cx="531" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="531" y="-139.8" font-family="Times,serif" font-size="14.00">io</text>
|
||||
<ellipse fill="none" stroke="black" cx="216" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="216" y="-139.8" font-family="Times,serif" font-size="14.00">io</text>
|
||||
</g>
|
||||
<!-- archive->io -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>archive->io</title>
|
||||
<path fill="none" stroke="black" d="M531,-216C531,-207.85 531,-199.06 531,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="534.5,-190.33 531,-180.33 527.5,-190.33 534.5,-190.33"/>
|
||||
<path fill="none" stroke="black" d="M216,-216C216,-207.85 216,-199.06 216,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="219.5,-190.33 216,-180.33 212.5,-190.33 219.5,-190.33"/>
|
||||
</g>
|
||||
<!-- bytes -->
|
||||
<g id="node6" class="node">
|
||||
<title>bytes</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="576" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="576" y="-31.8" font-family="Times,serif" font-size="14.00">bytes</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="261" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="261" y="-31.8" font-family="Times,serif" font-size="14.00">bytes</text>
|
||||
</g>
|
||||
<!-- io->bytes -->
|
||||
<g id="edge17" class="edge">
|
||||
<g id="edge16" class="edge">
|
||||
<title>io->bytes</title>
|
||||
<path fill="none" stroke="black" d="M544.75,-110.62C548.98,-100.65 553.71,-89.51 558.17,-78.99"/>
|
||||
<polygon fill="black" stroke="black" points="561.5,-80.12 562.18,-69.55 555.05,-77.38 561.5,-80.12"/>
|
||||
<path fill="none" stroke="black" d="M229.75,-110.62C233.98,-100.65 238.71,-89.51 243.17,-78.99"/>
|
||||
<polygon fill="black" stroke="black" points="246.5,-80.12 247.18,-69.55 240.05,-77.38 246.5,-80.12"/>
|
||||
</g>
|
||||
<!-- assert -->
|
||||
<g id="node3" class="node">
|
||||
<title>assert</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1365" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1365" y="-139.8" font-family="Times,serif" font-size="14.00">assert</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1410" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1410" y="-139.8" font-family="Times,serif" font-size="14.00">assert</text>
|
||||
</g>
|
||||
<!-- internal -->
|
||||
<g id="node4" class="node">
|
||||
<title>internal</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1365" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1365" y="-31.8" font-family="Times,serif" font-size="14.00">internal</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1410" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1410" y="-31.8" font-family="Times,serif" font-size="14.00">internal</text>
|
||||
</g>
|
||||
<!-- assert->internal -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>assert->internal</title>
|
||||
<path fill="none" stroke="black" d="M1365,-108C1365,-99.85 1365,-91.06 1365,-82.54"/>
|
||||
<polygon fill="black" stroke="black" points="1368.5,-82.33 1365,-72.33 1361.5,-82.33 1368.5,-82.33"/>
|
||||
<path fill="none" stroke="black" d="M1410,-108C1410,-99.85 1410,-91.06 1410,-82.54"/>
|
||||
<polygon fill="black" stroke="black" points="1413.5,-82.33 1410,-72.33 1406.5,-82.33 1413.5,-82.33"/>
|
||||
</g>
|
||||
<!-- async -->
|
||||
<g id="node5" class="node">
|
||||
<title>async</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="929" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="929" y="-139.8" font-family="Times,serif" font-size="14.00">async</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1192" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1192" y="-139.8" font-family="Times,serif" font-size="14.00">async</text>
|
||||
</g>
|
||||
<!-- cli -->
|
||||
<g id="node7" class="node">
|
||||
<title>cli</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="171" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="171" y="-139.8" font-family="Times,serif" font-size="14.00">cli</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="486" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="486" y="-139.8" font-family="Times,serif" font-size="14.00">cli</text>
|
||||
</g>
|
||||
<!-- collections -->
|
||||
<g id="node8" class="node">
|
||||
<title>collections</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1493" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1493" y="-139.8" font-family="Times,serif" font-size="14.00">collections</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1551" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1551" y="-139.8" font-family="Times,serif" font-size="14.00">collections</text>
|
||||
</g>
|
||||
<!-- crypto -->
|
||||
<g id="node9" class="node">
|
||||
<title>crypto</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="711" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="711" y="-31.8" font-family="Times,serif" font-size="14.00">crypto</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="396" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="396" y="-31.8" font-family="Times,serif" font-size="14.00">crypto</text>
|
||||
</g>
|
||||
<!-- csv -->
|
||||
<g id="node10" class="node">
|
||||
<title>csv</title>
|
||||
<ellipse fill="none" stroke="black" cx="36" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="36" y="-247.8" font-family="Times,serif" font-size="14.00">csv</text>
|
||||
<ellipse fill="none" stroke="black" cx="126" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="126" y="-247.8" font-family="Times,serif" font-size="14.00">csv</text>
|
||||
</g>
|
||||
<!-- streams -->
|
||||
<g id="node11" class="node">
|
||||
<title>streams</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="81" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="81" y="-139.8" font-family="Times,serif" font-size="14.00">streams</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="126" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="126" y="-139.8" font-family="Times,serif" font-size="14.00">streams</text>
|
||||
</g>
|
||||
<!-- csv->streams -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>csv->streams</title>
|
||||
<path fill="none" stroke="black" d="M49.75,-218.62C53.98,-208.65 58.71,-197.51 63.17,-186.99"/>
|
||||
<polygon fill="black" stroke="black" points="66.5,-188.12 67.18,-177.55 60.05,-185.38 66.5,-188.12"/>
|
||||
<path fill="none" stroke="black" d="M126,-216C126,-207.85 126,-199.06 126,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="129.5,-190.33 126,-180.33 122.5,-190.33 129.5,-190.33"/>
|
||||
</g>
|
||||
<!-- streams->bytes -->
|
||||
<g id="edge24" class="edge">
|
||||
<g id="edge23" class="edge">
|
||||
<title>streams->bytes</title>
|
||||
<path fill="none" stroke="black" d="M107.19,-119.14C113.04,-114.84 119.46,-110.83 126,-108 264.15,-48.16 445.66,-38.05 529.66,-36.81"/>
|
||||
<polygon fill="black" stroke="black" points="529.93,-40.3 539.9,-36.69 529.86,-33.3 529.93,-40.3"/>
|
||||
<path fill="none" stroke="black" d="M153.97,-121.04C174.61,-104.83 202.85,-82.66 225.15,-65.15"/>
|
||||
<polygon fill="black" stroke="black" points="227.36,-67.86 233.06,-58.94 223.04,-62.36 227.36,-67.86"/>
|
||||
</g>
|
||||
<!-- data-\nstructures -->
|
||||
<g id="node12" class="node">
|
||||
<title>data-\nstructures</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1147" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1147" y="-148.2" font-family="Times,serif" font-size="14.00">data-</text>
|
||||
<text text-anchor="middle" x="1147" y="-131.4" font-family="Times,serif" font-size="14.00">structures</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1320" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1320" y="-148.2" font-family="Times,serif" font-size="14.00">data-</text>
|
||||
<text text-anchor="middle" x="1320" y="-131.4" font-family="Times,serif" font-size="14.00">structures</text>
|
||||
</g>
|
||||
<!-- datetime -->
|
||||
<g id="node13" class="node">
|
||||
<title>datetime</title>
|
||||
<ellipse fill="none" stroke="black" cx="1628" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1628" y="-355.8" font-family="Times,serif" font-size="14.00">datetime</text>
|
||||
<ellipse fill="none" stroke="black" cx="1686" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1686" y="-355.8" font-family="Times,serif" font-size="14.00">datetime</text>
|
||||
</g>
|
||||
<!-- dotenv -->
|
||||
<g id="node14" class="node">
|
||||
<title>dotenv</title>
|
||||
<ellipse fill="none" stroke="black" cx="1718" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1718" y="-355.8" font-family="Times,serif" font-size="14.00">dotenv</text>
|
||||
<ellipse fill="none" stroke="black" cx="1776" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1776" y="-355.8" font-family="Times,serif" font-size="14.00">dotenv</text>
|
||||
</g>
|
||||
<!-- encoding -->
|
||||
<g id="node15" class="node">
|
||||
<title>encoding</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="261" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="261" y="-139.8" font-family="Times,serif" font-size="14.00">encoding</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="756" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="756" y="-139.8" font-family="Times,serif" font-size="14.00">encoding</text>
|
||||
</g>
|
||||
<!-- expect -->
|
||||
<g id="node16" class="node">
|
||||
<title>expect</title>
|
||||
<ellipse fill="none" stroke="black" cx="1384" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1384" y="-247.8" font-family="Times,serif" font-size="14.00">expect</text>
|
||||
<ellipse fill="none" stroke="black" cx="1436" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1436" y="-247.8" font-family="Times,serif" font-size="14.00">expect</text>
|
||||
</g>
|
||||
<!-- expect->assert -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>expect->assert</title>
|
||||
<path fill="none" stroke="black" d="M1377.78,-216.29C1376.25,-207.78 1374.6,-198.55 1373,-189.65"/>
|
||||
<polygon fill="black" stroke="black" points="1376.44,-189.01 1371.24,-179.79 1369.55,-190.25 1376.44,-189.01"/>
|
||||
<path fill="none" stroke="black" d="M1427.63,-216.88C1425.45,-207.99 1423.07,-198.28 1420.78,-188.96"/>
|
||||
<polygon fill="black" stroke="black" points="1424.14,-187.94 1418.35,-179.06 1417.34,-189.6 1424.14,-187.94"/>
|
||||
</g>
|
||||
<!-- expect->internal -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>expect->internal</title>
|
||||
<path fill="none" stroke="black" d="M1398.51,-218.79C1403.15,-206.86 1407.68,-193.05 1410,-180 1415.59,-148.49 1418.92,-138.73 1410,-108 1406.41,-95.61 1399.93,-83.32 1392.99,-72.53"/>
|
||||
<polygon fill="black" stroke="black" points="1395.87,-70.54 1387.37,-64.22 1390.08,-74.47 1395.87,-70.54"/>
|
||||
<path fill="none" stroke="black" d="M1448.03,-217.76C1456.86,-188.4 1465.64,-144.68 1455,-108 1451.41,-95.61 1444.93,-83.32 1437.99,-72.53"/>
|
||||
<polygon fill="black" stroke="black" points="1440.87,-70.54 1432.37,-64.22 1435.08,-74.47 1440.87,-70.54"/>
|
||||
</g>
|
||||
<!-- fmt -->
|
||||
<g id="node17" class="node">
|
||||
<title>fmt</title>
|
||||
<ellipse fill="none" stroke="black" cx="839" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="839" y="-139.8" font-family="Times,serif" font-size="14.00">fmt</text>
|
||||
<ellipse fill="none" stroke="black" cx="884" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="884" y="-139.8" font-family="Times,serif" font-size="14.00">fmt</text>
|
||||
</g>
|
||||
<!-- front-\nmatter -->
|
||||
<g id="node18" class="node">
|
||||
<title>front-\nmatter</title>
|
||||
<ellipse fill="none" stroke="black" cx="1538" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1538" y="-364.2" font-family="Times,serif" font-size="14.00">front-</text>
|
||||
<text text-anchor="middle" x="1538" y="-347.4" font-family="Times,serif" font-size="14.00">matter</text>
|
||||
<ellipse fill="none" stroke="black" cx="1596" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1596" y="-364.2" font-family="Times,serif" font-size="14.00">front-</text>
|
||||
<text text-anchor="middle" x="1596" y="-347.4" font-family="Times,serif" font-size="14.00">matter</text>
|
||||
</g>
|
||||
<!-- toml -->
|
||||
<g id="node19" class="node">
|
||||
<title>toml</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1493" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1493" y="-247.8" font-family="Times,serif" font-size="14.00">toml</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1551" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1551" y="-247.8" font-family="Times,serif" font-size="14.00">toml</text>
|
||||
</g>
|
||||
<!-- front-\nmatter->toml -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>front-\nmatter->toml</title>
|
||||
<path fill="none" stroke="black" d="M1524.25,-326.62C1520.02,-316.65 1515.29,-305.51 1510.83,-294.99"/>
|
||||
<polygon fill="black" stroke="black" points="1513.95,-293.38 1506.82,-285.55 1507.5,-296.12 1513.95,-293.38"/>
|
||||
<path fill="none" stroke="black" d="M1582.25,-326.62C1578.02,-316.65 1573.29,-305.51 1568.83,-294.99"/>
|
||||
<polygon fill="black" stroke="black" points="1571.95,-293.38 1564.82,-285.55 1565.5,-296.12 1571.95,-293.38"/>
|
||||
</g>
|
||||
<!-- yaml -->
|
||||
<g id="node20" class="node">
|
||||
<title>yaml</title>
|
||||
<ellipse fill="none" stroke="black" cx="1583" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1583" y="-247.8" font-family="Times,serif" font-size="14.00">yaml</text>
|
||||
<ellipse fill="none" stroke="black" cx="1641" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1641" y="-247.8" font-family="Times,serif" font-size="14.00">yaml</text>
|
||||
</g>
|
||||
<!-- front-\nmatter->yaml -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>front-\nmatter->yaml</title>
|
||||
<path fill="none" stroke="black" d="M1551.75,-326.62C1555.98,-316.65 1560.71,-305.51 1565.17,-294.99"/>
|
||||
<polygon fill="black" stroke="black" points="1568.5,-296.12 1569.18,-285.55 1562.05,-293.38 1568.5,-296.12"/>
|
||||
<path fill="none" stroke="black" d="M1609.75,-326.62C1613.98,-316.65 1618.71,-305.51 1623.17,-294.99"/>
|
||||
<polygon fill="black" stroke="black" points="1626.5,-296.12 1627.18,-285.55 1620.05,-293.38 1626.5,-296.12"/>
|
||||
</g>
|
||||
<!-- toml->collections -->
|
||||
<g id="edge32" class="edge">
|
||||
<g id="edge31" class="edge">
|
||||
<title>toml->collections</title>
|
||||
<path fill="none" stroke="black" d="M1493,-216C1493,-207.85 1493,-199.06 1493,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="1496.5,-190.33 1493,-180.33 1489.5,-190.33 1496.5,-190.33"/>
|
||||
<path fill="none" stroke="black" d="M1551,-216C1551,-207.85 1551,-199.06 1551,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="1554.5,-190.33 1551,-180.33 1547.5,-190.33 1554.5,-190.33"/>
|
||||
</g>
|
||||
<!-- fs -->
|
||||
<g id="node21" class="node">
|
||||
<title>fs</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1019" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1019" y="-139.8" font-family="Times,serif" font-size="14.00">fs</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="974" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="974" y="-139.8" font-family="Times,serif" font-size="14.00">fs</text>
|
||||
</g>
|
||||
<!-- path -->
|
||||
<g id="node22" class="node">
|
||||
<title>path</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1051" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1051" y="-31.8" font-family="Times,serif" font-size="14.00">path</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1006" cy="-36" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1006" y="-31.8" font-family="Times,serif" font-size="14.00">path</text>
|
||||
</g>
|
||||
<!-- fs->path -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>fs->path</title>
|
||||
<path fill="none" stroke="black" d="M1029.21,-109.17C1031.96,-100.09 1034.96,-90.13 1037.84,-80.6"/>
|
||||
<polygon fill="black" stroke="black" points="1041.23,-81.46 1040.77,-70.87 1034.53,-79.43 1041.23,-81.46"/>
|
||||
<path fill="none" stroke="black" d="M984.21,-109.17C986.96,-100.09 989.96,-90.13 992.84,-80.6"/>
|
||||
<polygon fill="black" stroke="black" points="996.23,-81.46 995.77,-70.87 989.53,-79.43 996.23,-81.46"/>
|
||||
</g>
|
||||
<!-- html -->
|
||||
<g id="node23" class="node">
|
||||
<title>html</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1808" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1808" y="-355.8" font-family="Times,serif" font-size="14.00">html</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1866" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1866" y="-355.8" font-family="Times,serif" font-size="14.00">html</text>
|
||||
</g>
|
||||
<!-- http -->
|
||||
<g id="node24" class="node">
|
||||
<title>http</title>
|
||||
<ellipse fill="none" stroke="black" cx="396" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="396" y="-247.8" font-family="Times,serif" font-size="14.00">http</text>
|
||||
</g>
|
||||
<!-- http->async -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>http->async</title>
|
||||
<path fill="none" stroke="black" d="M428.63,-235.75C445.41,-228.57 466.41,-220.6 486,-216 658.91,-175.41 718.77,-245.16 884,-180 887.52,-178.61 891,-176.86 894.36,-174.88"/>
|
||||
<polygon fill="black" stroke="black" points="896.53,-177.63 902.95,-169.2 892.68,-171.79 896.53,-177.63"/>
|
||||
<ellipse fill="none" stroke="black" cx="666" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="666" y="-247.8" font-family="Times,serif" font-size="14.00">http</text>
|
||||
</g>
|
||||
<!-- http->cli -->
|
||||
<g id="edge14" class="edge">
|
||||
<g id="edge13" class="edge">
|
||||
<title>http->cli</title>
|
||||
<path fill="none" stroke="black" d="M361.51,-240.66C324.27,-228.76 263.86,-207.3 216,-180 212.8,-178.18 209.59,-176.14 206.42,-174"/>
|
||||
<polygon fill="black" stroke="black" points="208.39,-171.11 198.22,-168.14 204.32,-176.8 208.39,-171.11"/>
|
||||
<path fill="none" stroke="black" d="M633.46,-235.9C605.54,-222.47 564.61,-201.67 531,-180 527.91,-178.01 524.76,-175.85 521.65,-173.63"/>
|
||||
<polygon fill="black" stroke="black" points="523.65,-170.76 513.52,-167.64 519.49,-176.39 523.65,-170.76"/>
|
||||
</g>
|
||||
<!-- http->streams -->
|
||||
<g id="edge13" class="edge">
|
||||
<g id="edge12" class="edge">
|
||||
<title>http->streams</title>
|
||||
<path fill="none" stroke="black" d="M360.31,-246.3C307.05,-238.27 204.64,-218.88 126,-180 122.7,-178.37 119.41,-176.47 116.2,-174.42"/>
|
||||
<polygon fill="black" stroke="black" points="118.13,-171.51 107.91,-168.72 114.16,-177.27 118.13,-171.51"/>
|
||||
<path fill="none" stroke="black" d="M630.16,-248.26C530.92,-240.29 254.4,-215.43 171,-180 167.52,-178.52 164.07,-176.7 160.72,-174.68"/>
|
||||
<polygon fill="black" stroke="black" points="162.41,-171.6 152.16,-168.93 158.52,-177.41 162.41,-171.6"/>
|
||||
</g>
|
||||
<!-- http->encoding -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>http->encoding</title>
|
||||
<path fill="none" stroke="black" d="M368.03,-229.04C347.39,-212.83 319.15,-190.66 296.85,-173.15"/>
|
||||
<polygon fill="black" stroke="black" points="298.96,-170.36 288.94,-166.94 294.64,-175.86 298.96,-170.36"/>
|
||||
<path fill="none" stroke="black" d="M688.94,-223.98C700.37,-210.52 714.31,-194.1 726.52,-179.72"/>
|
||||
<polygon fill="black" stroke="black" points="729.29,-181.86 733.1,-171.97 723.96,-177.33 729.29,-181.86"/>
|
||||
</g>
|
||||
<!-- http->fmt -->
|
||||
<g id="edge15" class="edge">
|
||||
<g id="edge14" class="edge">
|
||||
<title>http->fmt</title>
|
||||
<path fill="none" stroke="black" d="M428.69,-235.99C445.49,-228.87 466.48,-220.87 486,-216 617.58,-183.16 662.3,-228.34 789,-180 793.77,-178.18 798.51,-175.81 803.07,-173.16"/>
|
||||
<polygon fill="black" stroke="black" points="804.98,-176.08 811.56,-167.78 801.24,-170.17 804.98,-176.08"/>
|
||||
<path fill="none" stroke="black" d="M699.81,-239.12C734.44,-226.4 789.39,-204.68 834,-180 838.29,-177.62 842.67,-174.96 846.96,-172.2"/>
|
||||
<polygon fill="black" stroke="black" points="849.22,-174.9 855.59,-166.43 845.33,-169.08 849.22,-174.9"/>
|
||||
</g>
|
||||
<!-- http->path -->
|
||||
<g id="edge11" class="edge">
|
||||
<g id="edge10" class="edge">
|
||||
<title>http->path</title>
|
||||
<path fill="none" stroke="black" d="M428.72,-236.1C445.52,-229.01 466.52,-221.01 486,-216 603.25,-185.85 656.69,-249.24 756,-180 785.68,-159.31 765.8,-130.68 794,-108 855.5,-58.53 949.09,-43.46 1004.74,-38.92"/>
|
||||
<polygon fill="black" stroke="black" points="1005.29,-42.38 1015.01,-38.16 1004.78,-35.4 1005.29,-42.38"/>
|
||||
<path fill="none" stroke="black" d="M700.05,-239.67C729.71,-228.4 772.33,-208.63 801,-180 826.6,-154.43 812.37,-132.49 839,-108 873.55,-76.23 924.45,-57.39 960.97,-47.19"/>
|
||||
<polygon fill="black" stroke="black" points="962.11,-50.51 970.86,-44.54 960.29,-43.75 962.11,-50.51"/>
|
||||
</g>
|
||||
<!-- media-\ntypes -->
|
||||
<g id="node25" class="node">
|
||||
<title>media-\ntypes</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="351" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="351" y="-148.2" font-family="Times,serif" font-size="14.00">media-</text>
|
||||
<text text-anchor="middle" x="351" y="-131.4" font-family="Times,serif" font-size="14.00">types</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="576" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="576" y="-148.2" font-family="Times,serif" font-size="14.00">media-</text>
|
||||
<text text-anchor="middle" x="576" y="-131.4" font-family="Times,serif" font-size="14.00">types</text>
|
||||
</g>
|
||||
<!-- http->media-\ntypes -->
|
||||
<g id="edge12" class="edge">
|
||||
<g id="edge11" class="edge">
|
||||
<title>http->media-\ntypes</title>
|
||||
<path fill="none" stroke="black" d="M382.25,-218.62C378.02,-208.65 373.29,-197.51 368.83,-186.99"/>
|
||||
<polygon fill="black" stroke="black" points="371.95,-185.38 364.82,-177.55 365.5,-188.12 371.95,-185.38"/>
|
||||
<path fill="none" stroke="black" d="M643.06,-223.98C631.63,-210.52 617.69,-194.1 605.48,-179.72"/>
|
||||
<polygon fill="black" stroke="black" points="608.04,-177.33 598.9,-171.97 602.71,-181.86 608.04,-177.33"/>
|
||||
</g>
|
||||
<!-- net -->
|
||||
<g id="node26" class="node">
|
||||
<title>net</title>
|
||||
<ellipse fill="none" stroke="black" cx="441" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="441" y="-139.8" font-family="Times,serif" font-size="14.00">net</text>
|
||||
<ellipse fill="none" stroke="black" cx="666" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="666" y="-139.8" font-family="Times,serif" font-size="14.00">net</text>
|
||||
</g>
|
||||
<!-- http->net -->
|
||||
<g id="edge16" class="edge">
|
||||
<g id="edge15" class="edge">
|
||||
<title>http->net</title>
|
||||
<path fill="none" stroke="black" d="M409.75,-218.62C413.98,-208.65 418.71,-197.51 423.17,-186.99"/>
|
||||
<polygon fill="black" stroke="black" points="426.5,-188.12 427.18,-177.55 420.05,-185.38 426.5,-188.12"/>
|
||||
<path fill="none" stroke="black" d="M666,-216C666,-207.85 666,-199.06 666,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="669.5,-190.33 666,-180.33 662.5,-190.33 669.5,-190.33"/>
|
||||
</g>
|
||||
<!-- ini -->
|
||||
<g id="node27" class="node">
|
||||
<title>ini</title>
|
||||
<ellipse fill="none" stroke="black" cx="1898" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1898" y="-355.8" font-family="Times,serif" font-size="14.00">ini</text>
|
||||
<ellipse fill="none" stroke="black" cx="1956" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1956" y="-355.8" font-family="Times,serif" font-size="14.00">ini</text>
|
||||
</g>
|
||||
<!-- json -->
|
||||
<g id="node28" class="node">
|
||||
<title>json</title>
|
||||
<ellipse fill="none" stroke="black" cx="126" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="126" y="-247.8" font-family="Times,serif" font-size="14.00">json</text>
|
||||
<ellipse fill="none" stroke="black" cx="36" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="36" y="-247.8" font-family="Times,serif" font-size="14.00">json</text>
|
||||
</g>
|
||||
<!-- json->streams -->
|
||||
<g id="edge18" class="edge">
|
||||
<g id="edge17" class="edge">
|
||||
<title>json->streams</title>
|
||||
<path fill="none" stroke="black" d="M112.25,-218.62C108.02,-208.65 103.29,-197.51 98.83,-186.99"/>
|
||||
<polygon fill="black" stroke="black" points="101.95,-185.38 94.82,-177.55 95.5,-188.12 101.95,-185.38"/>
|
||||
<path fill="none" stroke="black" d="M58.94,-223.98C70.37,-210.52 84.31,-194.1 96.52,-179.72"/>
|
||||
<polygon fill="black" stroke="black" points="99.29,-181.86 103.1,-171.97 93.96,-177.33 99.29,-181.86"/>
|
||||
</g>
|
||||
<!-- jsonc -->
|
||||
<g id="node29" class="node">
|
||||
<title>jsonc</title>
|
||||
<ellipse fill="none" stroke="black" cx="126" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="126" y="-355.8" font-family="Times,serif" font-size="14.00">jsonc</text>
|
||||
<ellipse fill="none" stroke="black" cx="36" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="36" y="-355.8" font-family="Times,serif" font-size="14.00">jsonc</text>
|
||||
</g>
|
||||
<!-- jsonc->json -->
|
||||
<g id="edge19" class="edge">
|
||||
<g id="edge18" class="edge">
|
||||
<title>jsonc->json</title>
|
||||
<path fill="none" stroke="black" d="M126,-324C126,-315.85 126,-307.06 126,-298.54"/>
|
||||
<polygon fill="black" stroke="black" points="129.5,-298.33 126,-288.33 122.5,-298.33 129.5,-298.33"/>
|
||||
<path fill="none" stroke="black" d="M36,-324C36,-315.85 36,-307.06 36,-298.54"/>
|
||||
<polygon fill="black" stroke="black" points="39.5,-298.33 36,-288.33 32.5,-298.33 39.5,-298.33"/>
|
||||
</g>
|
||||
<!-- log -->
|
||||
<g id="node30" class="node">
|
||||
<title>log</title>
|
||||
<ellipse fill="none" stroke="black" cx="839" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="839" y="-247.8" font-family="Times,serif" font-size="14.00">log</text>
|
||||
<ellipse fill="none" stroke="black" cx="884" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="884" y="-247.8" font-family="Times,serif" font-size="14.00">log</text>
|
||||
</g>
|
||||
<!-- log->io -->
|
||||
<g id="edge21" class="edge">
|
||||
<g id="edge20" class="edge">
|
||||
<title>log->io</title>
|
||||
<path fill="none" stroke="black" d="M803.37,-245.98C751.26,-237.65 652.19,-217.97 576,-180 572.71,-178.36 569.42,-176.45 566.21,-174.4"/>
|
||||
<polygon fill="black" stroke="black" points="568.14,-171.49 557.93,-168.69 564.17,-177.25 568.14,-171.49"/>
|
||||
<path fill="none" stroke="black" d="M849.09,-242.66C814.3,-234.64 759.25,-222.79 711,-216 611.66,-202.03 354.51,-216.32 261,-180 257.47,-178.63 253.99,-176.89 250.63,-174.91"/>
|
||||
<polygon fill="black" stroke="black" points="252.31,-171.83 242.03,-169.25 248.46,-177.68 252.31,-171.83"/>
|
||||
</g>
|
||||
<!-- log->fmt -->
|
||||
<g id="edge20" class="edge">
|
||||
<g id="edge19" class="edge">
|
||||
<title>log->fmt</title>
|
||||
<path fill="none" stroke="black" d="M839,-216C839,-207.85 839,-199.06 839,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="842.5,-190.33 839,-180.33 835.5,-190.33 842.5,-190.33"/>
|
||||
<path fill="none" stroke="black" d="M884,-216C884,-207.85 884,-199.06 884,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="887.5,-190.33 884,-180.33 880.5,-190.33 887.5,-190.33"/>
|
||||
</g>
|
||||
<!-- log->fs -->
|
||||
<g id="edge22" class="edge">
|
||||
<g id="edge21" class="edge">
|
||||
<title>log->fs</title>
|
||||
<path fill="none" stroke="black" d="M871.54,-235.9C899.46,-222.47 940.39,-201.67 974,-180 977.09,-178.01 980.24,-175.85 983.35,-173.63"/>
|
||||
<polygon fill="black" stroke="black" points="985.51,-176.39 991.48,-167.64 981.35,-170.76 985.51,-176.39"/>
|
||||
<path fill="none" stroke="black" d="M906.94,-223.98C918.37,-210.52 932.31,-194.1 944.52,-179.72"/>
|
||||
<polygon fill="black" stroke="black" points="947.29,-181.86 951.1,-171.97 941.96,-177.33 947.29,-181.86"/>
|
||||
</g>
|
||||
<!-- msgpack -->
|
||||
<g id="node31" class="node">
|
||||
<title>msgpack</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="621" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="621" y="-139.8" font-family="Times,serif" font-size="14.00">msgpack</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="306" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="306" y="-139.8" font-family="Times,serif" font-size="14.00">msgpack</text>
|
||||
</g>
|
||||
<!-- msgpack->bytes -->
|
||||
<g id="edge23" class="edge">
|
||||
<g id="edge22" class="edge">
|
||||
<title>msgpack->bytes</title>
|
||||
<path fill="none" stroke="black" d="M607.25,-110.62C603.02,-100.65 598.29,-89.51 593.83,-78.99"/>
|
||||
<polygon fill="black" stroke="black" points="596.95,-77.38 589.82,-69.55 590.5,-80.12 596.95,-77.38"/>
|
||||
<path fill="none" stroke="black" d="M292.25,-110.62C288.02,-100.65 283.29,-89.51 278.83,-78.99"/>
|
||||
<polygon fill="black" stroke="black" points="281.95,-77.38 274.82,-69.55 275.5,-80.12 281.95,-77.38"/>
|
||||
</g>
|
||||
<!-- regexp -->
|
||||
<g id="node32" class="node">
|
||||
<title>regexp</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1988" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1988" y="-355.8" font-family="Times,serif" font-size="14.00">regexp</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="2046" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2046" y="-355.8" font-family="Times,serif" font-size="14.00">regexp</text>
|
||||
</g>
|
||||
<!-- semver -->
|
||||
<g id="node33" class="node">
|
||||
<title>semver</title>
|
||||
<ellipse fill="none" stroke="black" cx="2078" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2078" y="-355.8" font-family="Times,serif" font-size="14.00">semver</text>
|
||||
<ellipse fill="none" stroke="black" cx="2136" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2136" y="-355.8" font-family="Times,serif" font-size="14.00">semver</text>
|
||||
</g>
|
||||
<!-- testing -->
|
||||
<g id="node34" class="node">
|
||||
<title>testing</title>
|
||||
<ellipse fill="none" stroke="black" cx="1083" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1083" y="-247.8" font-family="Times,serif" font-size="14.00">testing</text>
|
||||
<ellipse fill="none" stroke="black" cx="1192" cy="-252" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1192" y="-247.8" font-family="Times,serif" font-size="14.00">testing</text>
|
||||
</g>
|
||||
<!-- testing->assert -->
|
||||
<g id="edge25" class="edge">
|
||||
<g id="edge24" class="edge">
|
||||
<title>testing->assert</title>
|
||||
<path fill="none" stroke="black" d="M1118.08,-243.88C1164.66,-233.63 1248.75,-212.32 1315,-180 1319.58,-177.76 1324.21,-175.13 1328.71,-172.33"/>
|
||||
<polygon fill="black" stroke="black" points="1330.7,-175.21 1337.14,-166.79 1326.86,-169.36 1330.7,-175.21"/>
|
||||
<path fill="none" stroke="black" d="M1226.11,-240.09C1261.95,-227.93 1319.35,-206.45 1365,-180 1368.18,-178.15 1371.39,-176.11 1374.55,-173.95"/>
|
||||
<polygon fill="black" stroke="black" points="1376.66,-176.75 1382.75,-168.08 1372.58,-171.06 1376.66,-176.75"/>
|
||||
</g>
|
||||
<!-- testing->internal -->
|
||||
<g id="edge29" class="edge">
|
||||
<g id="edge28" class="edge">
|
||||
<title>testing->internal</title>
|
||||
<path fill="none" stroke="black" d="M1118.57,-246.3C1161.73,-238.95 1234.59,-221.07 1282,-180 1309.35,-156.31 1301.86,-139.31 1320,-108 1326.29,-97.15 1333.43,-85.58 1340.13,-75"/>
|
||||
<polygon fill="black" stroke="black" points="1343.21,-76.7 1345.64,-66.39 1337.31,-72.93 1343.21,-76.7"/>
|
||||
<path fill="none" stroke="black" d="M1211.36,-221.61C1219.51,-208.95 1228.95,-193.89 1237,-180 1255.14,-148.69 1249.4,-133.57 1275,-108 1300.76,-82.28 1337.78,-63.71 1366.54,-52.03"/>
|
||||
<polygon fill="black" stroke="black" points="1367.92,-55.24 1375.95,-48.33 1365.36,-48.73 1367.92,-55.24"/>
|
||||
</g>
|
||||
<!-- testing->async -->
|
||||
<g id="edge31" class="edge">
|
||||
<g id="edge30" class="edge">
|
||||
<title>testing->async</title>
|
||||
<path fill="none" stroke="black" d="M1052.47,-232.08C1030.36,-218.14 999.93,-198.48 974,-180 971,-177.86 967.93,-175.61 964.86,-173.32"/>
|
||||
<polygon fill="black" stroke="black" points="966.89,-170.47 956.81,-167.21 962.66,-176.04 966.89,-170.47"/>
|
||||
<path fill="none" stroke="black" d="M1192,-216C1192,-207.85 1192,-199.06 1192,-190.54"/>
|
||||
<polygon fill="black" stroke="black" points="1195.5,-190.33 1192,-180.33 1188.5,-190.33 1195.5,-190.33"/>
|
||||
</g>
|
||||
<!-- testing->data-\nstructures -->
|
||||
<g id="edge30" class="edge">
|
||||
<g id="edge29" class="edge">
|
||||
<title>testing->data-\nstructures</title>
|
||||
<path fill="none" stroke="black" d="M1101.17,-220.91C1108.13,-209.38 1116.17,-196.07 1123.55,-183.84"/>
|
||||
<polygon fill="black" stroke="black" points="1126.61,-185.54 1128.79,-175.17 1120.62,-181.92 1126.61,-185.54"/>
|
||||
<path fill="none" stroke="black" d="M1219.46,-228.26C1238.53,-212.47 1264.1,-191.29 1284.68,-174.25"/>
|
||||
<polygon fill="black" stroke="black" points="1287.12,-176.78 1292.59,-167.7 1282.65,-171.38 1287.12,-176.78"/>
|
||||
</g>
|
||||
<!-- testing->fmt -->
|
||||
<g id="edge28" class="edge">
|
||||
<g id="edge27" class="edge">
|
||||
<title>testing->fmt</title>
|
||||
<path fill="none" stroke="black" d="M1048.14,-242.21C1007.25,-231.09 938.19,-209.73 884,-180 880.77,-178.23 877.53,-176.23 874.36,-174.12"/>
|
||||
<polygon fill="black" stroke="black" points="876.31,-171.22 866.13,-168.3 872.27,-176.93 876.31,-171.22"/>
|
||||
<path fill="none" stroke="black" d="M1156.37,-245.98C1104.26,-237.65 1005.19,-217.97 929,-180 925.71,-178.36 922.42,-176.45 919.21,-174.4"/>
|
||||
<polygon fill="black" stroke="black" points="921.14,-171.49 910.93,-168.69 917.17,-177.25 921.14,-171.49"/>
|
||||
</g>
|
||||
<!-- testing->fs -->
|
||||
<g id="edge27" class="edge">
|
||||
<g id="edge26" class="edge">
|
||||
<title>testing->fs</title>
|
||||
<path fill="none" stroke="black" d="M1064.83,-220.91C1057.87,-209.38 1049.83,-196.07 1042.45,-183.84"/>
|
||||
<polygon fill="black" stroke="black" points="1045.38,-181.92 1037.21,-175.17 1039.39,-185.54 1045.38,-181.92"/>
|
||||
<path fill="none" stroke="black" d="M1158.19,-239.12C1123.56,-226.4 1068.61,-204.68 1024,-180 1019.71,-177.62 1015.33,-174.96 1011.04,-172.2"/>
|
||||
<polygon fill="black" stroke="black" points="1012.67,-169.08 1002.41,-166.43 1008.78,-174.9 1012.67,-169.08"/>
|
||||
</g>
|
||||
<!-- testing->path -->
|
||||
<g id="edge26" class="edge">
|
||||
<g id="edge25" class="edge">
|
||||
<title>testing->path</title>
|
||||
<path fill="none" stroke="black" d="M1078.83,-215.96C1075.26,-186.97 1069.8,-144.74 1064,-108 1062.65,-99.46 1061.09,-90.36 1059.52,-81.63"/>
|
||||
<polygon fill="black" stroke="black" points="1062.93,-80.82 1057.69,-71.61 1056.04,-82.08 1062.93,-80.82"/>
|
||||
<path fill="none" stroke="black" d="M1157.51,-240.84C1127.15,-230.24 1083.72,-210.8 1057,-180 1032.95,-152.27 1019.97,-112.4 1013.14,-81.79"/>
|
||||
<polygon fill="black" stroke="black" points="1016.52,-80.87 1011.05,-71.8 1009.67,-82.31 1016.52,-80.87"/>
|
||||
</g>
|
||||
<!-- text -->
|
||||
<g id="node35" class="node">
|
||||
<title>text</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="2168" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2168" y="-355.8" font-family="Times,serif" font-size="14.00">text</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="2226" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2226" y="-355.8" font-family="Times,serif" font-size="14.00">text</text>
|
||||
</g>
|
||||
<!-- ulid -->
|
||||
<g id="node36" class="node">
|
||||
<title>ulid</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="2258" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2258" y="-355.8" font-family="Times,serif" font-size="14.00">ulid</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="2316" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2316" y="-355.8" font-family="Times,serif" font-size="14.00">ulid</text>
|
||||
</g>
|
||||
<!-- url -->
|
||||
<g id="node37" class="node">
|
||||
<title>url</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1237" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1237" y="-139.8" font-family="Times,serif" font-size="14.00">url</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="1102" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="1102" y="-139.8" font-family="Times,serif" font-size="14.00">url</text>
|
||||
</g>
|
||||
<!-- url->path -->
|
||||
<g id="edge33" class="edge">
|
||||
<g id="edge32" class="edge">
|
||||
<title>url->path</title>
|
||||
<path fill="none" stroke="black" d="M1209.53,-120.28C1203.87,-116 1197.86,-111.7 1192,-108 1160.16,-87.87 1121.86,-68.88 1093.21,-55.62"/>
|
||||
<polygon fill="black" stroke="black" points="1094.44,-52.34 1083.9,-51.35 1091.53,-58.7 1094.44,-52.34"/>
|
||||
<path fill="none" stroke="black" d="M1078.27,-116.8C1065.69,-102.91 1050.1,-85.69 1036.62,-70.81"/>
|
||||
<polygon fill="black" stroke="black" points="1039.1,-68.33 1029.79,-63.27 1033.91,-73.03 1039.1,-68.33"/>
|
||||
</g>
|
||||
<!-- uuid -->
|
||||
<g id="node38" class="node">
|
||||
<title>uuid</title>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="711" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="711" y="-139.8" font-family="Times,serif" font-size="14.00">uuid</text>
|
||||
<ellipse fill="lightgreen" stroke="black" cx="396" cy="-144" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="396" y="-139.8" font-family="Times,serif" font-size="14.00">uuid</text>
|
||||
</g>
|
||||
<!-- uuid->bytes -->
|
||||
<g id="edge34" class="edge">
|
||||
<g id="edge33" class="edge">
|
||||
<title>uuid->bytes</title>
|
||||
<path fill="none" stroke="black" d="M683.03,-121.04C662.39,-104.83 634.15,-82.66 611.85,-65.15"/>
|
||||
<polygon fill="black" stroke="black" points="613.96,-62.36 603.94,-58.94 609.64,-67.86 613.96,-62.36"/>
|
||||
<path fill="none" stroke="black" d="M368.03,-121.04C347.39,-104.83 319.15,-82.66 296.85,-65.15"/>
|
||||
<polygon fill="black" stroke="black" points="298.96,-62.36 288.94,-58.94 294.64,-67.86 298.96,-62.36"/>
|
||||
</g>
|
||||
<!-- uuid->crypto -->
|
||||
<g id="edge35" class="edge">
|
||||
<g id="edge34" class="edge">
|
||||
<title>uuid->crypto</title>
|
||||
<path fill="none" stroke="black" d="M711,-108C711,-99.85 711,-91.06 711,-82.54"/>
|
||||
<polygon fill="black" stroke="black" points="714.5,-82.33 711,-72.33 707.5,-82.33 714.5,-82.33"/>
|
||||
<path fill="none" stroke="black" d="M396,-108C396,-99.85 396,-91.06 396,-82.54"/>
|
||||
<polygon fill="black" stroke="black" points="399.5,-82.33 396,-72.33 392.5,-82.33 399.5,-82.33"/>
|
||||
</g>
|
||||
<!-- webgpu -->
|
||||
<g id="node39" class="node">
|
||||
<title>webgpu</title>
|
||||
<ellipse fill="none" stroke="black" cx="2348" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2348" y="-355.8" font-family="Times,serif" font-size="14.00">webgpu</text>
|
||||
<ellipse fill="none" stroke="black" cx="2406" cy="-360" rx="36" ry="36"/>
|
||||
<text text-anchor="middle" x="2406" y="-355.8" font-family="Times,serif" font-size="14.00">webgpu</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
@ -7,7 +7,6 @@
|
||||
"./etag": "./etag.ts",
|
||||
"./file-server": "./file_server.ts",
|
||||
"./negotiation": "./negotiation.ts",
|
||||
"./server": "./server.ts",
|
||||
"./server-sent-event-stream": "./server_sent_event_stream.ts",
|
||||
"./status": "./status.ts",
|
||||
"./unstable-signed-cookie": "./unstable_signed_cookie.ts",
|
||||
|
@ -66,7 +66,6 @@ export * from "./cookie.ts";
|
||||
export * from "./etag.ts";
|
||||
export * from "./status.ts";
|
||||
export * from "./negotiation.ts";
|
||||
export * from "./server.ts";
|
||||
export * from "./unstable_signed_cookie.ts";
|
||||
export * from "./server_sent_event_stream.ts";
|
||||
export * from "./user_agent.ts";
|
||||
|
905
http/server.ts
905
http/server.ts
@ -1,905 +0,0 @@
|
||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
import { delay } from "@std/async/delay";
|
||||
|
||||
/** Thrown by Server after it has been closed. */
|
||||
const ERROR_SERVER_CLOSED = "Server closed";
|
||||
|
||||
/** Default port for serving HTTP. */
|
||||
const HTTP_PORT = 80;
|
||||
|
||||
/** Default port for serving HTTPS. */
|
||||
const HTTPS_PORT = 443;
|
||||
|
||||
/** Initial backoff delay of 5ms following a temporary accept failure. */
|
||||
const INITIAL_ACCEPT_BACKOFF_DELAY = 5;
|
||||
|
||||
/** Max backoff delay of 1s following a temporary accept failure. */
|
||||
const MAX_ACCEPT_BACKOFF_DELAY = 1000;
|
||||
|
||||
/**
|
||||
* Information about the connection a request arrived on.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeHandlerInfo} instead.
|
||||
*/
|
||||
export interface ConnInfo {
|
||||
/** The local address of the connection. */
|
||||
readonly localAddr: Deno.Addr;
|
||||
/** The remote address of the connection. */
|
||||
readonly remoteAddr: Deno.Addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler for HTTP requests. Consumes a request and connection information
|
||||
* and returns a response.
|
||||
*
|
||||
* If a handler throws, the server calling the handler will assume the impact
|
||||
* of the error is isolated to the individual request. It will catch the error
|
||||
* and close the underlying connection.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeHandler} instead.
|
||||
*/
|
||||
export type Handler = (
|
||||
request: Request,
|
||||
connInfo: ConnInfo,
|
||||
) => Response | Promise<Response>;
|
||||
|
||||
/**
|
||||
* Options for running an HTTP server.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeInit} instead.
|
||||
*/
|
||||
export interface ServerInit extends Partial<Deno.ListenOptions> {
|
||||
/** The handler to invoke for individual HTTP requests. */
|
||||
handler: Handler;
|
||||
|
||||
/**
|
||||
* The handler to invoke when route handlers throw an error.
|
||||
*
|
||||
* The default error handler logs and returns the error in JSON format.
|
||||
*/
|
||||
onError?: (error: unknown) => Response | Promise<Response>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to construct an HTTP server.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.serve} instead.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const port = 4505;
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ port, handler });
|
||||
* ```
|
||||
*/
|
||||
export class Server {
|
||||
#port?: number;
|
||||
#host?: string;
|
||||
#handler: Handler;
|
||||
#closed = false;
|
||||
#listeners: Set<Deno.Listener> = new Set();
|
||||
#acceptBackoffDelayAbortController = new AbortController();
|
||||
#httpConnections: Set<Deno.HttpConn> = new Set();
|
||||
#onError: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
/**
|
||||
* Constructs a new HTTP Server instance.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const port = 4505;
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ port, handler });
|
||||
* ```
|
||||
*
|
||||
* @param serverInit Options for running an HTTP server.
|
||||
*/
|
||||
constructor(serverInit: ServerInit) {
|
||||
this.#port = serverInit.port;
|
||||
this.#host = serverInit.hostname;
|
||||
this.#handler = serverInit.handler;
|
||||
this.#onError = serverInit.onError ??
|
||||
function (error: unknown) {
|
||||
console.error(error);
|
||||
return new Response("Internal Server Error", { status: 500 });
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept incoming connections on the given listener, and handle requests on
|
||||
* these connections with the given handler.
|
||||
*
|
||||
* HTTP/2 support is only enabled if the provided Deno.Listener returns TLS
|
||||
* connections and was configured with "h2" in the ALPN protocols.
|
||||
*
|
||||
* Throws a server closed error if called after the server has been closed.
|
||||
*
|
||||
* Will always close the created listener.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ handler });
|
||||
* const listener = Deno.listen({ port: 4505 });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* await server.serve(listener);
|
||||
* ```
|
||||
*
|
||||
* @param listener The listener to accept connections from.
|
||||
*/
|
||||
async serve(listener: Deno.Listener): Promise<void> {
|
||||
if (this.#closed) {
|
||||
throw new Deno.errors.Http(ERROR_SERVER_CLOSED);
|
||||
}
|
||||
|
||||
this.#trackListener(listener);
|
||||
|
||||
try {
|
||||
return await this.#accept(listener);
|
||||
} finally {
|
||||
this.#untrackListener(listener);
|
||||
|
||||
try {
|
||||
listener.close();
|
||||
} catch {
|
||||
// Listener has already been closed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a listener on the server, accept incoming connections, and handle
|
||||
* requests on these connections with the given handler.
|
||||
*
|
||||
* If the server was constructed without a specified port, 80 is used.
|
||||
*
|
||||
* If the server was constructed with the hostname omitted from the options, the
|
||||
* non-routable meta-address `0.0.0.0` is used.
|
||||
*
|
||||
* Throws a server closed error if the server has been closed.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const port = 4505;
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ port, handler });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* await server.listenAndServe();
|
||||
* ```
|
||||
*/
|
||||
async listenAndServe(): Promise<void> {
|
||||
if (this.#closed) {
|
||||
throw new Deno.errors.Http(ERROR_SERVER_CLOSED);
|
||||
}
|
||||
|
||||
const listener = Deno.listen({
|
||||
port: this.#port ?? HTTP_PORT,
|
||||
hostname: this.#host ?? "0.0.0.0",
|
||||
transport: "tcp",
|
||||
});
|
||||
|
||||
return await this.serve(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a listener on the server, accept incoming connections, upgrade them
|
||||
* to TLS, and handle requests on these connections with the given handler.
|
||||
*
|
||||
* If the server was constructed without a specified port, 443 is used.
|
||||
*
|
||||
* If the server was constructed with the hostname omitted from the options, the
|
||||
* non-routable meta-address `0.0.0.0` is used.
|
||||
*
|
||||
* Throws a server closed error if the server has been closed.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const port = 4505;
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ port, handler });
|
||||
*
|
||||
* const certFile = "/path/to/certFile.crt";
|
||||
* const keyFile = "/path/to/keyFile.key";
|
||||
*
|
||||
* console.log("server listening on https://localhost:4505");
|
||||
*
|
||||
* await server.listenAndServeTls(certFile, keyFile);
|
||||
* ```
|
||||
*
|
||||
* @param certFile The path to the file containing the TLS certificate.
|
||||
* @param keyFile The path to the file containing the TLS private key.
|
||||
*/
|
||||
async listenAndServeTls(certFile: string, keyFile: string): Promise<void> {
|
||||
if (this.#closed) {
|
||||
throw new Deno.errors.Http(ERROR_SERVER_CLOSED);
|
||||
}
|
||||
|
||||
const listener = Deno.listenTls({
|
||||
port: this.#port ?? HTTPS_PORT,
|
||||
hostname: this.#host ?? "0.0.0.0",
|
||||
cert: Deno.readTextFileSync(certFile),
|
||||
key: Deno.readTextFileSync(keyFile),
|
||||
transport: "tcp",
|
||||
// ALPN protocol support not yet stable.
|
||||
// alpnProtocols: ["h2", "http/1.1"],
|
||||
});
|
||||
|
||||
return await this.serve(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately close the server listeners and associated HTTP connections.
|
||||
*
|
||||
* Throws a server closed error if called after the server has been closed.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ handler });
|
||||
* const listener = Deno.listen({ port: 4505 });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* const serve = server.serve(listener);
|
||||
* setTimeout(() => {
|
||||
* server.close();
|
||||
* }, 1000);
|
||||
* await serve;
|
||||
* ```
|
||||
*/
|
||||
close() {
|
||||
if (this.#closed) {
|
||||
throw new Deno.errors.Http(ERROR_SERVER_CLOSED);
|
||||
}
|
||||
|
||||
this.#closed = true;
|
||||
|
||||
for (const listener of this.#listeners) {
|
||||
try {
|
||||
listener.close();
|
||||
} catch {
|
||||
// Listener has already been closed.
|
||||
}
|
||||
}
|
||||
|
||||
this.#listeners.clear();
|
||||
|
||||
this.#acceptBackoffDelayAbortController.abort();
|
||||
|
||||
for (const httpConn of this.#httpConnections) {
|
||||
this.#closeHttpConn(httpConn);
|
||||
}
|
||||
|
||||
this.#httpConnections.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the server is closed.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ handler });
|
||||
* const listener = Deno.listen({ port: 4505 });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* const serve = server.serve(listener);
|
||||
* setTimeout(() => {
|
||||
* server.close();
|
||||
* }, 1000);
|
||||
* await serve;
|
||||
* console.log(server.closed); // returns true
|
||||
* ```
|
||||
*
|
||||
* @returns Whether its closed or not.
|
||||
*/
|
||||
get closed(): boolean {
|
||||
return this.#closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of network addresses the server is listening on.
|
||||
*
|
||||
* @example Usage
|
||||
* ```tsm no-eval
|
||||
* import { Server } from "@std/http/server";
|
||||
*
|
||||
* const handler = (request: Request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* };
|
||||
*
|
||||
* const server = new Server({ handler });
|
||||
* const listener = Deno.listen({ port: 4505 });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* const serve = server.serve(listener);
|
||||
* setTimeout(() => {
|
||||
* console.log(server.addrs);
|
||||
* }, 1000);
|
||||
* await serve;
|
||||
* ```
|
||||
*
|
||||
* @returns List of addresses.
|
||||
*/
|
||||
get addrs(): Deno.Addr[] {
|
||||
return Array.from(this.#listeners).map((listener) => listener.addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to an HTTP request.
|
||||
*
|
||||
* @param requestEvent The HTTP request to respond to.
|
||||
* @param connInfo Information about the underlying connection.
|
||||
*/
|
||||
async #respond(
|
||||
requestEvent: Deno.RequestEvent,
|
||||
connInfo: ConnInfo,
|
||||
) {
|
||||
let response: Response;
|
||||
try {
|
||||
// Handle the request event, generating a response.
|
||||
response = await this.#handler(requestEvent.request, connInfo);
|
||||
|
||||
if (response.bodyUsed && response.body !== null) {
|
||||
throw new TypeError("Response body already consumed.");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// Invoke onError handler when request handler throws.
|
||||
response = await this.#onError(error);
|
||||
}
|
||||
|
||||
try {
|
||||
// Send the response.
|
||||
await requestEvent.respondWith(response);
|
||||
} catch {
|
||||
// `respondWith()` can throw for various reasons, including downstream and
|
||||
// upstream connection errors, as well as errors thrown during streaming
|
||||
// of the response content. In order to avoid false negatives, we ignore
|
||||
// the error here and let `serveHttp` close the connection on the
|
||||
// following iteration if it is in fact a downstream connection error.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves all HTTP requests on a single connection.
|
||||
*
|
||||
* @param httpConn The HTTP connection to yield requests from.
|
||||
* @param connInfo Information about the underlying connection.
|
||||
*/
|
||||
async #serveHttp(httpConn: Deno.HttpConn, connInfo: ConnInfo) {
|
||||
while (!this.#closed) {
|
||||
let requestEvent: Deno.RequestEvent | null;
|
||||
|
||||
try {
|
||||
// Yield the new HTTP request on the connection.
|
||||
requestEvent = await httpConn.nextRequest();
|
||||
} catch {
|
||||
// Connection has been closed.
|
||||
break;
|
||||
}
|
||||
|
||||
if (requestEvent === null) {
|
||||
// Connection has been closed.
|
||||
break;
|
||||
}
|
||||
|
||||
// Respond to the request. Note we do not await this async method to
|
||||
// allow the connection to handle multiple requests in the case of h2.
|
||||
this.#respond(requestEvent, connInfo);
|
||||
}
|
||||
|
||||
this.#closeHttpConn(httpConn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts all connections on a single network listener.
|
||||
*
|
||||
* @param listener The listener to accept connections from.
|
||||
*/
|
||||
async #accept(listener: Deno.Listener) {
|
||||
let acceptBackoffDelay: number | undefined;
|
||||
|
||||
while (!this.#closed) {
|
||||
let conn: Deno.Conn;
|
||||
|
||||
try {
|
||||
// Wait for a new connection.
|
||||
conn = await listener.accept();
|
||||
} catch (error) {
|
||||
if (
|
||||
// The listener is closed.
|
||||
error instanceof Deno.errors.BadResource ||
|
||||
// TLS handshake errors.
|
||||
error instanceof Deno.errors.InvalidData ||
|
||||
error instanceof Deno.errors.UnexpectedEof ||
|
||||
error instanceof Deno.errors.ConnectionReset ||
|
||||
error instanceof Deno.errors.NotConnected
|
||||
) {
|
||||
// Backoff after transient errors to allow time for the system to
|
||||
// recover, and avoid blocking up the event loop with a continuously
|
||||
// running loop.
|
||||
if (!acceptBackoffDelay) {
|
||||
acceptBackoffDelay = INITIAL_ACCEPT_BACKOFF_DELAY;
|
||||
} else {
|
||||
acceptBackoffDelay *= 2;
|
||||
}
|
||||
|
||||
if (acceptBackoffDelay >= MAX_ACCEPT_BACKOFF_DELAY) {
|
||||
acceptBackoffDelay = MAX_ACCEPT_BACKOFF_DELAY;
|
||||
}
|
||||
|
||||
try {
|
||||
await delay(acceptBackoffDelay, {
|
||||
signal: this.#acceptBackoffDelayAbortController.signal,
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
// The backoff delay timer is aborted when closing the server.
|
||||
if (!(err instanceof DOMException && err.name === "AbortError")) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
acceptBackoffDelay = undefined;
|
||||
|
||||
// "Upgrade" the network connection into an HTTP connection.
|
||||
let httpConn: Deno.HttpConn;
|
||||
|
||||
try {
|
||||
// deno-lint-ignore no-deprecated-deno-api
|
||||
httpConn = Deno.serveHttp(conn);
|
||||
} catch {
|
||||
// Connection has been closed.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Closing the underlying listener will not close HTTP connections, so we
|
||||
// track for closure upon server close.
|
||||
this.#trackHttpConnection(httpConn);
|
||||
|
||||
const connInfo: ConnInfo = {
|
||||
localAddr: conn.localAddr,
|
||||
remoteAddr: conn.remoteAddr,
|
||||
};
|
||||
|
||||
// Serve the requests that arrive on the just-accepted connection. Note
|
||||
// we do not await this async method to allow the server to accept new
|
||||
// connections.
|
||||
this.#serveHttp(httpConn, connInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Untracks and closes an HTTP connection.
|
||||
*
|
||||
* @param httpConn The HTTP connection to close.
|
||||
*/
|
||||
#closeHttpConn(httpConn: Deno.HttpConn) {
|
||||
this.#untrackHttpConnection(httpConn);
|
||||
|
||||
try {
|
||||
httpConn.close();
|
||||
} catch {
|
||||
// Connection has already been closed.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to the internal tracking list.
|
||||
*
|
||||
* @param listener Listener to track.
|
||||
*/
|
||||
#trackListener(listener: Deno.Listener) {
|
||||
this.#listeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from the internal tracking list.
|
||||
*
|
||||
* @param listener Listener to untrack.
|
||||
*/
|
||||
#untrackListener(listener: Deno.Listener) {
|
||||
this.#listeners.delete(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the HTTP connection to the internal tracking list.
|
||||
*
|
||||
* @param httpConn HTTP connection to track.
|
||||
*/
|
||||
#trackHttpConnection(httpConn: Deno.HttpConn) {
|
||||
this.#httpConnections.add(httpConn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the HTTP connection from the internal tracking list.
|
||||
*
|
||||
* @param httpConn HTTP connection to untrack.
|
||||
*/
|
||||
#untrackHttpConnection(httpConn: Deno.HttpConn) {
|
||||
this.#httpConnections.delete(httpConn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional serve options.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeInit} instead.
|
||||
*/
|
||||
export interface ServeInit extends Partial<Deno.ListenOptions> {
|
||||
/** An AbortSignal to close the server and all connections. */
|
||||
signal?: AbortSignal;
|
||||
|
||||
/** The handler to invoke when route handlers throw an error. */
|
||||
onError?: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
/** The callback which is called when the server started listening */
|
||||
onListen?: (params: { hostname: string; port: number }) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional serve listener options.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeOptions} instead.
|
||||
*/
|
||||
export interface ServeListenerOptions {
|
||||
/** An AbortSignal to close the server and all connections. */
|
||||
signal?: AbortSignal;
|
||||
|
||||
/** The handler to invoke when route handlers throw an error. */
|
||||
onError?: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
/** The callback which is called when the server started listening */
|
||||
onListen?: (params: { hostname: string; port: number }) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a server, accepts incoming connections on the given listener, and
|
||||
* handles requests on these connections with the given handler.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { serveListener } from "@std/http/server";
|
||||
*
|
||||
* const listener = Deno.listen({ port: 4505 });
|
||||
*
|
||||
* console.log("server listening on http://localhost:4505");
|
||||
*
|
||||
* await serveListener(listener, (request) => {
|
||||
* const body = `Your user-agent is:\n\n${request.headers.get(
|
||||
* "user-agent",
|
||||
* ) ?? "Unknown"}`;
|
||||
*
|
||||
* return new Response(body, { status: 200 });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param listener The listener to accept connections from.
|
||||
* @param handler The handler for individual HTTP requests.
|
||||
* @param options Optional serve options.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.serve} instead.
|
||||
*/
|
||||
export async function serveListener(
|
||||
listener: Deno.Listener,
|
||||
handler: Handler,
|
||||
options?: ServeListenerOptions,
|
||||
): Promise<void> {
|
||||
const server = new Server({ handler, onError: options?.onError });
|
||||
|
||||
options?.signal?.addEventListener("abort", () => server.close(), {
|
||||
once: true,
|
||||
});
|
||||
|
||||
return await server.serve(listener);
|
||||
}
|
||||
|
||||
function hostnameForDisplay(hostname: string) {
|
||||
// If the hostname is "0.0.0.0", we display "localhost" in console
|
||||
// because browsers in Windows don't resolve "0.0.0.0".
|
||||
// See the discussion in https://github.com/denoland/deno_std/issues/1165
|
||||
return hostname === "0.0.0.0" ? "localhost" : hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves HTTP requests with the given handler.
|
||||
*
|
||||
* You can specify an object with a port and hostname option, which is the
|
||||
* address to listen on. The default is port 8000 on hostname "0.0.0.0".
|
||||
*
|
||||
* @example The below example serves with the port 8000.
|
||||
* ```ts no-eval
|
||||
* import { serve } from "@std/http/server";
|
||||
* serve((_req) => new Response("Hello, world"));
|
||||
* ```
|
||||
*
|
||||
* @example You can change the listening address by the `hostname` and `port` options.
|
||||
* The below example serves with the port 3000.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serve } from "@std/http/server";
|
||||
* serve((_req) => new Response("Hello, world"), { port: 3000 });
|
||||
* ```
|
||||
*
|
||||
* @example `serve` function prints the message `Listening on http://<hostname>:<port>/`
|
||||
* on start-up by default. If you like to change this message, you can specify
|
||||
* `onListen` option to override it.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serve } from "@std/http/server";
|
||||
* serve((_req) => new Response("Hello, world"), {
|
||||
* onListen({ port, hostname }) {
|
||||
* console.log(`Server started at http://${hostname}:${port}`);
|
||||
* // ... more info specific to your server ..
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example You can also specify `undefined` or `null` to stop the logging behavior.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serve } from "@std/http/server";
|
||||
* serve((_req) => new Response("Hello, world"), { onListen: undefined });
|
||||
* ```
|
||||
*
|
||||
* @param handler The handler for individual HTTP requests.
|
||||
* @param options The options. See `ServeInit` documentation for details.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.serve} instead.
|
||||
*/
|
||||
export async function serve(
|
||||
handler: Handler,
|
||||
options: ServeInit = {},
|
||||
): Promise<void> {
|
||||
let port = options.port ?? 8000;
|
||||
if (typeof port !== "number") {
|
||||
port = Number(port);
|
||||
}
|
||||
|
||||
const hostname = options.hostname ?? "0.0.0.0";
|
||||
const server = new Server({
|
||||
port,
|
||||
hostname,
|
||||
handler,
|
||||
onError: options.onError,
|
||||
});
|
||||
|
||||
options?.signal?.addEventListener("abort", () => server.close(), {
|
||||
once: true,
|
||||
});
|
||||
|
||||
const listener = Deno.listen({
|
||||
port,
|
||||
hostname,
|
||||
transport: "tcp",
|
||||
});
|
||||
|
||||
const s = server.serve(listener);
|
||||
|
||||
port = (server.addrs[0] as Deno.NetAddr).port;
|
||||
|
||||
if ("onListen" in options) {
|
||||
options.onListen?.({ port, hostname });
|
||||
} else {
|
||||
console.log(`Listening on http://${hostnameForDisplay(hostname)}:${port}/`);
|
||||
}
|
||||
|
||||
return await s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization parameters for {@linkcode serveTls}.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.ServeTlsOptions} instead.
|
||||
*/
|
||||
export interface ServeTlsInit extends ServeInit {
|
||||
/** Server private key in PEM format */
|
||||
key?: string;
|
||||
|
||||
/** Cert chain in PEM format */
|
||||
cert?: string;
|
||||
|
||||
/** The path to the file containing the TLS private key. */
|
||||
keyFile?: string;
|
||||
|
||||
/** The path to the file containing the TLS certificate */
|
||||
certFile?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves HTTPS requests with the given handler.
|
||||
*
|
||||
* You must specify `key` or `keyFile` and `cert` or `certFile` options.
|
||||
*
|
||||
* You can specify an object with a port and hostname option, which is the
|
||||
* address to listen on. The default is port 8443 on hostname "0.0.0.0".
|
||||
*
|
||||
* @example The below example serves with the default port 8443.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serveTls } from "@std/http/server";
|
||||
*
|
||||
* const cert = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n";
|
||||
* const key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n";
|
||||
* serveTls((_req) => new Response("Hello, world"), { cert, key });
|
||||
*
|
||||
* // Or
|
||||
*
|
||||
* const certFile = "/path/to/certFile.crt";
|
||||
* const keyFile = "/path/to/keyFile.key";
|
||||
* serveTls((_req) => new Response("Hello, world"), { certFile, keyFile });
|
||||
* ```
|
||||
*
|
||||
* @example `serveTls` function prints the message `Listening on https://<hostname>:<port>/`
|
||||
* on start-up by default. If you like to change this message, you can specify
|
||||
* `onListen` option to override it.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serveTls } from "@std/http/server";
|
||||
* const certFile = "/path/to/certFile.crt";
|
||||
* const keyFile = "/path/to/keyFile.key";
|
||||
* serveTls((_req) => new Response("Hello, world"), {
|
||||
* certFile,
|
||||
* keyFile,
|
||||
* onListen({ port, hostname }) {
|
||||
* console.log(`Server started at https://${hostname}:${port}`);
|
||||
* // ... more info specific to your server ..
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example You can also specify `undefined` or `null` to stop the logging behavior.
|
||||
*
|
||||
* ```ts no-eval
|
||||
* import { serveTls } from "@std/http/server";
|
||||
* const certFile = "/path/to/certFile.crt";
|
||||
* const keyFile = "/path/to/keyFile.key";
|
||||
* serveTls((_req) => new Response("Hello, world"), {
|
||||
* certFile,
|
||||
* keyFile,
|
||||
* onListen: undefined,
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param handler The handler for individual HTTPS requests.
|
||||
* @param options The options. See `ServeTlsInit` documentation for details.
|
||||
* @returns
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use {@linkcode Deno.serve} instead.
|
||||
*/
|
||||
export async function serveTls(
|
||||
handler: Handler,
|
||||
options: ServeTlsInit,
|
||||
): Promise<void> {
|
||||
if (!options.key && !options.keyFile) {
|
||||
throw new Error("TLS config is given, but 'key' is missing.");
|
||||
}
|
||||
|
||||
if (!options.cert && !options.certFile) {
|
||||
throw new Error("TLS config is given, but 'cert' is missing.");
|
||||
}
|
||||
|
||||
let port = options.port ?? 8443;
|
||||
if (typeof port !== "number") {
|
||||
port = Number(port);
|
||||
}
|
||||
|
||||
const hostname = options.hostname ?? "0.0.0.0";
|
||||
const server = new Server({
|
||||
port,
|
||||
hostname,
|
||||
handler,
|
||||
onError: options.onError,
|
||||
});
|
||||
|
||||
options?.signal?.addEventListener("abort", () => server.close(), {
|
||||
once: true,
|
||||
});
|
||||
|
||||
// deno-lint-ignore no-sync-fn-in-async-fn
|
||||
const key = options.key || Deno.readTextFileSync(options.keyFile!);
|
||||
// deno-lint-ignore no-sync-fn-in-async-fn
|
||||
const cert = options.cert || Deno.readTextFileSync(options.certFile!);
|
||||
|
||||
const listener = Deno.listenTls({
|
||||
port,
|
||||
hostname,
|
||||
cert,
|
||||
key,
|
||||
transport: "tcp",
|
||||
// ALPN protocol support not yet stable.
|
||||
// alpnProtocols: ["h2", "http/1.1"],
|
||||
});
|
||||
|
||||
const s = server.serve(listener);
|
||||
|
||||
port = (server.addrs[0] as Deno.NetAddr).port;
|
||||
|
||||
if ("onListen" in options) {
|
||||
options.onListen?.({ port, hostname });
|
||||
} else {
|
||||
console.log(
|
||||
`Listening on https://${hostnameForDisplay(hostname)}:${port}/`,
|
||||
);
|
||||
}
|
||||
|
||||
return await s;
|
||||
}
|
1631
http/server_test.ts
1631
http/server_test.ts
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user