From f560e1c3a00f6dbcc47a451031474083bb34fb5b Mon Sep 17 00:00:00 2001 From: c-cube Date: Thu, 17 Mar 2022 02:46:20 +0000 Subject: [PATCH] deploy: 5a156490ab6fbe318c5031ce2225dde67ec54f7a --- dev/highlight.pack.js | 2 + dev/index.html | 20 + dev/odoc.css | 783 ++++++++++++++++++ dev/tiny_httpd/Tiny_httpd/.dummy | 0 dev/tiny_httpd/Tiny_httpd/index.html | 97 +++ dev/tiny_httpd/Tiny_httpd_buf/.dummy | 0 dev/tiny_httpd/Tiny_httpd_buf/index.html | 2 + dev/tiny_httpd/Tiny_httpd_dir/.dummy | 0 .../Tiny_httpd_dir/Embedded_fs/index.html | 2 + dev/tiny_httpd/Tiny_httpd_dir/index.html | 25 + .../Tiny_httpd_dir/module-type-VFS/index.html | 2 + dev/tiny_httpd/Tiny_httpd_html/.dummy | 0 dev/tiny_httpd/Tiny_httpd_html/index.html | 2 + dev/tiny_httpd/Tiny_httpd_html_/.dummy | 0 dev/tiny_httpd/Tiny_httpd_html_/A/index.html | 2 + .../Tiny_httpd_html_/Out/index.html | 2 + dev/tiny_httpd/Tiny_httpd_html_/index.html | 2 + dev/tiny_httpd/Tiny_httpd_server/.dummy | 0 .../Tiny_httpd_server/Headers/index.html | 2 + .../Tiny_httpd_server/Meth/index.html | 2 + .../Tiny_httpd_server/Middleware/index.html | 2 + .../Tiny_httpd_server/Request/index.html | 2 + .../Tiny_httpd_server/Response/index.html | 19 + .../Response_code/index.html | 2 + .../Tiny_httpd_server/Route/index.html | 2 + dev/tiny_httpd/Tiny_httpd_server/index.html | 47 ++ .../index.html | 8 + dev/tiny_httpd/Tiny_httpd_stream/.dummy | 0 dev/tiny_httpd/Tiny_httpd_stream/index.html | 18 + dev/tiny_httpd/Tiny_httpd_util/.dummy | 0 dev/tiny_httpd/Tiny_httpd_util/index.html | 2 + dev/tiny_httpd/index.html | 2 + .../Tiny_httpd_camlzip/.dummy | 0 .../Tiny_httpd_camlzip/index.html | 6 + dev/tiny_httpd_camlzip/index.html | 2 + 35 files changed, 1057 insertions(+) create mode 100644 dev/highlight.pack.js create mode 100644 dev/index.html create mode 100644 dev/odoc.css create mode 100644 dev/tiny_httpd/Tiny_httpd/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_buf/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_buf/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_dir/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_dir/Embedded_fs/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_dir/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_dir/module-type-VFS/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_html/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_html/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_html_/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_html_/A/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_html_/Out/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_html_/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Headers/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Meth/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Middleware/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Request/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Response/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Response_code/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/Route/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_server/module-type-SERVER_SENT_GENERATOR/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_stream/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_stream/index.html create mode 100644 dev/tiny_httpd/Tiny_httpd_util/.dummy create mode 100644 dev/tiny_httpd/Tiny_httpd_util/index.html create mode 100644 dev/tiny_httpd/index.html create mode 100644 dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/.dummy create mode 100644 dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/index.html create mode 100644 dev/tiny_httpd_camlzip/index.html diff --git a/dev/highlight.pack.js b/dev/highlight.pack.js new file mode 100644 index 00000000..2e55d491 --- /dev/null +++ b/dev/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.15.8 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(a){var f=[],u=Object.keys,N={},c={},n=/^(no-?highlight|plain|text)$/i,s=/\blang(?:uage)?-([\w-]+)\b/i,t=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},b="",h={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function _(e){return e.replace(/&/g,"&").replace(//g,">")}function E(e){return e.nodeName.toLowerCase()}function v(e,n){var t=e&&e.exec(n);return t&&0===t.index}function l(e){return n.test(e)}function g(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function R(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),E(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function i(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(i)}}function m(o){function s(e){return e&&e.source||e}function c(e,n){return new RegExp(s(e),"m"+(o.cI?"i":"")+(n?"g":""))}!function n(t,e){if(!t.compiled){if(t.compiled=!0,t.k=t.k||t.bK,t.k){function r(t,e){o.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,n[1]?Number(n[1]):1]})}var a={};"string"==typeof t.k?r("keyword",t.k):u(t.k).forEach(function(e){r(e,t.k[e])}),t.k=a}t.lR=c(t.l||/\w+/,!0),e&&(t.bK&&(t.b="\\b("+t.bK.split(" ").join("|")+")\\b"),t.b||(t.b=/\B|\b/),t.bR=c(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\B|\b/),t.e&&(t.eR=c(t.e)),t.tE=s(t.e)||"",t.eW&&e.tE&&(t.tE+=(t.e?"|":"")+e.tE)),t.i&&(t.iR=c(t.i)),null==t.r&&(t.r=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return function(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return g(n,{v:null},e)})),n.cached_variants||n.eW&&[g(n)]||[n]}("self"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e);var i=t.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([t.tE,t.i]).map(s).filter(Boolean);t.t=i.length?c(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i')+n+(t?"":b):n}function o(){E+=null!=l.sL?function(){var e="string"==typeof l.sL;if(e&&!N[l.sL])return _(g);var n=e?C(l.sL,g,!0,f[l.sL]):O(g,l.sL.length?l.sL:void 0);return 0")+'"');return g+=n,n.length||1}var s=B(e);if(!s)throw new Error('Unknown language: "'+e+'"');m(s);var a,l=t||s,f={},E="";for(a=l;a!==s;a=a.parent)a.cN&&(E=c(a.cN,"",!0)+E);var g="",R=0;try{for(var d,p,M=0;l.t.lastIndex=M,d=l.t.exec(n);)p=r(n.substring(M,d.index),d[0]),M=d.index+p;for(r(n.substr(M)),a=l;a.parent;a=a.parent)a.cN&&(E+=b);return{r:R,value:E,language:e,top:l}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:_(n)};throw e}}function O(t,e){e=e||h.languages||u(N);var r={r:0,value:_(t)},a=r;return e.filter(B).filter(M).forEach(function(e){var n=C(e,t,!1);n.language=e,n.r>a.r&&(a=n),n.r>r.r&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function d(e){return h.tabReplace||h.useBR?e.replace(t,function(e,n){return h.useBR&&"\n"===e?"
":h.tabReplace?n.replace(/\t/g,h.tabReplace):""}):e}function o(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=s.exec(i))return B(t[1])?t[1]:"no-highlight";for(n=0,r=(i=i.split(/\s+/)).length;n/g,"\n"):n=e,i=n.textContent,r=o?C(o,i,!0):O(i),(t=R(n)).length&&((a=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=function(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function u(e){a+=""}function s(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var l=o();if(a+=_(t.substring(r,l[0].offset)),r=l[0].offset,l===e){for(i.reverse().forEach(u);s(l.splice(0,1)[0]),(l=o())===e&&l.length&&l[0].offset===r;);i.reverse().forEach(c)}else"start"===l[0].event?i.push(l[0].node):i.pop(),s(l.splice(0,1)[0])}return a+_(t.substr(r))}(t,R(a),i)),r.value=d(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function p(){if(!p.called){p.called=!0;var e=document.querySelectorAll("pre code");f.forEach.call(e,o)}}function B(e){return e=(e||"").toLowerCase(),N[e]||N[c[e]]}function M(e){var n=B(e);return n&&!n.disableAutodetect}return a.highlight=C,a.highlightAuto=O,a.fixMarkup=d,a.highlightBlock=o,a.configure=function(e){h=g(h,e)},a.initHighlighting=p,a.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",p,!1),addEventListener("load",p,!1)},a.registerLanguage=function(n,e){var t=N[n]=e(a);i(t),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return u(N)},a.getLanguage=B,a.autoDetection=M,a.inherit=g,a.IR=a.IDENT_RE="[a-zA-Z]\\w*",a.UIR=a.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",a.NR=a.NUMBER_RE="\\b\\d+(\\.\\d+)?",a.CNR=a.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",a.BNR=a.BINARY_NUMBER_RE="\\b(0b[01]+)",a.RSR=a.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",a.BE=a.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},a.ASM=a.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:"comment",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C("//","$"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C("/\\*","\\*/"),a.HCM=a.HASH_COMMENT_MODE=a.C("#","$"),a.NM=a.NUMBER_MODE={cN:"number",b:a.NR,r:0},a.CNM=a.C_NUMBER_MODE={cN:"number",b:a.CNR,r:0},a.BNM=a.BINARY_NUMBER_MODE={cN:"number",b:a.BNR,r:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:"number",b:a.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},a.RM=a.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[a.BE,{b:/\[/,e:/\]/,r:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:"title",b:a.IR,r:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:"title",b:a.UIR,r:0},a.METHOD_GUARD={b:"\\.\\s*"+a.UIR,r:0},a});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("reasonml",function(r){var e="~?[a-z$_][0-9a-zA-Z$_]*",a="`?[A-Z$_][0-9a-zA-Z$_]*",c="("+["||","&&","++","**","+.","*","/","*.","/.","...","|>"].map(function(r){return r.split("").map(function(r){return"\\"+r}).join("")}).join("|")+"|==|===)",n="\\s+"+c+"\\s+",t={keyword:"and as asr assert begin class constraint do done downto else end exception externalfor fun function functor if in include inherit initializerland lazy let lor lsl lsr lxor match method mod module mutable new nonrecobject of open or private rec sig struct then to try type val virtual when while with",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ",literal:"true false"},i="\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",s={cN:"number",r:0,v:[{b:i},{b:"\\(\\-"+i+"\\)"}]},b={cN:"operator",r:0,b:c},o=[{cN:"identifier",r:0,b:e},b,s],l=[r.QSM,b,{cN:"module",b:"\\b"+a,rB:!0,e:".",c:[{cN:"identifier",b:a,r:0}]}],u=[{cN:"module",b:"\\b"+a,rB:!0,e:".",r:0,c:[{cN:"identifier",b:a,r:0}]}],_={cN:"function",r:0,k:t,v:[{b:"\\s(\\(\\.?.*?\\)|"+e+")\\s*=>",e:"\\s*=>",rB:!0,r:0,c:[{cN:"params",v:[{b:e},{b:"~?[a-z$_][0-9a-zA-Z$_]*(s*:s*[a-z$_][0-9a-z$_]*((s*('?[a-z$_][0-9a-z$_]*s*(,'?[a-z$_][0-9a-z$_]*)*)?s*))?)?(s*:s*[a-z$_][0-9a-z$_]*((s*('?[a-z$_][0-9a-z$_]*s*(,'?[a-z$_][0-9a-z$_]*)*)?s*))?)?"},{b:/\(\s*\)/}]}]},{b:"\\s\\(\\.?[^;\\|]*\\)\\s*=>",e:"\\s=>",rB:!0,r:0,c:[{cN:"params",r:0,v:[{b:e,e:"(,|\\n|\\))",r:0,c:[b,{cN:"typing",b:":",e:"(,|\\n)",rB:!0,r:0,c:u}]}]}]},{b:"\\(\\.\\s"+e+"\\)\\s*=>"}]};l.push(_);var N={cN:"constructor",b:a+"\\(",e:"\\)",i:"\\n",k:t,c:[r.QSM,b,{cN:"params",b:"\\b"+e}]},d={cN:"pattern-match",b:"\\|",rB:!0,k:t,e:"=>",r:0,c:[N,b,{r:0,cN:"constructor",b:a}]},z={cN:"module-access",k:t,rB:!0,v:[{b:"\\b("+a+"\\.)+"+e},{b:"\\b("+a+"\\.)+\\(",e:"\\)",rB:!0,c:[_,{b:"\\(",e:"\\)",skip:!0}].concat(l)},{b:"\\b("+a+"\\.)+{",e:"}"}],c:l};return u.push(z),{aliases:["re"],k:t,i:"(:\\-|:=|\\${|\\+=)",c:[r.C("/\\*","\\*/",{i:"^(\\#,\\/\\/)"}),{cN:"character",b:"'(\\\\[^']+|[^'])'",i:"\\n",r:0},r.QSM,{cN:"literal",b:"\\(\\)",r:0},{cN:"literal",b:"\\[\\|",e:"\\|\\]",r:0,c:o},{cN:"literal",b:"\\[",e:"\\]",r:0,c:o},N,{cN:"operator",b:n,i:"\\-\\->",r:0},s,r.CLCM,d,_,{cN:"module-def",b:"\\bmodule\\s+"+e+"\\s+"+a+"\\s+=\\s+{",e:"}",rB:!0,k:t,r:0,c:[{cN:"module",r:0,b:a},{b:"{",e:"}",skip:!0}].concat(l)},z]}}); \ No newline at end of file diff --git a/dev/index.html b/dev/index.html new file mode 100644 index 00000000..561f97ec --- /dev/null +++ b/dev/index.html @@ -0,0 +1,20 @@ + + + + index + + + + + +
+
+

OCaml package documentation

+
    +
  1. tiny_httpd 0.11
  2. +
  3. tiny_httpd_camlzip 0.11
  4. +
+
+
+ + \ No newline at end of file diff --git a/dev/odoc.css b/dev/odoc.css new file mode 100644 index 00000000..5362774e --- /dev/null +++ b/dev/odoc.css @@ -0,0 +1,783 @@ +@charset "UTF-8"; +/* Copyright (c) 2016 The odoc contributors. All rights reserved. + Distributed under the ISC license, see terms at the end of the file. + odoc 2.1.0 */ + +/* Fonts */ +@import url('https://fonts.googleapis.com/css?family=Fira+Mono:400,500'); +@import url('https://fonts.googleapis.com/css?family=Noticia+Text:400,400i,700'); +@import url('https://fonts.googleapis.com/css?family=Fira+Sans:400,400i,500,500i,600,600i,700,700i'); + +:root, +.light:root { + --main-background: #FFFFFF; + + --color: #333333; + --link-color: #2C94BD; + --anchor-hover: #555; + --anchor-color: #d5d5d5; + --xref-shadow: #cc6666; + --header-shadow: #ddd; + --by-name-version-color: #aaa; + --by-name-nav-link-color: #222; + --target-background: rgba(187, 239, 253, 0.3); + --target-shadow: rgba(187, 239, 253, 0.8); + --pre-border-color: #eee; + --code-background: #f6f8fa; + + --li-code-background: #f6f8fa; + --li-code-color: #0d2b3e; + --toc-color: #1F2D3D; + --toc-before-color: #777; + --toc-background: #f6f8fa; + --toc-list-border: #ccc; + + --spec-summary-border-color: #5c9cf5; + --spec-summary-background: var(--code-background); + --spec-summary-hover-background: #ebeff2; + --spec-details-after-background: rgba(0, 4, 15, 0.05); + --spec-details-after-shadow: rgba(204, 204, 204, 0.53); +} + +.dark:root { + --main-background: #202020; + --code-background: #222; + --line-numbers-background: rgba(0, 0, 0, 0.125); + --navbar-background: #202020; + + --color: #bebebe; + --dirname-color: #666; + --underline-color: #444; + --visited-color: #002800; + --visited-number-color: #252; + --unvisited-color: #380000; + --unvisited-number-color: #622; + --somevisited-color: #303000; + --highlight-color: #303e3f; + --line-number-color: rgba(230, 230, 230, 0.3); + --unvisited-margin-color: #622; + --border: #333; + --navbar-border: #333; + --code-color: #ccc; + + --li-code-background: #373737; + --li-code-color: #999; + --toc-color: #777; + --toc-background: #252525; + + --hljs-link: #999; + --hljs-keyword: #cda869; + --hljs-regexp: #f9ee98; + --hljs-title: #dcdcaa; + --hljs-type: #ac885b; + --hljs-meta: #82aaff; + --hljs-variable: #cf6a4c; +} + +@media (prefers-color-scheme: dark) { + :root { + --main-background: #202020; + --code-background: #333; + --line-numbers-background: rgba(0, 0, 0, 0.125); + --navbar-background: #202020; + + --meter-unvisited-color: #622; + --meter-visited-color: #252; + --meter-separator-color: black; + + --color: #bebebe; + --dirname-color: #666; + --underline-color: #444; + --visited-color: #002800; + --visited-number-color: #252; + --unvisited-color: #380000; + --unvisited-number-color: #622; + --somevisited-color: #303000; + --highlight-color: #303e3f; + --line-number-color: rgba(230, 230, 230, 0.3); + --unvisited-margin-color: #622; + --border: #333; + --navbar-border: #333; + --code-color: #ccc; + --by-name-nav-link-color: var(--color); + + --li-code-background: #373737; + --li-code-color: #999; + --toc-color: #777; + --toc-before-color: #777; + --toc-background: #252525; + --toc-list-border: #ccc; + --spec-summary-hover-background: #ebeff2; + --spec-details-after-background: rgba(0, 4, 15, 0.05); + --spec-details-after-shadow: rgba(204, 204, 204, 0.53); + + --hljs-link: #999; + --hljs-keyword: #cda869; + --hljs-regexp: #f9ee98; + --hljs-title: #dcdcaa; + --hljs-type: #ac885b; + --hljs-meta: #82aaff; + --hljs-variable: #cf6a4c; + } +} + +/* Reset a few things. */ + +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; + +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +*, *:before, *:after { + box-sizing: border-box; +} + +html { + font-size: 15px; +} + +body { + text-align: left; + background: #FFFFFF; + color: var(--color); + background-color: var(--main-background); +} + +body { + max-width: 100ex; + margin-left: calc(10vw + 20ex); + margin-right: 4ex; + margin-top: 20px; + margin-bottom: 50px; + font-family: "Noticia Text", Georgia, serif; + line-height: 1.5; +} + +header { + margin-bottom: 30px; +} + +nav { + font-family: "Fira Sans", Helvetica, Arial, sans-serif; +} + +/* Basic markup elements */ + +b, strong { + font-weight: bold; +} + +i { + font-style: italic; +} + +em, i em.odd{ + font-style: italic; +} + +em.odd, i em { + font-style: normal; +} + +sup { + vertical-align: super; +} + +sub { + vertical-align: sub; +} + +sup, sub { + font-size: 12px; + line-height: 0; + margin-left: 0.2ex; +} + +ul, ol { + list-style-position: outside +} + +ul>li { + margin-left: 22px; +} + +ol>li { + margin-left: 27.2px; +} + +li>*:first-child { + margin-top: 0 +} + +/* Text alignements, this should be forbidden. */ + +.left { + text-align: left; +} + +.right { + text-align: right; +} + +.center { + text-align: center; +} + +/* Links and anchors */ + +a { + text-decoration: none; + color: var(--link-color); +} + +a:hover { + box-shadow: 0 1px 0 0 var(--link-color); +} + +/* Linked highlight */ +*:target { + background-color: var(--target-background) !important; + box-shadow: 0 0px 0 1px var(--target-shadow) !important; + border-radius: 1px; +} + +*:hover > a.anchor { + visibility: visible; +} + +a.anchor:before { + content: "#"; +} + +a.anchor:hover { + box-shadow: none; + text-decoration: none; + color: var(--anchor-hover); +} + +a.anchor { + visibility: hidden; + position: absolute; + /* top: 0px; */ + /* margin-left: -3ex; */ + margin-left: -1.3em; + font-weight: normal; + font-style: normal; + padding-right: 0.4em; + padding-left: 0.4em; + /* To remain selectable */ + color: var(--anchor-color); +} + +.spec > a.anchor { + margin-left: -2.3em; + padding-right: 0.9em; +} + +.xref-unresolved { + color: #2C94BD; +} +.xref-unresolved:hover { + box-shadow: 0 1px 0 0 var(--xref-shadow); +} + +/* Section and document divisions. + Until at least 4.03 many of the modules of the stdlib start at .h7, + we restart the sequence there like h2 */ + +h1, h2, h3, h4, h5, h6, .h7, .h8, .h9, .h10 { + font-family: "Fira Sans", Helvetica, Arial, sans-serif; + font-weight: 400; + padding-top: 0.1em; + line-height: 1.2; + overflow-wrap: break-word; +} + +h1 { + font-weight: 500; + font-size: 2.441em; +} + +h1 { + font-weight: 500; + font-size: 1.953em; + box-shadow: 0 1px 0 0 var(--header-shadow); +} + +h2 { + font-size: 1.563em; +} + +h3 { + font-size: 1.25em; +} + +small, .font_small { + font-size: 0.8em; +} + +h1 code, h1 tt { + font-size: inherit; + font-weight: inherit; +} + +h2 code, h2 tt { + font-size: inherit; + font-weight: inherit; +} + +h3 code, h3 tt { + font-size: inherit; + font-weight: inherit; +} + +h3 code, h3 tt { + font-size: inherit; + font-weight: inherit; +} + +h4 { + font-size: 1.12em; +} + +/* Comment delimiters, hidden but accessible to screen readers and + selected for copy/pasting */ + +/* Taken from bootstrap */ +/* See also https://stackoverflow.com/a/27769435/4220738 */ +.comment-delim { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* Preformatted and code */ + +tt, code, pre { + font-family: "Fira Mono", courier; + font-weight: 400; +} + +pre { + padding: 0.1em; + border: 1px solid var(--pre-border-color); + border-radius: 5px; + overflow-x: auto; +} + +p code, +li code { + background-color: var(--li-code-background); + color: var(--li-code-color); + border-radius: 3px; + padding: 0 0.3ex; +} + +p a > code { + color: var(--link-color); +} + +code { + white-space: pre-wrap; +} + +/* Code blocks (e.g. Examples) */ + +pre code { + font-size: 0.893rem; +} + +/* Code lexemes */ + +.keyword { + font-weight: 500; +} + +.arrow { white-space: nowrap } + +/* Module member specification */ + +.spec { + background-color: var(--spec-summary-background); + border-radius: 3px; + border-left: 4px solid var(--spec-summary-border-color); + border-right: 5px solid transparent; + padding: 0.35em 0.5em; +} + +.def-doc { + margin-bottom: 10px; +} + +/* Spacing between items */ +div.odoc-spec,.odoc-include { + margin-bottom: 2em; +} + +.spec.type .variant { + margin-left: 2ch; +} +.spec.type .variant p { + margin: 0; + font-style: italic; +} +.spec.type .record { + margin-left: 2ch; +} +.spec.type .record p { + margin: 0; + font-style: italic; +} + +div.def { + margin-top: 0; + text-indent: -2ex; + padding-left: 2ex; +} + +div.def+div.def-doc { + margin-left: 1ex; + margin-top: 2.5px +} + +div.def-doc>*:first-child { + margin-top: 0; +} + +/* Collapsible inlined include and module */ + +.odoc-include details { + position: relative; +} + +.odoc-include.shadowed-include { + display: none; +} + +.odoc-include details:after { + z-index: -100; + display: block; + content: " "; + position: absolute; + border-radius: 0 1ex 1ex 0; + right: -20px; + top: 1px; + bottom: 1px; + width: 15px; + background: var(--spec-details-after-background, rgba(0, 4, 15, 0.05)); + box-shadow: 0 0px 0 1px var(--spec-details-after-shadow, rgba(204, 204, 204, 0.53)); +} + +.odoc-include summary { + position: relative; + margin-bottom: 1em; + cursor: pointer; + outline: none; +} + +.odoc-include summary:hover { + background-color: var(--spec-summary-hover-background); +} + +/* FIXME: Does not work in Firefox. */ +.odoc-include summary::-webkit-details-marker { + color: #888; + transform: scaleX(-1); + position: absolute; + top: calc(50% - 5px); + height: 11px; + right: -29px; +} + +/* Records and variants FIXME */ + +div.def table { + text-indent: 0em; + padding: 0; + margin-left: -2ex; +} + +td.def { + padding-left: 2ex; +} + +td.def-doc *:first-child { + margin-top: 0em; +} + +/* Lists of @tags */ + +.at-tags { list-style-type: none; margin-left: -3ex; } +.at-tags li { padding-left: 3ex; text-indent: -3ex; } +.at-tags .at-tag { text-transform: capitalize } + +/* Lists of modules */ + +.modules { list-style-type: none; margin-left: -3ex; } +.modules li { padding-left: 3ex; text-indent: -3ex; margin-top: 5px } +.modules .synopsis { padding-left: 1ch; } + +/* Odig package index */ + +.packages { list-style-type: none; margin-left: -3ex; } +.packages li { padding-left: 3ex; text-indent: -3ex } +.packages li a.anchor { padding-right: 0.5ch; padding-left: 3ch; } +.packages .version { font-size: 10px; color: var(--by-name-version-color); } +.packages .synopsis { padding-left: 1ch } + +.by-name nav a { + text-transform: uppercase; + font-size: 18px; + margin-right: 1ex; + color: var(--by-name-nav-link-color,); + display: inline-block; +} + +.by-tag nav a { + margin-right: 1ex; + color: var(--by-name-nav-link-color); + display: inline-block; +} + +.by-tag ol { list-style-type: none; } +.by-tag ol.tags li { margin-left: 1ch; display: inline-block } +.by-tag td:first-child { text-transform: uppercase; } + +/* Odig package page */ + +.package nav { + display: inline; + font-size: 14px; + font-weight: normal; +} + +.package .version { + font-size: 14px; +} + +.package.info { + margin: 0; +} + +.package.info td:first-child { + font-style: italic; + padding-right: 2ex; +} + +.package.info ul { + list-style-type: none; + display: inline; + margin: 0; +} + +.package.info li { + display: inline-block; + margin: 0; + margin-right: 1ex; +} + +#info-authors li, #info-maintainers li { + display: block; +} + +/* Sidebar and TOC */ + +.odoc-toc:before { + display: block; + content: "Contents"; + text-transform: uppercase; + font-size: 1em; + margin: 1.414em 0 0.5em; + font-weight: 500; + color: var(--toc-before-color); + line-height: 1.2; +} + +.odoc-toc { + position: fixed; + top: 0px; + bottom: 0px; + left: 0px; + max-width: 30ex; + min-width: 26ex; + width: 20%; + background: var(--toc-background); + overflow: auto; + color: var(--toc-color); + padding-left: 2ex; + padding-right: 2ex; +} + +.odoc-toc ul li a { + font-family: "Fira Sans", sans-serif; + font-size: 0.95em; + color: var(--color); + font-weight: 400; + line-height: 1.6em; + display: block; +} + +.odoc-toc ul li a:hover { + box-shadow: none; + text-decoration: underline; +} + +/* First level titles */ + +.odoc-toc>ul>li>a { + font-weight: 500; +} + +.odoc-toc li ul { + margin: 0px; +} + +.odoc-toc ul { + list-style-type: none; +} + +.odoc-toc ul li { + margin: 0; +} +.odoc-toc>ul>li { + margin-bottom: 0.3em; +} + +.odoc-toc ul li li { + border-left: 1px solid var(--toc-list-border); + margin-left: 5px; + padding-left: 12px; +} + +/* Mobile adjustements. */ + +@media only screen and (max-width: 95ex) { + .odoc-content { + margin: auto; + padding: 2em; + } + .odoc-toc { + position: static; + width: auto; + min-width: unset; + max-width: unset; + border: none; + padding: 0.2em 1em; + border-radius: 5px; + } +} + +/* Print adjustements. */ + +@media print { + body { + color: black; + background: white; + } + body nav:first-child { + visibility: hidden; + } +} + +/* Syntax highlighting (based on github-gist) */ + +.hljs { + display: block; + background: var(--code-background); + padding: 0.5em; + color: var(--color); + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag { + color: #a71d5d; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: 500; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} + +/*--------------------------------------------------------------------------- + Copyright (c) 2016 The odoc contributors + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ---------------------------------------------------------------------------*/ diff --git a/dev/tiny_httpd/Tiny_httpd/.dummy b/dev/tiny_httpd/Tiny_httpd/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd/index.html b/dev/tiny_httpd/Tiny_httpd/index.html new file mode 100644 index 00000000..9012e172 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd/index.html @@ -0,0 +1,97 @@ + +Tiny_httpd (tiny_httpd.Tiny_httpd)

Module Tiny_httpd

Tiny Http Server

This library implements a very simple, basic HTTP/1.1 server using blocking IOs and threads. Basic routing based on Scanf is provided for convenience, so that several handlers can be registered.

It is possible to use a thread pool, see create's argument new_thread.

The echo example (see src/examples/echo.ml) demonstrates some of the features by declaring a few endpoints, including one for uploading files:

module S = Tiny_httpd
+
+let () =
+  let server = S.create () in
+
+  (* say hello *)
+  S.add_route_handler ~meth:`GET server
+    S.Route.(exact "hello" @/ string @/ return)
+    (fun name _req -> S.Response.make_string (Ok ("hello " ^name ^"!\n")));
+
+  (* echo request *)
+  S.add_route_handler server
+    S.Route.(exact "echo" @/ return)
+    (fun req -> S.Response.make_string
+        (Ok (Format.asprintf "echo:@ %a@." S.Request.pp req)));
+
+  (* file upload *)
+  S.add_route_handler ~meth:`PUT server
+    S.Route.(exact "upload" @/ string_urlencoded @/ return)
+    (fun path req ->
+        try
+          let oc = open_out @@ "/tmp/" ^ path in
+          output_string oc req.S.Request.body;
+          flush oc;
+          S.Response.make_string (Ok "uploaded file")
+        with e ->
+          S.Response.fail ~code:500 "couldn't upload file: %s"
+            (Printexc.to_string e)
+      );
+
+  (* run the server *)
+  Printf.printf "listening on http://%s:%d\n%!" (S.addr server) (S.port server);
+  match S.run server with
+  | Ok () -> ()
+  | Error e -> raise e

It is then possible to query it using curl:

$ dune exec src/examples/echo.exe &
+listening on http://127.0.0.1:8080
+
+# the path "hello/name" greets you.
+$ curl -X GET http://localhost:8080/hello/quadrarotaphile
+hello quadrarotaphile!
+
+# the path "echo" just prints the request.
+$ curl -X GET http://localhost:8080/echo --data "howdy y'all"
+echo:
+{meth=GET;
+ headers=Host: localhost:8080
+         User-Agent: curl/7.66.0
+         Accept: */*
+         Content-Length: 10
+         Content-Type: application/x-www-form-urlencoded;
+ path="/echo"; body="howdy y'all"}

Tiny buffer implementation

These buffers are used to avoid allocating too many byte arrays when processing streams and parsing requests.

module Buf = Tiny_httpd_buf

Generic stream of data

Streams are used to represent a series of bytes that can arrive progressively. For example, an uploaded file will be sent as a series of chunks.

module Byte_stream = Tiny_httpd_stream

Main Server Type

include module type of struct include Tiny_httpd_server end
type buf = Tiny_httpd_buf.t
type byte_stream = Tiny_httpd_stream.t

Methods

Headers

Headers are metadata associated with a request or response.

module Headers = Tiny_httpd_server.Headers

Requests

Requests are sent by a client, e.g. a web browser or cURL.

module Request = Tiny_httpd_server.Request

Response Codes

module Response_code = Tiny_httpd_server.Response_code

Responses

Responses are what a http server, such as Tiny_httpd, send back to the client to answer a Request.t

module Response = Tiny_httpd_server.Response
module Middleware = Tiny_httpd_server.Middleware

Main Server type

A HTTP server. See create for more details.

val create : + ?masksigpipe:bool -> + ?max_connections:int -> + ?timeout:float -> + ?buf_size:int -> + ?get_time_s:( unit -> float ) -> + ?new_thread:( ( unit -> unit ) -> unit ) -> + ?addr:string -> + ?port:int -> + ?sock:Unix.file_descr -> + ?middlewares:([ `Encoding | `Stage of int ] * Middleware.t) list -> + unit -> + t

Create a new webserver.

The server will not do anything until run is called on it. Before starting the server, one can use add_path_handler and set_top_handler to specify how to handle incoming requests.

  • parameter masksigpipe

    if true, block the signal Sys.sigpipe which otherwise tends to kill client threads when they try to write on broken sockets. Default: true.

  • parameter buf_size

    size for buffers (since 0.11)

  • parameter new_thread

    a function used to spawn a new thread to handle a new client connection. By default it is Thread.create but one could use a thread pool instead.

  • parameter middlewares

    see add_middleware for more details.

  • parameter max_connections

    maximum number of simultaneous connections.

  • parameter timeout

    connection is closed if the socket does not do read or write for the amount of second. Default: 0.0 which means no timeout. timeout is not recommended when using proxy.

  • parameter addr

    address (IPv4 or IPv6) to listen on. Default "127.0.0.1".

  • parameter port

    to listen on. Default 8080.

  • parameter sock

    an existing socket given to the server to listen on, e.g. by systemd on Linux (or launchd on macOS). If passed in, this socket will be used instead of the addr and port. If not passed in, those will be used. This parameter exists since 0.10.

  • parameter get_time_s

    obtain the current timestamp in seconds. This parameter exists since 0.11.

val addr : t -> string

Address on which the server listens.

val is_ipv6 : t -> bool

is_ipv6 server returns true iff the address of the server is an IPv6 address.

  • since 0.3
val port : t -> int

Port on which the server listens.

val active_connections : t -> int

Number of active connections

val add_decode_request_cb : + t -> + ( unit Request.t -> + (unit Request.t * ( byte_stream -> byte_stream )) option ) -> + unit

Add a callback for every request. The callback can provide a stream transformer and a new request (with modified headers, typically). A possible use is to handle decompression by looking for a Transfer-Encoding header and returning a stream transformer that decompresses on the fly.

  • deprecated

    use add_middleware instead

val add_encode_response_cb : + t -> + ( unit Request.t -> Response.t -> Response.t option ) -> + unit

Add a callback for every request/response pair. Similarly to add_encode_response_cb the callback can return a new response, for example to compress it. The callback is given the query with only its headers, as well as the current response.

  • deprecated

    use add_middleware instead

val add_middleware : + stage:[ `Encoding | `Stage of int ] -> + t -> + Middleware.t -> + unit

Add a middleware to every request/response pair.

  • parameter stage

    specify when middleware applies. Encoding comes first (outermost layer), then stages in increasing order.

  • raises Invalid_argument

    if stage is `Stage n where n < 1

  • since 0.11

Request handlers

val set_top_handler : t -> ( string Request.t -> Response.t ) -> unit

Setup a handler called by default.

This handler is called with any request not accepted by any handler installed via add_path_handler. If no top handler is installed, unhandled paths will return a 404 not found.

val add_route_handler : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + ?middlewares:Middleware.t list -> + ?meth:Meth.t -> + t -> + ( 'a, string Request.t -> Response.t ) Route.t -> + 'a -> + unit

add_route_handler server Route.(exact "path" @/ string @/ int @/ return) f calls f "foo" 42 request when a request with path "path/foo/42/" is received.

Note that the handlers are called in the reverse order of their addition, so the last registered handler can override previously registered ones.

  • parameter meth

    if provided, only accept requests with the given method. Typically one could react to `GET or `PUT.

  • parameter accept

    should return Ok() if the given request (before its body is read) should be accepted, Error (code,message) if it's to be rejected (e.g. because its content is too big, or for some permission error). See the http_of_dir program for an example of how to use accept to filter uploads that are too large before the upload even starts. The default always returns Ok(), i.e. it accepts all requests.

  • since 0.6
val add_route_handler_stream : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + ?middlewares:Middleware.t list -> + ?meth:Meth.t -> + t -> + ( 'a, byte_stream Request.t -> Response.t ) Route.t -> + 'a -> + unit

Similar to add_route_handler, but where the body of the request is a stream of bytes that has not been read yet. This is useful when one wants to stream the body directly into a parser, json decoder (such as Jsonm) or into a file.

  • since 0.6

Server-sent events

EXPERIMENTAL: this API is not stable yet.

module type SERVER_SENT_GENERATOR = Tiny_httpd_server.SERVER_SENT_GENERATOR

A server-side function to generate of Server-sent events.

type server_sent_generator = (module SERVER_SENT_GENERATOR)

Server-sent event generator

  • since 0.9
val add_route_server_sent_handler : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + t -> + ( 'a, string Request.t -> server_sent_generator -> unit ) Route.t -> + 'a -> + unit

Add a handler on an endpoint, that serves server-sent events.

The callback is given a generator that can be used to send events as it pleases. The connection is always closed by the client, and the accepted method is always GET. This will set the header "content-type" to "text/event-stream" automatically and reply with a 200 immediately. See server_sent_generator for more details.

This handler stays on the original thread (it is synchronous).

  • since 0.9

Run the server

val stop : t -> unit

Ask the server to stop. This might not have an immediate effect as run might currently be waiting on IO.

val run : t -> ( unit, exn ) Stdlib.result

Run the main loop of the server, listening on a socket described at the server's creation time, using new_thread to start a thread for each new client.

This returns Ok () if the server exits gracefully, or Error e if it exits with an error.

Utils

module Util = Tiny_httpd_util

Static directory serving

module Dir = Tiny_httpd_dir
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_buf/.dummy b/dev/tiny_httpd/Tiny_httpd_buf/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_buf/index.html b/dev/tiny_httpd/Tiny_httpd_buf/index.html new file mode 100644 index 00000000..87b4027e --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_buf/index.html @@ -0,0 +1,2 @@ + +Tiny_httpd_buf (tiny_httpd.Tiny_httpd_buf)

Module Tiny_httpd_buf

Simple buffer.

These buffers are used to avoid allocating too many byte arrays when processing streams and parsing requests.

  • since NEXT_RELEASE
type t
val size : t -> int
val clear : t -> unit
val create : ?size:int -> unit -> t
val contents : t -> string
val bytes_slice : t -> bytes

Access underlying slice of bytes.

  • since 0.5
val contents_and_clear : t -> string

Get contents of the buffer and clear it.

  • since 0.5
val add_bytes : t -> bytes -> int -> int -> unit

Append given bytes slice to the buffer.

  • since 0.5
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_dir/.dummy b/dev/tiny_httpd/Tiny_httpd_dir/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_dir/Embedded_fs/index.html b/dev/tiny_httpd/Tiny_httpd_dir/Embedded_fs/index.html new file mode 100644 index 00000000..c2c40f14 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_dir/Embedded_fs/index.html @@ -0,0 +1,2 @@ + +Embedded_fs (tiny_httpd.Tiny_httpd_dir.Embedded_fs)

Module Tiny_httpd_dir.Embedded_fs

An embedded file system, as a list of files with (relative) paths. This is useful in combination with the "tiny-httpd-mkfs" tool, which embeds the files it's given into a OCaml module.

  • since NEXT_RELEASE
type t

The pseudo-filesystem

val create : ?mtime:float -> unit -> t
val add_file : ?mtime:float -> t -> path:string -> string -> unit

Add file to the virtual file system.

  • raises Invalid_argument

    if the path contains '..' or if it tries to make a directory out of an existing path that is a file.

val to_vfs : t -> (module VFS)
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_dir/index.html b/dev/tiny_httpd/Tiny_httpd_dir/index.html new file mode 100644 index 00000000..7ea54436 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_dir/index.html @@ -0,0 +1,25 @@ + +Tiny_httpd_dir (tiny_httpd.Tiny_httpd_dir)

Module Tiny_httpd_dir

Serving static content from directories

This module provides the same functionality as the "http_of_dir" tool. It exposes a directory (and its subdirectories), with the optional ability to delete or upload files.

  • since 0.11
type dir_behavior =
| Index(*

Redirect to index.html if present, else fails.

*)
| Lists(*

Lists content of directory. Be careful of security implications.

*)
| Index_or_lists(*

Redirect to index.html if present and lists content otherwise. This is useful for tilde ("~") directories and other per-user behavior, but be mindful of security implications

*)
| Forbidden(*

Forbid access to directory. This is suited for serving assets, for example.

*)

behavior of static directory.

This controls what happens when the user requests the path to a directory rather than a file.

type hidden

Type used to prevent users from building a config directly. Use default_config or config instead.

type config = {
mutable download : bool;(*

Is downloading files allowed?

*)
mutable dir_behavior : dir_behavior;(*

Behavior when serving a directory and not a file

*)
mutable delete : bool;(*

Is deleting a file allowed? (with method DELETE)

*)
mutable upload : bool;(*

Is uploading a file allowed? (with method PUT)

*)
mutable max_upload_size : int;(*

If upload is true, this is the maximum size in bytes for uploaded files.

*)
_rest : hidden;(*

Just ignore this field.

*)
}

configuration for static file handlers. This might get more fields over time.

val default_config : unit -> config

default configuration: + { download=true + ; dir_behavior=Forbidden + ; delete=false + ; upload=false + ; max_upload_size = 10 * 1024 * 1024 + }

val config : + ?download:bool -> + ?dir_behavior:dir_behavior -> + ?delete:bool -> + ?upload:bool -> + ?max_upload_size:int -> + unit -> + config

Build a config from default_config.

  • since NEXT_RELEASE
val add_dir_path : + config:config -> + dir:string -> + prefix:string -> + Tiny_httpd_server.t -> + unit

add_dirpath ~config ~dir ~prefix server adds route handle to the server to serve static files in dir when url starts with prefix, using the given configuration config.

module type VFS = sig ... end

Virtual file system.

val vfs_of_dir : string -> (module VFS)

vfs_of_dir dir makes a virtual file system that reads from the disk.

  • since NEXT_RELEASE
val add_vfs : + config:config -> + vfs:(module VFS) -> + prefix:string -> + Tiny_httpd_server.t -> + unit

Similar to add_dir_path but using a virtual file system instead.

  • since NEXT_RELEASE
module Embedded_fs : sig ... end

An embedded file system, as a list of files with (relative) paths. This is useful in combination with the "tiny-httpd-mkfs" tool, which embeds the files it's given into a OCaml module.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_dir/module-type-VFS/index.html b/dev/tiny_httpd/Tiny_httpd_dir/module-type-VFS/index.html new file mode 100644 index 00000000..56c13c50 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_dir/module-type-VFS/index.html @@ -0,0 +1,2 @@ + +VFS (tiny_httpd.Tiny_httpd_dir.VFS)

Module type Tiny_httpd_dir.VFS

Virtual file system.

This is used to emulate a file system from pure OCaml functions and data, e.g. for resources bundled inside the web server.

  • since NEXT_RELEASE
val descr : string

Description of the VFS

val is_directory : string -> bool
val contains : string -> bool

file_exists vfs path returns true if path points to a file or directory inside vfs.

val list_dir : string -> string array

List directory. This only returns basenames, the files need to be put in the directory path using Filename.concat.

val delete : string -> unit

Delete path

val create : string -> ( bytes -> int -> int -> unit ) * ( unit -> unit )

Create a file and obtain a pair write, close

val read_file_content : string -> Tiny_httpd_stream.t

Read content of a file

val file_size : string -> int option

File size, e.g. using "stat"

val file_mtime : string -> float option

File modification time, e.g. using "stat"

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_html/.dummy b/dev/tiny_httpd/Tiny_httpd_html/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_html/index.html b/dev/tiny_httpd/Tiny_httpd_html/index.html new file mode 100644 index 00000000..e060c295 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_html/index.html @@ -0,0 +1,2 @@ + +Tiny_httpd_html (tiny_httpd.Tiny_httpd_html)

Module Tiny_httpd_html

Output for HTML combinators.

type attribute = string * string

An attribute, i.e. a key/value pair

type elt = Out.t -> unit

A html element. It is represented by its output function, so we can directly print it.

type void = ?if_:bool -> attribute list -> elt

Element without children.

type nary = ?if_:bool -> attribute list -> elt list -> elt

Element with children, represented as a list.

  • parameter if_

    if false, do not print anything (default true)

type nary' = ?if_:bool -> attribute list -> ( Out.t -> unit ) -> elt

Element with children, represented as a continuation.

  • parameter if_

    if false, do not print anything (default true)

val str_escape : Out.t -> string -> unit

Escape string so it can be safely embedded in HTML text.

val attr_escape : Out.t -> string -> unit

Print the value part of an attribute

val write_attrs : Out.t -> attribute list -> unit

Output a list of attributes.

val txt : string -> elt

Emit a string value, which will be escaped.

val raw_html : string -> elt

Emit raw HTML. Caution, this can lead to injection vulnerabilities, never use with text that comes from untrusted users.

val area : void

tag "area", see mdn

val base : void

tag "base", see mdn

val br : void

tag "br", see mdn

val col : void

tag "col", see mdn

val embed : void

tag "embed", see mdn

val hr : void

tag "hr", see mdn

val img : void

tag "img", see mdn

val input : void

tag "input", see mdn

tag "link", see mdn

val menuitem : void

tag "menuitem", see mdn

val meta : void

tag "meta", see mdn

val param : void

tag "param", see mdn

val source : void

tag "source", see mdn

val track : void

tag "track", see mdn

val wbr : void

tag "wbr", see mdn

val a : nary

tag "a", see mdn

val a' : nary'

tag "a", see mdn

val abbr : nary

tag "abbr", see mdn

val abbr' : nary'

tag "abbr", see mdn

val address : nary

tag "address", see mdn

val address' : nary'

tag "address", see mdn

val article : nary

tag "article", see mdn

val article' : nary'

tag "article", see mdn

val aside : nary

tag "aside", see mdn

val aside' : nary'

tag "aside", see mdn

val audio : nary

tag "audio", see mdn

val audio' : nary'

tag "audio", see mdn

val b : nary

tag "b", see mdn

val b' : nary'

tag "b", see mdn

val bdi : nary

tag "bdi", see mdn

val bdi' : nary'

tag "bdi", see mdn

val bdo : nary

tag "bdo", see mdn

val bdo' : nary'

tag "bdo", see mdn

val blockquote : nary

tag "blockquote", see mdn

val blockquote' : nary'

tag "blockquote", see mdn

val body : nary

tag "body", see mdn

val body' : nary'

tag "body", see mdn

val button : nary

tag "button", see mdn

val button' : nary'

tag "button", see mdn

val canvas : nary

tag "canvas", see mdn

val canvas' : nary'

tag "canvas", see mdn

val caption : nary

tag "caption", see mdn

val caption' : nary'

tag "caption", see mdn

val cite : nary

tag "cite", see mdn

val cite' : nary'

tag "cite", see mdn

val code : nary

tag "code", see mdn

val code' : nary'

tag "code", see mdn

val colgroup : nary

tag "colgroup", see mdn

val colgroup' : nary'

tag "colgroup", see mdn

val data : nary

tag "data", see mdn

val data' : nary'

tag "data", see mdn

val datalist : nary

tag "datalist", see mdn

val datalist' : nary'

tag "datalist", see mdn

val dd : nary

tag "dd", see mdn

val dd' : nary'

tag "dd", see mdn

val del : nary

tag "del", see mdn

val del' : nary'

tag "del", see mdn

val details : nary

tag "details", see mdn

val details' : nary'

tag "details", see mdn

val dfn : nary

tag "dfn", see mdn

val dfn' : nary'

tag "dfn", see mdn

val dialog : nary

tag "dialog", see mdn

val dialog' : nary'

tag "dialog", see mdn

val div : nary

tag "div", see mdn

val div' : nary'

tag "div", see mdn

val dl : nary

tag "dl", see mdn

val dl' : nary'

tag "dl", see mdn

val dt : nary

tag "dt", see mdn

val dt' : nary'

tag "dt", see mdn

val em : nary

tag "em", see mdn

val em' : nary'

tag "em", see mdn

val fieldset : nary

tag "fieldset", see mdn

val fieldset' : nary'

tag "fieldset", see mdn

val figcaption : nary

tag "figcaption", see mdn

val figcaption' : nary'

tag "figcaption", see mdn

val figure : nary

tag "figure", see mdn

val figure' : nary'

tag "figure", see mdn

tag "footer", see mdn

val footer' : nary'

tag "footer", see mdn

val form : nary

tag "form", see mdn

val form' : nary'

tag "form", see mdn

val h1 : nary

tag "h1", see mdn

val h1' : nary'

tag "h1", see mdn

val h2 : nary

tag "h2", see mdn

val h2' : nary'

tag "h2", see mdn

val h3 : nary

tag "h3", see mdn

val h3' : nary'

tag "h3", see mdn

val h4 : nary

tag "h4", see mdn

val h4' : nary'

tag "h4", see mdn

val h5 : nary

tag "h5", see mdn

val h5' : nary'

tag "h5", see mdn

val h6 : nary

tag "h6", see mdn

val h6' : nary'

tag "h6", see mdn

val head : nary

tag "head", see mdn

val head' : nary'

tag "head", see mdn

val header : nary

tag "header", see mdn

val header' : nary'

tag "header", see mdn

val hgroup : nary

tag "hgroup", see mdn

val hgroup' : nary'

tag "hgroup", see mdn

val html : nary

tag "html", see mdn

val html' : nary'

tag "html", see mdn

val i : nary

tag "i", see mdn

val i' : nary'

tag "i", see mdn

val iframe : nary

tag "iframe", see mdn

val iframe' : nary'

tag "iframe", see mdn

val ins : nary

tag "ins", see mdn

val ins' : nary'

tag "ins", see mdn

val kbd : nary

tag "kbd", see mdn

val kbd' : nary'

tag "kbd", see mdn

val label : nary

tag "label", see mdn

val label' : nary'

tag "label", see mdn

val legend : nary

tag "legend", see mdn

val legend' : nary'

tag "legend", see mdn

val li : nary

tag "li", see mdn

val li' : nary'

tag "li", see mdn

val main : nary

tag "main", see mdn

val main' : nary'

tag "main", see mdn

val map : nary

tag "map", see mdn

val map' : nary'

tag "map", see mdn

val mark : nary

tag "mark", see mdn

val mark' : nary'

tag "mark", see mdn

val math : nary

tag "math", see mdn

val math' : nary'

tag "math", see mdn

val menu : nary

tag "menu", see mdn

val menu' : nary'

tag "menu", see mdn

val meter : nary

tag "meter", see mdn

val meter' : nary'

tag "meter", see mdn

val nav : nary

tag "nav", see mdn

val nav' : nary'

tag "nav", see mdn

val noscript : nary

tag "noscript", see mdn

val noscript' : nary'

tag "noscript", see mdn

val object_ : nary

tag "object", see mdn

val object_' : nary'

tag "object", see mdn

val ol : nary

tag "ol", see mdn

val ol' : nary'

tag "ol", see mdn

val optgroup : nary

tag "optgroup", see mdn

val optgroup' : nary'

tag "optgroup", see mdn

val option : nary

tag "option", see mdn

val option' : nary'

tag "option", see mdn

val output : nary

tag "output", see mdn

val output' : nary'

tag "output", see mdn

val p : nary

tag "p", see mdn

val p' : nary'

tag "p", see mdn

val picture : nary

tag "picture", see mdn

val picture' : nary'

tag "picture", see mdn

val pre : nary

tag "pre", see mdn

val pre' : nary'

tag "pre", see mdn

val progress : nary

tag "progress", see mdn

val progress' : nary'

tag "progress", see mdn

val q : nary

tag "q", see mdn

val q' : nary'

tag "q", see mdn

val rb : nary

tag "rb", see mdn

val rb' : nary'

tag "rb", see mdn

val rp : nary

tag "rp", see mdn

val rp' : nary'

tag "rp", see mdn

val rt : nary

tag "rt", see mdn

val rt' : nary'

tag "rt", see mdn

val rtc : nary

tag "rtc", see mdn

val rtc' : nary'

tag "rtc", see mdn

val ruby : nary

tag "ruby", see mdn

val ruby' : nary'

tag "ruby", see mdn

val s : nary

tag "s", see mdn

val s' : nary'

tag "s", see mdn

val samp : nary

tag "samp", see mdn

val samp' : nary'

tag "samp", see mdn

val script : nary

tag "script", see mdn

val script' : nary'

tag "script", see mdn

val section : nary

tag "section", see mdn

val section' : nary'

tag "section", see mdn

val select : nary

tag "select", see mdn

val select' : nary'

tag "select", see mdn

val slot : nary

tag "slot", see mdn

val slot' : nary'

tag "slot", see mdn

val small : nary

tag "small", see mdn

val small' : nary'

tag "small", see mdn

val span : nary

tag "span", see mdn

val span' : nary'

tag "span", see mdn

val strong : nary

tag "strong", see mdn

val strong' : nary'

tag "strong", see mdn

val style : nary

tag "style", see mdn

val style' : nary'

tag "style", see mdn

val sub : nary

tag "sub", see mdn

val sub' : nary'

tag "sub", see mdn

val summary : nary

tag "summary", see mdn

val summary' : nary'

tag "summary", see mdn

val sup : nary

tag "sup", see mdn

val sup' : nary'

tag "sup", see mdn

val svg : nary

tag "svg", see mdn

val svg' : nary'

tag "svg", see mdn

val table : nary

tag "table", see mdn

val table' : nary'

tag "table", see mdn

val tbody : nary

tag "tbody", see mdn

val tbody' : nary'

tag "tbody", see mdn

val td : nary

tag "td", see mdn

val td' : nary'

tag "td", see mdn

val template : nary

tag "template", see mdn

val template' : nary'

tag "template", see mdn

val textarea : nary

tag "textarea", see mdn

val textarea' : nary'

tag "textarea", see mdn

val tfoot : nary

tag "tfoot", see mdn

val tfoot' : nary'

tag "tfoot", see mdn

val th : nary

tag "th", see mdn

val th' : nary'

tag "th", see mdn

val thead : nary

tag "thead", see mdn

val thead' : nary'

tag "thead", see mdn

val time : nary

tag "time", see mdn

val time' : nary'

tag "time", see mdn

val title : nary

tag "title", see mdn

val title' : nary'

tag "title", see mdn

val tr : nary

tag "tr", see mdn

val tr' : nary'

tag "tr", see mdn

val u : nary

tag "u", see mdn

val u' : nary'

tag "u", see mdn

val ul : nary

tag "ul", see mdn

val ul' : nary'

tag "ul", see mdn

val var : nary

tag "var", see mdn

val var' : nary'

tag "var", see mdn

val video : nary

tag "video", see mdn

val video' : nary'

tag "video", see mdn

Attributes

val to_string : ?top:bool -> elt -> string

Convert a HTML element to a string.

  • parameter top

    if true, add DOCTYPE at the beginning. The top element should then be a "html" tag.

val to_string_top : elt -> string
val to_stream : elt -> Tiny_httpd_stream.t

Convert a HTML element to a stream. This might just convert it to a string first, do not assume it to be more efficient.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_html_/.dummy b/dev/tiny_httpd/Tiny_httpd_html_/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_html_/A/index.html b/dev/tiny_httpd/Tiny_httpd_html_/A/index.html new file mode 100644 index 00000000..ad32043a --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_html_/A/index.html @@ -0,0 +1,2 @@ + +A (tiny_httpd.Tiny_httpd_html_.A)

Module Tiny_httpd_html_.A

Attributes

type t = string -> attribute

Attribute builder

val accept : t

Attribute "accept".

val accept_charset : t

Attribute "accept-charset".

val accesskey : t

Attribute "accesskey".

val action : t

Attribute "action".

val align : t

Attribute "align".

val allow : t

Attribute "allow".

val alt : t

Attribute "alt".

val async : t

Attribute "async".

val autocapitalize : t

Attribute "autocapitalize".

val autocomplete : t

Attribute "autocomplete".

val autofocus : t

Attribute "autofocus".

val autoplay : t

Attribute "autoplay".

val buffered : t

Attribute "buffered".

val capture : t

Attribute "capture".

val challenge : t

Attribute "challenge".

val charset : t

Attribute "charset".

val checked : t

Attribute "checked".

val cite : t

Attribute "cite".

val class_ : t

Attribute "class".

val code : t

Attribute "code".

val codebase : t

Attribute "codebase".

val cols : t

Attribute "cols".

val colspan : t

Attribute "colspan".

val content : t

Attribute "content".

val contenteditable : t

Attribute "contenteditable".

val contextmenu : t

Attribute "contextmenu".

val controls : t

Attribute "controls".

val coords : t

Attribute "coords".

val crossorigin : t

Attribute "crossorigin".

val csp : t

Attribute "csp".

val data : t

Attribute "data".

val data_star : t

Attribute "data-*".

val datetime : t

Attribute "datetime".

val decoding : t

Attribute "decoding".

val default : t

Attribute "default".

val defer : t

Attribute "defer".

val dir : t

Attribute "dir".

val dirname : t

Attribute "dirname".

val disabled : t

Attribute "disabled".

val download : t

Attribute "download".

val draggable : t

Attribute "draggable".

val enctype : t

Attribute "enctype".

val enterkeyhint : t

Attribute "enterkeyhint".

val for_ : t

Attribute "for".

val form : t

Attribute "form".

val formaction : t

Attribute "formaction".

val formenctype : t

Attribute "formenctype".

val formmethod : t

Attribute "formmethod".

val formnovalidate : t

Attribute "formnovalidate".

val formtarget : t

Attribute "formtarget".

val headers : t

Attribute "headers".

val hidden : t

Attribute "hidden".

val high : t

Attribute "high".

val href : t

Attribute "href".

val hreflang : t

Attribute "hreflang".

val http_equiv : t

Attribute "http-equiv".

val icon : t

Attribute "icon".

val id : t

Attribute "id".

val importance : t

Attribute "importance".

val integrity : t

Attribute "integrity".

val ismap : t

Attribute "ismap".

val itemprop : t

Attribute "itemprop".

val keytype : t

Attribute "keytype".

val kind : t

Attribute "kind".

val label : t

Attribute "label".

val lang : t

Attribute "lang".

val language : t

Attribute "language".

val list : t

Attribute "list".

val loop : t

Attribute "loop".

val low : t

Attribute "low".

val manifest : t

Attribute "manifest".

val max : t

Attribute "max".

val maxlength : t

Attribute "maxlength".

val minlength : t

Attribute "minlength".

val media : t

Attribute "media".

val method_ : t

Attribute "method".

val min : t

Attribute "min".

val multiple : t

Attribute "multiple".

val muted : t

Attribute "muted".

val name : t

Attribute "name".

val novalidate : t

Attribute "novalidate".

val open_ : t

Attribute "open".

val optimum : t

Attribute "optimum".

val pattern : t

Attribute "pattern".

val ping : t

Attribute "ping".

val placeholder : t

Attribute "placeholder".

val poster : t

Attribute "poster".

val preload : t

Attribute "preload".

val radiogroup : t

Attribute "radiogroup".

val readonly : t

Attribute "readonly".

val referrerpolicy : t

Attribute "referrerpolicy".

val rel : t

Attribute "rel".

val required : t

Attribute "required".

val reversed : t

Attribute "reversed".

val rows : t

Attribute "rows".

val rowspan : t

Attribute "rowspan".

val sandbox : t

Attribute "sandbox".

val scope : t

Attribute "scope".

val scoped : t

Attribute "scoped".

val selected : t

Attribute "selected".

val shape : t

Attribute "shape".

val size : t

Attribute "size".

val sizes : t

Attribute "sizes".

val slot : t

Attribute "slot".

val span : t

Attribute "span".

val spellcheck : t

Attribute "spellcheck".

val src : t

Attribute "src".

val srcdoc : t

Attribute "srcdoc".

val srclang : t

Attribute "srclang".

val srcset : t

Attribute "srcset".

val start : t

Attribute "start".

val step : t

Attribute "step".

val style : t

Attribute "style".

val summary : t

Attribute "summary".

val tabindex : t

Attribute "tabindex".

val target : t

Attribute "target".

val title : t

Attribute "title".

val translate : t

Attribute "translate".

val text : t

Attribute "Text".

val type_ : t

Attribute "type".

val usemap : t

Attribute "usemap".

val value : t

Attribute "value".

val width : t

Attribute "width".

val wrap : t

Attribute "wrap".

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_html_/Out/index.html b/dev/tiny_httpd/Tiny_httpd_html_/Out/index.html new file mode 100644 index 00000000..c915f5ec --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_html_/Out/index.html @@ -0,0 +1,2 @@ + +Out (tiny_httpd.Tiny_httpd_html_.Out)

Module Tiny_httpd_html_.Out

Output for HTML combinators.

This output type is used to produce a string reasonably efficiently from a tree of combinators.

type t
val create : unit -> t
val clear : t -> unit
val add_char : t -> char -> unit
val add_string : t -> string -> unit
val to_string : t -> string
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_html_/index.html b/dev/tiny_httpd/Tiny_httpd_html_/index.html new file mode 100644 index 00000000..3560ef8b --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_html_/index.html @@ -0,0 +1,2 @@ + +Tiny_httpd_html_ (tiny_httpd.Tiny_httpd_html_)

Module Tiny_httpd_html_

module Out : sig ... end

Output for HTML combinators.

type attribute = string * string

An attribute, i.e. a key/value pair

type elt = Out.t -> unit

A html element. It is represented by its output function, so we can directly print it.

type void = ?if_:bool -> attribute list -> elt

Element without children.

type nary = ?if_:bool -> attribute list -> elt list -> elt

Element with children, represented as a list.

  • parameter if_

    if false, do not print anything (default true)

type nary' = ?if_:bool -> attribute list -> ( Out.t -> unit ) -> elt

Element with children, represented as a continuation.

  • parameter if_

    if false, do not print anything (default true)

val str_escape : Out.t -> string -> unit

Escape string so it can be safely embedded in HTML text.

val attr_escape : Out.t -> string -> unit

Print the value part of an attribute

val write_attrs : Out.t -> attribute list -> unit

Output a list of attributes.

val txt : string -> elt

Emit a string value, which will be escaped.

val raw_html : string -> elt

Emit raw HTML. Caution, this can lead to injection vulnerabilities, never use with text that comes from untrusted users.

val area : void

tag "area", see mdn

val base : void

tag "base", see mdn

val br : void

tag "br", see mdn

val col : void

tag "col", see mdn

val embed : void

tag "embed", see mdn

val hr : void

tag "hr", see mdn

val img : void

tag "img", see mdn

val input : void

tag "input", see mdn

tag "link", see mdn

val menuitem : void

tag "menuitem", see mdn

val meta : void

tag "meta", see mdn

val param : void

tag "param", see mdn

val source : void

tag "source", see mdn

val track : void

tag "track", see mdn

val wbr : void

tag "wbr", see mdn

val a : nary

tag "a", see mdn

val a' : nary'

tag "a", see mdn

val abbr : nary

tag "abbr", see mdn

val abbr' : nary'

tag "abbr", see mdn

val address : nary

tag "address", see mdn

val address' : nary'

tag "address", see mdn

val article : nary

tag "article", see mdn

val article' : nary'

tag "article", see mdn

val aside : nary

tag "aside", see mdn

val aside' : nary'

tag "aside", see mdn

val audio : nary

tag "audio", see mdn

val audio' : nary'

tag "audio", see mdn

val b : nary

tag "b", see mdn

val b' : nary'

tag "b", see mdn

val bdi : nary

tag "bdi", see mdn

val bdi' : nary'

tag "bdi", see mdn

val bdo : nary

tag "bdo", see mdn

val bdo' : nary'

tag "bdo", see mdn

val blockquote : nary

tag "blockquote", see mdn

val blockquote' : nary'

tag "blockquote", see mdn

val body : nary

tag "body", see mdn

val body' : nary'

tag "body", see mdn

val button : nary

tag "button", see mdn

val button' : nary'

tag "button", see mdn

val canvas : nary

tag "canvas", see mdn

val canvas' : nary'

tag "canvas", see mdn

val caption : nary

tag "caption", see mdn

val caption' : nary'

tag "caption", see mdn

val cite : nary

tag "cite", see mdn

val cite' : nary'

tag "cite", see mdn

val code : nary

tag "code", see mdn

val code' : nary'

tag "code", see mdn

val colgroup : nary

tag "colgroup", see mdn

val colgroup' : nary'

tag "colgroup", see mdn

val data : nary

tag "data", see mdn

val data' : nary'

tag "data", see mdn

val datalist : nary

tag "datalist", see mdn

val datalist' : nary'

tag "datalist", see mdn

val dd : nary

tag "dd", see mdn

val dd' : nary'

tag "dd", see mdn

val del : nary

tag "del", see mdn

val del' : nary'

tag "del", see mdn

val details : nary

tag "details", see mdn

val details' : nary'

tag "details", see mdn

val dfn : nary

tag "dfn", see mdn

val dfn' : nary'

tag "dfn", see mdn

val dialog : nary

tag "dialog", see mdn

val dialog' : nary'

tag "dialog", see mdn

val div : nary

tag "div", see mdn

val div' : nary'

tag "div", see mdn

val dl : nary

tag "dl", see mdn

val dl' : nary'

tag "dl", see mdn

val dt : nary

tag "dt", see mdn

val dt' : nary'

tag "dt", see mdn

val em : nary

tag "em", see mdn

val em' : nary'

tag "em", see mdn

val fieldset : nary

tag "fieldset", see mdn

val fieldset' : nary'

tag "fieldset", see mdn

val figcaption : nary

tag "figcaption", see mdn

val figcaption' : nary'

tag "figcaption", see mdn

val figure : nary

tag "figure", see mdn

val figure' : nary'

tag "figure", see mdn

tag "footer", see mdn

val footer' : nary'

tag "footer", see mdn

val form : nary

tag "form", see mdn

val form' : nary'

tag "form", see mdn

val h1 : nary

tag "h1", see mdn

val h1' : nary'

tag "h1", see mdn

val h2 : nary

tag "h2", see mdn

val h2' : nary'

tag "h2", see mdn

val h3 : nary

tag "h3", see mdn

val h3' : nary'

tag "h3", see mdn

val h4 : nary

tag "h4", see mdn

val h4' : nary'

tag "h4", see mdn

val h5 : nary

tag "h5", see mdn

val h5' : nary'

tag "h5", see mdn

val h6 : nary

tag "h6", see mdn

val h6' : nary'

tag "h6", see mdn

val head : nary

tag "head", see mdn

val head' : nary'

tag "head", see mdn

val header : nary

tag "header", see mdn

val header' : nary'

tag "header", see mdn

val hgroup : nary

tag "hgroup", see mdn

val hgroup' : nary'

tag "hgroup", see mdn

val html : nary

tag "html", see mdn

val html' : nary'

tag "html", see mdn

val i : nary

tag "i", see mdn

val i' : nary'

tag "i", see mdn

val iframe : nary

tag "iframe", see mdn

val iframe' : nary'

tag "iframe", see mdn

val ins : nary

tag "ins", see mdn

val ins' : nary'

tag "ins", see mdn

val kbd : nary

tag "kbd", see mdn

val kbd' : nary'

tag "kbd", see mdn

val label : nary

tag "label", see mdn

val label' : nary'

tag "label", see mdn

val legend : nary

tag "legend", see mdn

val legend' : nary'

tag "legend", see mdn

val li : nary

tag "li", see mdn

val li' : nary'

tag "li", see mdn

val main : nary

tag "main", see mdn

val main' : nary'

tag "main", see mdn

val map : nary

tag "map", see mdn

val map' : nary'

tag "map", see mdn

val mark : nary

tag "mark", see mdn

val mark' : nary'

tag "mark", see mdn

val math : nary

tag "math", see mdn

val math' : nary'

tag "math", see mdn

val menu : nary

tag "menu", see mdn

val menu' : nary'

tag "menu", see mdn

val meter : nary

tag "meter", see mdn

val meter' : nary'

tag "meter", see mdn

val nav : nary

tag "nav", see mdn

val nav' : nary'

tag "nav", see mdn

val noscript : nary

tag "noscript", see mdn

val noscript' : nary'

tag "noscript", see mdn

val object_ : nary

tag "object", see mdn

val object_' : nary'

tag "object", see mdn

val ol : nary

tag "ol", see mdn

val ol' : nary'

tag "ol", see mdn

val optgroup : nary

tag "optgroup", see mdn

val optgroup' : nary'

tag "optgroup", see mdn

val option : nary

tag "option", see mdn

val option' : nary'

tag "option", see mdn

val output : nary

tag "output", see mdn

val output' : nary'

tag "output", see mdn

val p : nary

tag "p", see mdn

val p' : nary'

tag "p", see mdn

val picture : nary

tag "picture", see mdn

val picture' : nary'

tag "picture", see mdn

val pre : nary

tag "pre", see mdn

val pre' : nary'

tag "pre", see mdn

val progress : nary

tag "progress", see mdn

val progress' : nary'

tag "progress", see mdn

val q : nary

tag "q", see mdn

val q' : nary'

tag "q", see mdn

val rb : nary

tag "rb", see mdn

val rb' : nary'

tag "rb", see mdn

val rp : nary

tag "rp", see mdn

val rp' : nary'

tag "rp", see mdn

val rt : nary

tag "rt", see mdn

val rt' : nary'

tag "rt", see mdn

val rtc : nary

tag "rtc", see mdn

val rtc' : nary'

tag "rtc", see mdn

val ruby : nary

tag "ruby", see mdn

val ruby' : nary'

tag "ruby", see mdn

val s : nary

tag "s", see mdn

val s' : nary'

tag "s", see mdn

val samp : nary

tag "samp", see mdn

val samp' : nary'

tag "samp", see mdn

val script : nary

tag "script", see mdn

val script' : nary'

tag "script", see mdn

val section : nary

tag "section", see mdn

val section' : nary'

tag "section", see mdn

val select : nary

tag "select", see mdn

val select' : nary'

tag "select", see mdn

val slot : nary

tag "slot", see mdn

val slot' : nary'

tag "slot", see mdn

val small : nary

tag "small", see mdn

val small' : nary'

tag "small", see mdn

val span : nary

tag "span", see mdn

val span' : nary'

tag "span", see mdn

val strong : nary

tag "strong", see mdn

val strong' : nary'

tag "strong", see mdn

val style : nary

tag "style", see mdn

val style' : nary'

tag "style", see mdn

val sub : nary

tag "sub", see mdn

val sub' : nary'

tag "sub", see mdn

val summary : nary

tag "summary", see mdn

val summary' : nary'

tag "summary", see mdn

val sup : nary

tag "sup", see mdn

val sup' : nary'

tag "sup", see mdn

val svg : nary

tag "svg", see mdn

val svg' : nary'

tag "svg", see mdn

val table : nary

tag "table", see mdn

val table' : nary'

tag "table", see mdn

val tbody : nary

tag "tbody", see mdn

val tbody' : nary'

tag "tbody", see mdn

val td : nary

tag "td", see mdn

val td' : nary'

tag "td", see mdn

val template : nary

tag "template", see mdn

val template' : nary'

tag "template", see mdn

val textarea : nary

tag "textarea", see mdn

val textarea' : nary'

tag "textarea", see mdn

val tfoot : nary

tag "tfoot", see mdn

val tfoot' : nary'

tag "tfoot", see mdn

val th : nary

tag "th", see mdn

val th' : nary'

tag "th", see mdn

val thead : nary

tag "thead", see mdn

val thead' : nary'

tag "thead", see mdn

val time : nary

tag "time", see mdn

val time' : nary'

tag "time", see mdn

val title : nary

tag "title", see mdn

val title' : nary'

tag "title", see mdn

val tr : nary

tag "tr", see mdn

val tr' : nary'

tag "tr", see mdn

val u : nary

tag "u", see mdn

val u' : nary'

tag "u", see mdn

val ul : nary

tag "ul", see mdn

val ul' : nary'

tag "ul", see mdn

val var : nary

tag "var", see mdn

val var' : nary'

tag "var", see mdn

val video : nary

tag "video", see mdn

val video' : nary'

tag "video", see mdn

module A : sig ... end

Attributes

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/.dummy b/dev/tiny_httpd/Tiny_httpd_server/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_server/Headers/index.html b/dev/tiny_httpd/Tiny_httpd_server/Headers/index.html new file mode 100644 index 00000000..1bd19b53 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Headers/index.html @@ -0,0 +1,2 @@ + +Headers (tiny_httpd.Tiny_httpd_server.Headers)

Module Tiny_httpd_server.Headers

type t = (string * string) list

The header files of a request or response.

Neither the key nor the value can contain '\r' or '\n'. See https://tools.ietf.org/html/rfc7230#section-3.2

val empty : t

Empty list of headers

  • since 0.5
val get : ?f:( string -> string ) -> string -> t -> string option

get k headers looks for the header field with key k.

  • parameter f

    if provided, will transform the value before it is returned.

val set : string -> string -> t -> t

set k v headers sets the key k to value v. It erases any previous entry for k

val remove : string -> t -> t

Remove the key from the headers, if present.

val contains : string -> t -> bool

Is there a header with the given key?

val pp : Stdlib.Format.formatter -> t -> unit

Pretty print the headers.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Meth/index.html b/dev/tiny_httpd/Tiny_httpd_server/Meth/index.html new file mode 100644 index 00000000..532d824d --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Meth/index.html @@ -0,0 +1,2 @@ + +Meth (tiny_httpd.Tiny_httpd_server.Meth)

Module Tiny_httpd_server.Meth

type t = [
| `GET
| `PUT
| `POST
| `HEAD
| `DELETE
]

A HTTP method. For now we only handle a subset of these.

See https://tools.ietf.org/html/rfc7231#section-4

val pp : Stdlib.Format.formatter -> t -> unit
val to_string : t -> string
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Middleware/index.html b/dev/tiny_httpd/Tiny_httpd_server/Middleware/index.html new file mode 100644 index 00000000..6ee77bd2 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Middleware/index.html @@ -0,0 +1,2 @@ + +Middleware (tiny_httpd.Tiny_httpd_server.Middleware)

Module Tiny_httpd_server.Middleware

Middlewares

A middleware can be inserted in a handler to modify or observe its behavior.

  • since 0.11
type handler = byte_stream Request.t -> resp:( Response.t -> unit ) -> unit

Handlers are functions returning a response to a request. The response can be delayed, hence the use of a continuation as the resp parameter.

type t = handler -> handler

A middleware is a handler transformation.

It takes the existing handler h, and returns a new one which, given a query, modify it or log it before passing it to h, or fail. It can also log or modify or drop the response.

val nil : t

Trivial middleware that does nothing.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Request/index.html b/dev/tiny_httpd/Tiny_httpd_server/Request/index.html new file mode 100644 index 00000000..6ee8034b --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Request/index.html @@ -0,0 +1,2 @@ + +Request (tiny_httpd.Tiny_httpd_server.Request)

Module Tiny_httpd_server.Request

type 'body t = private {
meth : Meth.t;
host : string;
headers : Headers.t;
http_version : int * int;
path : string;
path_components : string list;
query : (string * string) list;
body : 'body;
start_time : float;(*

Obtained via get_time_s in create

  • since 0.11
*)
}

A request with method, path, host, headers, and a body, sent by a client.

The body is polymorphic because the request goes through several transformations. First it has no body, as only the request and headers are read; then it has a stream body; then the body might be entirely read as a string via read_body_full.

  • since 0.6 The field [query] was added and contains the query parameters in ["?foo=bar,x=y"]
  • since 0.6 The field [path_components] is the part of the path that precedes [query] and is split on ["/"].
  • since 0.11 the type is a private alias
  • since 0.11 the field [start_time] was added
val pp : Stdlib.Format.formatter -> string t -> unit

Pretty print the request and its body

val pp_ : Stdlib.Format.formatter -> _ t -> unit

Pretty print the request without its body

val headers : _ t -> Headers.t

List of headers of the request, including "Host"

val get_header : ?f:( string -> string ) -> _ t -> string -> string option
val get_header_int : _ t -> string -> int option
val set_header : string -> string -> 'a t -> 'a t

set_header k v req sets k: v in the request req's headers.

val update_headers : ( Headers.t -> Headers.t ) -> 'a t -> 'a t

Modify headers

  • since 0.11
val set_body : 'a -> _ t -> 'a t

set_body b req returns a new query whose body is b.

  • since 0.11
val host : _ t -> string

Host field of the request. It also appears in the headers.

val meth : _ t -> Meth.t

Method for the request.

val path : _ t -> string

Request path.

val query : _ t -> (string * string) list

Decode the query part of the path field

  • since 0.4
val body : 'b t -> 'b

Request body, possibly empty.

val start_time : _ t -> float

time stamp (from Unix.gettimeofday) after parsing the first line of the request

  • since 0.11
val limit_body_size : max_size:int -> byte_stream t -> byte_stream t

Limit the body size to max_size bytes, or return a 413 error.

  • since 0.3
val read_body_full : ?buf_size:int -> byte_stream t -> string t

Read the whole body into a string. Potentially blocking.

  • parameter buf_size

    initial size of underlying buffer (since 0.11)

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Response/index.html b/dev/tiny_httpd/Tiny_httpd_server/Response/index.html new file mode 100644 index 00000000..5b129e45 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Response/index.html @@ -0,0 +1,19 @@ + +Response (tiny_httpd.Tiny_httpd_server.Response)

Module Tiny_httpd_server.Response

type body = [
| `String of string
| `Stream of byte_stream
| `Void
]

Body of a response, either as a simple string, or a stream of bytes, or nothing (for server-sent events).

type t = private {
code : Response_code.t;(*

HTTP response code. See Response_code.

*)
headers : Headers.t;(*

Headers of the reply. Some will be set by Tiny_httpd automatically.

*)
body : body;(*

Body of the response. Can be empty.

*)
}

A response to send back to a client.

val set_body : body -> t -> t

Set the body of the response.

  • since 0.11
val set_header : string -> string -> t -> t

Set a header.

  • since 0.11
val update_headers : ( Headers.t -> Headers.t ) -> t -> t

Modify headers

  • since 0.11
val set_headers : Headers.t -> t -> t

Set all headers.

  • since 0.11
val set_code : Response_code.t -> t -> t

Set the response code.

  • since 0.11
val make_raw : ?headers:Headers.t -> code:Response_code.t -> string -> t

Make a response from its raw components, with a string body. Use "" to not send a body at all.

val make_raw_stream : + ?headers:Headers.t -> + code:Response_code.t -> + byte_stream -> + t

Same as make_raw but with a stream body. The body will be sent with the chunked transfer-encoding.

val make : + ?headers:Headers.t -> + ( body, Response_code.t * string ) Stdlib.result -> + t

make r turns a result into a response.

  • make (Ok body) replies with 200 and the body.
  • make (Error (code,msg)) replies with the given error code and message as body.
val make_string : + ?headers:Headers.t -> + ( string, Response_code.t * string ) Stdlib.result -> + t

Same as make but with a string body.

val make_stream : + ?headers:Headers.t -> + ( byte_stream, Response_code.t * string ) Stdlib.result -> + t

Same as make but with a stream body.

val fail : + ?headers:Headers.t -> + code:int -> + ( 'a, unit, string, t ) Stdlib.format4 -> + 'a

Make the current request fail with the given code and message. Example: fail ~code:404 "oh noes, %s not found" "waldo".

val fail_raise : code:int -> ( 'a, unit, string, 'b ) Stdlib.format4 -> 'a

Similar to fail but raises an exception that exits the current handler. This should not be used outside of a (path) handler. Example: fail_raise ~code:404 "oh noes, %s not found" "waldo"; never_executed()

val pp : Stdlib.Format.formatter -> t -> unit

Pretty print the response.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Response_code/index.html b/dev/tiny_httpd/Tiny_httpd_server/Response_code/index.html new file mode 100644 index 00000000..1221c1ee --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Response_code/index.html @@ -0,0 +1,2 @@ + +Response_code (tiny_httpd.Tiny_httpd_server.Response_code)

Module Tiny_httpd_server.Response_code

type t = int

A standard HTTP code.

https://tools.ietf.org/html/rfc7231#section-6

val ok : t

The code 200

val not_found : t

The code 404

val descr : t -> string

A description of some of the error codes. NOTE: this is not complete (yet).

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/Route/index.html b/dev/tiny_httpd/Tiny_httpd_server/Route/index.html new file mode 100644 index 00000000..f366ec40 --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/Route/index.html @@ -0,0 +1,2 @@ + +Route (tiny_httpd.Tiny_httpd_server.Route)

Module Tiny_httpd_server.Route

Routing

Basic type-safe routing.

  • since 0.6
type ('a, 'b) comp

An atomic component of a path

type ('a, 'b) t

A route, composed of path components

val int : ( int -> 'a, 'a ) comp

Matches an integer.

val string : ( string -> 'a, 'a ) comp

Matches a string not containing '/' and binds it as is.

val string_urlencoded : ( string -> 'a, 'a ) comp

Matches a URL-encoded string, and decodes it.

val exact : string -> ( 'a, 'a ) comp

exact "s" matches "s" and nothing else.

val return : ( 'a, 'a ) t

Matches the empty path.

val rest_of_path : ( string -> 'a, 'a ) t

Matches a string, even containing '/'. This will match the entirety of the remaining route.

  • since 0.7
val rest_of_path_urlencoded : ( string -> 'a, 'a ) t

Matches a string, even containing '/', an URL-decode it. This will match the entirety of the remaining route.

  • since 0.7
val (@/) : ( 'a, 'b ) comp -> ( 'b, 'c ) t -> ( 'a, 'c ) t

comp / route matches "foo/bar/…" iff comp matches "foo", and route matches "bar/…".

val exact_path : string -> ( 'a, 'b ) t -> ( 'a, 'b ) t

exact_path "foo/bar/..." r is equivalent to exact "foo" @/ exact "bar" @/ ... @/ r

  • since 0.11 *
val pp : Stdlib.Format.formatter -> ( _, _ ) t -> unit

Print the route.

  • since 0.7
val to_string : ( _, _ ) t -> string

Print the route.

  • since 0.7
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/index.html b/dev/tiny_httpd/Tiny_httpd_server/index.html new file mode 100644 index 00000000..9d43811b --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/index.html @@ -0,0 +1,47 @@ + +Tiny_httpd_server (tiny_httpd.Tiny_httpd_server)

Module Tiny_httpd_server

HTTP server.

This library implements a very simple, basic HTTP/1.1 server using blocking IOs and threads.

It is possible to use a thread pool, see create's argument new_thread.

type buf = Tiny_httpd_buf.t
type byte_stream = Tiny_httpd_stream.t

Methods

module Meth : sig ... end

Headers

Headers are metadata associated with a request or response.

module Headers : sig ... end

Requests

Requests are sent by a client, e.g. a web browser or cURL.

module Request : sig ... end

Response Codes

module Response_code : sig ... end

Responses

Responses are what a http server, such as Tiny_httpd, send back to the client to answer a Request.t

module Response : sig ... end
module Route : sig ... end
module Middleware : sig ... end

Main Server type

type t

A HTTP server. See create for more details.

val create : + ?masksigpipe:bool -> + ?max_connections:int -> + ?timeout:float -> + ?buf_size:int -> + ?get_time_s:( unit -> float ) -> + ?new_thread:( ( unit -> unit ) -> unit ) -> + ?addr:string -> + ?port:int -> + ?sock:Unix.file_descr -> + ?middlewares:([ `Encoding | `Stage of int ] * Middleware.t) list -> + unit -> + t

Create a new webserver.

The server will not do anything until run is called on it. Before starting the server, one can use add_path_handler and set_top_handler to specify how to handle incoming requests.

  • parameter masksigpipe

    if true, block the signal Sys.sigpipe which otherwise tends to kill client threads when they try to write on broken sockets. Default: true.

  • parameter buf_size

    size for buffers (since 0.11)

  • parameter new_thread

    a function used to spawn a new thread to handle a new client connection. By default it is Thread.create but one could use a thread pool instead.

  • parameter middlewares

    see add_middleware for more details.

  • parameter max_connections

    maximum number of simultaneous connections.

  • parameter timeout

    connection is closed if the socket does not do read or write for the amount of second. Default: 0.0 which means no timeout. timeout is not recommended when using proxy.

  • parameter addr

    address (IPv4 or IPv6) to listen on. Default "127.0.0.1".

  • parameter port

    to listen on. Default 8080.

  • parameter sock

    an existing socket given to the server to listen on, e.g. by systemd on Linux (or launchd on macOS). If passed in, this socket will be used instead of the addr and port. If not passed in, those will be used. This parameter exists since 0.10.

  • parameter get_time_s

    obtain the current timestamp in seconds. This parameter exists since 0.11.

val addr : t -> string

Address on which the server listens.

val is_ipv6 : t -> bool

is_ipv6 server returns true iff the address of the server is an IPv6 address.

  • since 0.3
val port : t -> int

Port on which the server listens.

val active_connections : t -> int

Number of active connections

val add_decode_request_cb : + t -> + ( unit Request.t -> + (unit Request.t * ( byte_stream -> byte_stream )) option ) -> + unit

Add a callback for every request. The callback can provide a stream transformer and a new request (with modified headers, typically). A possible use is to handle decompression by looking for a Transfer-Encoding header and returning a stream transformer that decompresses on the fly.

  • deprecated

    use add_middleware instead

val add_encode_response_cb : + t -> + ( unit Request.t -> Response.t -> Response.t option ) -> + unit

Add a callback for every request/response pair. Similarly to add_encode_response_cb the callback can return a new response, for example to compress it. The callback is given the query with only its headers, as well as the current response.

  • deprecated

    use add_middleware instead

val add_middleware : + stage:[ `Encoding | `Stage of int ] -> + t -> + Middleware.t -> + unit

Add a middleware to every request/response pair.

  • parameter stage

    specify when middleware applies. Encoding comes first (outermost layer), then stages in increasing order.

  • raises Invalid_argument

    if stage is `Stage n where n < 1

  • since 0.11

Request handlers

val set_top_handler : t -> ( string Request.t -> Response.t ) -> unit

Setup a handler called by default.

This handler is called with any request not accepted by any handler installed via add_path_handler. If no top handler is installed, unhandled paths will return a 404 not found.

val add_route_handler : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + ?middlewares:Middleware.t list -> + ?meth:Meth.t -> + t -> + ( 'a, string Request.t -> Response.t ) Route.t -> + 'a -> + unit

add_route_handler server Route.(exact "path" @/ string @/ int @/ return) f calls f "foo" 42 request when a request with path "path/foo/42/" is received.

Note that the handlers are called in the reverse order of their addition, so the last registered handler can override previously registered ones.

  • parameter meth

    if provided, only accept requests with the given method. Typically one could react to `GET or `PUT.

  • parameter accept

    should return Ok() if the given request (before its body is read) should be accepted, Error (code,message) if it's to be rejected (e.g. because its content is too big, or for some permission error). See the http_of_dir program for an example of how to use accept to filter uploads that are too large before the upload even starts. The default always returns Ok(), i.e. it accepts all requests.

  • since 0.6
val add_route_handler_stream : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + ?middlewares:Middleware.t list -> + ?meth:Meth.t -> + t -> + ( 'a, byte_stream Request.t -> Response.t ) Route.t -> + 'a -> + unit

Similar to add_route_handler, but where the body of the request is a stream of bytes that has not been read yet. This is useful when one wants to stream the body directly into a parser, json decoder (such as Jsonm) or into a file.

  • since 0.6

Server-sent events

EXPERIMENTAL: this API is not stable yet.

module type SERVER_SENT_GENERATOR = sig ... end

A server-side function to generate of Server-sent events.

type server_sent_generator = (module SERVER_SENT_GENERATOR)

Server-sent event generator

  • since 0.9
val add_route_server_sent_handler : + ?accept: + ( unit Request.t -> ( unit, Response_code.t * string ) Stdlib.result ) -> + t -> + ( 'a, string Request.t -> server_sent_generator -> unit ) Route.t -> + 'a -> + unit

Add a handler on an endpoint, that serves server-sent events.

The callback is given a generator that can be used to send events as it pleases. The connection is always closed by the client, and the accepted method is always GET. This will set the header "content-type" to "text/event-stream" automatically and reply with a 200 immediately. See server_sent_generator for more details.

This handler stays on the original thread (it is synchronous).

  • since 0.9

Run the server

val stop : t -> unit

Ask the server to stop. This might not have an immediate effect as run might currently be waiting on IO.

val run : t -> ( unit, exn ) Stdlib.result

Run the main loop of the server, listening on a socket described at the server's creation time, using new_thread to start a thread for each new client.

This returns Ok () if the server exits gracefully, or Error e if it exits with an error.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_server/module-type-SERVER_SENT_GENERATOR/index.html b/dev/tiny_httpd/Tiny_httpd_server/module-type-SERVER_SENT_GENERATOR/index.html new file mode 100644 index 00000000..a602d7ff --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_server/module-type-SERVER_SENT_GENERATOR/index.html @@ -0,0 +1,8 @@ + +SERVER_SENT_GENERATOR (tiny_httpd.Tiny_httpd_server.SERVER_SENT_GENERATOR)

Module type Tiny_httpd_server.SERVER_SENT_GENERATOR

A server-side function to generate of Server-sent events.

See the w3c page and this blog post.

  • since 0.9
val set_headers : Headers.t -> unit

Set headers of the response. This is not mandatory but if used at all, it must be called before any call to send_event (once events are sent the response is already sent too).

val send_event : + ?event:string -> + ?id:string -> + ?retry:string -> + data:string -> + unit -> + unit

Send an event from the server. If data is a multiline string, it will be sent on separate "data:" lines.

val close : unit -> unit

Close connection.

  • since 0.11
\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_stream/.dummy b/dev/tiny_httpd/Tiny_httpd_stream/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_stream/index.html b/dev/tiny_httpd/Tiny_httpd_stream/index.html new file mode 100644 index 00000000..b85d125d --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_stream/index.html @@ -0,0 +1,18 @@ + +Tiny_httpd_stream (tiny_httpd.Tiny_httpd_stream)

Module Tiny_httpd_stream

type hidden
type t = {
mutable bs : bytes;(*

The bytes

*)
mutable off : int;(*

Beginning of valid slice in bs

*)
mutable len : int;(*

Length of valid slice in bs. If len = 0 after a call to fill, then the stream is finished.

*)
fill_buf : unit -> unit;(*

See the current slice of the internal buffer as bytes, i, len, where the slice is bytes[i] .. [bytes[i+len-1]]. Can block to refill the buffer if there is currently no content. If len=0 then there is no more data.

*)
consume : int -> unit;(*

Consume n bytes from the buffer. This should only be called with n <= len.

*)
close : unit -> unit;(*

Close the stream.

*)
_rest : hidden;(*

Use make to build a stream.

*)
}

A buffered stream, with a view into the current buffer (or refill if empty), and a function to consume n bytes. See Byte_stream for more details.

val close : t -> unit
val empty : t
val of_chan : ?buf_size:int -> Stdlib.in_channel -> t

Make a buffered stream from the given channel.

val of_chan_close_noerr : ?buf_size:int -> Stdlib.in_channel -> t

Same as of_chan but the close method will never fail.

val of_bytes : ?i:int -> ?len:int -> bytes -> t

A stream that just returns the slice of bytes starting from i and of length len.

val of_string : string -> t
val iter : ( bytes -> int -> int -> unit ) -> t -> unit

Iterate on the chunks of the stream

  • since 0.3
val to_chan : Stdlib.out_channel -> t -> unit

Write the stream to the channel.

  • since 0.3
val make : + ?bs:bytes -> + ?close:( t -> unit ) -> + consume:( t -> int -> unit ) -> + fill:( t -> unit ) -> + unit -> + t

make ~fill () creates a byte stream.

  • parameter fill

    is used to refill the buffer, and is called initially.

  • parameter close

    optional closing.

  • parameter init_size

    size of the buffer.

val with_file : ?buf_size:int -> string -> ( t -> 'a ) -> 'a

Open a file with given name, and obtain an input stream on its content. When the function returns, the stream (and file) are closed.

val read_line : ?buf:Tiny_httpd_buf.t -> t -> string

Read a line from the stream.

  • parameter buf

    a buffer to (re)use. Its content will be cleared.

val read_all : ?buf:Tiny_httpd_buf.t -> t -> string

Read the whole stream into a string.

  • parameter buf

    a buffer to (re)use. Its content will be cleared.

val limit_size_to : + close_rec:bool -> + max_size:int -> + too_big:( int -> unit ) -> + t -> + t
val read_chunked : ?buf:Tiny_httpd_buf.t -> fail:( string -> exn ) -> t -> t

Convert a stream into a stream of byte chunks using the chunked encoding. The size of chunks is not specified.

  • parameter buf

    buffer used for intermediate storage.

  • parameter fail

    used to build an exception if reading fails.

val read_exactly : + close_rec:bool -> + size:int -> + too_short:( int -> unit ) -> + t -> + t

read_exactly ~size bs returns a new stream that reads exactly size bytes from bs, and then closes.

  • parameter close_rec

    if true, closing the resulting stream also closes bs

  • parameter too_short

    is called if bs closes with still n bytes remaining

val output_chunked : Stdlib.out_channel -> t -> unit

Write the stream into the channel, using the chunked encoding.

\ No newline at end of file diff --git a/dev/tiny_httpd/Tiny_httpd_util/.dummy b/dev/tiny_httpd/Tiny_httpd_util/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd/Tiny_httpd_util/index.html b/dev/tiny_httpd/Tiny_httpd_util/index.html new file mode 100644 index 00000000..e7a5173d --- /dev/null +++ b/dev/tiny_httpd/Tiny_httpd_util/index.html @@ -0,0 +1,2 @@ + +Tiny_httpd_util (tiny_httpd.Tiny_httpd_util)

Module Tiny_httpd_util

Some utils for writing web servers

  • since 0.2
val percent_encode : ?skip:( char -> bool ) -> string -> string

Encode the string into a valid path following https://tools.ietf.org/html/rfc3986#section-2.1

  • parameter skip

    if provided, allows to preserve some characters, e.g. '/' in a path.

val percent_decode : string -> string option

Inverse operation of percent_encode. Can fail since some strings are not valid percent encodings.

val split_query : string -> string * string

Split a path between the path and the query

  • since 0.5
val split_on_slash : string -> string list

Split a string on '/', remove the trailing '/' if any.

  • since 0.6
val get_non_query_path : string -> string

get the part of the path that is not the query parameters.

  • since 0.5
val get_query : string -> string

Obtain the query part of a path.

  • since 0.4
val parse_query : string -> ( (string * string) list, string ) Stdlib.result

Parse a query as a list of '&' or ';' separated key=value pairs. The order might not be preserved.

  • since 0.3
\ No newline at end of file diff --git a/dev/tiny_httpd/index.html b/dev/tiny_httpd/index.html new file mode 100644 index 00000000..6d3cd4db --- /dev/null +++ b/dev/tiny_httpd/index.html @@ -0,0 +1,2 @@ + +index (tiny_httpd.index)

tiny_httpd index

Library tiny_httpd

This library exposes the following toplevel modules:

\ No newline at end of file diff --git a/dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/.dummy b/dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/.dummy new file mode 100644 index 00000000..e69de29b diff --git a/dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/index.html b/dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/index.html new file mode 100644 index 00000000..7c3668d1 --- /dev/null +++ b/dev/tiny_httpd_camlzip/Tiny_httpd_camlzip/index.html @@ -0,0 +1,6 @@ + +Tiny_httpd_camlzip (tiny_httpd_camlzip.Tiny_httpd_camlzip)

Module Tiny_httpd_camlzip

val middleware : + ?compress_above:int -> + ?buf_size:int -> + unit -> + Tiny_httpd_server.Middleware.t

Middleware responsible for deflate compression/decompression.

  • since 0.11
val setup : ?compress_above:int -> ?buf_size:int -> Tiny_httpd_server.t -> unit

Install middleware for tiny_httpd to be able to encode/decode compressed streams

  • parameter compress_above

    threshold above with string responses are compressed

  • parameter buf_size

    size of the underlying buffer for compression/decompression

\ No newline at end of file diff --git a/dev/tiny_httpd_camlzip/index.html b/dev/tiny_httpd_camlzip/index.html new file mode 100644 index 00000000..ced1a01e --- /dev/null +++ b/dev/tiny_httpd_camlzip/index.html @@ -0,0 +1,2 @@ + +index (tiny_httpd_camlzip.index)

tiny_httpd_camlzip index

Library tiny_httpd_camlzip

The entry point of this library is the module: Tiny_httpd_camlzip.

\ No newline at end of file