--- /dev/null
+Copyright (c) 2013, Michael Wallner <mike@php.net>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
--- /dev/null
+# namespace http
+
+This is pecl_http-v2.
+
+This documentation is work-in-progress.
The http\Env module overrides PHP's builtin POST data parser to be run also if
the request method is not POST. Additionally it will handle
-```application/json``` payloads if ```ext/json``` is available. Successfully
+application/json payloads if ext/json is available. Successfully
parsed JSON will be put right into the $_POST array.
## Constants:
-> None.
+None.
## Properties:
-* ```protected $query = NULL```
+* protected $query = NULL
The request's query parameters. ($_GET)
-* ```protected $form = NULL```
+* protected $form = NULL
The request's form parameters. ($_POST)
-* ```protected $files = NULL```
+* protected $files = NULL
The request's form uploads. ($_FILES)
+# void http\Env\Request::__construct(void)
+
+Instantiate the server's current HTTP request.
+
+## Params:
+
+None.
## Parameters:
-* Optional ```string $body_class_name```
+* Optional string $body_class_name
A user class extending http\Body.
## Returns:
-* ```http\Message\Body``` instance representing the request body
+* http\Message\Body instance representing the request body
## Throws:
## Parameters:
-* Optional ```string $header_name```
+* Optional string $header_name
The key of a header to retrieve.
## Returns:
-* ```NULL```, if $header_name was not found
-* ```string```, the compound header when $header_name was found
-* ```array``` of all headers if $header_name was not specified
+* NULL, if $header_name was not found
+* string, the compound header when $header_name was found
+* array of all headers if $header_name was not specified
## Parameters:
-> None.
+None.
## Returns:
-* ```int```, the HTTP response code.
+* int, the HTTP response code.
## Parameters:
-* Optional ```string $header_name```
+* Optional string $header_name
The name of the response header to retrieve.
## Returns:
-* ```string```, the compound value of the response header to send
-* ```NULL```, if the header was not found
-* ```array```, of all response headers, if $header_name was not specified
+* string, the compound value of the response header to send
+* NULL, if the header was not found
+* array, of all response headers, if $header_name was not specified
## Parameters:
-> None.
+None.
## Returns:
-* ```array``` mapping of the form \[
+* array mapping of the form \[
...
- ```int $code``` => ```string $status```
+ int $code => string $status
...
\]
## Parameters:
-* ```int $code```
+* int $code
The HTTP response code to get the string representation for.
## Returns:
-* ```string```, the HTTP response status message
-* empty ```string```, if no message for this code was found
+* string, the HTTP response status message
+* empty string, if no message for this code was found
## Params:
-* ```string $params```
+* string $params
HTTP header parameter's value to negotiate.
-* ```array $supported```
+* array $supported
List of supported negotiation operands.
-* Optional ```string $prim_typ_sep```
+* Optional string $prim_typ_sep
A "primary type separator", i.e. that would be a hyphen for content language negotiation (en-US, de-DE, etc.).
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the closest match negotiated, or the default (first entry of $supported).
+* NULL, if negotiation fails.
+* string, the closest match negotiated, or the default (first entry of $supported).
## Params:
-* ```array $supported```
+* array $supported
List of supported content character sets.
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the negotiated character set.
+* NULL, if negotiation fails.
+* string, the negotiated character set.
## Params:
-* ```array $supported```
+* array $supported
List of supported MIME content types.
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the negotiated content type.
+* NULL, if negotiation fails.
+* string, the negotiated content type.
## Example:
-A client indicates his accepted MIME content types by sending an ```Accept```
-header. The static ```http\Env``` class provides a facility to negotiate the
+A client indicates his accepted MIME content types by sending an Accept
+header. The static http\Env class provides a facility to negotiate the
client's preferred content type:
<?php
## Params:
-* ```array $supported```
+* array $supported
List of supported content encodings.
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the negotiated encoding.
+* NULL, if negotiation fails.
+* string, the negotiated encoding.
## Params:
-* ```array $supported```
+* array $supported
List of supported content languages.
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the negotiated language.
+* NULL, if negotiation fails.
+* string, the negotiated language.
## Params:
-* ```int $code```
+* int $code
The HTTP response status code.
## Returns:
-* ```bool``` Success.
+* bool Success.
Set a response header, either replacing a prior set header, or appending the new header value, depending on $replace.
-If no $header_value is specified, or $header_value is ```NULL```, then a previously set header with the same key will be deleted from the list.
+If no $header_value is specified, or $header_value is NULL, then a previously set header with the same key will be deleted from the list.
-If $response_code is not ```0```, the response status code is updated accordingly.
+If $response_code is not 0, the response status code is updated accordingly.
## Parameters:
-* ```string $header_name```, the name of the response header.
-* Optional ```mixed $header_value```, the header value.
-* Optional ```int $response_code```, any HTTP response status code to set.
-* Optional ```bool $replace```, whether to replace a previously set response header with the same name.
+* string $header_name, the name of the response header.
+* Optional mixed $header_value, the header value.
+* Optional int $response_code, any HTTP response status code to set.
+* Optional bool $replace, whether to replace a previously set response header with the same name.
## Returns:
-* ```bool``` Success.
+* bool Success.
## Constants:
-* ```MATCH_LOOSE```
+* MATCH_LOOSE
None of the following match constraints applies.
-* ```MATCH_CASE```
+* MATCH_CASE
Perform case sensitive matching.
-* ```MATCH_WORD```
+* MATCH_WORD
Match only on word boundaries (according by CTYPE alpha-numeric).
-* ```MATCH_FULL```
+* MATCH_FULL
Match the complete string.
-* ```MATCH_STRICT```
- Case sensitively match the full string (same as ```MATCH_CASE|MATCH_FULL```).
+* MATCH_STRICT
+ Case sensitively match the full string (same as MATCH_CASE|MATCH_FULL).
## Properties:
-* ```public $name = NULL```
+* public $name = NULL
The name of the HTTP header.
-* ```public $value = NULL```
+* public $value = NULL
The value of the HTTP header.
## Params:
-* Optional ```string $name```
+* Optional string $name
The HTTP header name.
-* Optional ```mixed $value```
+* Optional mixed $value
The value of the header.
# Throws:
## Params:
-> None.
+None.
## Returns:
-* ```string```, the serialized form of the HTTP header (i.e. "Name: value").
+* string, the serialized form of the HTTP header (i.e. "Name: value").
## Params:
-* Optional ```mixed $ps```
+* Optional mixed $ps
The parameter separator(s).
-* Optional ```mixed $as```
+* Optional mixed $as
The argument separator(s).
-* Optional ```mixed```
+* Optional mixed
The value separator(s).
-* Optional ```int $flags```
+* Optional int $flags
The modus operandi. See http\Params constants.
## Returns:
-* ```http\Params``` instance
+* http\Params instance
## Params:
-* ```string $value```
+* string $value
The comparison value.
-* Optional ```int $flags```
+* Optional int $flags
The modus operandi. See http\Header constants.
## Returns:
-* ```bool```, whether $value matches the header value according to $flags.
+* bool, whether $value matches the header value according to $flags.
Negotiate the header's value against a list of supported values in $supported.
Negotiation operation is adopted according to the header name, i.e. if the
-header being negotiated is ```Accept```, then a slash is used as primary type
-separator, and if the header is ```Accept-Language``` respectively, a hyphen is
+header being negotiated is Accept, then a slash is used as primary type
+separator, and if the header is Accept-Language respectively, a hyphen is
used instead.
> ***NOTE:*** The first elemement of $supported serves as a default if no operand matches.
## Params:
-* ```array $supported```
+* array $supported
The list of supported values to negotiate.
-* Optional reference ```array &$result```
+* Optional reference array &$result
Out parameter recording the negotiation results.
## Returns:
-* ```NULL```, if negotiation fails.
-* ```string```, the closest match negotiated, or the default (first entry of $supported).
+* NULL, if negotiation fails.
+* string, the closest match negotiated, or the default (first entry of $supported).
## Params:
-* ```string $header```
+* string $header
The complete string of headers.
-* Optional ```string $header_class```
+* Optional string $header_class
A class extending http\Header.
## Returns:
-* ```array``` of parsed headers, where the elements are instances of $header_class if specified.
+* array of parsed headers, where the elements are instances of $header_class if specified.
## Params:
-> None.
+None.
## Returns:
-* ```string```, serialized representation of HTTP header (i.e. "Name: value")
+* string, serialized representation of HTTP header (i.e. "Name: value")
## Params:
-> None.
+None.
## Returns:
-* ```string```, the serialized form of the HTTP header (i.e. "Name: value").
+* string, the serialized form of the HTTP header (i.e. "Name: value").
## Params:
-* ```string $serialized```
+* string $serialized
The serialized HTTP header (i.e. "Name: value")
## Constants:
-* ```DEF_PARAM_SEP```
+* DEF_PARAM_SEP
The default parameter separator (",").
-* ```DEF_ARG_SEP```
+* DEF_ARG_SEP
The default argument separator (";").
-* ```DEF_VAL_SEP```
+* DEF_VAL_SEP
The default value separator ("=").
-* ```COOKIE_PARAM_SEP```
+* COOKIE_PARAM_SEP
TBD
-* ```PARSE_RAW```
+* PARSE_RAW
Do not interpret the parsed parameters.
-* ```PARSE_DEFAULT```
+* PARSE_DEFAULT
Interpret input as default formatted parameters.
-* ```PARSE_URLENCODED```
+* PARSE_URLENCODED
Urldecode single units of parameters, arguments and values.
-* ```PARSE_DIMENSION```
+* PARSE_DIMENSION
Parse sub dimensions indicated by square brackets.
-* ```PARSE_QUERY```
+* PARSE_QUERY
Parse URL query string (same as http\Params::PARSE_URLENCODED|http\Params::PARSE_DIMENSION).
## Properties:
-* ```public $params = NULL```
+* public $params = NULL
The (parsed) parameters.
-* ```public $param_sep = http\Header::DEF_PARAM_SEP```
+* public $param_sep = http\Params::DEF_PARAM_SEP
The parameter separator(s).
-* ```public $arg_sep = http\Header::DEF_ARG_SEP```
+* public $arg_sep = http\Params::DEF_ARG_SEP
The argument separator(s).
-* ```public $val_sep = http\Header::DEF_VAL_SEP```
+* public $val_sep = http\Params::DEF_VAL_SEP
The value separator(s).
-* ```public $flags = http\Params::PARSE_DEFAULT```
+* public $flags = http\Params::PARSE_DEFAULT
The modus operandi of the parser. See http\Params::PARSE_* constants.
## Params:
-* Optional ```mixed $params```
+* Optional mixed $params
Pre-parsed parameters or a string to be parsed.
-* Optional ```mixed $ps```
+* Optional mixed $ps
The parameter separator(s).
-* Optional ```mixed $as```
+* Optional mixed $as
The argument separator(s).
-* Optional ```mixed $vs```
+* Optional mixed $vs
The value separator(s).
-* Optional ```int $flags```
+* Optional int $flags
The modus operandi. See http\Params::PARSE_* constants.
## Throws:
## Params:
-> None.
+None.
## Returns:
-* ```string``` version of the parameters.
+* string version of the parameters.
## Params:
-* ```string $name```
+* string $name
The offset to look after.
## Returns:
-* ```bool``` Existence.
+* bool Existence.
## Params:
-* ```string $name```
+* string $name
The offset to retrieve.
## Returns:
-* ```mixed```, contents at offset.
+* mixed, contents at offset.
## Params:
-* ```string $name```
+* string $name
The offset to modify.
-* ```mixed $value```
+* mixed $value
The value to set.
## Params:
-* ```string $name```
+* string $name
The offset to delete.
## Params:
-> None.
+None.
## Returns:
-* ```array``` of paramters.
+* array of paramters.
## Params:
-> None.
+None.
## Returns:
-* ```string``` version of the parameters.
+* string version of the parameters.
font-family: monospace;
font-size: 1.5em;
margin: 0;
- padding: 4em 0 0 0;
+ padding: 0;
}
body>* {
+ margin-left: 1em;
+}
+
+.sidebar {
+ float: right;
+ width: 400px;
+ background: #f0f0f0;
+ border-bottom-left-radius: 10px;
+ padding: 0;
+ margin-bottom: 1em;
margin-left: 2em;
- margin-right: 2em;
+}
+.sidebar>ul {
+ paddinng: 1em;
+ margin-left: 1em;
}
code {
}
h1 {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
margin: 0;
padding: 1em;
}
p {
color: #3f3f3f;
- margin: 1em;
+ margin: 1em 2em;
}
blockquote {
padding: 1em;
border-radius: 4px;
- max-width: 1000px;
}
blockquote, blockquote p {
color: #f0f0f0;
.var {
color: #800000;
}
+.constant {
+ color: #2e8b57;
+}
.invert, h1, blockquote, blockquote p {
- background: #030303;
- color: #f0f0f0;
+ background: #708090;
+ color: #f5f5dc;
+}
+
+.invert .constant, h1 .constant, blockquote .constant {
+ color: #98fb98;
}
.invert .var, h1 .var, blockquote .var {
.invert a, h1 a, blockquote a {
color: #b0e0e6;
}
-
+function is_constant(s) {
+ return s.length > 3 && s.toUpperCase(s) === s;
+}
+
+function is_variable(s) {
+ return s.substring(0,1) === "$";
+}
+
function type(s) {
+ var i, j, t;
// nothing
if (!s.match(/[a-zA-Z]/)) {
case "array":
case "object":
case "callable":
+ case "mixed":
return "<code>";
// keywords
return "<em>";
}
- var is_namespace, is_method;
-
- if ((is_method = (s.indexOf("::") !== -1)) || (is_namespace = (s.indexOf("\\") !== -1))) {
- return "<a href=\"/" + s.replace(/::|\\/g, "/") + (is_method ? ".md":"") + "\">";
+ // class members
+ if (-1 !== (i = s.indexOf("::"))) {
+ t = s.substring(i+2);
+ if (!is_constant(t) && !is_variable(t)) {
+ // methods
+ return "<a href=\"/" + s.replace(/::|\\/g, "/") + "\">";
+ }
+ }
+ if (-1 !== (j = s.indexOf("\\"))) {
+ return "<a href=\"/" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
}
switch (s.toLowerCase()) {
// variables
default:
- if (s.substring(0,1) !== "$") {
+ if (!is_variable(s)) {
break;
}
// special constants
}
// constants
- if (s.toUpperCase() === s) {
- return "<code>";
+ if (is_constant(s)) {
+ return "<span class=\"constant\">";
}
}
function node(s) {
}
});
}
-$(document).ready(function() {
- //console.log("ready");
+function hashchange() {
+ if (location.hash.length > 1) {
+ var hash = location.hash.substring(1);
+
+ $(is_variable(hash) ? ".var" : ".constant").each(function(i, c) {
+
+ if (c.textContent === hash) {
+ var $c = $(c);
+
+ $(window).scrollTop($c.offset().top - 100);
+ $c.fadeOut("slow").queue(function(next) {
+ this.style.color = "red";
+ next();
+ }).fadeIn("fast").fadeOut("fast").queue(function(next) {
+ this.style.color = "";
+ next();
+ }).fadeIn("slow");
+ return false;
+ }
+ });
+ }
+}
+
+$(function() {
$("h1,h2,h3,h4,h5,h6,p,li,code").each(walk);
+ $(window).on("hashchange", hashchange);
+ hashchange();
});
error_reporting(E_ALL &~ E_DEPRECATED);
-define("OUTPUT", fopen("php://memory", "w+"));
-
function cut(array $lines, array $specs) {
$delim = "[[:space:]]+";
$bytes = [];
}
function urlpath($dir, $file) {
- return (strlen($dir) ? $dir . "/" : "") . urlencode($file);
+ return (strlen($dir) ? $dir . "/" : "") . basename($file, ".md");
}
-function ls($dir, $invert = false) {
- fprintf(OUTPUT, "<ul>\n");
- foreach (scandir($dir) as $file) {
- $dir = trim($dir, "./");
- $html = "";
- if ($file === ".") {
- continue;
- } elseif ($file === "..") {
- if ($dir === "" || $invert) {
+function ls($dir) {
+ $dir = rtrim(is_dir($dir) ? $dir : dirname($dir) ."/". basename($dir, ".md"), "/");
+ printf("<ul>\n");
+ printf("<li><a href=/>Home</a></li>\n");
+ if ($dir !== "." && ($dn = dirname($dir)) !== ".") {
+ printf("<li><a href=/%s>%s</a></li>\n",
+ urlpath($dir, ".."),
+ ns($dn));
+ }
+ if (is_dir($dir)) {
+ if ($dir !== ".") {
+ printf("<li>%s</li>\n", ns($dir));
+ }
+ foreach (scandir($dir) as $file) {
+ /* ignore dot-files */
+ if ($file{0} === ".") {
continue;
}
- $name = sprintf("namespace %s", ns(dirname($dir)));
- } elseif (!$invert && is_dir("./$dir/$file")) {
- $name = sprintf("namespace %s", ns("./$dir/$file"));
- } elseif (!$invert && ctype_upper($file{0})) {
- $name = join(" ", cut(head("./$dir/$file"), ["f"=>"1-2"]));
- } elseif (!$invert || ctype_upper($file{0})) {
- continue;
- } else {
- $name = ns($dir)."::".basename($file, ".md");
- $html = "<p>".join(" ", cut(head("./$dir/$file"), ["f"=>"1-"]))."</p>";
+
+ $path = "$dir/$file";
+
+ if (is_file($path)) {
+ $pi = pathinfo($path);
+ /* ignore files not ending in .md */
+ if (!isset($pi["extension"]) || $pi["extension"] != "md") {
+ continue;
+ }
+ if (!ctype_upper($file{0}) && !is_dir("$dir/".$pi["filename"])) {
+ continue;
+ }
+ } else {
+ /* ignore directories where an companying file exists */
+ if (is_file("$path.md")) {
+ continue;
+ }
+ }
+
+ printf("<li><a href=\"/%s\">%s</a></li>\n",
+ urlpath($dir, $file),
+ ns("$dir/".basename($file, ".md")));
}
-
- fprintf(OUTPUT, "<li><a href=\"/%s\">%s</a>%s</li>\n",
- urlpath($dir, $file),
- htmlspecialchars($name),
- $html);
}
- fprintf(OUTPUT, "</ul>\n");
+
+ printf("</ul>\n");
}
function ml($file) {
$pi = pathinfo($file);
if (ctype_upper($pi["filename"][0])) {
- fprintf(OUTPUT, "<h2>Methods:</h2>\n");
- $el = $pi["dirname"] . "/" . $pi["filename"];
- ls($el, true);
+ printf("<h2>Methods:</h2>\n");
+ $dir = $pi["dirname"] . "/" . $pi["filename"];
+ if (is_dir($dir)) {
+ printf("<ul>\n");
+ foreach (scandir($dir) as $file) {
+ if (!is_file("$dir/$file") || ctype_upper($file{0})) {
+ continue;
+ }
+ printf("<li><h3>%s</h3><p>%s</p></li>\n",
+ basename($file, ".md"),
+ join(" ", cut(head("$dir/$file"), ["f"=>"1-"]))
+ );
+ }
+ printf("</ul>\n");
+ }
}
}
function md($file) {
- $r = fopen($file, "r");
- $md = MarkdownDocument::createFromStream($r);
- $md->compile();
- $md->writeHtml(OUTPUT);
- unset($md);
- fclose($r);
+ $file = rtrim($file, "/");
+ if (is_file($file) || is_file($file .= ".md")) {
+ $r = fopen($file, "r");
+ $md = MarkdownDocument::createFromStream($r);
+ $md->compile();
+ echo $md->getHtml();
+ fclose($r);
+ ml($file);
+ } else {
+ printf("<h1>Quick Markdown Doc Browser</h1>\n");
+ printf("<p>v0.1.0</p>\n");
+ printf("<p>");
+ ob_start(function($s) {
+ return nl2br(htmlspecialchars($s));
+ });
+ readfile("LICENSE");
+ ob_end_flush();
+ printf("</p>\n");
+ }
+}
- // BS Markdown seeks around...
- fseek(OUTPUT, 0, SEEK_END);
-
- ml($file);
+
+function index($pn) {
+ ?>
+ <!doctype html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title><?=ns($pn)?></title>
+ <link rel="stylesheet" href="/index.css">
+ </head>
+ <body>
+ <div class="sidebar">
+ <?php ls($pn); ?>
+ </div>
+ <?php md($pn); ?>
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+ <script src="/index.js"></script>
+ </body>
+ </html>
+ <?php
}
+chdir($_SERVER["DOCUMENT_ROOT"]);
+$t = ["css"=>"text/css", "js"=>"application/javascript"];
$r = new http\Env\Request;
$u = new http\Url($r->getRequestUrl());
-$t = ["css"=>"text/css", "js"=>"application/javascript"];
+$s = new http\Env\Response;
switch($u->path) {
case "/index.js":
case "/index.css":
- $s = new http\Env\Response;
$s->setHeader("Content-type", $t[pathinfo($u->path, PATHINFO_EXTENSION)]);
$s->setBody(new http\Message\Body(fopen(basename($u->path), "r")));
$s->send();
exit;
+default:
+ ob_start($s);
+ index(".".$u->path);
+ ob_end_flush();
+ $s->send();
+ break;
}
-if (is_dir(".".$u->path)) {
- ls(".".$u->path);
-} else {
- md(".".$u->path);
-}
-
-?>
-<!doctype html>
-<html>
-<head>
-<meta charset="utf-8">
-<title><?=$u->path?></title>
-<link rel="stylesheet" href="/index.css">
-</head>
-<body>
-<?php
-rewind(OUTPUT);
-fpassthru(OUTPUT);
-fclose(OUTPUT);
?>
-<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
-<script src="/index.js"></script>
-</body>
-</html>