/** * @param string $name * @param array $attr * @param string $content * @return string */ function html_tag($name, $attr, $content) { $attrChain = array(array_filter_key_dg(function ($val, $key) { $skip = $val === false; return !$skip; })); if (Doctype::isXhtml()) { $attrChain[] = array_map_val_dg(function ($val, $key) { if (true === $val) { $val = $key; } return $val; }); } $attrChain[] = array_map_key_dg(function ($val, $key) { return preg_replace('/([\\t\\n\\f \\/>"\'=]+)/', '', $key); }); $flags = htmlspecialchars_flags(); $attrChain[] = array_map_val_dg(function ($val, $key) use($flags) { $val = str_wrap(htmlspecialchars($val, ENT_QUOTES | $flags), '"'); return " {$key}={$val}"; }); $attrChain[] = array_implode_dg(''); $attr = call_user_func_array('array_chain', array_merge(array($attr), $attrChain)); if (empty($content)) { if (Doctype::isXhtml()) { $ret = "<{$name}{$attr}/>"; } else { $ret = "<{$name}{$attr}>"; } } else { $ret = "<{$name}{$attr}>{$content}</{$name}>"; } return $ret; }
/** * @param string $packet * @return array */ function http_response_deassemble($packet) { $pivot = strpos($packet, "\r\n\r\n"); // header $header = array_chain(str_first($packet, $pivot), str_explode_dg("\r\n")); $statusLine = array_shift($header); $versionEndPos = strpos($statusLine, " "); $version = str_first($statusLine, $versionEndPos); $statusLine = str_from($statusLine, $versionEndPos + 1); $code = str_first($statusLine, 3); $reason = str_from($statusLine, 4); debug_enforce(str_first($version, 5) === 'HTTP/' && $version[6] === '.', var_dump_human_compact($version)); $statusLine = ['Version' => ['Major' => $version[5], 'Minor' => $version[7]], 'Code' => $code, 'Reason' => $reason]; $header = array_chain($header, array_map_key_dg(str_find_before_dg(':')), array_map_val_dg(str_find_after_dg(':')), array_map_val_dg(trim_dg())); //content $content = str_from($packet, $pivot + 4); if (array_key_exists('Transfer-Encoding', $header) && $header['Transfer-Encoding'] === 'chunked') { $chunks = ''; while (!empty($content)) { $pivot = strpos($content, "\r\n"); $length = intval(str_first($content, $pivot), 16); $chunks .= str_first(str_from($content, $pivot + 2), $length); $content = str_from($content, $pivot + 2 + $length); debug_enforce(str_startswith($content, "\r\n")); $content = str_from($content, 2); } $content = $chunks; } return array_merge(['Status Line' => $statusLine, 'Content' => $content], $header); }