<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>分享 &#8211; 寂静花园</title>
	<atom:link href="https://www.addesp.com/archives/category/%E5%88%86%E4%BA%AB/feed" rel="self" type="application/rss+xml" />
	<link>https://www.addesp.com</link>
	<description>寂静中交织着热情</description>
	<lastBuildDate>Thu, 06 Jan 2022 03:28:42 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>
	<item>
		<title>Fluent Reader — 开源的 RSS 阅读器</title>
		<link>https://www.addesp.com/archives/4967</link>
					<comments>https://www.addesp.com/archives/4967#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Fri, 30 Jul 2021 15:16:17 +0000</pubDate>
				<category><![CDATA[软件分享]]></category>
		<category><![CDATA[RSS]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=4967</guid>

					<description><![CDATA[支持 Windows（含 Microsoft Store）、macOS 和 Linux 的开源 RSS 阅读器，支持中文。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">简介</h2>



<p class="wp-block-paragraph">支持 Windows（含 Microsoft Store）、macOS 和 Linux 的开源 RSS 阅读器，<strong>支持中文</strong>。</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://cdn.jsdelivr.net/gh/yang991178/fluent-reader@master/docs/imgs/screenshot.jpg" alt="Fluent Reader" class="wp-image-4968"/><figcaption>Fluent Reader</figcaption></figure>



<h2 class="wp-block-heading">相关链接</h2>



<ul class="wp-block-list"><li>官方网站：<a href="https://hyliu.me/fluent-reader/" target="_blank" rel="noreferrer noopener">https://hyliu.me/fluent-reader/</a></li><li>Github：<a href="https://github.com/yang991178/fluent-reader" target="_blank" rel="noreferrer noopener">https://github.com/yang991178/fluent-reader</a></li></ul>



<h2 class="wp-block-heading">功能</h2>



<ul class="wp-block-list"><li>支持夜间模式。</li><li>可以从本地阅读，亦可于 Fever 或兼容 Google Reader API 的服务同步阅读内容。</li><li>可以从一些 RSS 服务中同步，包括但不限于 Inoreader, Feedbin, The Old Reader, BazQux Reader。</li><li>支持导入/导出 OPML 文件，用来备份/恢复订阅源。</li><li>支持导入/导出程序的配置和数据，用来备份/恢复程序的配置和已经下载的订阅源内容。</li><li>支持使用内置的阅读器或者加载源网页。</li><li>支持使用正则表达式搜索文章或按照阅读状态过滤。</li><li>支持通过文件夹来管理你的订阅。</li><li>单按键的快捷键。</li><li>后台获取文章并发送通知。</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/4967/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>nginx 防火墙模块开发总结</title>
		<link>https://www.addesp.com/archives/2876</link>
					<comments>https://www.addesp.com/archives/2876#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Mon, 21 Dec 2020 11:01:33 +0000</pubDate>
				<category><![CDATA[随笔]]></category>
		<category><![CDATA[项目分享]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[防火墙]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=2876</guid>

					<description><![CDATA[我起初并没有写这篇文章的意思，因为无论是从难度还是代码复杂度来说这个项目在我写过的项目里只能算中等，但是它却有一个特点，就是我的第一个专门开发出来供他人使用并且希望被他人使用的项目。先前的项目要不然不能公开，要不然个人属性非常强，不适合他人使用。所以这篇文章主要是以纪念为目的的。]]></description>
										<content:encoded><![CDATA[<div class='github-info-card github-info-card-full card shadow-sm' data-author='ADD-SP' data-project='ngx_waf' githubinfo-card-id='4919051583' data-getdata='frontend' data-description='' data-stars='' data-forks=''><div class='github-info-card-header'><a href='https://github.com/' ref='nofollow' target='_blank' title='Github' no-pjax><span><i class='fa fa-github'></i> GitHub</span></a></div><div class='github-info-card-body'>
			<div class='github-info-card-name-a'>
				<a href='https://github.com/ADD-SP/ngx_waf' target='_blank' no-pjax>
					<span class='github-info-card-name'>ADD-SP/ngx_waf</span>
				</a>
				</div>
			<div class='github-info-card-description'></div>
		</div><div class='github-info-card-bottom'>
				<span class='github-info-card-meta github-info-card-meta-stars'>
					<i class='fa fa-star'></i> <span class='github-info-card-stars'></span>
				</span>
				<span class='github-info-card-meta github-info-card-meta-forks'>
					<i class='fa fa-code-fork'></i> <span class='github-info-card-forks'></span>
				</span>
			</div></div>



<h2 class="wp-block-heading">为什么要写这篇文章？</h2>



<p class="wp-block-paragraph">我起初并没有写这篇文章的意思，因为无论是从难度还是代码复杂度来说这个项目在我写过的项目里只能算中等，但是它却有一个特点，就是我的第一个专门开发出来供他人使用并且希望被他人使用的项目。先前的项目要不然不能公开，要不然个人属性非常强，不适合他人使用。所以这篇文章主要是以纪念为目的的。</p>



<h2 class="wp-block-heading">为什么要开启这个项目？</h2>



<p class="wp-block-paragraph">那段时间我的站点有时会打不开，起初以为是网络问题，后来越来越严重，进入后台才发现数据库 IO 拉满了。看了看 nginx 的日志才发现站点被疯扫，于是打算做点什么。</p>



<p class="wp-block-paragraph">我先从网上搜索到了一些基础的拦截扫站的规则，直接 copy 到 <code>nginx.conf</code> 里就能用，但是这些规则都特别多，而且杂，直接丢到配置文件里会大大降低配置的可读性，所以当初就被否了。</p>



<p class="wp-block-paragraph">后来我拉黑了一些 IP，不过这也就一时起作用，过段时间换了 IP 继续来扫。补救措施是用 <code>whois</code> 找到 IP 地址快直接全部拉黑。但是这导致了一些误伤，于是这个方案也被否了。</p>



<p class="wp-block-paragraph">然后我找到了 <a href="https://github.com/loveshell/ngx_lua_waf" target="_blank" rel="noreferrer noopener">ngx_lua_waf</a>，用了一段觉得还行，但是也发现了一些缺陷，最明显的就是拉黑 IP 的时候只能拉黑单个 IP，而不能拉黑一个地址块。但是这个模块大概已经停止维护了，不能指望作者更新了。</p>



<p class="wp-block-paragraph">然后在 Github 上看了几个防火墙模块，要不然功能不全，要不然使用复杂，于是萌生了自己写模块的想法。</p>



<h2 class="wp-block-heading">为什么用 C 语言开发？</h2>



<p class="wp-block-paragraph">主要是因为这样可以不用安装 <a href="https://github.com/openresty/lua-nginx-module" target="_blank" rel="noreferrer noopener">lua_nginx_module</a>，其次是因为 C 的执行效率理论上要高于 lua，因为 lua 需要启动一个 VM。</p>



<p class="wp-block-paragraph">不过我主要考虑的是安装是否方便，性能倒不是那么看重，因为 <a href="https://github.com/openresty/lua-nginx-module" target="_blank" rel="noreferrer noopener">lua_nginx_module</a> 身经百战，性能完全可以保证。</p>



<p class="wp-block-paragraph">不过用 C 语言开发必然增加开发难度，最重要的是要自己控制内存，这类 Web 服务器上的模块一旦内存泄露、段错误啥的那麻烦就大了，不过我还是有信心不出大问题的。</p>



<h2 class="wp-block-heading">设计原则</h2>



<p class="wp-block-paragraph">只实现基础的防护，即 IP 检测、Url 检测、Get 参数检测、Cookie 检测、Post 检测、Referer 检测和 CC 防御。不会引入更复杂的功能，比如根据某个 IP 的行为进行综合判断是否拦截。</p>



<p class="wp-block-paragraph">在保证代码良好可读性的情况下提高性能。</p>



<h2 class="wp-block-heading"><a href="https://semver.org/lang/zh-CN/" target="_blank" rel="noreferrer noopener">语义化版本</a></h2>



<p class="wp-block-paragraph">说实话我之前还真没把这个当回事，但是当我打算把这个项目给别人用的时候我发现版本号似乎也能传递一些比较重要的信息，所以开发这个项目的时候我是一直遵守这个标准的。</p>



<p class="wp-block-paragraph">简单来说语义化版本将版本号分为 X.Y.Z。</p>



<ul class="wp-block-list"><li>当你做了不向下兼容的更改之后 X 要递增。</li><li>当你做了向下兼容的功能性新增的时候 Y 要递增。</li><li>当你做了向下兼容的修正时 Z 要递增。</li></ul>



<p class="wp-block-paragraph">这样版本号就可以向用户传递对应的信息，这无疑是十分有用的，最明显的就是当用户看到 X 递增的时候就会十分谨慎，因为贸然更新可能会导致现有的程序出现不兼容的情况。</p>



<h2 class="wp-block-heading">Change Log</h2>



<p class="wp-block-paragraph">作为一个打算给他人使用的项目，一个清晰的 Change Log 就是很必要的了，它可以将每次更新的内容展示出来，方便他人了解也方便自己记录。</p>



<p class="wp-block-paragraph">格式上基本遵循：<a href="https://keepachangelog.com/zh-CN/1.0.0/" target="_blank" rel="noreferrer noopener">https://keepachangelog.com/zh-CN/1.0.0/</a></p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1151" height="817" src="https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_02-51-16.webp" alt="" class="wp-image-2950"/><figcaption>效果图</figcaption></figure>



<p class="wp-block-paragraph">从效果上来看应该还算是清晰准确的 Change Log。</p>



<h2 class="wp-block-heading">开发文档</h2>



<p class="wp-block-paragraph">项目写到后期就不得不写开发文档了，首先是方便了自己，其次也是方便别人。可以从头开始写效率太低了，强烈推荐 <a href="https://www.doxygen.nl/index.html" target="_blank" rel="noreferrer noopener">doxygen</a>。这个工具可以通过代码内的注释自动生成文档，这样为源代码写注释的同时还能生成开发文档，十分方便。</p>



<p class="wp-block-paragraph">下面是对应的注释以及生成的开发文档。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="769" src="https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_03-03-19-1024x769.png" alt="" class="wp-image-2961" srcset="https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_03-03-19-1024x769.png 1024w, https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_03-03-19-300x225.png 300w, https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_03-03-19-768x577.png 768w, https://www.addesp.com/wp-content/uploads/2020/12/Snipaste_2020-12-20_03-03-19.png 1053w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>注释内容</figcaption></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="1894" height="3196" src="https://www.addesp.com/wp-content/uploads/2020/12/0.webp" alt="" class="wp-image-2963"/><figcaption>开发文档</figcaption></figure>



<p class="wp-block-paragraph">开发文档简单，清晰，还能自动生成函数调用图和被调用图等一系列图。如果觉得丑还能自定义 CSS，不过对于我这个前端困难户来说就不搞了。</p>



<h2 class="wp-block-heading">性能优化</h2>



<p class="wp-block-paragraph">性能优化的主要工作就是降低请求检查花费的时间。</p>



<h3 class="wp-block-heading">缓存</h3>



<p class="wp-block-paragraph">Url 检查、Get 参数检查、Post 检查、Cookie 检查和 Referer 检查都需要执行正则匹配，暂时没发现什么合适的方法去优化，只能一个一个地去检查。时间复杂度为 $\text{O}(nm)$，$n$ 为需要测试的正则条数，$m$ 为执行正则匹配的时间。</p>



<p class="wp-block-paragraph">不过由于本模块只会在 nginx 启动时读取规则，运行时规则不会改变，所以对于同一个 URL 无论检测多少次结果都不会变，于是本模块会缓存检查的结果，每次检查前先读取缓存，如果命中则直接取出结果，反之则走流程检查。除了 IP 检查和 Post 检查以外所有的检查都使用了缓存机制。</p>



<p class="wp-block-paragraph">缓存淘汰策略为 LRU。当缓存的内存不足时会引起频繁的淘汰，增加内存碎片。于是本模块会周期性地按照 LRU 的策略淘汰掉一定比例的缓存。</p>



<h3 class="wp-block-heading">前缀树优化</h3>



<p class="wp-block-paragraph">IP 检查很有搞头。本模块使用了一种经过修改的前缀树来改进 IP 检查的性能，见下图。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="872" height="712" src="https://www.addesp.com/wp-content/uploads/2020/12/未命名绘图.webp" alt="" class="wp-image-2981"/><figcaption>本模块所使用的前缀树</figcaption></figure>



<p class="wp-block-paragraph">从图示就可以看出此结构可以方便地处理单个 IP 的检查和 IP 地址块的检查。</p>



<p class="wp-block-paragraph">前缀树的查找时间为 $\text{O}(h)$，其中 $h$ 为树的高度。对于 IPV4 来说一共有 32 位，那么树高最多 32，IPV6 对应的树高最多为 128。那么查找时间复杂度为 $\text{O}(1)$，也就是说执行 IP 检查的时间基本上不会受到 IP 黑白名单规模的影响。</p>



<h3 class="wp-block-heading">测试</h3>



<p class="wp-block-paragraph">经过比较极限的测试，QPS 降低了约 4%，详情见<a href="https://docs.addesp.com/ngx_waf/zh-cn/guide/test.html#%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95" target="_blank" rel="noreferrer noopener" title="https://docs.addesp.com/ngx_waf/zh-cn/guide/test.html#%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95">性能测试</a>。</p>



<h2 class="wp-block-heading">我上 Trending 了！</h2>



<p class="wp-block-paragraph">2021 年 4 月 8 日晚上我发现我的项目出现在了 Github Trending（C 语言） 下，截图纪念一下。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1077" height="635" src="https://www.addesp.com/wp-content/uploads/2021/04/KK7o9cR.webp" alt="" class="wp-image-4223"/></figure>



<p class="wp-block-paragraph">希望不要明天起来就没了，多撑几天吧。</p>



<p class="wp-block-paragraph">第二天晚更新：博主已经凉了，散了吧。</p>



<h2 class="wp-block-heading">验证码</h2>



<p class="wp-block-paragraph">这里的验证码特指用于人机验证的验证码，比如滑块解锁等，也就是我们通常所说的 <a href="https://baike.baidu.com/item/CAPTCHA/9630117" target="_blank" rel="noreferrer noopener nofollow" title="https://baike.baidu.com/item/CAPTCHA/9630117">CAPTCHA</a>，比较有名的就是 reCAPTCHA。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1576" height="992" src="https://www.addesp.com/wp-content/uploads/2022/01/5f7614c93b38651b67b75add_931071.webp" alt="" class="wp-image-5554"/><figcaption>reCAPTCHA</figcaption></figure>



<p class="wp-block-paragraph">目前已经集成了 reCAPTCHA 的全部种类的验证码以及 hCAPTCHA。本来想着集成一下腾讯云的验证码，但是发现集成起来好麻烦，远没有前两种简单，就一直搁置到现在。</p>



<p class="wp-block-paragraph">验证码的集成也带来了不小的好处，比如 CC 防护不再只能简单地拉黑了。有了验证码后就可以将 CC 防护的阈值降低一些，超出时弹出验证码，通过验证则放行，反之则拉黑一段时间。同时，根据某个用户的建议，现在当触发任何的拦截时，就会对该 IP 启用验证码，当且仅当通过验证时才会放行，否则无法进行任何访问。</p>



<h2 class="wp-block-heading">集成 ModSecurity</h2>



<p class="wp-block-paragraph">ModSecurity 是一个广泛使用的开源的 WAF 引擎，并且在网络上有现成的安全规则可以套用，所以本模块也继承了 ModSecurity 的引擎，可以加载 ModSecurity 的规则。</p>



<p class="wp-block-paragraph">（ModSecurity 的内存泄漏问题官方什么时候修一下）</p>



<h2 class="wp-block-heading">后续计划</h2>



<p class="wp-block-paragraph">本项目已经完成了性能优化，后续应该不会有大的改动，不过如果有合适的需求就另说了。有了新的进展我也会更新本文。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/2876/feed</wfw:commentRss>
			<slash:comments>36</slash:comments>
		
		
			</item>
		<item>
		<title>检查你的字体是否可以商用</title>
		<link>https://www.addesp.com/archives/469</link>
					<comments>https://www.addesp.com/archives/469#respond</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Sat, 05 Sep 2020 13:26:29 +0000</pubDate>
				<category><![CDATA[项目分享]]></category>
		<category><![CDATA[Github]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=469</guid>

					<description><![CDATA[这个项目可以查询一些字体的授权方式并提供下载地址。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">前言</h2>



<p class="wp-block-paragraph">偶然看到了这个项目，这个项目可以查询一些字体的授权方式并提供下载地址，挺实用的一个项目，所以分享一下。</p>



<h2 class="wp-block-heading">相关链接</h2>



<ul class="wp-block-list"><li><a href="https://github.com/muruoxi2018/Check_Font_Copyright" data-type="URL" data-id="https://github.com/muruoxi2018/Check_Font_Copyright">Github</a></li><li><a rel="noreferrer noopener" href="https://www.muruoxi.com/font/index.html" data-type="URL" data-id="https://www.muruoxi.com/font/index.html" target="_blank">演示地址</a></li></ul>



<h2 class="wp-block-heading">官方介绍</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>如你所见，我是一名设计爱好者，这是我用屁股想的说明文档，因此如果发现阅读起来狗屁不通，属于正常情况。</p><p>在前些年我看到了好多起因为各种版权产生了法律纠纷的事件。</p><p>比如<strong>视觉中国版权门</strong>事件。</p><p>再比如很多设计师甚至不知道<strong>微软雅黑</strong>字体居然不能用来商用。</p><p>近年来这类事件屡见不鲜。</p><p>在我之前，有“360查字体”这个网站，遗憾的是，它看起来已经不再维护了。</p><p>这令人有点儿伤心。</p><p>因此我在闲暇时间制作了这个网站，我希望他能帮我们简单的排查出字体方面的隐患，降低一些不必要的版权纠纷。</p><p>好吧，虽然我觉得一个好的设计师，肯定会知道哪些字体可以被用作商业设计。</p><cite><a href="https://github.com/muruoxi2018/Check_Font_Copyright">https://github.com/muruoxi2018/Check_Font_Copyright</a></cite></blockquote>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/469/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>libmpv-开源的媒体播放库</title>
		<link>https://www.addesp.com/archives/324</link>
					<comments>https://www.addesp.com/archives/324#respond</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Sat, 25 Apr 2020 14:40:00 +0000</pubDate>
				<category><![CDATA[项目分享]]></category>
		<category><![CDATA[mpv]]></category>
		<guid isPermaLink="false">http://69a274df.addesp.com/?p=324</guid>

					<description><![CDATA[概述 官方网站 开源主页 官方文档 mpv是基于MPlayer和mplayer2的媒体播放器。 支持各种视频文 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" href="https://mpv.io/" data-type="URL" data-id="https://mpv.io/" target="_blank">官方网站</a></li><li><a rel="noreferrer noopener" href="https://github.com/mpv-player/mpv" data-type="URL" data-id="https://github.com/mpv-player/mpv" target="_blank">开源主页</a></li><li><a rel="noreferrer noopener" href="https://mpv.io/manual/stable/" data-type="URL" data-id="https://mpv.io/manual/stable/" target="_blank">官方文档</a></li></ul>



<ul class="wp-block-list"><li>mpv是基于MPlayer和mplayer2的媒体播放器。</li><li>支持各种视频文件格式、音频和视频编解码器以及字幕。</li><li>媒体来源也不仅限于本地，如URL等。</li><li>根据平台的不同，支持各种不同的视频和音频输出方法。</li></ul>



<p class="wp-block-paragraph"><strong>不过重点是提供了它提供了&nbsp;C&nbsp;语言的库——libmpv，可以让我们将&nbsp;mpv&nbsp;嵌入到自己的程序中。</strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/324/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
