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:
parent
f8242556bb
commit
78b284446e
1085
CODE_OF_CONDUCT.md
1085
CODE_OF_CONDUCT.md
File diff suppressed because it is too large
Load Diff
970
CONTRIBUTING.md
970
CONTRIBUTING.md
|
@ -1,965 +1,5 @@
|
||||||
|
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
|
||||||
|
|
||||||
<!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&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="/<user-name>/<repo-name>/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="✓" /></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…
|
|
||||||
</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="✓" /></div>
|
|
||||||
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" 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">© 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>
|
|
||||||
|
|
||||||
|
|
8
configure
vendored
8
configure
vendored
|
@ -1805,7 +1805,7 @@ Optional Features:
|
||||||
--enable-GSDS enable GDB Stack Dump Support [default=no]
|
--enable-GSDS enable GDB Stack Dump Support [default=no]
|
||||||
--enable-HCRS enable Cache Request Support [default=no]
|
--enable-HCRS enable Cache Request Support [default=no]
|
||||||
--enable-HPRS enable Homogeneous Pipeline 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-http2 enable HTTP/2 support [default=no]
|
||||||
--enable-check-time enable server check time between request for parallelization [default=no]
|
--enable-check-time enable server check time between request for parallelization [default=no]
|
||||||
--enable-classic enable server classic model support [default=no]
|
--enable-classic enable server classic model support [default=no]
|
||||||
|
@ -28336,11 +28336,7 @@ if test "${enable_SSE+set}" = set; then :
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "$enable_SSE"; then
|
if test -z "$enable_SSE"; then
|
||||||
if test "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO"; then
|
enable_SSE="no"
|
||||||
enable_SSE="no"
|
|
||||||
else
|
|
||||||
enable_SSE="yes"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
if test "$enable_SSE" = "yes"; then
|
if test "$enable_SSE" = "yes"; then
|
||||||
|
|
||||||
|
|
|
@ -3,57 +3,44 @@
|
||||||
#include <ulib/net/server/usp_macro.h>
|
#include <ulib/net/server/usp_macro.h>
|
||||||
|
|
||||||
#include "ir_session.h"
|
#include "ir_session.h"
|
||||||
#include <ulib/debug/crono.h>
|
#include <ulib/debug/crono.h>
|
||||||
|
#define IR_SESSION (*(IRDataSession*)UHTTP::data_session)
|
||||||
#define IR_SESSION (*(IRDataSession*)UHTTP::data_session)
|
static IR* ir;
|
||||||
|
static Query* query;
|
||||||
static IR* ir;
|
static UCrono* crono;
|
||||||
static Query* query;
|
static UString* footer;
|
||||||
static UCrono* crono;
|
static void usp_init_ir_web()
|
||||||
static UString* footer;
|
{
|
||||||
|
U_TRACE(5, "::usp_init_ir_web()")
|
||||||
static void usp_init_ir_web()
|
U_INTERNAL_ASSERT_EQUALS(ir, U_NULLPTR)
|
||||||
{
|
U_INTERNAL_ASSERT_EQUALS(query, U_NULLPTR)
|
||||||
U_TRACE(5, "::usp_init_ir_web()")
|
U_INTERNAL_ASSERT_EQUALS(crono, U_NULLPTR)
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(footer, U_NULLPTR)
|
||||||
U_INTERNAL_ASSERT_EQUALS(ir, U_NULLPTR)
|
U_NEW(IR, ir, IR);
|
||||||
U_INTERNAL_ASSERT_EQUALS(query, U_NULLPTR)
|
U_NEW(Query, query, Query);
|
||||||
U_INTERNAL_ASSERT_EQUALS(crono, U_NULLPTR)
|
U_NEW(UCrono, crono, UCrono);
|
||||||
U_INTERNAL_ASSERT_EQUALS(footer, U_NULLPTR)
|
U_NEW(UString, footer, UString(200U));
|
||||||
|
ir->loadFileConfig();
|
||||||
U_NEW(IR, ir, IR);
|
if (ir->openCDB(false) == false)
|
||||||
U_NEW(Query, query, Query);
|
{
|
||||||
U_NEW(UCrono, crono, UCrono);
|
U_ERROR("usp_init() of servlet ir_web failed");
|
||||||
U_NEW(UString, footer, UString(200U));
|
}
|
||||||
|
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());
|
||||||
ir->loadFileConfig();
|
U_NEW(IRDataSession, UHTTP::data_session, IRDataSession);
|
||||||
|
UHTTP::initSession();
|
||||||
if (ir->openCDB(false) == false)
|
}
|
||||||
{
|
static void usp_end_ir_web()
|
||||||
U_ERROR("usp_init() of servlet ir_web failed");
|
{
|
||||||
}
|
U_TRACE(5, "::usp_end_ir_web()")
|
||||||
|
U_INTERNAL_ASSERT_POINTER(ir)
|
||||||
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_INTERNAL_ASSERT_POINTER(query)
|
||||||
|
U_INTERNAL_ASSERT_POINTER(crono)
|
||||||
U_NEW(IRDataSession, UHTTP::data_session, IRDataSession);
|
U_INTERNAL_ASSERT_POINTER(footer)
|
||||||
|
delete ir;
|
||||||
UHTTP::initSession();
|
delete query;
|
||||||
}
|
delete crono;
|
||||||
|
delete footer;
|
||||||
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;
|
|
||||||
delete footer;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern U_EXPORT void runDynamicPage_ir_web(int param);
|
extern U_EXPORT void runDynamicPage_ir_web(int param);
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
#include <ulib/net/server/usp_macro.h>
|
#include <ulib/net/server/usp_macro.h>
|
||||||
|
|
||||||
static void usp_end_wi_auth();
|
static void usp_end_wi_auth();
|
||||||
static void usp_init_wi_auth();
|
static void usp_init_wi_auth();
|
||||||
static void usp_sighup_wi_auth();
|
static void usp_sighup_wi_auth();
|
||||||
|
#include <ulib/examples/wi_auth_declaration.h>
|
||||||
#include <ulib/examples/wi_auth_declaration.h>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern U_EXPORT void runDynamicPage_wi_auth(int param);
|
extern U_EXPORT void runDynamicPage_wi_auth(int param);
|
||||||
|
|
|
@ -93,19 +93,19 @@ U_DO_PRAGMA(message ("Sorry I was compiled without thread enabled so I cannot us
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(U_THROTTLING_SUPPORT) && !defined(U_HTTP2_DISABLE)
|
#if defined(U_THROTTLING_SUPPORT) && !defined(U_HTTP2_DISABLE)
|
||||||
# undef U_THROTTLING_SUPPORT
|
# undef U_THROTTLING_SUPPORT
|
||||||
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support bandwidth throttling"))
|
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support bandwidth throttling"))
|
||||||
#endif
|
#endif
|
||||||
#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && !defined(U_HTTP2_DISABLE)
|
#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && !defined(U_HTTP2_DISABLE)
|
||||||
# undef U_SERVER_CHECK_TIME_BETWEEN_REQUEST
|
# undef U_SERVER_CHECK_TIME_BETWEEN_REQUEST
|
||||||
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support check time between request"))
|
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support check time between request"))
|
||||||
#endif
|
#endif
|
||||||
#if !defined(U_CACHE_REQUEST_DISABLE) && !defined(U_HTTP2_DISABLE)
|
#if !defined(U_CACHE_REQUEST_DISABLE) && !defined(U_HTTP2_DISABLE)
|
||||||
# define U_CACHE_REQUEST_DISABLE
|
# define U_CACHE_REQUEST_DISABLE
|
||||||
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support cache request"))
|
U_DO_PRAGMA(message ("Sorry I was compiled with http2 enabled so I cannot support cache request"))
|
||||||
#endif
|
#endif
|
||||||
#if defined(U_HTTP_INOTIFY_SUPPORT) && defined(U_SERVER_CAPTIVE_PORTAL)
|
#if defined(U_HTTP_INOTIFY_SUPPORT) && defined(U_SERVER_CAPTIVE_PORTAL)
|
||||||
# undef U_HTTP_INOTIFY_SUPPORT
|
# undef U_HTTP_INOTIFY_SUPPORT
|
||||||
U_DO_PRAGMA(message ("Sorry I was compiled with server captive portal mode enabled so I cannot support http inotify"))
|
U_DO_PRAGMA(message ("Sorry I was compiled with server captive portal mode enabled so I cannot support http inotify"))
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_CXX17) && defined(__GNUC__) && !defined(HAVE_CONFIG_H)
|
#if defined(HAVE_CXX17) && defined(__GNUC__) && !defined(HAVE_CONFIG_H)
|
||||||
|
@ -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 */
|
#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"))
|
U_DO_PRAGMA(message ("ULib is configured with crc32 intrinsics support, so you must use the -mcrc32 g++ option for compilation"))
|
||||||
#endif
|
#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 <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -247,7 +256,7 @@ extern U_EXPORT uint32_t u_buffer_len; /* assert that u_buffer is busy if u_buff
|
||||||
|
|
||||||
/* Startup */
|
/* Startup */
|
||||||
|
|
||||||
extern U_EXPORT pid_t u_pid;
|
extern U_EXPORT pid_t u_pid;
|
||||||
extern U_EXPORT char u_pid_str[10];
|
extern U_EXPORT char u_pid_str[10];
|
||||||
extern U_EXPORT uint32_t u_pid_str_len;
|
extern U_EXPORT uint32_t u_pid_str_len;
|
||||||
extern U_EXPORT uint32_t u_progname_len;
|
extern U_EXPORT uint32_t u_progname_len;
|
||||||
|
|
|
@ -5711,7 +5711,7 @@ loop: (void) nodog_rec->sendRequestToNodog(U_CONSTANT_TO_PARAM("check"), 0);
|
||||||
{
|
{
|
||||||
db_nodog->callForAllEntryWithVector(WiAuthNodog::checkAccessPoint);
|
db_nodog->callForAllEntryWithVector(WiAuthNodog::checkAccessPoint);
|
||||||
|
|
||||||
if ((U_SRV_CNT_USR4++ % 10) == 0) resync();
|
if ((U_SRV_CNT_WIAUTH++ % 10) == 0) resync();
|
||||||
}
|
}
|
||||||
|
|
||||||
USSIPlugIn::setAlternativeResponse();
|
USSIPlugIn::setAlternativeResponse();
|
||||||
|
|
|
@ -40,13 +40,9 @@
|
||||||
|
|
||||||
// File-permission-bit symbols
|
// File-permission-bit symbols
|
||||||
|
|
||||||
#define U_PERM__rw_r__r__ 0644
|
#define PERM_FILE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) // rw_rw_r__
|
||||||
#define U_PERM__r________ 0400
|
#define PERM_FIFO (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) // rw_rw_rw_
|
||||||
#define U_PERM__r__r__r__ 0444
|
#define PERM_DIRECTORY S_IRWXU // rwx
|
||||||
#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_DIRECTORY S_IRWXU // rwx
|
|
||||||
|
|
||||||
// NB: the UString pathname maybe not writeable so path_relativ[path_relativ_len] maybe != '\0' (not null-terminate)...
|
// 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)
|
// 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)
|
U_TRACE(1, "UFile::mkfifo(%S,%d)", _pathname, mode)
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,8 @@ class USSLSocket;
|
||||||
class USSIPlugIn;
|
class USSIPlugIn;
|
||||||
class UWebSocket;
|
class UWebSocket;
|
||||||
class USocketExt;
|
class USocketExt;
|
||||||
|
class USSEClient;
|
||||||
|
class USSEThread;
|
||||||
class Application;
|
class Application;
|
||||||
class UTimeThread;
|
class UTimeThread;
|
||||||
class UFileConfig;
|
class UFileConfig;
|
||||||
|
@ -321,6 +323,13 @@ public:
|
||||||
sem_t lock_ocsp_staple;
|
sem_t lock_ocsp_staple;
|
||||||
# endif
|
# endif
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
# endif
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
||||||
|
sem_t lock_sse;
|
||||||
|
# ifdef USE_LIBSSL
|
||||||
|
sem_t lock_sse_ssl;
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
# if defined(U_LINUX) && defined(ENABLE_THREAD)
|
# 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_USR7 UServer_Base::ptr_shared_data->cnt_usr7
|
||||||
#define U_SRV_CNT_USR8 UServer_Base::ptr_shared_data->cnt_usr8
|
#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_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_MY_LOAD UServer_Base::ptr_shared_data->my_load
|
||||||
#define U_SRV_FLAG_SIGTERM UServer_Base::ptr_shared_data->flag_sigterm
|
#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
|
#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_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_USER1 &(UServer_Base::ptr_shared_data->lock_user1)
|
||||||
#define U_SRV_LOCK_USER2 &(UServer_Base::ptr_shared_data->lock_user2)
|
#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_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_RDB_SERVER &(UServer_Base::ptr_shared_data->lock_rdb_server)
|
||||||
#define U_SRV_LOCK_SSL_SESSION &(UServer_Base::ptr_shared_data->lock_ssl_session)
|
#define U_SRV_LOCK_SSL_SESSION &(UServer_Base::ptr_shared_data->lock_ssl_session)
|
||||||
|
@ -637,6 +652,109 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
// DEBUG
|
||||||
|
|
||||||
#if defined(DEBUG) && defined(U_STDCPP_ENABLE)
|
#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);
|
static bool checkHitStats(const char* key, uint32_t key_len, uint32_t interval, uint32_t count);
|
||||||
#endif
|
#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);
|
UServer_Base(UFileConfig* pcfg = U_NULLPTR);
|
||||||
virtual ~UServer_Base();
|
virtual ~UServer_Base();
|
||||||
|
|
||||||
|
@ -976,6 +1122,8 @@ private:
|
||||||
friend class USSIPlugIn;
|
friend class USSIPlugIn;
|
||||||
friend class UWebSocket;
|
friend class UWebSocket;
|
||||||
friend class USocketExt;
|
friend class USocketExt;
|
||||||
|
friend class USSEClient;
|
||||||
|
friend class USSEThread;
|
||||||
friend class Application;
|
friend class Application;
|
||||||
friend class UTimeThread;
|
friend class UTimeThread;
|
||||||
friend class UHttpPlugIn;
|
friend class UHttpPlugIn;
|
||||||
|
|
|
@ -1840,28 +1840,10 @@ public:
|
||||||
// The `find' function searches string for a specified string (possibly a single character) and returns
|
// 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
|
// 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 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(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)
|
// 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
|
// and returns its starting position. You can supply the parameter pos to specify the position where search must begin
|
||||||
|
|
||||||
|
|
|
@ -679,55 +679,27 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
#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)
|
||||||
|
|
||||||
U_RETURN(last_event_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
UServer_Base::eventSSE(U_CONSTANT_TO_PARAM("DEL %v\n"), UServer_Base::sse_id->rep);
|
||||||
|
|
||||||
|
UServer_Base::endNewChild(); // no return
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
@ -1399,8 +1371,6 @@ private:
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UHTTP::checkForCompression(%u)", size)
|
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)
|
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)
|
if (size > U_MIN_SIZE_FOR_DEFLATE)
|
||||||
|
|
|
@ -211,13 +211,9 @@ AC_DEFUN([AC_COMPILATION_OPTIONS],[
|
||||||
|
|
||||||
AC_MSG_CHECKING(if you want to enable Server-Sent Events support)
|
AC_MSG_CHECKING(if you want to enable Server-Sent Events support)
|
||||||
AC_ARG_ENABLE(SSE,
|
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 -z "$enable_SSE"; then
|
||||||
if test "$USP_FLAGS" = "-DAS_cpoll_cppsp_DO"; then
|
enable_SSE="no"
|
||||||
enable_SSE="no"
|
|
||||||
else
|
|
||||||
enable_SSE="yes"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
if test "$enable_SSE" = "yes"; then
|
if test "$enable_SSE" = "yes"; then
|
||||||
AC_DEFINE(U_SSE_ENABLE, 1, [enable Server-Sent Events support])
|
AC_DEFINE(U_SSE_ENABLE, 1, [enable Server-Sent Events support])
|
||||||
|
|
|
@ -2309,8 +2309,8 @@ int UNoCatPlugIn::handlerFork()
|
||||||
|
|
||||||
UString msg(300U), output(U_CAPACITY), allowed_web_hosts(U_CAPACITY);
|
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);
|
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_USR9 = u_pid;
|
U_SRV_CNT_NOCAT = u_pid;
|
||||||
|
|
||||||
for (i = 0, n = vauth_url->size(); i < n; ++i)
|
for (i = 0, n = vauth_url->size(); i < n; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,7 +123,13 @@ public:
|
||||||
|
|
||||||
if (pos != U_NOT_FOUND)
|
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
|
# ifdef DEBUG
|
||||||
|
@ -152,8 +158,7 @@ public:
|
||||||
* <!--#vcode ... -->
|
* <!--#vcode ... -->
|
||||||
* <!--#pcode ... -->
|
* <!--#pcode ... -->
|
||||||
* <!--#lcode ... -->
|
* <!--#lcode ... -->
|
||||||
* <!--#ssecode ... -->
|
* <!--#sse ... -->
|
||||||
* <!--#sseloop ... -->
|
|
||||||
* <!--#number ... -->
|
* <!--#number ... -->
|
||||||
* <!--#puts ... -->
|
* <!--#puts ... -->
|
||||||
* <!--#xmlputs ... -->
|
* <!--#xmlputs ... -->
|
||||||
|
@ -249,7 +254,7 @@ public:
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(token)
|
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)
|
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);
|
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_ASSERT(http_header.empty())
|
||||||
U_INTERNAL_ASSERT_EQUALS(bfirst_pass, false)
|
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)
|
(void) http_header.append(U_CONSTANT_TO_PARAM(
|
||||||
|
|
||||||
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(
|
|
||||||
"\n\tif (U_http_accept_len != U_CONSTANT_SIZE(\"text/event-stream\") ||"
|
"\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\t u_get_unalignedp64(U_http_info.accept) != U_MULTICHAR_CONSTANT64('t','e','x','t','/','e','v','e'))"
|
||||||
"\n\telse"
|
|
||||||
"\n\t\t{"
|
"\n\t\t{"
|
||||||
"\n\t\tUHTTP::bsse = true;"
|
"\n\t\tUHTTP::setBadRequest();"
|
||||||
"\n\t\t(void) UServer_Base::csocket->shutdown(SHUT_RD);"
|
"\n\t\treturn;"
|
||||||
"\n\t\tU_INTERNAL_ASSERT_EQUALS(UClientImage_Base::wbuffer->findEndHeader(),false)"
|
"\n\t\t}"));
|
||||||
"\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
|
|
||||||
{
|
|
||||||
U_ASSERT(sseloop.empty())
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(bfirst_pass, false)
|
|
||||||
|
|
||||||
setDirectiveItem(directive, U_CONSTANT_SIZE("sseloop"));
|
setDirectiveItem(directive, U_CONSTANT_SIZE("sse"));
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(token)
|
if (token.empty())
|
||||||
|
|
||||||
uint32_t sz = token.size();
|
|
||||||
const char* data = token.data();
|
|
||||||
|
|
||||||
uint32_t sse_time_to_sleep = 1;
|
|
||||||
|
|
||||||
if (*data == ':')
|
|
||||||
{
|
{
|
||||||
++data;
|
(void) declaration.reserve(100U + basename_sz);
|
||||||
|
|
||||||
sse_time_to_sleep = u_strtoulp(&data);
|
declaration.snprintf(U_CONSTANT_TO_PARAM("\n#ifdef USE_LIBSSL\nstatic UString sse_%.*s() { return UString::getStringNull(); }\n#endif"), basename_sz, basename_ptr);
|
||||||
|
|
||||||
sz = token.remain(data);
|
(void) sseloop.append(U_CONSTANT_TO_PARAM("\n\t\tif (UHTTP::sse_func) UHTTP::readSSE(-1);"));
|
||||||
|
|
||||||
|
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 sz = token.size(), sse_timeout = 1000;
|
||||||
|
|
||||||
char buffer[200];
|
if (*data == ':')
|
||||||
|
{
|
||||||
|
++data;
|
||||||
|
|
||||||
(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));
|
sse_timeout *= u_strtoulp(&data);
|
||||||
|
|
||||||
sseloop = UStringExt::substitute(data, sz, '\n', U_CONSTANT_TO_PARAM("\n\t"));
|
sz = token.remain(data);
|
||||||
|
}
|
||||||
|
|
||||||
(void) output2.reserve(200U + sseloop.size());
|
UString sse_code = UStringExt::substitute(data, sz, '\n', U_CONSTANT_TO_PARAM("\n\t"));
|
||||||
|
|
||||||
output2.snprintf(U_CONSTANT_TO_PARAM(
|
(void) declaration.reserve(100U + basename_sz + basename_sz + sse_code.size());
|
||||||
"\n\treturn;\n\t\n"
|
|
||||||
"sseloop:"
|
declaration.snprintf_add(U_CONSTANT_TO_PARAM(
|
||||||
"\n\tsse_time_to_sleep.nanosleep();"
|
"\nstatic UString sse_%.*s()"
|
||||||
"\n\t%v"
|
"\n{"
|
||||||
"\n\tgoto sseloop;"), sseloop.rep);
|
"\n\tU_TRACE(5, \"::sse_%.*s()\")"
|
||||||
|
"\n\tUString sse_data;"
|
||||||
|
"\n\t%v"
|
||||||
|
"\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)
|
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 ... -->
|
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();
|
processUSP();
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
|
@ -699,7 +702,6 @@ loop: distance = t.getDistance();
|
||||||
bsighup, // usp_sighup
|
bsighup, // usp_sighup
|
||||||
bfork; // usp_fork
|
bfork; // usp_fork
|
||||||
|
|
||||||
const char* ptr0 = (sseloop ? "\n\t\tif (UHTTP::bsse) goto sseloop;\n" : "");
|
|
||||||
char ptr1[100] = { '\0' };
|
char ptr1[100] = { '\0' };
|
||||||
char ptr2[100] = { '\0' };
|
char ptr2[100] = { '\0' };
|
||||||
char ptr3[100] = { '\0' };
|
char ptr3[100] = { '\0' };
|
||||||
|
@ -707,7 +709,7 @@ loop: distance = t.getDistance();
|
||||||
char ptr5[100] = { '\0' };
|
char ptr5[100] = { '\0' };
|
||||||
const char* ptr6 = "";
|
const char* ptr6 = "";
|
||||||
const char* ptr7 = "";
|
const char* ptr7 = "";
|
||||||
|
|
||||||
# ifndef U_CACHE_REQUEST_DISABLE
|
# ifndef U_CACHE_REQUEST_DISABLE
|
||||||
if (usp.c_char(4) == '#' &&
|
if (usp.c_char(4) == '#' &&
|
||||||
u__isspace(usp.c_char(5)) &&
|
u__isspace(usp.c_char(5)) &&
|
||||||
|
@ -717,11 +719,6 @@ loop: distance = t.getDistance();
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
UString basename = UStringExt::basename(filename);
|
|
||||||
|
|
||||||
uint32_t basename_sz = basename.size() - U_CONSTANT_SIZE(".usp");
|
|
||||||
const char* basename_ptr = basename.data();
|
|
||||||
|
|
||||||
if (declaration)
|
if (declaration)
|
||||||
{
|
{
|
||||||
binit = (U_STRING_FIND(declaration, 0, "static void usp_init_") != U_NOT_FOUND);
|
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"));
|
(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(
|
result.snprintf(U_CONSTANT_TO_PARAM(
|
||||||
"// %.*s.cpp - dynamic page translation (%.*s.usp => %.*s.cpp)\n"
|
"// %.*s.cpp - dynamic page translation (%.*s.usp => %.*s.cpp)\n"
|
||||||
|
@ -818,7 +815,7 @@ loop: distance = t.getDistance();
|
||||||
"\t\n"
|
"\t\n"
|
||||||
"\tif (param)\n"
|
"\tif (param)\n"
|
||||||
"\t\t{\n"
|
"\t\t{\n"
|
||||||
"%s"
|
"%v"
|
||||||
"%s"
|
"%s"
|
||||||
"%s"
|
"%s"
|
||||||
"%s"
|
"%s"
|
||||||
|
@ -844,7 +841,7 @@ loop: distance = t.getDistance();
|
||||||
basename_sz, basename_ptr,
|
basename_sz, basename_ptr,
|
||||||
basename_sz, basename_ptr,
|
basename_sz, basename_ptr,
|
||||||
vars.rep,
|
vars.rep,
|
||||||
ptr0,
|
sseloop.rep,
|
||||||
ptr1,
|
ptr1,
|
||||||
ptr2,
|
ptr2,
|
||||||
ptr3,
|
ptr3,
|
||||||
|
@ -869,6 +866,8 @@ private:
|
||||||
UTokenizer t;
|
UTokenizer t;
|
||||||
UVector<UString> vdefine;
|
UVector<UString> vdefine;
|
||||||
UString pinclude, usp, token, output0, output1, output2, declaration, vcode, http_header, sseloop, vars;
|
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;
|
bool bvar, bsession, bstorage, bfirst_pass, is_html, test_if_html, bpreprocessing_failed;
|
||||||
|
|
||||||
U_DISALLOW_COPY_AND_ASSIGN(Application)
|
U_DISALLOW_COPY_AND_ASSIGN(Application)
|
||||||
|
|
|
@ -1339,6 +1339,306 @@ private:
|
||||||
ULock* UServer_Base::lock_ocsp_staple;
|
ULock* UServer_Base::lock_ocsp_staple;
|
||||||
UThread* UServer_Base::pthread_ocsp;
|
UThread* UServer_Base::pthread_ocsp;
|
||||||
# endif
|
# 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
|
#endif
|
||||||
|
|
||||||
#ifdef U_LINUX
|
#ifdef U_LINUX
|
||||||
|
@ -1443,9 +1743,17 @@ UServer_Base::~UServer_Base()
|
||||||
|
|
||||||
USSLSocket::cleanupStapling();
|
USSLSocket::cleanupStapling();
|
||||||
|
|
||||||
if (UServer_Base::lock_ocsp_staple) delete UServer_Base::lock_ocsp_staple;
|
if (lock_ocsp_staple) delete lock_ocsp_staple;
|
||||||
}
|
}
|
||||||
# endif
|
# 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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3099,6 +3407,45 @@ next:
|
||||||
initEvasive();
|
initEvasive();
|
||||||
#endif
|
#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();
|
if (cfg) cfg->clear();
|
||||||
|
|
||||||
UInterrupt::syscall_restart = false;
|
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 defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
if (pthread_ocsp) pthread_ocsp->suspend();
|
if (pthread_ocsp) pthread_ocsp->suspend();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
||||||
|
if (pthread_sse) pthread_sse->suspend();
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
|
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
|
||||||
|
@ -3169,9 +3520,13 @@ void UServer_Base::sendSignalToAllChildren(int signo, sighandler_t handler)
|
||||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||||
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->resume();
|
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->resume();
|
||||||
|
|
||||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
if (pthread_ocsp) pthread_ocsp->resume();
|
if (pthread_ocsp) pthread_ocsp->resume();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
||||||
|
if (pthread_sse) pthread_sse->resume();
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4214,6 +4569,10 @@ void UServer_Base::run()
|
||||||
|
|
||||||
if (proc->child())
|
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)
|
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))
|
# if defined(HAVE_SCHED_GETAFFINITY) && (!defined(U_SERVER_CAPTIVE_PORTAL) || defined(ENABLE_THREAD))
|
||||||
|
@ -4412,6 +4771,10 @@ stop:
|
||||||
closeLog();
|
closeLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
||||||
|
if (pthread_sse) sse_vclient->clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
pthis->deallocate();
|
pthis->deallocate();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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)
|
U_TRACE(1, "UNotifier::read(%d,%p,%d,%d)", fd, buffer, count, timeoutMS)
|
||||||
|
|
||||||
if (fd < 0 &&
|
U_INTERNAL_ASSERT_DIFFERS(fd, -1)
|
||||||
timeoutMS != -1 &&
|
|
||||||
|
if (timeoutMS != -1 &&
|
||||||
waitForRead(fd, timeoutMS) != 1)
|
waitForRead(fd, timeoutMS) != 1)
|
||||||
{
|
{
|
||||||
U_RETURN(-1);
|
U_RETURN(-1);
|
||||||
|
|
|
@ -37,13 +37,16 @@ bool UProcess::fork()
|
||||||
|
|
||||||
_pid = U_FORK();
|
_pid = U_FORK();
|
||||||
|
|
||||||
if (child()) u_setPid();
|
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
|
// inlining failed in call to 'UProcess::setStdInOutErr(bool, bool, bool)': call is unlikely and code size would grow
|
||||||
|
|
|
@ -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
|
// 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
|
// 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
|
__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)
|
U_TRACE(0, "UString::find(%.*S,%u,%u,%u)", s_len, s, pos, s_len, how_much)
|
||||||
|
@ -1406,9 +1429,14 @@ __pure uint32_t UString::find(const char* s, uint32_t pos, uint32_t s_len, uint3
|
||||||
const char* str = rep->str;
|
const char* str = rep->str;
|
||||||
const char* ptr = (const char*) u_find(str + pos, n, s, s_len);
|
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(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
|
__pure uint32_t UString::findnocase(const char* s, uint32_t pos, uint32_t s_len, uint32_t how_much) const
|
||||||
|
|
|
@ -169,7 +169,9 @@ UVector<UIPAllow*>* UHTTP::vallow_IP;
|
||||||
URDBObjectHandler<UDataStorage*>* UHTTP::db_session_ssl;
|
URDBObjectHandler<UDataStorage*>* UHTTP::db_session_ssl;
|
||||||
#endif
|
#endif
|
||||||
#ifdef U_SSE_ENABLE // SERVER SENT EVENTS (SSE)
|
#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
|
#endif
|
||||||
#ifdef USE_LOAD_BALANCE
|
#ifdef USE_LOAD_BALANCE
|
||||||
UClient<USSLSocket>* UHTTP::client_http;
|
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)
|
U_ClientImage_request, U_http_info.nResponseCode, U_ClientImage_request_is_cached, U_http_info.startHeader)
|
||||||
|
|
||||||
#ifdef U_SSE_ENABLE
|
#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())
|
if (UServer_Base::startParallelization())
|
||||||
{
|
{
|
||||||
// parent
|
// parent
|
||||||
|
|
||||||
bsse = false;
|
sse_func = U_NULLPTR;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5334,6 +5332,24 @@ void UHTTP::setEndRequestProcessing()
|
||||||
|
|
||||||
U_SET_MODULE_NAME(sse);
|
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);
|
usp->runDynamicPage(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7082,15 +7098,176 @@ void UHTTP::setUnAuthorized()
|
||||||
// end HTTP main error message
|
// 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()
|
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_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_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)
|
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;
|
char* ptr;
|
||||||
const char* pEndHeader;
|
const char* pEndHeader;
|
||||||
uint32_t clength = UClientImage_Base::wbuffer->size();
|
uint32_t clength = UClientImage_Base::wbuffer->size();
|
||||||
|
@ -7128,19 +7305,6 @@ void UHTTP::setDynamicResponse()
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef U_SSE_ENABLE
|
|
||||||
U_INTERNAL_DUMP("bsse = %b", bsse)
|
|
||||||
|
|
||||||
if (bsse)
|
|
||||||
{
|
|
||||||
*ext = *UClientImage_Base::wbuffer;
|
|
||||||
|
|
||||||
handlerResponse();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if (bcompress == false)
|
if (bcompress == false)
|
||||||
{
|
{
|
||||||
(void) UClientImage_Base::body->replace(pEndHeader + U_http_info.endHeader, clength);
|
(void) UClientImage_Base::body->replace(pEndHeader + U_http_info.endHeader, clength);
|
||||||
|
|
|
@ -1,27 +1,12 @@
|
||||||
<!--#declaration
|
<!--#sse:10
|
||||||
static uint32_t counter;
|
static double price = 1.2;
|
||||||
|
|
||||||
static UString getPrice()
|
if (U_SRV_SSE_CNT1)
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(5, "::getPrice()")
|
price = price + (double)rand() / RAND_MAX * 2.0 - 1;
|
||||||
|
|
||||||
static double price = 1.2;
|
if (price <= 0.01) price = 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
if (counter++)
|
sse_data = UStringExt::numberToString(price);
|
||||||
{
|
|
||||||
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());
|
|
||||||
-->
|
-->
|
||||||
|
|
2
tests/examples/sse_example/get_ticker1.usp
Normal file
2
tests/examples/sse_example/get_ticker1.usp
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<!--#sse
|
||||||
|
-->
|
|
@ -1,7 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<script type="text/javascript" src="jquery.min.js"></script>
|
|
||||||
<title>SSE example</title>
|
<title>SSE example</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
24
tests/examples/sse_example/index1.html
Normal file
24
tests/examples/sse_example/index1.html
Normal 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>
|
4
tests/examples/sse_example/jquery.min.js
vendored
4
tests/examples/sse_example/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
6
tests/examples/sse_example/set_ticker.usp
Normal file
6
tests/examples/sse_example/set_ticker.usp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!--#args
|
||||||
|
value("13.333");
|
||||||
|
-->
|
||||||
|
<!--#code
|
||||||
|
UServer_Base::sendToAllSSE(value);
|
||||||
|
-->
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
(cd benchmark; rm -f db; creat_link FrameworkBenchmarks/ULib/db db)
|
(cd benchmark; rm -f db; creat_link FrameworkBenchmarks/ULib/db db)
|
||||||
|
|
||||||
DOC_ROOT=docroot
|
#DOC_ROOT=docroot
|
||||||
#DOC_ROOT=sse_example
|
DOC_ROOT=sse_example
|
||||||
#DOC_ROOT=ruby/blog
|
#DOC_ROOT=ruby/blog
|
||||||
#DOC_ROOT=benchmark/docroot
|
#DOC_ROOT=benchmark/docroot
|
||||||
#DOC_ROOT=ShivShankarDayal/docroot
|
#DOC_ROOT=ShivShankarDayal/docroot
|
||||||
|
@ -18,10 +18,12 @@ rm -f tmp/usp_compile.sh.err /tmp/*.hpack.* \
|
||||||
|
|
||||||
UTRACE="0 50M 0"
|
UTRACE="0 50M 0"
|
||||||
UTRACE_SIGNAL="0 50M 0"
|
UTRACE_SIGNAL="0 50M 0"
|
||||||
|
UTRACE_FOLDER=/tmp
|
||||||
|
TMPDIR=/tmp
|
||||||
#UOBJDUMP="0 10M 100"
|
#UOBJDUMP="0 10M 100"
|
||||||
#USIMERR="error.sim"
|
#USIMERR="error.sim"
|
||||||
#UMEMUSAGE=yes
|
#UMEMUSAGE=yes
|
||||||
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL UMEMUSAGE
|
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL UMEMUSAGE UTRACE_FOLDER TMPDIR
|
||||||
|
|
||||||
SOCK1=tmp/fcgi.socket
|
SOCK1=tmp/fcgi.socket
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ userver {
|
||||||
#LOAD_BALANCE_CLUSTER 10.30.0.1,10.30.0.2
|
#LOAD_BALANCE_CLUSTER 10.30.0.1,10.30.0.2
|
||||||
#LOAD_BALANCE_DEVICE_NETWORK enp0s20u1
|
#LOAD_BALANCE_DEVICE_NETWORK enp0s20u1
|
||||||
#LOAD_BALANCE_LOADAVG_THRESHOLD 4.0
|
#LOAD_BALANCE_LOADAVG_THRESHOLD 4.0
|
||||||
PREFORK_CHILD 0
|
PREFORK_CHILD 2
|
||||||
#CRASH_COUNT 1
|
#CRASH_COUNT 1
|
||||||
#CRASH_EMAIL_NOTIFY mail.unirel.com:stefano.casazza@unirel.com
|
#CRASH_EMAIL_NOTIFY mail.unirel.com:stefano.casazza@unirel.com
|
||||||
#DOS_SITE_COUNT 1
|
#DOS_SITE_COUNT 1
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
. ../.function
|
. ../.function
|
||||||
|
|
||||||
|
# set -x
|
||||||
|
|
||||||
|
## web_server_proxy.test -- Test web server proxy feature
|
||||||
|
|
||||||
|
start_msg web_server_proxy
|
||||||
|
|
||||||
DOC_ROOT1=benchmark/docroot
|
DOC_ROOT1=benchmark/docroot
|
||||||
DOC_ROOT2=docroot
|
DOC_ROOT2=docroot
|
||||||
|
|
||||||
|
@ -87,3 +93,6 @@ pkill userver_tcp 2>/dev/null
|
||||||
|
|
||||||
cat err/userver_tcp.err >> err/webserver_proxy.err
|
cat err/userver_tcp.err >> err/webserver_proxy.err
|
||||||
rm err/userver_tcp.err
|
rm err/userver_tcp.err
|
||||||
|
|
||||||
|
# Test against expected output
|
||||||
|
test_output_wc l webserver_proxy
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
"A JSON payload should be an object or array, not a string."
|
|
|
@ -1 +0,0 @@
|
||||||
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
|
|
|
@ -1 +0,0 @@
|
||||||
["Unclosed array"
|
|
|
@ -1 +0,0 @@
|
||||||
{unquoted_key: "keys must be quoted"}
|
|
|
@ -1 +0,0 @@
|
||||||
["extra comma",]
|
|
|
@ -1 +0,0 @@
|
||||||
["double extra comma",,]
|
|
|
@ -1 +0,0 @@
|
||||||
[ , "<-- missing value"]
|
|
|
@ -1 +0,0 @@
|
||||||
["Comma after the close"],
|
|
|
@ -1 +0,0 @@
|
||||||
["Extra close"]]
|
|
|
@ -1 +0,0 @@
|
||||||
{"Extra comma": true,}
|
|
|
@ -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": "" \u0022 %22 0x22 034 "",
|
|
||||||
"\/\"\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"]
|
|
|
@ -1 +0,0 @@
|
||||||
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"JSON Test Pattern pass3": {
|
|
||||||
"The outermost value": "must be an object or array.",
|
|
||||||
"In this test": "It is an object."
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
@ -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
|
@ -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
|
|
||||||
}
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include <ulib/file.h>
|
#include <ulib/file.h>
|
||||||
#include <ulib/base/hash.h>
|
#include <ulib/base/hash.h>
|
||||||
#include <ulib/utility/dir_walk.h>
|
#include <ulib/utility/dir_walk.h>
|
||||||
|
/*
|
||||||
|
#include <ulib/net/server/server.h>
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#define _GLIBCXX_USE_C99_DYNAMIC 1
|
#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 )
|
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
|
int
|
||||||
U_EXPORT main (int argc, char* argv[])
|
U_EXPORT main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -242,6 +338,11 @@ U_EXPORT main (int argc, char* argv[])
|
||||||
|
|
||||||
U_TRACE(5,"main(%d)",argc)
|
U_TRACE(5,"main(%d)",argc)
|
||||||
|
|
||||||
|
/*
|
||||||
|
check_bound(80);
|
||||||
|
exit(0);
|
||||||
|
*/
|
||||||
|
|
||||||
UString tmp;
|
UString tmp;
|
||||||
|
|
||||||
#if defined(U_STDCPP_ENABLE) && defined(HAVE_CXX11) && defined(U_COMPILER_RANGE_FOR)
|
#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
|
// EXTENSION
|
||||||
|
|
||||||
{
|
{
|
||||||
UDirWalk dirwalk(0, U_CONSTANT_TO_PARAM("?db.*test*"));
|
UDirWalk dirwalk(U_NULLPTR, U_CONSTANT_TO_PARAM("?db.*test*"));
|
||||||
|
|
||||||
n = dirwalk.walk(y);
|
n = dirwalk.walk(y);
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
|
|
||||||
start_msg vector
|
start_msg vector
|
||||||
|
|
||||||
#UTRACE="0 50M -1"
|
#UTRACE="0 50M 0"
|
||||||
#UOBJDUMP="0 1M 10"
|
#UOBJDUMP="0 1M 10"
|
||||||
#USIMERR="error.sim"
|
#USIMERR="error.sim"
|
||||||
export UTRACE UOBJDUMP USIMERR
|
export UTRACE UOBJDUMP USIMERR
|
||||||
|
|
||||||
start_prg vector inp/words.lst < inp/vector.input
|
start_prg vector inp/words.lst < inp/vector.input
|
||||||
|
|
||||||
tr ' ' '\n' < vector.sort > word.sort
|
tr ' ' '\n' < vector.sort > word.sort
|
||||||
rm -f vector.sort
|
rm -f vector.sort
|
||||||
|
|
||||||
# Test against expected output
|
# Test against expected output
|
||||||
test_output_diff vector word.sort
|
test_output_diff vector word.sort
|
||||||
|
|
Loading…
Reference in New Issue
Block a user