1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00

SSE implementation improvement

This commit is contained in:
stefanocasazza 2018-01-06 18:14:58 +01:00
parent f8242556bb
commit 78b284446e
47 changed files with 1129 additions and 5828 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,965 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://assets-cdn.github.com">
<link rel="dns-prefetch" href="https://avatars0.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars1.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars2.githubusercontent.com">
<link rel="dns-prefetch" href="https://avatars3.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-7db951ed87f8f6cbd3a9e89c294e300cf23c1a83ad7ae64c70b8f99b21031340.css" media="all" rel="stylesheet" />
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-d3ad50db48a301d9b185b1ca6f32b92c19645ba69f8f9bdb9de0fcf143cb7d64.css" media="all" rel="stylesheet" />
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/site-955690c4e09b2eeb3627ae6048471522eb98b42054150bd855ad4183db364816.css" media="all" rel="stylesheet" />
<meta name="viewport" content="width=device-width">
<title>ULib/CONTRIBUTING.md at master · stefanocasazza/ULib · GitHub</title>
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
<meta property="fb:app_id" content="1401488693436528">
<meta content="https://avatars1.githubusercontent.com/u/107614?v=4&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="stefanocasazza/ULib" property="og:title" /><meta content="https://github.com/stefanocasazza/ULib" property="og:url" /><meta content="ULib - C++ application development framework, to help developers create and deploy applications very fast and more simple" property="og:description" />
<link rel="assets" href="https://assets-cdn.github.com/">
<meta name="pjax-timeout" content="1000">
<meta name="request-id" content="810D:24AB:2C643A9:46294DD:59AD25F2" data-pjax-transient>
<meta name="selected-link" value="repo_source" data-pjax-transient>
<meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
<meta name="google-analytics" content="UA-3769691-2">
<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="https://collector.githubapp.com/github-external/browser_event" name="octolytics-event-url" /><meta content="810D:24AB:2C643A9:46294DD:59AD25F2" name="octolytics-dimension-request_id" /><meta content="iad" name="octolytics-dimension-region_edge" /><meta content="iad" name="octolytics-dimension-region_render" />
<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
<meta class="js-ga-set" name="dimension1" content="Logged Out">
<meta name="hostname" content="github.com">
<meta name="user-login" content="">
<meta name="expected-hostname" content="github.com">
<meta name="js-proxy-site-detection-payload" content="NGYzZGRmMWNhNmE3MjBkYWY4NWIzODVmYjA4ODc3N2JkNzE3ZGEzY2JmN2NkMDBjOGI0MzA2MGMzM2Q5NTkwZHx7InJlbW90ZV9hZGRyZXNzIjoiNjIuMTguMjQ3LjEwNCIsInJlcXVlc3RfaWQiOiI4MTBEOjI0QUI6MkM2NDNBOTo0NjI5NEREOjU5QUQyNUYyIiwidGltZXN0YW1wIjoxNTA0NTE5NjY3LCJob3N0IjoiZ2l0aHViLmNvbSJ9">
<meta name="html-safe-nonce" content="bc51ec7127c047af5d86986780f4c75edae1353b">
<meta http-equiv="x-pjax-version" content="184895e84e5531b2a7ddbcc46a45573a">
<link href="https://github.com/stefanocasazza/ULib/commits/master.atom" rel="alternate" title="Recent Commits to ULib:master" type="application/atom+xml">
<meta name="description" content="ULib - C++ application development framework, to help developers create and deploy applications very fast and more simple">
<meta name="go-import" content="github.com/stefanocasazza/ULib git https://github.com/stefanocasazza/ULib.git">
<meta content="107614" name="octolytics-dimension-user_id" /><meta content="stefanocasazza" name="octolytics-dimension-user_login" /><meta content="448055" name="octolytics-dimension-repository_id" /><meta content="stefanocasazza/ULib" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="448055" name="octolytics-dimension-repository_network_root_id" /><meta content="stefanocasazza/ULib" name="octolytics-dimension-repository_network_root_nwo" /><meta content="false" name="octolytics-dimension-repository_explore_github_marketplace_ci_cta_shown" />
<link rel="canonical" href="https://github.com/stefanocasazza/ULib/blob/master/CONTRIBUTING.md" data-pjax-transient>
<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
<link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
<link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
<meta name="theme-color" content="#1e2327">
</head>
<body class="logged-out env-production page-blob">
<div class="position-relative js-header-wrapper ">
<a href="#start-of-content" tabindex="1" class="px-2 py-4 show-on-focus js-skip-to-content">Skip to content</a>
<div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
<header class="Header header-logged-out position-relative f4 py-3" role="banner">
<div class="container-lg d-flex px-3">
<div class="d-flex flex-justify-between flex-items-center">
<a class="header-logo-invertocat my-0" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1" viewBox="0 0 16 16" width="32"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
</a>
</div>
<div class="HeaderMenu HeaderMenu--bright d-flex flex-justify-between flex-auto">
<nav class="mt-0">
<ul class="d-flex list-style-none">
<li class="ml-2">
<a href="/features" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:features" data-selected-links="/features /features/project-management /features/code-review /features/project-management /features/integrations /features">
Features
</a> </li>
<li class="ml-4">
<a href="/business" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:business" data-selected-links="/business /business/security /business/customers /business">
Business
</a> </li>
<li class="ml-4">
<a href="/explore" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship showcases showcases_search showcases_landing /explore">
Explore
</a> </li>
<li class="ml-4">
<a href="/marketplace" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:marketplace" data-selected-links=" /marketplace">
Marketplace
</a> </li>
<li class="ml-4">
<a href="/pricing" class="js-selected-navigation-item HeaderNavlink px-0 py-2 m-0" data-ga-click="Header, click, Nav menu - item:pricing" data-selected-links="/pricing /pricing/developer /pricing/team /pricing/business-hosted /pricing/business-enterprise /pricing">
Pricing
</a> </li>
</ul>
</nav>
<div class="d-flex">
<div class="d-lg-flex flex-items-center mr-3">
<div class="header-search scoped-search site-scoped-search js-site-search" role="search">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/stefanocasazza/ULib/search" class="js-site-search-form" data-scoped-search-url="/stefanocasazza/ULib/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
<label class="form-control header-search-wrapper js-chromeless-input-container">
<a href="/stefanocasazza/ULib/blob/master/CONTRIBUTING.md" class="header-search-scope no-underline">This repository</a>
<input type="text"
class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
data-hotkey="s"
name="q"
value=""
placeholder="Search"
aria-label="Search this repository"
data-unscoped-placeholder="Search GitHub"
data-scoped-placeholder="Search"
autocapitalize="off">
<input type="hidden" class="js-site-search-type-field" name="type" >
</label>
</form></div>
</div>
<span class="d-inline-block">
<div class="HeaderNavlink px-0 py-2 m-0">
<a class="text-bold text-white no-underline" href="/login?return_to=%2Fstefanocasazza%2FULib%2Fblob%2Fmaster%2FCONTRIBUTING.md" data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in">Sign in</a>
<span class="text-gray">or</span>
<a class="text-bold text-white no-underline" href="/join?source=header-repo" data-ga-click="(Logged out) Header, clicked Sign up, text:sign-up">Sign up</a>
</div>
</span>
</div>
</div>
</div>
</header>
</div>
<div id="start-of-content" class="show-on-focus"></div>
<div id="js-flash-container">
</div>
<div role="main">
<div itemscope itemtype="http://schema.org/SoftwareSourceCode">
<div id="js-repo-pjax-container" data-pjax-container>
<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
<div class="container repohead-details-container">
<ul class="pagehead-actions">
<li>
<a href="/login?return_to=%2Fstefanocasazza%2FULib"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to watch a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
Watch
</a>
<a class="social-count" href="/stefanocasazza/ULib/watchers"
aria-label="60 users are watching this repository">
60
</a>
</li>
<li>
<a href="/login?return_to=%2Fstefanocasazza%2FULib"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to star a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
Star
</a>
<a class="social-count js-social-count" href="/stefanocasazza/ULib/stargazers"
aria-label="516 users starred this repository">
516
</a>
</li>
<li>
<a href="/login?return_to=%2Fstefanocasazza%2FULib"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to fork a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
Fork
</a>
<a href="/stefanocasazza/ULib/network" class="social-count"
aria-label="73 users forked this repository">
73
</a>
</li>
</ul>
<h1 class="public ">
<svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
<span class="author" itemprop="author"><a href="/stefanocasazza" class="url fn" rel="author">stefanocasazza</a></span><!--
--><span class="path-divider">/</span><!--
--><strong itemprop="name"><a href="/stefanocasazza/ULib" data-pjax="#js-repo-pjax-container">ULib</a></strong>
</h1>
</div>
<div class="container">
<nav class="reponav js-repo-nav js-sidenav-container-pjax"
itemscope
itemtype="http://schema.org/BreadcrumbList"
role="navigation"
data-pjax="#js-repo-pjax-container">
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/stefanocasazza/ULib" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /stefanocasazza/ULib" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
<span itemprop="name">Code</span>
<meta itemprop="position" content="1">
</a> </span>
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/stefanocasazza/ULib/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /stefanocasazza/ULib/issues" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>
<span itemprop="name">Issues</span>
<span class="Counter">1</span>
<meta itemprop="position" content="2">
</a> </span>
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/stefanocasazza/ULib/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /stefanocasazza/ULib/pulls" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
<span itemprop="name">Pull requests</span>
<span class="Counter">0</span>
<meta itemprop="position" content="3">
</a> </span>
<a href="/stefanocasazza/ULib/projects" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /stefanocasazza/ULib/projects">
<svg aria-hidden="true" class="octicon octicon-project" height="16" version="1.1" viewBox="0 0 15 16" width="15"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
Projects
<span class="Counter" >0</span>
</a>
<a href="/stefanocasazza/ULib/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /stefanocasazza/ULib/wiki">
<svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"/></svg>
Wiki
</a>
<div class="reponav-dropdown js-menu-container">
<button type="button" class="btn-link reponav-item reponav-dropdown js-menu-target " data-no-toggle aria-expanded="false" aria-haspopup="true">
Insights
<svg aria-hidden="true" class="octicon octicon-triangle-down v-align-middle text-gray" height="11" version="1.1" viewBox="0 0 12 16" width="8"><path fill-rule="evenodd" d="M0 5l6 6 6-6z"/></svg>
</button>
<div class="dropdown-menu-content js-menu-content">
<div class="dropdown-menu dropdown-menu-sw">
<a class="dropdown-item" href="/stefanocasazza/ULib/pulse" data-skip-pjax>
<svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"/></svg>
Pulse
</a>
<a class="dropdown-item" href="/stefanocasazza/ULib/graphs" data-skip-pjax>
<svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
Graphs
</a>
</div>
</div>
</div>
</nav>
</div>
</div>
<div class="container new-discussion-timeline experiment-repo-nav">
<div class="repository-content">
<a href="/stefanocasazza/ULib/blob/f0d89a1cb1878a17c0b9ba53a6ac7f2f2a99b46e/CONTRIBUTING.md" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
<!-- blob contrib key: blob_contributors:v21:2cbb5e13d8d96591bec601e38630572e -->
<div class="file-navigation js-zeroclipboard-container">
<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
<button class=" btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
type="button" aria-label="Switch branches or tags" aria-expanded="false" aria-haspopup="true">
<i>Branch:</i>
<span class="js-select-button css-truncate-target">master</span>
</button>
<div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax>
<div class="select-menu-modal">
<div class="select-menu-header">
<svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
<span class="select-menu-title">Switch branches/tags</span>
</div>
<div class="select-menu-filters">
<div class="select-menu-text-filter">
<input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
</div>
<div class="select-menu-tabs">
<ul>
<li class="select-menu-tab">
<a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
</li>
<li class="select-menu-tab">
<a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
</li>
</ul>
</div>
</div>
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/blob/add-code-of-conduct-1/CONTRIBUTING.md"
data-name="add-code-of-conduct-1"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
add-code-of-conduct-1
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/blob/gh-pages/CONTRIBUTING.md"
data-name="gh-pages"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
gh-pages
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open selected"
href="/stefanocasazza/ULib/blob/master/CONTRIBUTING.md"
data-name="master"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
master
</span>
</a>
</div>
<div class="select-menu-no-results">Nothing to show</div>
</div>
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.3.4/CONTRIBUTING.md"
data-name="v2.3.4"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.3.4">
v2.3.4
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.3.3/CONTRIBUTING.md"
data-name="v2.3.3"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.3.3">
v2.3.3
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.3.2/CONTRIBUTING.md"
data-name="v2.3.2"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.3.2">
v2.3.2
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.3.1/CONTRIBUTING.md"
data-name="v2.3.1"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.3.1">
v2.3.1
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.3.0/CONTRIBUTING.md"
data-name="v2.3.0"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.3.0">
v2.3.0
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.2.4/CONTRIBUTING.md"
data-name="v2.2.4"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.2.4">
v2.2.4
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.2.3/CONTRIBUTING.md"
data-name="v2.2.3"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.2.3">
v2.2.3
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.2.2/CONTRIBUTING.md"
data-name="v2.2.2"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.2.2">
v2.2.2
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.2.1/CONTRIBUTING.md"
data-name="v2.2.1"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.2.1">
v2.2.1
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.2.0/CONTRIBUTING.md"
data-name="v2.2.0"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.2.0">
v2.2.0
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.18/CONTRIBUTING.md"
data-name="v2.1.18"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.18">
v2.1.18
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.17/CONTRIBUTING.md"
data-name="v2.1.17"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.17">
v2.1.17
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.16/CONTRIBUTING.md"
data-name="v2.1.16"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.16">
v2.1.16
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.15/CONTRIBUTING.md"
data-name="v2.1.15"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.15">
v2.1.15
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.14/CONTRIBUTING.md"
data-name="v2.1.14"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.14">
v2.1.14
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.13/CONTRIBUTING.md"
data-name="v2.1.13"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.13">
v2.1.13
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.12/CONTRIBUTING.md"
data-name="v2.1.12"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.12">
v2.1.12
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.11/CONTRIBUTING.md"
data-name="v2.1.11"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.11">
v2.1.11
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.10/CONTRIBUTING.md"
data-name="v2.1.10"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.10">
v2.1.10
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.9/CONTRIBUTING.md"
data-name="v2.1.9"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.9">
v2.1.9
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.8/CONTRIBUTING.md"
data-name="v2.1.8"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.8">
v2.1.8
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.7/CONTRIBUTING.md"
data-name="v2.1.7"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.7">
v2.1.7
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.6/CONTRIBUTING.md"
data-name="v2.1.6"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.6">
v2.1.6
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.5/CONTRIBUTING.md"
data-name="v2.1.5"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.5">
v2.1.5
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.4/CONTRIBUTING.md"
data-name="v2.1.4"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.4">
v2.1.4
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.3/CONTRIBUTING.md"
data-name="v2.1.3"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.3">
v2.1.3
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.2/CONTRIBUTING.md"
data-name="v2.1.2"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.2">
v2.1.2
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.1/CONTRIBUTING.md"
data-name="v2.1.1"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.1">
v2.1.1
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.1.0/CONTRIBUTING.md"
data-name="v2.1.0"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.1.0">
v2.1.0
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.9/CONTRIBUTING.md"
data-name="v2.0.9"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.9">
v2.0.9
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.8/CONTRIBUTING.md"
data-name="v2.0.8"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.8">
v2.0.8
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.7/CONTRIBUTING.md"
data-name="v2.0.7"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.7">
v2.0.7
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.6/CONTRIBUTING.md"
data-name="v2.0.6"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.6">
v2.0.6
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.5/CONTRIBUTING.md"
data-name="v2.0.5"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.5">
v2.0.5
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.4/CONTRIBUTING.md"
data-name="v2.0.4"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.4">
v2.0.4
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.3/CONTRIBUTING.md"
data-name="v2.0.3"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.3">
v2.0.3
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.2/CONTRIBUTING.md"
data-name="v2.0.2"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.2">
v2.0.2
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.1/CONTRIBUTING.md"
data-name="v2.0.1"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.1">
v2.0.1
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v2.0.0/CONTRIBUTING.md"
data-name="v2.0.0"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v2.0.0">
v2.0.0
</span>
</a>
<a class="select-menu-item js-navigation-item js-navigation-open "
href="/stefanocasazza/ULib/tree/v1.4.2/CONTRIBUTING.md"
data-name="v1.4.2"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target" title="v1.4.2">
v1.4.2
</span>
</a>
</div>
<div class="select-menu-no-results">Nothing to show</div>
</div>
</div>
</div>
</div>
<div class="BtnGroup float-right">
<a href="/stefanocasazza/ULib/find/master"
class="js-pjax-capture-input btn btn-sm BtnGroup-item"
data-pjax
data-hotkey="t">
Find file
</a>
<button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm BtnGroup-item tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
</div>
<div class="breadcrumb js-zeroclipboard-target">
<span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/stefanocasazza/ULib"><span>ULib</span></a></span></span><span class="separator">/</span><strong class="final-path">CONTRIBUTING.md</strong>
</div>
</div>
<include-fragment class="commit-tease" src="/stefanocasazza/ULib/contributors/master/CONTRIBUTING.md">
<div>
Fetching contributors&hellip;
</div>
<div class="commit-tease-contributors">
<img alt="" class="loader-loading float-left" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32-EAF2F5.gif" width="16" />
<span class="loader-error">Cannot retrieve contributors at this time</span>
</div>
</include-fragment>
<div class="file">
<div class="file-header">
<div class="file-actions">
<div class="BtnGroup">
<a href="/stefanocasazza/ULib/raw/master/CONTRIBUTING.md" class="btn btn-sm BtnGroup-item" id="raw-url">Raw</a>
<a href="/stefanocasazza/ULib/blame/master/CONTRIBUTING.md" class="btn btn-sm js-update-url-with-hash BtnGroup-item" data-hotkey="b">Blame</a>
<a href="/stefanocasazza/ULib/commits/master/CONTRIBUTING.md" class="btn btn-sm BtnGroup-item" rel="nofollow">History</a>
</div>
<button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg aria-hidden="true" class="octicon octicon-pencil" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
</button>
<button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
</button>
</div>
<div class="file-info">
6 lines (5 sloc)
<span class="file-info-divider"></span>
274 Bytes
</div>
</div>
<div id="readme" class="readme blob instapaper_body">
<article class="markdown-body entry-content" itemprop="text"><ol>
<li>Fork it ( <a href="http://github.com/">http://github.com/</a>/ULib/fork )</li>
<li>Create your feature branch (<code>git checkout -b my-new-feature</code>)</li>
<li>Commit your changes (<code>git commit -am 'Add some feature'</code>)</li>
<li>Push to the branch (<code>git push origin my-new-feature</code>)</li>
<li>Create new Pull Request</li>
</ol>
</article>
</div>
</div>
<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
<div id="jump-to-line" style="display:none">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
<button type="submit" class="btn">Go</button>
</form> </div>
</div>
<div class="modal-backdrop js-touch-events"></div>
</div>
</div>
</div>
</div>
<div class="footer container-lg px-3" role="contentinfo">
<div class="position-relative d-flex flex-justify-between py-6 mt-6 f6 text-gray border-top border-gray-light ">
<ul class="list-style-none d-flex flex-wrap ">
<li class="mr-3">&copy; 2017 <span title="0.11121s from unicorn-561453760-0cz26">GitHub</span>, Inc.</li>
<li class="mr-3"><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
<li class="mr-3"><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
<li class="mr-3"><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
<li class="mr-3"><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
<li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
</ul>
<a href="https://github.com" aria-label="Homepage" class="footer-octicon" title="GitHub">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
</a>
<ul class="list-style-none d-flex flex-wrap ">
<li class="mr-3"><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
<li class="mr-3"><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
<li class="mr-3"><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
<li class="mr-3"><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
<li class="mr-3"><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
<li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
</ul>
</div>
</div>
<div id="ajax-error-message" class="ajax-error-message flash flash-error">
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
<button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
</button>
You can't perform that action at this time.
</div>
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/compat-91f98c37fc84eac24836eec2567e9912742094369a04c4eba6e3cd1fa18902d9.js"></script>
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-71424a6727cc4994da57b8806631af0bf8cf7f77e82cf971412d12823d70debb.js"></script>
<script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-77c762635d5878f399b1271738299f8db3dd9315566fd4fff97056e25f1fdb57.js"></script>
<div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
<span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
<span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
</div>
<div class="facebox" id="facebox" style="display:none;">
<div class="facebox-popup">
<div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
</div>
<button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
</button>
</div>
</div>
</body>
</html>
1. Fork it ( [http://github.com](http://github.com)/ULib/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create new Pull Request

6
configure vendored
View File

@ -1805,7 +1805,7 @@ Optional Features:
--enable-GSDS enable GDB Stack Dump Support [default=no]
--enable-HCRS enable Cache Request Support [default=no]
--enable-HPRS enable Homogeneous Pipeline Request Support [default=no]
--enable-SSE enable Server-Sent Events Support [default=yes]
--enable-SSE enable Server-Sent Events Support [default=no]
--enable-http2 enable HTTP/2 support [default=no]
--enable-check-time enable server check time between request for parallelization [default=no]
--enable-classic enable server classic model support [default=no]
@ -28336,11 +28336,7 @@ if test "${enable_SSE+set}" = set; then :
fi
if test -z "$enable_SSE"; then
if test "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO"; then
enable_SSE="no"
else
enable_SSE="yes"
fi
fi
if test "$enable_SSE" = "yes"; then

View File

@ -4,51 +4,38 @@
#include "ir_session.h"
#include <ulib/debug/crono.h>
#define IR_SESSION (*(IRDataSession*)UHTTP::data_session)
static IR* ir;
static Query* query;
static UCrono* crono;
static UString* footer;
static void usp_init_ir_web()
{
U_TRACE(5, "::usp_init_ir_web()")
U_INTERNAL_ASSERT_EQUALS(ir, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(query, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(crono, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(footer, U_NULLPTR)
U_NEW(IR, ir, IR);
U_NEW(Query, query, Query);
U_NEW(UCrono, crono, UCrono);
U_NEW(UString, footer, UString(200U));
ir->loadFileConfig();
if (ir->openCDB(false) == false)
{
U_ERROR("usp_init() of servlet ir_web failed");
}
footer->snprintf(U_CONSTANT_TO_PARAM("ver. %.*s, with %u documents and %u words."), U_CONSTANT_TO_TRACE(ULIB_VERSION), cdb_names->size(), cdb_words->size());
U_NEW(IRDataSession, UHTTP::data_session, IRDataSession);
UHTTP::initSession();
}
static void usp_end_ir_web()
{
U_TRACE(5, "::usp_end_ir_web()")
U_INTERNAL_ASSERT_POINTER(ir)
U_INTERNAL_ASSERT_POINTER(query)
U_INTERNAL_ASSERT_POINTER(crono)
U_INTERNAL_ASSERT_POINTER(footer)
delete ir;
delete query;
delete crono;

View File

@ -5,7 +5,6 @@
static void usp_end_wi_auth();
static void usp_init_wi_auth();
static void usp_sighup_wi_auth();
#include <ulib/examples/wi_auth_declaration.h>
extern "C" {

View File

@ -114,6 +114,15 @@ U_DO_PRAGMA(message ("ULib is configured with C++17 support, so you must use the
#if defined(USE_HARDWARE_CRC32) && defined(__GNUC__) && !defined(HAVE_CONFIG_H) /* The built-in functions __builtin_ia32_crc32 are available when -mcrc32 is used */
U_DO_PRAGMA(message ("ULib is configured with crc32 intrinsics support, so you must use the -mcrc32 g++ option for compilation"))
#endif
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
# ifndef U_LINUX
# undef U_SSE_ENABLE
U_DO_PRAGMA(message ("Sorry I was not compiled on Linux so I cannot use SSE"))
# elif !defined(ENABLE_THREAD)
# undef U_SSE_ENABLE
U_DO_PRAGMA(message ("Sorry I was compiled without thread enabled so I cannot use SSE"))
# endif
#endif
#include <stddef.h>
#include <stdarg.h>

View File

@ -5711,7 +5711,7 @@ loop: (void) nodog_rec->sendRequestToNodog(U_CONSTANT_TO_PARAM("check"), 0);
{
db_nodog->callForAllEntryWithVector(WiAuthNodog::checkAccessPoint);
if ((U_SRV_CNT_USR4++ % 10) == 0) resync();
if ((U_SRV_CNT_WIAUTH++ % 10) == 0) resync();
}
USSIPlugIn::setAlternativeResponse();

View File

@ -40,12 +40,8 @@
// File-permission-bit symbols
#define U_PERM__rw_r__r__ 0644
#define U_PERM__r________ 0400
#define U_PERM__r__r__r__ 0444
#define U_PERM__r_xr_xr_x 0555
#define PERM_FILE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) // rw_rw_r__
#define PERM_FIFO (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) // rw_rw_rw_
#define PERM_DIRECTORY S_IRWXU // rwx
// NB: the UString pathname maybe not writeable so path_relativ[path_relativ_len] maybe != '\0' (not null-terminate)...
@ -980,7 +976,7 @@ public:
// make a FIFO special file (a named pipe)
static bool mkfifo(const char* _pathname, mode_t mode = S_IRUSR | S_IWUSR)
static bool mkfifo(const char* _pathname, mode_t mode = PERM_FIFO)
{
U_TRACE(1, "UFile::mkfifo(%S,%d)", _pathname, mode)

View File

@ -105,6 +105,8 @@ class USSLSocket;
class USSIPlugIn;
class UWebSocket;
class USocketExt;
class USSEClient;
class USSEThread;
class Application;
class UTimeThread;
class UFileConfig;
@ -321,6 +323,13 @@ public:
sem_t lock_ocsp_staple;
# endif
// ------------------------------------------------------------------------------
# endif
// ------------------------------------------------------------------------------
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
sem_t lock_sse;
# ifdef USE_LIBSSL
sem_t lock_sse_ssl;
# endif
# endif
// ------------------------------------------------------------------------------
# if defined(U_LINUX) && defined(ENABLE_THREAD)
@ -352,6 +361,10 @@ public:
#define U_SRV_CNT_USR7 UServer_Base::ptr_shared_data->cnt_usr7
#define U_SRV_CNT_USR8 UServer_Base::ptr_shared_data->cnt_usr8
#define U_SRV_CNT_USR9 UServer_Base::ptr_shared_data->cnt_usr9
#define U_SRV_CNT_NOCAT UServer_Base::ptr_shared_data->cnt_usr7
#define U_SRV_CNT_WIAUTH UServer_Base::ptr_shared_data->cnt_usr7
#define U_SRV_SSE_CNT1 UServer_Base::ptr_shared_data->cnt_usr8
#define U_SRV_SSE_CNT2 UServer_Base::ptr_shared_data->cnt_usr9
#define U_SRV_MY_LOAD UServer_Base::ptr_shared_data->my_load
#define U_SRV_FLAG_SIGTERM UServer_Base::ptr_shared_data->flag_sigterm
#define U_SRV_LEN_OCSP_STAPLE UServer_Base::ptr_shared_data->len_ocsp_staple
@ -362,6 +375,8 @@ public:
#define U_SRV_CNT_PARALLELIZATION UServer_Base::ptr_shared_data->cnt_parallelization
#define U_SRV_LOCK_USER1 &(UServer_Base::ptr_shared_data->lock_user1)
#define U_SRV_LOCK_USER2 &(UServer_Base::ptr_shared_data->lock_user2)
#define U_SRV_LOCK_SSE &(UServer_Base::ptr_shared_data->lock_sse)
#define U_SRV_LOCK_SSE_SSL &(UServer_Base::ptr_shared_data->lock_sse_ssl)
#define U_SRV_LOCK_THROTTLING &(UServer_Base::ptr_shared_data->lock_throttling)
#define U_SRV_LOCK_RDB_SERVER &(UServer_Base::ptr_shared_data->lock_rdb_server)
#define U_SRV_LOCK_SSL_SESSION &(UServer_Base::ptr_shared_data->lock_ssl_session)
@ -637,6 +652,109 @@ public:
}
#endif
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
static ULock* lock_sse;
# ifdef USE_LIBSSL
static ULock* lock_sse_ssl;
# endif
static void setLockSSE()
{
U_TRACE_NO_PARAM(0, "UServer_Base::setLockSSE()")
# ifdef USE_LIBSSL
if (bssl)
{
U_INTERNAL_ASSERT_EQUALS(lock_sse_ssl, U_NULLPTR)
U_NEW(ULock, lock_sse_ssl, ULock);
lock_sse_ssl->init(&(ptr_shared_data->lock_sse_ssl));
}
else
# endif
{
U_INTERNAL_ASSERT_EQUALS(lock_sse, U_NULLPTR)
U_NEW(ULock, lock_sse, ULock);
lock_sse->init(&(ptr_shared_data->lock_sse));
}
}
static void lockSSE()
{
U_TRACE_NO_PARAM(0, "UServer_Base::lockSSE()")
# ifdef USE_LIBSSL
if (bssl) lock_sse_ssl->lock();
else
# endif
lock_sse->lock();
}
static void unlockSSE()
{
U_TRACE_NO_PARAM(0, "UServer_Base::unlockSSE()")
# ifdef USE_LIBSSL
if (bssl) lock_sse_ssl->unlock();
else
# endif
lock_sse->unlock();
}
static UString printSSE(uint32_t id, const UString& data, UString* pevent = U_NULLPTR)
{
U_TRACE(0, "UServer_Base::printSSE(%u,%V,%p)", id, data.rep, pevent)
U_ASSERT_EQUALS(u_find(U_STRING_TO_PARAM(data),"\n",1), U_NULLPTR)
UString buffer(U_CAPACITY);
if (pevent == U_NULLPTR) buffer.snprintf(U_CONSTANT_TO_PARAM("id:%u\ndata:%v\n\n"), id, data.rep);
else buffer.snprintf(U_CONSTANT_TO_PARAM("id:%u\nevent:%v\ndata:%v\n\n"), id, pevent->rep, data.rep);
U_RETURN_STRING(buffer);
}
static void eventSSE(const char* format, uint32_t fmt_size, ...)
{
U_TRACE(0, "UServer_Base::eventSSE(%.*S,%u)", fmt_size, format, fmt_size)
U_INTERNAL_ASSERT_POINTER(format)
U_INTERNAL_ASSERT_DIFFERS(sse_event_fd, -1)
uint32_t len;
char buffer[4096];
va_list argp;
va_start(argp, fmt_size);
len = u__vsnprintf(buffer, sizeof(buffer), format, fmt_size, argp);
va_end(argp);
lockSSE();
(void) U_SYSCALL(write, "%u,%S,%u", sse_event_fd, buffer, len);
}
static void sendToAllSSE(const UString& data)
{
U_TRACE(0, "UServer_Base::sendToAllSSE(%V)", data.rep)
eventSSE(U_CONSTANT_TO_PARAM("*=%v\n"), data.rep);
}
static void sendToAllExceptSSE(const UString& data)
{
U_TRACE(0, "UServer_Base::sendToAllExceptSSE(%V)", data.rep)
eventSSE(U_CONSTANT_TO_PARAM("%v-%v=%v\n"), (sse_event ? sse_event : str_asterisk)->rep, sse_id->rep, data.rep);
}
#endif
// DEBUG
#if defined(DEBUG) && defined(U_STDCPP_ENABLE)
@ -837,6 +955,34 @@ protected:
static bool checkHitStats(const char* key, uint32_t key_len, uint32_t interval, uint32_t count);
#endif
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
struct ucmsghdr {
size_t cmsg_len; /* Length data in cmsg_data + length of cmsghdr struct */
int cmsg_level; /* Originating protocol. */
int cmsg_type; /* Protocol specific type. */
int cmsg_data; /* Ancillary data. */
};
static UThread* pthread_sse;
static UString* sse_id;
static UString* sse_event;
static struct msghdr msg;
static struct iovec iov[1];
static struct ucmsghdr cmsg;
static UString* str_asterisk;
static uint32_t sse_fifo_pos;
static UVector<USSEClient*>* sse_vclient;
static char sse_fifo_name[256], iovbuf[1];
static int sse_event_fd, sse_socketpair[2];
static void setFIFOForSSE(const UString& id)
{
U_TRACE(0, "UServer_Base::setFIFOForSSE(%V)", id.rep)
(void) u__snprintf(sse_fifo_name+sse_fifo_pos, 256-sse_fifo_pos, U_CONSTANT_TO_PARAM("%v"), id.rep);
}
#endif
UServer_Base(UFileConfig* pcfg = U_NULLPTR);
virtual ~UServer_Base();
@ -976,6 +1122,8 @@ private:
friend class USSIPlugIn;
friend class UWebSocket;
friend class USocketExt;
friend class USSEClient;
friend class USSEThread;
friend class Application;
friend class UTimeThread;
friend class UHttpPlugIn;

View File

@ -1840,28 +1840,10 @@ public:
// The `find' function searches string for a specified string (possibly a single character) and returns
// its starting position. You can supply the parameter pos to specify the position where search must begin
uint32_t find(unsigned char c, uint32_t pos = 0, uint32_t how_much = U_NOT_FOUND) const __pure;
uint32_t find(const char* s, uint32_t pos, uint32_t s_len, uint32_t how_much = U_NOT_FOUND) const __pure;
uint32_t find(const UString& str, uint32_t pos = 0, uint32_t how_much = U_NOT_FOUND) const { return find(str.data(), pos, str.size(), how_much); }
uint32_t find(unsigned char c, uint32_t pos = 0) const
{
U_TRACE(0, "UString::find(%C,%u)", c, pos)
uint32_t sz = size(),
ret = U_NOT_FOUND;
if (pos < sz)
{
const char* str = rep->str;
void* p = (void*) memchr(str + pos, c, sz - pos);
if (p) ret = (const char*)p - str;
}
U_RETURN(ret);
}
// The `rfind' function searches from end to beginning string for a specified string (possibly a single character)
// and returns its starting position. You can supply the parameter pos to specify the position where search must begin

View File

@ -679,55 +679,27 @@ public:
}
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
static bool bsse;
typedef UString (*strPF)();
static uint32_t getSSELastEventID()
static strPF sse_func;
static int sse_pipe_fd;
static const char* sse_corsbase;
static void readSSE(int timeoutMS) __noreturn;
static void sendSSE(const UString& data)
{
U_TRACE_NO_PARAM(0, "UHTTP::getSSELastEventID()")
U_TRACE(0, "UHTTP::sendSSE(%V)", data.rep)
U_INTERNAL_ASSERT(bsse)
UString buffer = UServer_Base::printSSE(U_SRV_SSE_CNT1, data, UServer_Base::sse_event);
const char* ptr = UHTTP::getHeaderValuePtr(U_CONSTANT_TO_PARAM("last-event-id"), true);
uint32_t sz = buffer.size();
uint32_t last_event_id = (ptr ? u_atoi(ptr) : 0);
if (USocketExt::write(UServer_Base::csocket, buffer.data(), sz, UServer_Base::timeoutMS) != (int32_t)sz)
{
UServer_Base::eventSSE(U_CONSTANT_TO_PARAM("DEL %v\n"), UServer_Base::sse_id->rep);
U_RETURN(last_event_id);
UServer_Base::endNewChild(); // no return
}
static void writeSSE(uint32_t id, const UString& data, const UString* pevent = U_NULLPTR)
{
U_TRACE(0, "UHTTP::writeSSE(%u,%V,%p)", id, data.rep, pevent)
if (pevent) UClientImage_Base::wbuffer->snprintf_add(U_CONSTANT_TO_PARAM("id:%u\nevent:%v\ndata:"), id, pevent->rep);
else UClientImage_Base::wbuffer->snprintf_add(U_CONSTANT_TO_PARAM("id:%u\ndata:"), id);
UVector<UString> vec(data, '\n');
UClientImage_Base::wbuffer->append(vec[0]);
for (uint32_t i = 1, n = vec.size(); i < n; ++i)
{
UClientImage_Base::wbuffer->snprintf_add(U_CONSTANT_TO_PARAM("\ndata:%v"), vec[i].rep);
}
UClientImage_Base::wbuffer->append(U_CONSTANT_TO_PARAM("\n\n"));
}
static void sendSSE(uint32_t id, const UString& data, const UString* pevent = U_NULLPTR)
{
U_TRACE(0, "UHTTP::sendSSE(%u,%V,%p)", id, data.rep, pevent)
U_INTERNAL_ASSERT(bsse)
UClientImage_Base::wbuffer->setBuffer(U_CAPACITY);
writeSSE(id, data, pevent);
uint32_t sz = UClientImage_Base::wbuffer->size();
U_SRV_LOG_WITH_ADDR("send message (%u bytes) %#.*S to", sz, sz, UClientImage_Base::wbuffer->data());
if (USocketExt::write(UServer_Base::csocket, UClientImage_Base::wbuffer->data(), sz, UServer_Base::timeoutMS) != (int32_t)sz) UServer_Base::endNewChild(); // no return
}
#endif
@ -1399,8 +1371,6 @@ private:
{
U_TRACE(0, "UHTTP::checkForCompression(%u)", size)
U_INTERNAL_ASSERT_MAJOR(size, 0)
U_INTERNAL_DUMP("U_http_is_accept_gzip = %b U_http_is_accept_brotli = %b", U_http_is_accept_gzip, U_http_is_accept_brotli)
if (size > U_MIN_SIZE_FOR_DEFLATE)

View File

@ -211,13 +211,9 @@ AC_DEFUN([AC_COMPILATION_OPTIONS],[
AC_MSG_CHECKING(if you want to enable Server-Sent Events support)
AC_ARG_ENABLE(SSE,
[ --enable-SSE enable Server-Sent Events Support [[default=yes]]])
[ --enable-SSE enable Server-Sent Events Support [[default=no]]])
if test -z "$enable_SSE"; then
if test "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO"; then
enable_SSE="no"
else
enable_SSE="yes"
fi
fi
if test "$enable_SSE" = "yes"; then
AC_DEFINE(U_SSE_ENABLE, 1, [enable Server-Sent Events support])

View File

@ -2309,8 +2309,8 @@ int UNoCatPlugIn::handlerFork()
UString msg(300U), output(U_CAPACITY), allowed_web_hosts(U_CAPACITY);
msg.snprintf(U_CONSTANT_TO_PARAM("/start_ap?ap=%v@%v&public=%v%%3A%u&pid=%u"), label->rep, hostname->rep, IP_address_trust->rep, UServer_Base::port, U_SRV_CNT_USR9);
U_SRV_CNT_USR9 = u_pid;
msg.snprintf(U_CONSTANT_TO_PARAM("/start_ap?ap=%v@%v&public=%v%%3A%u&pid=%u"), label->rep, hostname->rep, IP_address_trust->rep, UServer_Base::port, U_SRV_CNT_NOCAT);
U_SRV_CNT_NOCAT = u_pid;
for (i = 0, n = vauth_url->size(); i < n; ++i)
{

View File

@ -123,7 +123,13 @@ public:
if (pos != U_NOT_FOUND)
{
output0.snprintf_add(U_CONSTANT_TO_PARAM("\n\tif (%v.empty()) %v = U_STRING_FROM_CONSTANT(%.*s);\n"), id.rep, id.rep, tmp.size()-pos-2, tmp.c_pointer(pos+1));
uint32_t sz = tmp.size()-pos-2;
const char* ptr = tmp.c_pointer(pos+1);
const char* quote = (*ptr == '"' ? "" : "\"");
U_INTERNAL_ASSERT_MAJOR(sz, 0)
output0.snprintf_add(U_CONSTANT_TO_PARAM("\n\tif (%v.empty()) %v = U_STRING_FROM_CONSTANT(%s%.*s%s);\n"), id.rep, id.rep, quote, sz, ptr, quote);
}
# ifdef DEBUG
@ -152,8 +158,7 @@ public:
* <!--#vcode ... -->
* <!--#pcode ... -->
* <!--#lcode ... -->
* <!--#ssecode ... -->
* <!--#sseloop ... -->
* <!--#sse ... -->
* <!--#number ... -->
* <!--#puts ... -->
* <!--#xmlputs ... -->
@ -249,7 +254,7 @@ public:
U_INTERNAL_ASSERT(token)
declaration = UStringExt::substitute(token, '\n', U_CONSTANT_TO_PARAM("\n\t"));
declaration = token;
}
else if (strncmp(directive, U_CONSTANT_TO_PARAM("session")) == 0)
{
@ -368,80 +373,73 @@ public:
output0.snprintf_add(U_CONSTANT_TO_PARAM("\n\t%v\n\t\n"), token.rep);
}
else if (strncmp(directive, U_CONSTANT_TO_PARAM("ssecode")) == 0) // SSE code
else if (strncmp(directive, U_CONSTANT_TO_PARAM("sse")) == 0) // SSE code
{
U_ASSERT(output2.empty())
U_ASSERT(sseloop.empty())
U_ASSERT(http_header.empty())
U_INTERNAL_ASSERT_EQUALS(bfirst_pass, false)
setDirectiveItem(directive, U_CONSTANT_SIZE("ssecode"));
(void) sseloop.reserve(100U);
(void) http_header.reserve(300U + basename_sz + basename_sz);
U_INTERNAL_ASSERT(token)
token = UStringExt::substitute(token, '\n', U_CONSTANT_TO_PARAM("\n\t\t"));
/**
* we must insert:
*
* <!--#header
* Content-Type: text/event-stream
* Cache-Control: no-cache
* -->
*/
(void) http_header.reserve(1000U + token.size());
(void) http_header.snprintf(U_CONSTANT_TO_PARAM(
(void) http_header.append(U_CONSTANT_TO_PARAM(
"\n\tif (U_http_accept_len != U_CONSTANT_SIZE(\"text/event-stream\") ||"
" u_get_unalignedp64(U_http_info.accept) != U_MULTICHAR_CONSTANT64('t','e','x','t','/','e','v','e')) UHTTP::setBadRequest();"
"\n\telse"
"\n\t u_get_unalignedp64(U_http_info.accept) != U_MULTICHAR_CONSTANT64('t','e','x','t','/','e','v','e'))"
"\n\t\t{"
"\n\t\tUHTTP::bsse = true;"
"\n\t\t(void) UServer_Base::csocket->shutdown(SHUT_RD);"
"\n\t\tU_INTERNAL_ASSERT_EQUALS(UClientImage_Base::wbuffer->findEndHeader(),false)"
"\n\t\tU_http_info.endHeader = 61;"
"\n\t\t(void) UClientImage_Base::wbuffer->insert(0, U_CONSTANT_TO_PARAM(\"Content-Type: text/event-stream\\r\\nCache-Control: no-cache\\r\\n\\r\\n\"));"
"\n\t\tU_http_content_type_len = 1;"
"\n\t\t%v"
"\n\t\t}"), token.rep);
}
else if (strncmp(directive, U_CONSTANT_TO_PARAM("sseloop")) == 0) // SSE loop
"\n\t\tUHTTP::setBadRequest();"
"\n\t\treturn;"
"\n\t\t}"));
setDirectiveItem(directive, U_CONSTANT_SIZE("sse"));
if (token.empty())
{
U_ASSERT(sseloop.empty())
U_INTERNAL_ASSERT_EQUALS(bfirst_pass, false)
(void) declaration.reserve(100U + basename_sz);
setDirectiveItem(directive, U_CONSTANT_SIZE("sseloop"));
declaration.snprintf(U_CONSTANT_TO_PARAM("\n#ifdef USE_LIBSSL\nstatic UString sse_%.*s() { return UString::getStringNull(); }\n#endif"), basename_sz, basename_ptr);
U_INTERNAL_ASSERT(token)
(void) sseloop.append(U_CONSTANT_TO_PARAM("\n\t\tif (UHTTP::sse_func) UHTTP::readSSE(-1);"));
uint32_t sz = token.size();
http_header.snprintf(U_CONSTANT_TO_PARAM(
"\n#ifdef USE_LIBSSL"
"\n\tif (UServer_Base::bssl) UHTTP::sse_func = sse_%.*s;"
"\n\telse"
"\n#endif"
"\n\tUHTTP::sse_func = (UHTTP::strPF)(void*)1L;"), basename_sz, basename_ptr);
}
else
{
const char* data = token.data();
uint32_t sse_time_to_sleep = 1;
uint32_t sz = token.size(), sse_timeout = 1000;
if (*data == ':')
{
++data;
sse_time_to_sleep = u_strtoulp(&data);
sse_timeout *= u_strtoulp(&data);
sz = token.remain(data);
}
char buffer[200];
UString sse_code = UStringExt::substitute(data, sz, '\n', U_CONSTANT_TO_PARAM("\n\t"));
(void) vars.append(buffer, u__snprintf(buffer, sizeof(buffer), U_CONSTANT_TO_PARAM("\n\tUTimeVal sse_time_to_sleep(%u, 0L);\n"), sse_time_to_sleep));
(void) declaration.reserve(100U + basename_sz + basename_sz + sse_code.size());
sseloop = UStringExt::substitute(data, sz, '\n', U_CONSTANT_TO_PARAM("\n\t"));
(void) output2.reserve(200U + sseloop.size());
output2.snprintf(U_CONSTANT_TO_PARAM(
"\n\treturn;\n\t\n"
"sseloop:"
"\n\tsse_time_to_sleep.nanosleep();"
declaration.snprintf_add(U_CONSTANT_TO_PARAM(
"\nstatic UString sse_%.*s()"
"\n{"
"\n\tU_TRACE(5, \"::sse_%.*s()\")"
"\n\tUString sse_data;"
"\n\t%v"
"\n\tgoto sseloop;"), sseloop.rep);
"\n\tU_RETURN_STRING(sse_data);"
"\n}"),
basename_sz, basename_ptr,
basename_sz, basename_ptr, sse_code.rep);
sseloop.snprintf(U_CONSTANT_TO_PARAM("\n\t\tif (UHTTP::sse_func) UHTTP::readSSE(%u);"), sse_timeout);
http_header.snprintf_add(U_CONSTANT_TO_PARAM("\n\tUHTTP::sse_func = sse_%.*s;"), basename_sz, basename_ptr);
}
}
else if (strncmp(directive, U_CONSTANT_TO_PARAM("header")) == 0)
{
@ -678,6 +676,11 @@ loop: distance = t.getDistance();
bfirst_pass = true; // NB: we check for <!--#define ... --> and <!--#include ... -->
UString basename = UStringExt::basename(filename);
basename_sz = basename.size() - U_CONSTANT_SIZE(".usp");
basename_ptr = basename.data();
processUSP();
# ifdef DEBUG
@ -699,7 +702,6 @@ loop: distance = t.getDistance();
bsighup, // usp_sighup
bfork; // usp_fork
const char* ptr0 = (sseloop ? "\n\t\tif (UHTTP::bsse) goto sseloop;\n" : "");
char ptr1[100] = { '\0' };
char ptr2[100] = { '\0' };
char ptr3[100] = { '\0' };
@ -717,11 +719,6 @@ loop: distance = t.getDistance();
}
# endif
UString basename = UStringExt::basename(filename);
uint32_t basename_sz = basename.size() - U_CONSTANT_SIZE(".usp");
const char* basename_ptr = basename.data();
if (declaration)
{
binit = (U_STRING_FIND(declaration, 0, "static void usp_init_") != U_NOT_FOUND);
@ -799,7 +796,7 @@ loop: distance = t.getDistance();
(void) http_header.append(U_CONSTANT_TO_PARAM("\n\tU_http_info.endHeader = 0;\n"));
}
UString result(1024U + declaration.size() + http_header.size() + output0.size() + output1.size() + output2.size() + sseloop.size() + vars.size());
UString result(1024U + declaration.size() + http_header.size() + output0.size() + output1.size() + output2.size() + vars.size());
result.snprintf(U_CONSTANT_TO_PARAM(
"// %.*s.cpp - dynamic page translation (%.*s.usp => %.*s.cpp)\n"
@ -818,7 +815,7 @@ loop: distance = t.getDistance();
"\t\n"
"\tif (param)\n"
"\t\t{\n"
"%s"
"%v"
"%s"
"%s"
"%s"
@ -844,7 +841,7 @@ loop: distance = t.getDistance();
basename_sz, basename_ptr,
basename_sz, basename_ptr,
vars.rep,
ptr0,
sseloop.rep,
ptr1,
ptr2,
ptr3,
@ -869,6 +866,8 @@ private:
UTokenizer t;
UVector<UString> vdefine;
UString pinclude, usp, token, output0, output1, output2, declaration, vcode, http_header, sseloop, vars;
const char* basename_ptr;
uint32_t basename_sz;
bool bvar, bsession, bstorage, bfirst_pass, is_html, test_if_html, bpreprocessing_failed;
U_DISALLOW_COPY_AND_ASSIGN(Application)

View File

@ -1339,6 +1339,306 @@ private:
ULock* UServer_Base::lock_ocsp_staple;
UThread* UServer_Base::pthread_ocsp;
# endif
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
int UServer_Base::sse_event_fd;
int UServer_Base::sse_socketpair[2];
char UServer_Base::iovbuf[1] = { 0 };
char UServer_Base::sse_fifo_name[256];
ULock* UServer_Base::lock_sse;
uint32_t UServer_Base::sse_fifo_pos;
UThread* UServer_Base::pthread_sse;
UString* UServer_Base::sse_id;
UString* UServer_Base::sse_event;
UString* UServer_Base::str_asterisk;
struct iovec UServer_Base::iov[1] = { { iovbuf, 1 } };
struct msghdr UServer_Base::msg = { 0, 0, iov, 1, &cmsg, sizeof(struct ucmsghdr), 0 };
UVector<USSEClient*>* UServer_Base::sse_vclient;
struct UServer_Base::ucmsghdr UServer_Base::cmsg = { sizeof(struct ucmsghdr), SOL_SOCKET, SCM_RIGHTS, 0 };
#ifdef USE_LIBSSL
ULock* UServer_Base::lock_sse_ssl;
#endif
class USSEThread;
class U_NO_EXPORT USSEClient {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
USSEClient(const UString& id, const UString& subscribe, int _fd, bool process) : sub(subscribe), uniq_id(id), fd(_fd), bprocess(process)
{
U_TRACE_REGISTER_OBJECT(0, USSEClient, "%V,%V,%d,%b", id.rep, subscribe.rep, _fd, process)
U_INTERNAL_ASSERT_DIFFERS(fd, -1)
}
~USSEClient()
{
U_TRACE_UNREGISTER_OBJECT(0, USSEClient)
UFile::close(fd);
if (bprocess)
{
UServer_Base::setFIFOForSSE(uniq_id);
(void) UFile::_unlink(UServer_Base::sse_fifo_name);
}
}
#if defined(DEBUG) && defined(U_STDCPP_ENABLE)
const char* dump(bool _reset) const { return ""; }
#endif
protected:
UString sub, // Token of subscribe (optional). Can be set by parameter "subscribe"
uniq_id; // unique client id (optional). Can be set by parameter "id"
int fd;
bool bprocess;
private:
friend class USSEThread;
};
class USSEThread : public UThread {
public:
USSEThread() : UThread(PTHREAD_CREATE_DETACHED) {}
virtual void run() U_DECL_FINAL
{
U_TRACE_NO_PARAM(0, "USSEThread::run()")
int fd;
const char* ptr;
USSEClient* client;
UVector<UString> vec;
bool ball, bprocess, err;
UVector<UString> vmessage;
uint32_t pos, mr, sz, last_event_id, i, n, k, start = 0, end = 0;
UString input(U_CAPACITY), output(U_CAPACITY), row, _id, token, rID, message, tmp;
while (U_SRV_FLAG_SIGTERM == false)
{
if (UNotifier::waitForRead(UServer_Base::sse_event_fd) == 1 &&
UServices::read(UServer_Base::sse_event_fd, input))
{
/**
* NEW <id> <token> <last_event_id> <bprocess>
* DEL <id>
*
* LIST - List clients to /tmp/SSE_list.txt
*
* <token>=<message> - Send message to the subscribers of <token>
* <token>-<rId>=<message> - Send message to the subscribers of <token> (* => all) except <rId>
*/
for (k = 0, sz = vec.split(input); k < sz; ++k)
{
row = vec[k];
pos = row.find('=');
if (pos > 32)
{
ptr = row.data();
if (u_get_unalignedp32(ptr) == U_MULTICHAR_CONSTANT32('N','E','W',' ')) // NEW <id> <token> <last_event_id> <bprocess>
{
_id = vec[k+1];
token = vec[k+2];
last_event_id = vec[k+3].strtoul();
bprocess = vec[k+4].strtoul();
U_INTERNAL_DUMP("_id = %V token = %V bprocess = %b last_event_id = %u U_SRV_SSE_CNT1 = %u", _id.rep, token.rep, bprocess, last_event_id, U_SRV_SSE_CNT1)
if ((ball = token.equal(*UServer_Base::str_asterisk))) token = *UServer_Base::str_asterisk;
else token.duplicate();
if (last_event_id &&
last_event_id < U_SRV_SSE_CNT1)
{
if (last_event_id < start) last_event_id = start;
for (i = last_event_id; i < end; ++i)
{
message = vmessage[i % vmessage.capacity()];
pos = message.find('=');
U_INTERNAL_DUMP("vmessage[%u] = %V pos = %u", i % vmessage.capacity(), message.rep, pos)
if (ball ||
token.equal(message.data(), pos))
{
(void) output.append(UServer_Base::printSSE(i+1, message.substr(pos+1), (ball ? U_NULLPTR : &token)));
}
}
output.push('\n');
(void) U_SYSCALL(write, "%u,%S,%u", UServer_Base::sse_event_fd, U_STRING_TO_PARAM(output));
output.setEmpty();
}
if (bprocess == false) fd = (U_SYSCALL(recvmsg, "%u,%p,%u", UServer_Base::sse_socketpair[0], &UServer_Base::msg, 0) == 1 ? UServer_Base::cmsg.cmsg_data : -1);
else
{
UServer_Base::setFIFOForSSE(_id);
(void) UFile::mkfifo(UServer_Base::sse_fifo_name);
fd = UFile::open(UServer_Base::sse_fifo_name, O_WRONLY, 0);
if (fd == -1) U_ERROR("Error on opening SSE FIFO: %S", UServer_Base::sse_fifo_name);
}
U_NEW(USSEClient, client, USSEClient(_id.copy(), token, fd, bprocess));
UServer_Base::sse_vclient->push(client);
k += 4;
}
else if (u_get_unalignedp32(ptr) == U_MULTICHAR_CONSTANT32('D','E','L',' ')) // DEL <id>
{
_id = vec[k+1];
U_INTERNAL_DUMP("_id = %V", _id.rep)
for (i = 0, n = UServer_Base::sse_vclient->size(); i < n; ++i)
{
client = UServer_Base::sse_vclient->at(i);
U_INTERNAL_DUMP("sse_vclient[%u]->uniq_id = %V", i, client->uniq_id.rep)
if (client->uniq_id == _id)
{
--n;
delete UServer_Base::sse_vclient->remove(i--);
break;
}
}
k += 1;
}
# ifdef DEBUG
else if (u_get_unalignedp32(ptr) == U_MULTICHAR_CONSTANT32('L','I','S','T'))
{
UString row1(U_CAPACITY);
for (i = 0, n = UServer_Base::sse_vclient->size(); i < n; ++i)
{
client = UServer_Base::sse_vclient->at(i);
row1.snprintf(U_CONSTANT_TO_PARAM("uniq_id: %V sub: %V fd: %u proc: %b\n"), client->uniq_id.rep, client->sub.rep, client->fd, client->bprocess);
(void) output.append(row1);
}
(void) UFile::writeToTmp(U_STRING_TO_PARAM(output), O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("SSE_client.txt"), 0);
output = vmessage.join('\n');
(void) UFile::writeToTmp(U_STRING_TO_PARAM(output), O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("SSE_message.txt"), 0);
output.setEmpty();
++k;
}
# endif
else
{
U_WARNING("Wrong formatted message from SSE FIFO, ignored: row = %V", row.rep);
++k;
}
}
else
{
mr = row.find('-', 0, pos);
if (mr == U_NOT_FOUND) token = row.substr(0U, pos);
else
{
token = row.substr(0U, mr);
rID = row.substr(mr+1, pos-mr-1);
}
message = row.substr(pos+1);
U_SRV_SSE_CNT1++;
U_INTERNAL_DUMP("token = %V rID = %V message = %V U_SRV_SSE_CNT1 = %u", token.rep, rID.rep, message.rep, U_SRV_SSE_CNT1)
U_SRV_LOG("[sse] send message(%u) to subscribers of %V%.*s%.*s: %V", U_SRV_SSE_CNT1, token.rep,
rID ? U_CONSTANT_SIZE(" except SSE_") : 0, " except SSE_", rID ? rID.size() : 0, rID.data(), message.rep);
tmp = ((ball = token.equal(*UServer_Base::str_asterisk)) ? "*="+message : token+'='+message);
if (end < vmessage.capacity()) vmessage.push_back(tmp);
else
{
++start;
vmessage.replace(end % vmessage.capacity(), tmp);
}
++end;
for (i = 0, n = UServer_Base::sse_vclient->size(); i < n; ++i)
{
client = UServer_Base::sse_vclient->at(i);
if (rID != client->uniq_id &&
(ball ||
client->sub.equal(token)))
{
if (client->bprocess) err = (U_SYSCALL(write, "%u,%S,%u", client->fd, U_STRING_TO_PARAM(message)) <= 0);
else
{
U_INTERNAL_ASSERT_EQUALS(UServer_Base::bssl, false)
tmp = UServer_Base::printSSE(U_SRV_SSE_CNT1, message, (ball ? U_NULLPTR : &token));
err = (U_SYSCALL(write, "%u,%S,%u", client->fd, U_STRING_TO_PARAM(tmp)) <= 0);
}
if (err)
{
--n;
delete UServer_Base::sse_vclient->remove(i--);
}
}
}
}
}
UServer_Base::unlockSSE();
vec.clear();
rID.clear();
token.clear();
input.setEmpty();
}
}
}
private:
U_DISALLOW_COPY_AND_ASSIGN(USSEThread)
};
# endif
#endif
#ifdef U_LINUX
@ -1443,9 +1743,17 @@ UServer_Base::~UServer_Base()
USSLSocket::cleanupStapling();
if (UServer_Base::lock_ocsp_staple) delete UServer_Base::lock_ocsp_staple;
if (lock_ocsp_staple) delete lock_ocsp_staple;
}
# endif
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
if (lock_sse) delete lock_sse;
# ifdef USE_LIBSSL
if (lock_sse_ssl) delete lock_sse_ssl;
# endif
if (pthread_sse) delete (USSEThread*)pthread_sse;
# endif
# endif
#endif
@ -3099,6 +3407,45 @@ next:
initEvasive();
#endif
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
# ifdef USERVER_UDP
if (budp == false)
# endif
{
sse_fifo_pos = u__snprintf(sse_fifo_name, 256, U_CONSTANT_TO_PARAM("%s/SSE_%s_EVENT"), u_tmpdir, bssl ? "SSL" : "TCP") - U_CONSTANT_SIZE("EVENT");
(void) UFile::mkfifo(sse_fifo_name, PERM_FILE);
sse_event_fd = UFile::open(sse_fifo_name, O_RDWR, PERM_FILE);
if (sse_event_fd == -1) U_ERROR("Error on opening SSE FIFO: %S", sse_fifo_name);
# ifndef DEBUG
(void) UFile::_unlink(sse_fifo_name);
# endif
setLockSSE();
U_INTERNAL_ASSERT_EQUALS(sse_id, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(sse_vclient, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(pthread_sse, U_NULLPTR)
U_INTERNAL_ASSERT_EQUALS(str_asterisk, U_NULLPTR)
U_NEW(UString, sse_id, UString);
U_NEW(USSEThread, pthread_sse, USSEThread);
U_NEW(UString, str_asterisk, U_STRING_FROM_CONSTANT("*"));
U_NEW(UVector<USSEClient*>, sse_vclient, UVector<USSEClient*>);
pthread_sse->start(0);
(void) U_SYSCALL(socketpair, "%d,%d,%d,%p", AF_UNIX, SOCK_STREAM, 0, sse_socketpair);
U_INTERNAL_DUMP("sse_socketpair[0] = %u sse_socketpair[1] = %u", sse_socketpair[0], sse_socketpair[1])
U_SRV_LOG("SSE thread activated: %s(%d)", sse_fifo_name, sse_event_fd);
}
#endif
if (cfg) cfg->clear();
UInterrupt::syscall_restart = false;
@ -3150,6 +3497,10 @@ void UServer_Base::sendSignalToAllChildren(int signo, sighandler_t handler)
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
if (pthread_ocsp) pthread_ocsp->suspend();
# endif
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
if (pthread_sse) pthread_sse->suspend();
# endif
#endif
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
@ -3172,6 +3523,10 @@ void UServer_Base::sendSignalToAllChildren(int signo, sighandler_t handler)
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
if (pthread_ocsp) pthread_ocsp->resume();
# endif
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
if (pthread_sse) pthread_sse->resume();
# endif
#endif
}
@ -4214,6 +4569,10 @@ void UServer_Base::run()
if (proc->child())
{
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
UFile::close(sse_socketpair[0]);
# endif
U_INTERNAL_DUMP("child = %P UNotifier::num_connection = %d", UNotifier::num_connection)
# if defined(HAVE_SCHED_GETAFFINITY) && (!defined(U_SERVER_CAPTIVE_PORTAL) || defined(ENABLE_THREAD))
@ -4412,6 +4771,10 @@ stop:
closeLog();
}
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
if (pthread_sse) sse_vclient->clear();
#endif
#ifdef DEBUG
pthis->deallocate();
#endif

View File

@ -1416,8 +1416,9 @@ int UNotifier::read(int fd, char* buffer, int count, int timeoutMS)
{
U_TRACE(1, "UNotifier::read(%d,%p,%d,%d)", fd, buffer, count, timeoutMS)
if (fd < 0 &&
timeoutMS != -1 &&
U_INTERNAL_ASSERT_DIFFERS(fd, -1)
if (timeoutMS != -1 &&
waitForRead(fd, timeoutMS) != 1)
{
U_RETURN(-1);

View File

@ -37,13 +37,16 @@ bool UProcess::fork()
_pid = U_FORK();
if ((running = (_pid != -1)))
{
if (child()) u_setPid();
running = (_pid != -1);
U_INTERNAL_DUMP("_pid = %u u_pid = %u %%P = %P running = %b", _pid, u_pid, running)
U_INTERNAL_DUMP("%P running = %b", running)
U_RETURN(true);
}
U_RETURN(running);
U_RETURN(false);
}
// inlining failed in call to 'UProcess::setStdInOutErr(bool, bool, bool)': call is unlikely and code size would grow

View File

@ -1388,6 +1388,29 @@ void UString::resize(uint32_t n, unsigned char c)
// The `find' function searches string for a specified string (possibly a single character) and returns
// its starting position. You can supply the parameter pos to specify the position where search must begin
__pure uint32_t UString::find(unsigned char c, uint32_t pos, uint32_t how_much) const
{
U_TRACE(0, "UString::find(%C,%u,%u)", c, pos, how_much)
uint32_t n = rep->fold(pos, how_much);
U_INTERNAL_DUMP("rep->_length = %u", rep->_length)
U_INTERNAL_ASSERT(n <= rep->_length)
const char* str = rep->str;
const char* ptr = (const char*) memchr(str + pos, c, n);
if (ptr)
{
n = ptr - str;
U_RETURN(n);
}
U_RETURN(U_NOT_FOUND);
}
__pure uint32_t UString::find(const char* s, uint32_t pos, uint32_t s_len, uint32_t how_much) const
{
U_TRACE(0, "UString::find(%.*S,%u,%u,%u)", s_len, s, pos, s_len, how_much)
@ -1406,11 +1429,16 @@ __pure uint32_t UString::find(const char* s, uint32_t pos, uint32_t s_len, uint3
const char* str = rep->str;
const char* ptr = (const char*) u_find(str + pos, n, s, s_len);
n = (ptr ? ptr - str : U_NOT_FOUND);
if (ptr)
{
n = ptr - str;
U_RETURN(n);
}
U_RETURN(U_NOT_FOUND);
}
__pure uint32_t UString::findnocase(const char* s, uint32_t pos, uint32_t s_len, uint32_t how_much) const
{
U_TRACE(0, "UString::findnocase(%.*S,%u,%u,%u)", s_len, s, pos, s_len, how_much)

View File

@ -169,7 +169,9 @@ UVector<UIPAllow*>* UHTTP::vallow_IP;
URDBObjectHandler<UDataStorage*>* UHTTP::db_session_ssl;
#endif
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
bool UHTTP::bsse;
int UHTTP::sse_pipe_fd;
const char* UHTTP::sse_corsbase = "*";
UHTTP::strPF UHTTP::sse_func;
#endif
#ifdef USE_LOAD_BALANCE
UClient<USSLSocket>* UHTTP::client_http;
@ -5312,19 +5314,15 @@ void UHTTP::setEndRequestProcessing()
U_ClientImage_request, U_http_info.nResponseCode, U_ClientImage_request_is_cached, U_http_info.startHeader)
#ifdef U_SSE_ENABLE
U_INTERNAL_DUMP("bsse = %b", bsse)
U_INTERNAL_DUMP("sse_func = %p", sse_func)
if (bsse)
if (sse_func)
{
U_INTERNAL_DUMP("Accept: = %.*S", U_HTTP_ACCEPT_TO_TRACE)
U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(U_http_info.accept+8), U_MULTICHAR_CONSTANT64('n','t','-','s','t','r','e','a'))
if (UServer_Base::startParallelization())
{
// parent
bsse = false;
sse_func = U_NULLPTR;
return;
}
@ -5334,6 +5332,24 @@ void UHTTP::setEndRequestProcessing()
U_SET_MODULE_NAME(sse);
UServer_Base::setFIFOForSSE(*UServer_Base::sse_id);
loop: sse_pipe_fd = UFile::open(UServer_Base::sse_fifo_name, O_RDONLY, 0);
if (sse_pipe_fd == -1)
{
U_INTERNAL_DUMP("errno = %u u_errno = %u", errno, u_errno)
if (errno == ENOENT)
{
(void) UFile::mkfifo(UServer_Base::sse_fifo_name);
goto loop;
}
U_ERROR("Error on opening SSE FIFO: %S", UServer_Base::sse_fifo_name);
}
usp->runDynamicPage(1);
}
#endif
@ -7082,15 +7098,176 @@ void UHTTP::setUnAuthorized()
// end HTTP main error message
// --------------------------------------------------------------------------------------------------------------------------------------
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
__noreturn void UHTTP::readSSE(int timeoutMS)
{
U_TRACE(0, "UHTTP::readSSE(%d)", timeoutMS)
UString input(U_CAPACITY), sse_data;
while (true)
{
if (UServices::read(sse_pipe_fd, input, U_SINGLE_READ, timeoutMS))
{
U_INTERNAL_ASSERT(input)
// external
sendSSE(input);
input.setEmpty();
continue;
}
if (U_SRV_FLAG_SIGTERM) U_EXIT(0);
# ifdef USE_LIBSSL
if (UServer_Base::bssl == false)
# endif
{
U_INTERNAL_ASSERT_POINTER(sse_func)
U_INTERNAL_ASSERT_DIFFERS(timeoutMS, -1)
// timeout (internal)
sse_data = sse_func();
if (sse_data)
{
UServer_Base::sendToAllExceptSSE(sse_data);
sendSSE(sse_data);
}
}
}
}
#endif
void UHTTP::setDynamicResponse()
{
U_TRACE_NO_PARAM(0, "UHTTP::setDynamicResponse()")
U_TRACE_NO_PARAM(1, "UHTTP::setDynamicResponse()")
U_INTERNAL_DUMP("U_http_info.endHeader = %u U_http_content_type_len = %u mime_index(%d) = %C UClientImage_Base::wbuffer(%u) = %V",
U_http_info.endHeader, U_http_content_type_len, mime_index, mime_index, UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
U_INTERNAL_ASSERT_MAJOR(U_http_info.nResponseCode, 0)
#ifdef U_SSE_ENABLE
U_INTERNAL_DUMP("sse_func = %p", sse_func)
if (sse_func)
{
U_INTERNAL_DUMP("Accept: = %.*S", U_HTTP_ACCEPT_TO_TRACE)
U_ASSERT(isGET())
U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(U_http_info.accept+8), U_MULTICHAR_CONSTANT64('n','t','-','s','t','r','e','a'))
/**
* we must insert:
*
* <!--#args
* subscribe;
* id;
* -->
*
* <!--#header
* Access-Control-Allow-Origin: *
* Access-Control-Allow-Methods: GET
* Access-Control-Allow-Headers: cache-control, last-event-id, X-Requested-With
* Content-Type: text/event-stream
* Cache-Control: no-cache
* -->
*/
UString subscribe;
bool bprocess = (sse_func != (void*)1L);
const char* ptr = getHeaderValuePtr(U_CONSTANT_TO_PARAM("last-event-id"), true);
uint32_t last_event_id = (ptr ? u_atoi(ptr) : 0);
UServer_Base::sse_id->clear();
if (UServer_Base::bssl == false) (void) UServer_Base::csocket->shutdown(SHUT_RD);
(void) UClientImage_Base::wbuffer->snprintf(U_CONSTANT_TO_PARAM("Access-Control-Allow-Origin: %s\r\n"
"Access-Control-Allow-Methods: GET\r\n"
"Access-Control-Allow-Headers: cache-control, last-event-id, X-Requested-With\r\n"
"Content-Type: text/event-stream\r\n"
"Cache-Control: no-cache\r\n\r\n"), sse_corsbase);
if (processForm())
{
getFormValue(subscribe, 1);
getFormValue(*UServer_Base::sse_id, 3);
}
if (subscribe) UServer_Base::sse_event = &subscribe;
else
{
subscribe = *UServer_Base::str_asterisk;
UServer_Base::sse_event = U_NULLPTR;
}
if (UServer_Base::sse_id->empty())
{
U_SRV_SSE_CNT2++;
U_INTERNAL_DUMP("U_SRV_SSE_CNT2 = %u", U_SRV_SSE_CNT2)
*UServer_Base::sse_id = UStringExt::numberToString(U_SRV_SSE_CNT2);
}
U_INTERNAL_DUMP("last_event_id = %u U_SRV_SSE_CNT1 = %u", last_event_id, U_SRV_SSE_CNT1)
UServer_Base::eventSSE(U_CONSTANT_TO_PARAM("NEW %v %v %u %u\n"), UServer_Base::sse_id->rep, subscribe.rep, last_event_id, bprocess);
if (ptr &&
last_event_id < U_SRV_SSE_CNT1)
{
UString buffer(U_CAPACITY);
(void) UServices::read(UServer_Base::sse_event_fd, buffer);
uint32_t sz = buffer.size();
if (sz > 1)
{
U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp16(buffer.data()), U_MULTICHAR_CONSTANT16('i','d'))
UClientImage_Base::wbuffer->append(buffer.data(), sz-1);
}
}
if (bprocess)
{
UString sse_data = sse_func();
if (sse_data)
{
UServer_Base::sendToAllExceptSSE(sse_data);
UClientImage_Base::wbuffer->append(UServer_Base::printSSE(U_SRV_SSE_CNT1, sse_data, UServer_Base::sse_event));
}
}
else
{
sse_func = U_NULLPTR;
UServer_Base::cmsg.cmsg_data = UServer_Base::csocket->getFd();
(void) U_SYSCALL(sendmsg, "%u,%p,%u", UServer_Base::sse_socketpair[1], &UServer_Base::msg, 0);
UClientImage_Base::resetPipelineAndSetCloseConnection();
}
*ext = *UClientImage_Base::wbuffer;
handlerResponse();
return;
}
#endif
char* ptr;
const char* pEndHeader;
uint32_t clength = UClientImage_Base::wbuffer->size();
@ -7128,19 +7305,6 @@ void UHTTP::setDynamicResponse()
}
# endif
# ifdef U_SSE_ENABLE
U_INTERNAL_DUMP("bsse = %b", bsse)
if (bsse)
{
*ext = *UClientImage_Base::wbuffer;
handlerResponse();
return;
}
# endif
if (bcompress == false)
{
(void) UClientImage_Base::body->replace(pEndHeader + U_http_info.endHeader, clength);

View File

@ -1,27 +1,12 @@
<!--#declaration
static uint32_t counter;
static UString getPrice()
{
U_TRACE_NO_PARAM(5, "::getPrice()")
<!--#sse:10
static double price = 1.2;
if (counter++)
if (U_SRV_SSE_CNT1)
{
price = price + (double)rand() / RAND_MAX * 2.0 - 1;
if (price <= 0.01) price = 0.01;
}
UString x = UStringExt::numberToString(price);
U_RETURN_STRING(x);
}
-->
<!--#ssecode
UHTTP::writeSSE(1, getPrice());
-->
<!--#sseloop:5
UHTTP::sendSSE(counter, getPrice());
sse_data = UStringExt::numberToString(price);
-->

View File

@ -0,0 +1,2 @@
<!--#sse
-->

View File

@ -1,7 +1,6 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="jquery.min.js"></script>
<title>SSE example</title>
</head>
<body>

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SSE example</title>
</head>
<body>
<h1>Stock Price</h1>
<script type="text/javascript">
function read_data() {
var stream = new EventSource('/get_ticker1');
stream.onmessage = function(e){
document.getElementById('price').innerHTML=e.data;
};
stream.onerror = function(e){
console.log(e);
};
}
read_data();
</script>
<p>Price: <span id="price"></span></p>
</body>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
<!--#args
value("13.333");
-->
<!--#code
UServer_Base::sendToAllSSE(value);
-->

View File

@ -4,8 +4,8 @@
(cd benchmark; rm -f db; creat_link FrameworkBenchmarks/ULib/db db)
DOC_ROOT=docroot
#DOC_ROOT=sse_example
#DOC_ROOT=docroot
DOC_ROOT=sse_example
#DOC_ROOT=ruby/blog
#DOC_ROOT=benchmark/docroot
#DOC_ROOT=ShivShankarDayal/docroot
@ -18,10 +18,12 @@ rm -f tmp/usp_compile.sh.err /tmp/*.hpack.* \
UTRACE="0 50M 0"
UTRACE_SIGNAL="0 50M 0"
UTRACE_FOLDER=/tmp
TMPDIR=/tmp
#UOBJDUMP="0 10M 100"
#USIMERR="error.sim"
#UMEMUSAGE=yes
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL UMEMUSAGE
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL UMEMUSAGE UTRACE_FOLDER TMPDIR
SOCK1=tmp/fcgi.socket
@ -69,7 +71,7 @@ userver {
#LOAD_BALANCE_CLUSTER 10.30.0.1,10.30.0.2
#LOAD_BALANCE_DEVICE_NETWORK enp0s20u1
#LOAD_BALANCE_LOADAVG_THRESHOLD 4.0
PREFORK_CHILD 0
PREFORK_CHILD 2
#CRASH_COUNT 1
#CRASH_EMAIL_NOTIFY mail.unirel.com:stefano.casazza@unirel.com
#DOS_SITE_COUNT 1

View File

@ -2,6 +2,12 @@
. ../.function
# set -x
## web_server_proxy.test -- Test web server proxy feature
start_msg web_server_proxy
DOC_ROOT1=benchmark/docroot
DOC_ROOT2=docroot
@ -87,3 +93,6 @@ pkill userver_tcp 2>/dev/null
cat err/userver_tcp.err >> err/webserver_proxy.err
rm err/userver_tcp.err
# Test against expected output
test_output_wc l webserver_proxy

View File

@ -1 +0,0 @@
"A JSON payload should be an object or array, not a string."

View File

@ -1 +0,0 @@
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]

View File

@ -1 +0,0 @@
["Unclosed array"

View File

@ -1 +0,0 @@
{unquoted_key: "keys must be quoted"}

View File

@ -1 +0,0 @@
["extra comma",]

View File

@ -1 +0,0 @@
["double extra comma",,]

View File

@ -1 +0,0 @@
[ , "<-- missing value"]

View File

@ -1 +0,0 @@
["Comma after the close"],

View File

@ -1 +0,0 @@
["Extra close"]]

View File

@ -1 +0,0 @@
{"Extra comma": true,}

View File

@ -1,58 +0,0 @@
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E66,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"0123456789": "digit",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066,
1e1,
0.1e1,
1e-1,
1e00,2e+00,2e-00
,"rosebud"]

View File

@ -1 +0,0 @@
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]

View File

@ -1,6 +0,0 @@
{
"JSON Test Pattern pass3": {
"The outermost value": "must be an object or array.",
"In this test": "It is an object."
}
}

View File

@ -1,131 +0,0 @@
/* Infix notation calculator-calc */
%{
#define YYDEBUG 1
/*
#define DEBUG_DEBUG
*/
#include <ulib/flex/bison.h>
#include <test_bison.h>
#include <math.h>
int yyerror(void*, char*);
#define yylex ((UBison*)obj)->UFlexer::yylex
%}
/* BISON Declarations */
%lex-param { void* obj }
%parse-param { void* obj }
%union {
int number;
UFlexerReference ref;
}
%token <number> NUM
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
%right '^' /* exponentiation */
%type <number> exp
/* Grammar follows */
%%
input: /* empty string */
| input line
;
line: '\n'
| exp '\n'
{
printf("\t%d\n", $1);
U_INTERNAL_TRACE("UBison::yyparse() <line> %d", $1);
}
;
exp: NUM
{
$$ = $1;
U_INTERNAL_TRACE("UBison::yyparse() <exp NUM> %d", $1);
}
| exp '+' exp
{
$$ = $1 + $3;
U_INTERNAL_TRACE("UBison::yyparse() <exp +> %d + %d", $1, $3);
}
| exp '-' exp
{
$$ = $1 - $3;
U_INTERNAL_TRACE("UBison::yyparse() <exp -> %d - %d", $1, $3);
}
| exp '*' exp
{
$$ = $1 * $3;
U_INTERNAL_TRACE("UBison::yyparse() <exp *> %d * %d", $1, $3);
}
| exp '/' exp
{
$$ = $1 / $3;
U_INTERNAL_TRACE("UBison::yyparse() <exp /> %d / %d", $1, $3);
}
| '-' exp %prec NEG
{
$$ = -$2;
U_INTERNAL_TRACE("UBison::yyparse() <exp NEG> %d", $2);
}
| exp '^' exp
{
$$ = (int) ::pow((float)$1, (float)$3);
U_INTERNAL_TRACE("UBison::yyparse() <exp ^> %d ^ %d", $1, $3);
}
| '(' exp ')'
{
$$ = $2;
U_INTERNAL_TRACE("UBison::yyparse() <exp ()> %d", $2);
}
;
%%
int yyerror(void* p, char* s)
{
U_INTERNAL_TRACE("yyerror(\"%p,%s\")", p, s);
/**
* extern int yylineno;
*
* U_INTERNAL_TRACE("yylineno=%d", yylineno)
*/
return -1;
}
#include <ulib/file.h>
int main(int argc, char* argv[])
{
U_ULIB_INIT(argv);
U_TRACE(5, "main(%d)", argc)
UBison parser(UFile::contentOf(argv[1]));
/*
*/
extern int yydebug;
yydebug = 1;
parser.parse();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
%{
/*
#define DEBUG_DEBUG
*/
#undef YY_DECL
#include <ulib/flex/flexer.h>
#include <test_bison.h>
#define YY_DECL int UFlexer::yylex(void* yyval)
#define YY_USER_ACTION ((YYSTYPE*)yyval)->ref.offset = parsed_chars; \
((YYSTYPE*)yyval)->ref.length = yyleng; parsed_chars += yyleng; \
((YYSTYPE*)yyval)->ref.ptr = yytext;
int line_num = 1;
%}
%option c++
%option yyclass="UFlexer" caseless
%option nounput
%option nostack
%option noreject
%option never-interactive
%option noyywrap
%option noyymore
dig [0-9]
num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)?
num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
number {num1}|{num2}
ws [ \f\t\r]+
%%
{ws} /* skip blanks and tabs */
{number} {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %d number <%s>", line_num, yytext);
yylval.number = strtol(yytext, 0, 0);
return NUM;
}
\n {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %d new line", line_num);
++line_num;
return '\n';
}
. return yytext[0];
%%

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
%{
/*
#define DEBUG_DEBUG
*/
#undef YY_DECL
#include <ulib/flex/flexer.h>
#define YY_DECL int UFlexer::yylex(void* yyval)
#define YY_USER_ACTION ((YYSTYPE*)yyval)->ref.offset = parsed_chars; \
((YYSTYPE*)yyval)->ref.length = yyleng; parsed_chars += yyleng; \
((YYSTYPE*)yyval)->ref.ptr = yytext;
int line_num = 1;
%}
%option c++
%option yyclass="UFlexer" caseless
%option nounput
%option nostack
%option noreject
%option never-interactive
%option noyywrap
%option noyymore
dig [0-9]
alpha [A-Za-z]
name ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])*
num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)?
num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
number {num1}|{num2}
ws [ \t]+
word [^ \t\n]+
string \"[^\n"]+\"
%x comment
%%
{ws} /* skip blanks and tabs */
\n {
++line_num;
}
{number} {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %4d number <%s>", line_num, yytext);
}
{name} {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %4d name <%s>", line_num, yytext);
}
{string} {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %4d string <%s>", line_num, yytext);
}
"/*" {
BEGIN(comment);
}
<comment>{
[^*\n]*
[^*\n]*\n ++line_num;
"*"+[^*/\n]*
"*"+[^*/\n]*\n ++line_num;
"*"+"/" BEGIN(INITIAL);
}
{word} {
U_INTERNAL_TRACE("UFlexer::yylex() line_num = %4d word <%s>", line_num, yytext);
}
%%
#include <ulib/file.h>
int main(int argc, char* argv[])
{
U_ULIB_INIT(argv);
U_TRACE(5, "main(%d)", argc)
UFlexer flexer;
flexer.setData(UFile::contentOf(argv[1]));
#ifdef DEBUG
flexer.test();
#endif
}

View File

@ -5,6 +5,9 @@
#include <ulib/file.h>
#include <ulib/base/hash.h>
#include <ulib/utility/dir_walk.h>
/*
#include <ulib/net/server/server.h>
*/
#ifdef __MINGW32__
#define _GLIBCXX_USE_C99_DYNAMIC 1
@ -235,6 +238,99 @@ static void check_equal()
U_ASSERT( b.find(U_STRING_FROM_CONSTANT("rilevazione-virus"), true) == true )
}
/**
static void check_bound(uint32_t last_event_id)
{
U_TRACE(5,"check_bound(%u)", last_event_id)
UVector<UString> vmessage;
uint32_t i, n, pos, start = 0, end = 0;
UString tmp, message(100U), output(U_CAPACITY);
for (i = 0, n = vmessage.capacity() * 1.5; i < n; ++i)
{
message.snprintf(U_CONSTANT_TO_PARAM("%u"), i);
tmp = "*="+message;
if (end < vmessage.capacity()) vmessage.push_back(tmp);
else
{
++start;
vmessage.replace(end % vmessage.capacity(), tmp);
}
++end;
}
if (last_event_id < start) last_event_id = start;
for (i = last_event_id; i < end; ++i)
{
message = vmessage[i % vmessage.capacity()];
pos = message.find('=');
U_INTERNAL_DUMP("vmessage[%u] = %V pos = %u", i % vmessage.capacity(), message.rep, pos)
(void) output.append(UServer_Base::printSSE(i+1, message.substr(pos+1), U_NULLPTR));
}
cout << vmessage << "\n" << output;
( *=64 *=65 *=66 *=67 *=68 *=69 *=70 *=71 *=72 *=73 *=74 *=75 *=76 *=77 *=78 *=79 *=80 *=81 *=82 *=83 *=84 *=85 *=86 *=87 *=88 *=89 *=90 *=91 *=92 *=93 *=94 *=95 *=32 *=33 *=34 *=35 *=36 *=37 *=38 *=39 *=40 *=41 *=42 *=43 *=44 *=45 *=46 *=47 *=48 *=49 *=50 *=51 *=52 *=53 *=54 *=55 *=56 *=57 *=58 *=59 *=60 *=61 *=62 *=63 )
id:81
data:80
id:82
data:81
id:83
data:82
id:84
data:83
id:85
data:84
id:86
data:85
id:87
data:86
id:88
data:87
id:89
data:88
id:90
data:89
id:91
data:90
id:92
data:91
id:93
data:92
id:94
data:93
id:95
data:94
id:96
data:95
}
*/
int
U_EXPORT main (int argc, char* argv[])
{
@ -242,6 +338,11 @@ U_EXPORT main (int argc, char* argv[])
U_TRACE(5,"main(%d)",argc)
/*
check_bound(80);
exit(0);
*/
UString tmp;
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX11) && defined(U_COMPILER_RANGE_FOR)
@ -325,7 +426,7 @@ U_EXPORT main (int argc, char* argv[])
// EXTENSION
{
UDirWalk dirwalk(0, U_CONSTANT_TO_PARAM("?db.*test*"));
UDirWalk dirwalk(U_NULLPTR, U_CONSTANT_TO_PARAM("?db.*test*"));
n = dirwalk.walk(y);

View File

@ -6,7 +6,7 @@
start_msg vector
#UTRACE="0 50M -1"
#UTRACE="0 50M 0"
#UOBJDUMP="0 1M 10"
#USIMERR="error.sim"
export UTRACE UOBJDUMP USIMERR