-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
8 lines (8 loc) · 74.5 KB
/
index.html
1
2
3
4
5
6
7
8
<!DOCTYPE html><html lang="zh-CN"><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta content="yes" name="apple-mobile-web-app-capable"><meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"><meta content="telephone=no" name="format-detection"><meta name="description"><title>Codes Online | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _enjoying</title><link rel="stylesheet" type="text/css" href="/css/style.css?v=0.0.0"><link rel="stylesheet" type="text/css" href="/css/normalize.min.css"><link rel="stylesheet" type="text/css" href="/css/pure-min.css"><link rel="stylesheet" type="text/css" href="/css/grids-responsive-min.css"><link rel="stylesheet" href="/css/font-awesome.min.css"><script type="text/javascript" src="/js/jquery.min.js"></script><link rel="Shortcut Icon" type="image/x-icon" href="/favicon.ico"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><link rel="apple-touch-icon-precomposed" href="/apple-touch-icon.png"></head><body><div class="body_container"><div id="header"><div class="site-name"><h1 class="hidden">Codes Online</h1><a id="logo" href="/.">Codes Online</a><p class="description">_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _enjoying</p></div><div id="nav-menu"><a href="/." class="current"><i class="fa fa-home"> 首页</i></a><a href="/archives/"><i class="fa fa-archive"> 归档</i></a><a href="/about/"><i class="fa fa-user"> 关于</i></a></div></div><div id="layout" class="pure-g"><div class="pure-u-1 pure-u-md-3-4"><div class="content_container"><div class="post"><h1 class="post-title"><a href="/2018/07/22/netty-protocol/">Netty私有协议栈开发编解码失败的问题</a></h1><div class="post-meta">2018-07-22</div><div class="post-content"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//解码器参数:固定</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> maxFrameLength = <span class="number">1024</span> * <span class="number">1024</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> lengthFieldOffset = <span class="number">4</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> lengthFieldLength = <span class="number">4</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> lengthAdjustment = -<span class="number">8</span>; <span class="comment">//这个参数很关键,使用marshall工具,调用底层decode时候会做偏移</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> initialBytesToStrip = <span class="number">0</span>;</span><br></pre></td></tr></table></figure></div><p class="readmore"><a href="/2018/07/22/netty-protocol/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/22/xss/">4类防御XSS的有效方法</a></h1><div class="post-meta">2018-07-22</div><div class="post-content"><h3 id="XSS的本质"><a href="#XSS的本质" class="headerlink" title="XSS的本质"></a>XSS的本质</h3><p>XSS事件发生在网站前端,在相关的数据替换到前端页面中时,新旧数据结合,混淆了页面原本的语义,产生了新的语义。以下面这种情况为例:</p></div><p class="readmore"><a href="/2018/07/22/xss/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/22/tcp_order/">关于同一条TCP链接数据包到达顺序的问题</a></h1><div class="post-meta">2018-07-22</div><div class="post-content"><p><strong><em>同一个TCP连接,数据包是不一定先发先到,但是对于TCP有一点特殊</em></strong>,若我们接受的数据包是在应用层,并且应用层用的是TCP的传输协议的话,这个顺序是保证,这个顺序的保证是在传输层保证的,举个例子:</p>
<p>client发生数据A,B给server,使用的TCP传输,client发送毫无疑问是先发送A,然后发送B,但是有些搞网络的同学可能会有这个疑问,A跟B在物理层走的链路不一样,传输速度不一样,B是会比A先到达Server,这个是没有错的,但是这个数据包被接受是在网络层跟传输层,</p></div><p class="readmore"><a href="/2018/07/22/tcp_order/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/22/mysql-bug/">Mysql插入中文时提示编码问题</a></h1><div class="post-meta">2018-07-22</div><div class="post-content"><p>Mysql插入中文时提示:ERROR 1366 (HY000): Incorrect string value: ‘\xE5\x8F\xB0\xE5\xBC\x8F…’</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">首先通过语句查看:</span><br><span class="line">show create table tdb_goods_cates ;</span><br></pre></td></tr></table></figure></div><p class="readmore"><a href="/2018/07/22/mysql-bug/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/22/mybatis/">Spring Boot添加 Mybatis-generator 插件</a></h1><div class="post-meta">2018-07-22</div><div class="post-content"><p>支持Druid连接池设置、多个mapper.xml目录配置, 解决自定义sql扩展在每次执行插件后被覆盖的问题</p>
<h4 id="1-pom-xml"><a href="#1-pom-xml" class="headerlink" title="1-pom.xml"></a>1-pom.xml</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependencies</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.alibaba<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>druid<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.0.25<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.mybatis.spring.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>mybatis-spring-boot-starter<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.1.1<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 分页插件 --></span></span><br><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.github.pagehelper<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>pagehelper<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>5.1.4<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependencies</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">build</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">plugins</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">plugin</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.mybatis.generator<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>mybatis-generator-maven-plugin<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.3.7<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">configuration</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">configurationFile</span>></span>src/main/resources/mybatis-generator-config.xml<span class="tag"></<span class="name">configurationFile</span>></span></span><br><span class="line"> <span class="comment"><!--允许移动生成的文件--></span></span><br><span class="line"> <span class="tag"><<span class="name">verbose</span>></span>true<span class="tag"></<span class="name">verbose</span>></span></span><br><span class="line"> <span class="comment"><!--允许覆盖生成的文件--></span></span><br><span class="line"> <span class="tag"><<span class="name">overwrite</span>></span>true<span class="tag"></<span class="name">overwrite</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">configuration</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">executions</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">execution</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">id</span>></span>Generate MyBatis Artifacts<span class="tag"></<span class="name">id</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">goals</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">goal</span>></span>generate<span class="tag"></<span class="name">goal</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">goals</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">execution</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">executions</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">dependencies</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.mybatis.generator<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>mybatis-generator-core<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.3.7<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependencies</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">plugin</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">plugins</span>></span></span><br><span class="line"><span class="tag"></<span class="name">build</span>></span></span><br></pre></td></tr></table></figure></div><p class="readmore"><a href="/2018/07/22/mybatis/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/08/vue-debugger/">vue+webpack项目调试方法</a></h1><div class="post-meta">2018-07-08</div><div class="post-content"><h4 id="修改配置"><a href="#修改配置" class="headerlink" title="修改配置"></a>修改配置</h4><p>-sourcemap</p>
<p>./config/index.js, devtool这个选项, 如果设置为 ‘#source-map’,则可以生成.map文件,在chrome浏览器中调试的时候可以显示源代码</p></div><p class="readmore"><a href="/2018/07/08/vue-debugger/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/06/nodejs-vue-bug/">Vue项目打包后打开空白解决办法</a></h1><div class="post-meta">2018-07-06</div><div class="post-content"><p>1、记得改一下config下面的index.js中bulid模块导出的路径。因为index.html里边的内容都是通过script标签引入的,而你的路径不对,打开肯定是空白的。先看一下默认的路径<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">module.exports = {</span><br><span class="line"> build: {</span><br><span class="line"> env: require(<span class="string">'./prod.env'</span>),</span><br><span class="line"> index: path.resolve(__dirname, <span class="string">'../dist/index.html'</span>),</span><br><span class="line"> assetsRoot: path.resolve(__dirname, <span class="string">'../dist'</span>),</span><br><span class="line"> assetsSubDirectory: <span class="string">'static'</span>,</span><br><span class="line"> assetsPublicPath: <span class="string">'/'</span>,</span><br><span class="line"> productionSourceMap: <span class="literal">true</span>,</span><br></pre></td></tr></table></figure></p></div><p class="readmore"><a href="/2018/07/06/nodejs-vue-bug/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/07/05/linux-crontab/">CentOS下Tomcat服务器宕机自动启动方法</a></h1><div class="post-meta">2018-07-05</div><div class="post-content"><h4 id="监控启动脚本monitor-sh"><a href="#监控启动脚本monitor-sh" class="headerlink" title="监控启动脚本monitor.sh"></a>监控启动脚本monitor.sh</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line"><span class="comment"># 获取tomcat进程ID /usr/local/tomcat</span></span><br><span class="line">TomcatID=$(ps -ef |grep tomcat |grep -w <span class="string">'tomcat'</span>|grep -v <span class="string">'grep'</span>|awk <span class="string">'{print $2}'</span>) </span><br><span class="line"> </span><br><span class="line"><span class="comment"># tomcat启动程序(这里注意tomcat实际安装的路径) </span></span><br><span class="line">StartTomcat=/usr/<span class="built_in">local</span>/tomcat/bin/startup.sh</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 定义要监控的页面地址 </span></span><br><span class="line">WebUrl=http://localhost:8080</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 日志输出 </span></span><br><span class="line">TomcatMonitorLog=/usr/<span class="built_in">local</span>/tomcat/logs/TomcatMonitor.log </span><br><span class="line"> </span><br><span class="line">Monitor() </span><br><span class="line">{ </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[info]开始监控tomcat...[<span class="variable">$(date +'%F %H:%M:%S')</span>]"</span> </span><br><span class="line"> <span class="keyword">if</span> [[ <span class="variable">$TomcatID</span> ]];<span class="keyword">then</span> <span class="comment"># 这里判断TOMCAT进程是否存在 </span></span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[info]当前tomcat进程ID为:<span class="variable">$TomcatID</span>,继续检测页面..."</span> </span><br><span class="line"> <span class="comment"># 检测是否启动成功(成功的话页面会返回状态"200") </span></span><br><span class="line"> TomcatServiceCode=$(curl -I -m 10 -o /dev/null -s -w %{http_code} <span class="variable">$WebUrl</span>) </span><br><span class="line"> <span class="keyword">if</span> [ <span class="variable">$TomcatServiceCode</span> -eq 200 ];<span class="keyword">then</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[info]页面返回码为<span class="variable">$TomcatServiceCode</span>,tomcat启动成功,测试页面正常......"</span> </span><br><span class="line"> <span class="keyword">else</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[error]tomcat页面出错,请注意......状态码为<span class="variable">$TomcatServiceCode</span>,错误日志已输出到<span class="variable">$GetPageInfo</span>"</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[error]页面访问出错,开始重启tomcat"</span> </span><br><span class="line"> <span class="built_in">kill</span> -9 <span class="variable">$TomcatID</span> <span class="comment"># 杀掉原tomcat进程 </span></span><br><span class="line"> sleep 3 </span><br><span class="line"> rm -rf <span class="variable">$TomcatCache</span> <span class="comment"># 清理tomcat缓存 </span></span><br><span class="line"> <span class="variable">$StartTomcat</span> </span><br><span class="line"> <span class="keyword">fi</span> </span><br><span class="line"> <span class="keyword">else</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[error]tomcat进程不存在!tomcat开始自动重启..."</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"[info]<span class="variable">$StartTomcat</span>,请稍候......"</span> </span><br><span class="line"> <span class="comment">#rm -rf $TomcatCache </span></span><br><span class="line"> <span class="variable">$StartTomcat</span> </span><br><span class="line"> <span class="keyword">fi</span> </span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"------------------------------"</span> </span><br><span class="line">} </span><br><span class="line">Monitor>><span class="variable">$TomcatMonitorLog</span></span><br></pre></td></tr></table></figure></div><p class="readmore"><a href="/2018/07/05/linux-crontab/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/06/12/java-jar/">在intellij中打jar包,运行提示没有主清单属性</a></h1><div class="post-meta">2018-06-12</div><div class="post-content"><ul>
<li>在Intellij中通过Project Structure - Artifacts打jar包,每次java -jar运行时候总是提示没有主清单属性。查看Manifest.mf文件里面确实没有Main-Class.</li>
</ul>
<h4 id="可能是-IntelliJ-的问题"><a href="#可能是-IntelliJ-的问题" class="headerlink" title="可能是 IntelliJ 的问题"></a>可能是 IntelliJ 的问题</h4><ul></div><p class="readmore"><a href="/2018/06/12/java-jar/">阅读全文</a></p></div><div class="post"><h1 class="post-title"><a href="/2018/06/01/ngrok-auth/">解决Ngrok Server无法认证AuthTokens问题</a></h1><div class="post-meta">2018-06-01</div><div class="post-content"><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> server</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"> <span class="string">"fmt"</span></span><br><span class="line"> <span class="string">"io"</span></span><br><span class="line"> <span class="string">"ngrok/conn"</span></span><br><span class="line"> <span class="string">"ngrok/msg"</span></span><br><span class="line"> <span class="string">"ngrok/util"</span></span><br><span class="line"> <span class="string">"ngrok/version"</span></span><br><span class="line"> <span class="string">"runtime/debug"</span></span><br><span class="line"> <span class="string">"strings"</span></span><br><span class="line"> <span class="string">"time"</span></span><br><span class="line"> <span class="string">"os"</span></span><br><span class="line"> <span class="string">"bufio"</span></span><br><span class="line"> <span class="string">"errors"</span></span><br><span class="line"> <span class="string">"os/exec"</span></span><br><span class="line"> <span class="string">"path/filepath"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line"> pingTimeoutInterval = <span class="number">30</span> * time.Second</span><br><span class="line"> connReapInterval = <span class="number">10</span> * time.Second</span><br><span class="line"> controlWriteTimeout = <span class="number">10</span> * time.Second</span><br><span class="line"> proxyStaleDuration = <span class="number">60</span> * time.Second</span><br><span class="line"> proxyMaxPoolSize = <span class="number">10</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Control <span class="keyword">struct</span> {</span><br><span class="line"> <span class="comment">// auth message</span></span><br><span class="line"> auth *msg.Auth</span><br><span class="line"></span><br><span class="line"> <span class="comment">// actual connection</span></span><br><span class="line"> conn conn.Conn</span><br><span class="line"></span><br><span class="line"> <span class="comment">// put a message in this channel to send it over</span></span><br><span class="line"> <span class="comment">// conn to the client</span></span><br><span class="line"> out <span class="keyword">chan</span> (msg.Message)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// read from this channel to get the next message sent</span></span><br><span class="line"> <span class="comment">// to us over conn by the client</span></span><br><span class="line"> in <span class="keyword">chan</span> (msg.Message)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// the last time we received a ping from the client - for heartbeats</span></span><br><span class="line"> lastPing time.Time</span><br><span class="line"></span><br><span class="line"> <span class="comment">// all of the tunnels this control connection handles</span></span><br><span class="line"> tunnels []*Tunnel</span><br><span class="line"></span><br><span class="line"> <span class="comment">// proxy connections</span></span><br><span class="line"> proxies <span class="keyword">chan</span> conn.Conn</span><br><span class="line"></span><br><span class="line"> <span class="comment">// identifier</span></span><br><span class="line"> id <span class="keyword">string</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// synchronizer for controlled shutdown of writer()</span></span><br><span class="line"> writerShutdown *util.Shutdown</span><br><span class="line"></span><br><span class="line"> <span class="comment">// synchronizer for controlled shutdown of reader()</span></span><br><span class="line"> readerShutdown *util.Shutdown</span><br><span class="line"></span><br><span class="line"> <span class="comment">// synchronizer for controlled shutdown of manager()</span></span><br><span class="line"> managerShutdown *util.Shutdown</span><br><span class="line"></span><br><span class="line"> <span class="comment">// synchronizer for controller shutdown of entire Control</span></span><br><span class="line"> shutdown *util.Shutdown</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GetCurrentPath</span><span class="params">()</span> <span class="params">(<span class="keyword">string</span>, error)</span></span> {</span><br><span class="line"> file, err := exec.LookPath(os.Args[<span class="number">0</span>])</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>, err</span><br><span class="line"> }</span><br><span class="line"> path, err := filepath.Abs(file)</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>, err</span><br><span class="line"> }</span><br><span class="line"> i := strings.LastIndex(path, <span class="string">"/"</span>)</span><br><span class="line"> <span class="keyword">if</span> i < <span class="number">0</span> {</span><br><span class="line"> i = strings.LastIndex(path, <span class="string">"\\"</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> i < <span class="number">0</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>, errors.New(<span class="string">`error: Can't find "/" or "\".`</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">string</span>(path[<span class="number">0</span> : i+<span class="number">1</span>]), <span class="literal">nil</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">NewControl</span><span class="params">(ctlConn conn.Conn, authMsg *msg.Auth)</span></span> {</span><br><span class="line"> <span class="keyword">var</span> err error</span><br><span class="line"></span><br><span class="line"> <span class="comment">// create the object</span></span><br><span class="line"> c := &Control{</span><br><span class="line"> auth: authMsg,</span><br><span class="line"> conn: ctlConn,</span><br><span class="line"> out: <span class="built_in">make</span>(<span class="keyword">chan</span> msg.Message),</span><br><span class="line"> in: <span class="built_in">make</span>(<span class="keyword">chan</span> msg.Message),</span><br><span class="line"> proxies: <span class="built_in">make</span>(<span class="keyword">chan</span> conn.Conn, <span class="number">10</span>),</span><br><span class="line"> lastPing: time.Now(),</span><br><span class="line"> writerShutdown: util.NewShutdown(),</span><br><span class="line"> readerShutdown: util.NewShutdown(),</span><br><span class="line"> managerShutdown: util.NewShutdown(),</span><br><span class="line"> shutdown: util.NewShutdown(),</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> failAuth := <span class="function"><span class="keyword">func</span><span class="params">(e error)</span></span> {</span><br><span class="line"> _ = msg.WriteMsg(ctlConn, &msg.AuthResp{Error: e.Error()})</span><br><span class="line"> ctlConn.Close()</span><br><span class="line"> }</span><br><span class="line"> readLine := <span class="function"><span class="keyword">func</span><span class="params">(token <span class="keyword">string</span>, filename <span class="keyword">string</span>)</span> <span class="params">(<span class="keyword">bool</span>, error)</span></span> {</span><br><span class="line"> tokenpath, err := GetCurrentPath()</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> fmt.Println(<span class="string">"---------->current path faild"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> token == <span class="string">""</span> {</span><br><span class="line"> fmt.Println(<span class="string">"---------->token="</span> + token)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span>;</span><br><span class="line"> }</span><br><span class="line"> f, err := os.Open(tokenpath + filename)</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> fmt.Println(<span class="string">"---------->open token file fail="</span> + filename + <span class="string">", path="</span> + tokenpath)</span><br><span class="line"> fmt.Println(err)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line"> }</span><br><span class="line"> buf := bufio.NewReader(f)</span><br><span class="line"> <span class="keyword">for</span> {</span><br><span class="line"> line, err := buf.ReadString(<span class="string">'\n'</span>)</span><br><span class="line"> line = strings.TrimSpace(line)</span><br><span class="line"> fmt.Println(<span class="string">"---------->open token file line="</span> + line)</span><br><span class="line"> <span class="keyword">if</span> line == token {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="keyword">if</span> err == io.EOF {</span><br><span class="line"> fmt.Println(<span class="string">"---------->read token file io.EOF"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line"> }</span><br><span class="line"> fmt.Println(<span class="string">"---------->read token file err"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> fmt.Println(<span class="string">"---------->read token and none equals"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// register the clientid</span></span><br><span class="line"> c.id = authMsg.ClientId</span><br><span class="line"> <span class="keyword">if</span> c.id == <span class="string">""</span> {</span><br><span class="line"> <span class="comment">// it's a new session, assign an ID</span></span><br><span class="line"> <span class="keyword">if</span> c.id, err = util.SecureRandId(<span class="number">16</span>); err != <span class="literal">nil</span> {</span><br><span class="line"> failAuth(err)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// set logging prefix</span></span><br><span class="line"> ctlConn.SetType(<span class="string">"ctl"</span>)</span><br><span class="line"> ctlConn.AddLogPrefix(c.id)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> authMsg.Version != version.Proto {</span><br><span class="line"> failAuth(fmt.Errorf(<span class="string">"Incompatible versions. Server %s, client %s. Download a new version at http://ngrok.com"</span>, version.MajorMinor(), authMsg.Version))</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> authd, err := readLine(authMsg.User, <span class="string">"authtokens.txt"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> authd != <span class="literal">true</span> {</span><br><span class="line"> failAuth(fmt.Errorf(<span class="string">"authtoken %s invalid"</span>, <span class="string">"is"</span>));</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// register the control</span></span><br><span class="line"> <span class="keyword">if</span> replaced := controlRegistry.Add(c.id, c); replaced != <span class="literal">nil</span> {</span><br><span class="line"> replaced.shutdown.WaitComplete()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// start the writer first so that the following messages get sent</span></span><br><span class="line"> <span class="keyword">go</span> c.writer()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Respond to authentication</span></span><br><span class="line"> c.out <- &msg.AuthResp{</span><br><span class="line"> Version: version.Proto,</span><br><span class="line"> MmVersion: version.MajorMinor(),</span><br><span class="line"> ClientId: c.id,</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// As a performance optimization, ask for a proxy connection up front</span></span><br><span class="line"> c.out <- &msg.ReqProxy{}</span><br><span class="line"></span><br><span class="line"> <span class="comment">// manage the connection</span></span><br><span class="line"> <span class="keyword">go</span> c.manager()</span><br><span class="line"> <span class="keyword">go</span> c.reader()</span><br><span class="line"> <span class="keyword">go</span> c.stopper()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Register a new tunnel on this control connection</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">registerTunnel</span><span class="params">(rawTunnelReq *msg.ReqTunnel)</span></span> {</span><br><span class="line"> <span class="keyword">for</span> _, proto := <span class="keyword">range</span> strings.Split(rawTunnelReq.Protocol, <span class="string">"+"</span>) {</span><br><span class="line"> tunnelReq := *rawTunnelReq</span><br><span class="line"> tunnelReq.Protocol = proto</span><br><span class="line"></span><br><span class="line"> c.conn.Debug(<span class="string">"Registering new tunnel"</span>)</span><br><span class="line"> t, err := NewTunnel(&tunnelReq, c)</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"> c.out <- &msg.NewTunnel{Error: err.Error()}</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(c.tunnels) == <span class="number">0</span> {</span><br><span class="line"> c.shutdown.Begin()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// we're done</span></span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// add it to the list of tunnels</span></span><br><span class="line"> c.tunnels = <span class="built_in">append</span>(c.tunnels, t)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// acknowledge success</span></span><br><span class="line"> c.out <- &msg.NewTunnel{</span><br><span class="line"> Url: t.url,</span><br><span class="line"> Protocol: proto,</span><br><span class="line"> ReqId: rawTunnelReq.ReqId,</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> rawTunnelReq.Hostname = strings.Replace(t.url, proto + <span class="string">"://"</span>, <span class="string">""</span>, <span class="number">1</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">manager</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="comment">// don't crash on panics</span></span><br><span class="line"> <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> {</span><br><span class="line"> c.conn.Info(<span class="string">"Control::manager failed with error %v: %s"</span>, err, debug.Stack())</span><br><span class="line"> }</span><br><span class="line"> }()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// kill everything if the control manager stops</span></span><br><span class="line"> <span class="keyword">defer</span> c.shutdown.Begin()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// notify that manager() has shutdown</span></span><br><span class="line"> <span class="keyword">defer</span> c.managerShutdown.Complete()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// reaping timer for detecting heartbeat failure</span></span><br><span class="line"> reap := time.NewTicker(connReapInterval)</span><br><span class="line"> <span class="keyword">defer</span> reap.Stop()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> {</span><br><span class="line"> <span class="keyword">select</span> {</span><br><span class="line"> <span class="keyword">case</span> <-reap.C:</span><br><span class="line"> <span class="keyword">if</span> time.Since(c.lastPing) > pingTimeoutInterval {</span><br><span class="line"> c.conn.Info(<span class="string">"Lost heartbeat"</span>)</span><br><span class="line"> c.shutdown.Begin()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> mRaw, ok := <-c.in:</span><br><span class="line"> <span class="comment">// c.in closes to indicate shutdown</span></span><br><span class="line"> <span class="keyword">if</span> !ok {</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">switch</span> m := mRaw.(<span class="keyword">type</span>) {</span><br><span class="line"> <span class="keyword">case</span> *msg.ReqTunnel:</span><br><span class="line"> c.registerTunnel(m)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> *msg.Ping:</span><br><span class="line"> c.lastPing = time.Now()</span><br><span class="line"> c.out <- &msg.Pong{}</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">writer</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> {</span><br><span class="line"> c.conn.Info(<span class="string">"Control::writer failed with error %v: %s"</span>, err, debug.Stack())</span><br><span class="line"> }</span><br><span class="line"> }()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// kill everything if the writer() stops</span></span><br><span class="line"> <span class="keyword">defer</span> c.shutdown.Begin()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// notify that we've flushed all messages</span></span><br><span class="line"> <span class="keyword">defer</span> c.writerShutdown.Complete()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// write messages to the control channel</span></span><br><span class="line"> <span class="keyword">for</span> m := <span class="keyword">range</span> c.out {</span><br><span class="line"> c.conn.SetWriteDeadline(time.Now().Add(controlWriteTimeout))</span><br><span class="line"> <span class="keyword">if</span> err := msg.WriteMsg(c.conn, m); err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="built_in">panic</span>(err)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">reader</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> {</span><br><span class="line"> c.conn.Warn(<span class="string">"Control::reader failed with error %v: %s"</span>, err, debug.Stack())</span><br><span class="line"> }</span><br><span class="line"> }()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// kill everything if the reader stops</span></span><br><span class="line"> <span class="keyword">defer</span> c.shutdown.Begin()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// notify that we're done</span></span><br><span class="line"> <span class="keyword">defer</span> c.readerShutdown.Complete()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// read messages from the control channel</span></span><br><span class="line"> <span class="keyword">for</span> {</span><br><span class="line"> <span class="keyword">if</span> msg, err := msg.ReadMsg(c.conn); err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="keyword">if</span> err == io.EOF {</span><br><span class="line"> c.conn.Info(<span class="string">"EOF"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">panic</span>(err)</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// this can also panic during shutdown</span></span><br><span class="line"> c.in <- msg</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">stopper</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">if</span> r := <span class="built_in">recover</span>(); r != <span class="literal">nil</span> {</span><br><span class="line"> c.conn.Error(<span class="string">"Failed to shut down control: %v"</span>, r)</span><br><span class="line"> }</span><br><span class="line"> }()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// wait until we're instructed to shutdown</span></span><br><span class="line"> c.shutdown.WaitBegin()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// remove ourself from the control registry</span></span><br><span class="line"> controlRegistry.Del(c.id)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// shutdown manager() so that we have no more work to do</span></span><br><span class="line"> <span class="built_in">close</span>(c.in)</span><br><span class="line"> c.managerShutdown.WaitComplete()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// shutdown writer()</span></span><br><span class="line"> <span class="built_in">close</span>(c.out)</span><br><span class="line"> c.writerShutdown.WaitComplete()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// close connection fully</span></span><br><span class="line"> c.conn.Close()</span><br><span class="line"></span><br><span class="line"> <span class="comment">// shutdown all of the tunnels</span></span><br><span class="line"> <span class="keyword">for</span> _, t := <span class="keyword">range</span> c.tunnels {</span><br><span class="line"> t.Shutdown()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// shutdown all of the proxy connections</span></span><br><span class="line"> <span class="built_in">close</span>(c.proxies)</span><br><span class="line"> <span class="keyword">for</span> p := <span class="keyword">range</span> c.proxies {</span><br><span class="line"> p.Close()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> c.shutdown.Complete()</span><br><span class="line"> c.conn.Info(<span class="string">"Shutdown complete"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">RegisterProxy</span><span class="params">(conn conn.Conn)</span></span> {</span><br><span class="line"> conn.AddLogPrefix(c.id)</span><br><span class="line"></span><br><span class="line"> conn.SetDeadline(time.Now().Add(proxyStaleDuration))</span><br><span class="line"> <span class="keyword">select</span> {</span><br><span class="line"> <span class="keyword">case</span> c.proxies <- conn:</span><br><span class="line"> conn.Info(<span class="string">"Registered"</span>)</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> conn.Info(<span class="string">"Proxies buffer is full, discarding."</span>)</span><br><span class="line"> conn.Close()</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Remove a proxy connection from the pool and return it</span></span><br><span class="line"><span class="comment">// If not proxy connections are in the pool, request one</span></span><br><span class="line"><span class="comment">// and wait until it is available</span></span><br><span class="line"><span class="comment">// Returns an error if we couldn't get a proxy because it took too long</span></span><br><span class="line"><span class="comment">// or the tunnel is closing</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">GetProxy</span><span class="params">()</span> <span class="params">(proxyConn conn.Conn, err error)</span></span> {</span><br><span class="line"> <span class="keyword">var</span> ok <span class="keyword">bool</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// get a proxy connection from the pool</span></span><br><span class="line"> <span class="keyword">select</span> {</span><br><span class="line"> <span class="keyword">case</span> proxyConn, ok = <-c.proxies:</span><br><span class="line"> <span class="keyword">if</span> !ok {</span><br><span class="line"> err = fmt.Errorf(<span class="string">"No proxy connections available, control is closing"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="comment">// no proxy available in the pool, ask for one over the control channel</span></span><br><span class="line"> c.conn.Debug(<span class="string">"No proxy in pool, requesting proxy from control . . ."</span>)</span><br><span class="line"> <span class="keyword">if</span> err = util.PanicToError(<span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</span><br><span class="line"> c.out <- &msg.ReqProxy{}</span><br><span class="line"> }); err != <span class="literal">nil</span> {</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">select</span> {</span><br><span class="line"> <span class="keyword">case</span> proxyConn, ok = <-c.proxies:</span><br><span class="line"> <span class="keyword">if</span> !ok {</span><br><span class="line"> err = fmt.Errorf(<span class="string">"No proxy connections available, control is closing"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> <-time.After(pingTimeoutInterval):</span><br><span class="line"> err = fmt.Errorf(<span class="string">"Timeout trying to get proxy connection"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Called when this control is replaced by another control</span></span><br><span class="line"><span class="comment">// this can happen if the network drops out and the client reconnects</span></span><br><span class="line"><span class="comment">// before the old tunnel has lost its heartbeat</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *Control)</span> <span class="title">Replaced</span><span class="params">(replacement *Control)</span></span> {</span><br><span class="line"> c.conn.Info(<span class="string">"Replaced by control: %s"</span>, replacement.conn.Id())</span><br><span class="line"></span><br><span class="line"> <span class="comment">// set the control id to empty string so that when stopper()</span></span><br><span class="line"> <span class="comment">// calls registry.Del it won't delete the replacement</span></span><br><span class="line"> c.id = <span class="string">""</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// tell the old one to shutdown</span></span><br><span class="line"> c.shutdown.Begin()</span><br><span class="line">}</span><br></pre></td></tr></table></figure></div><p class="readmore"><a href="/2018/06/01/ngrok-auth/">阅读全文</a></p></div><nav class="page-navigator"><span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="space">…</span><a class="page-number" href="/page/12/">12</a><a class="extend next" rel="next" href="/page/2/">下一页</a></nav></div></div><div class="pure-u-1-4 hidden_mid_and_down"><div id="sidebar"><div class="widget"><div class="widget-title"><i class="fa fa-folder-o"> 分类</i></div><ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Android/">Android</a><span class="category-list-count">13</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Hexo/">Hexo</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a><span class="category-list-count">15</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Kotlin/">Kotlin</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Maven/">Maven</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Netty/">Netty</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Node-js/">Node.js</a><span class="category-list-count">8</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/OpenCV/">OpenCV</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Spring-Cloud/">Spring Cloud</a><span class="category-list-count">9</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Web/">Web</a><span class="category-list-count">15</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/大数据/">大数据</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/安全/">安全</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/嵌入式/">嵌入式</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库/">数据库</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/架构/">架构</a><span class="category-list-count">20</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/环境搭建/">环境搭建</a><span class="category-list-count">9</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/行业/">行业</a><span class="category-list-count">1</span></li></ul></div><div class="widget"><div class="widget-title"><i class="fa fa-external-link"> 友情链接</i></div><ul></ul><a href="http://www.linkedkeeper.com/" title="张松然" target="_blank">张松然</a><ul></ul><a href="http://weishu.me/" title="维术" target="_blank">维术</a><ul></ul><a href="http://zhixinliu.com/" title="Zhixin Liu" target="_blank">Zhixin Liu</a><ul></ul><a href="http://www.ruanyifeng.com/" title="阮一峰" target="_blank">阮一峰</a><ul></ul><a href="https://www.tianmaying.com/user/luoruici" title="Ricky" target="_blank">Ricky</a><ul></ul><a href="http://jeffdeng.me/" title="荒于嬉" target="_blank">荒于嬉</a><ul></ul><a href="https://kcaogen.com/blog" title="康草根" target="_blank">康草根</a><ul></ul><a href="http://13blog.site/" title="zhenfeng13" target="_blank">zhenfeng13</a><ul></ul><a href="http://binux.cn/" title="Binux" target="_blank">Binux</a></div></div></div><div class="pure-u-1 pure-u-md-3-4"><div id="footer">Copyright © 2018 <a href="/." rel="nofollow">Codes Online.</a> Powered by<a rel="nofollow" target="_blank" href="https://hexo.io"> Hexo.</a><a rel="nofollow" target="_blank" href="https://github.com/tufu9441/maupassant-hexo"> Theme</a> by<a rel="nofollow" target="_blank" href="https://github.com/pagecho"> Cho.</a></div></div></div><a id="rocket" href="#top" class="show"></a><script type="text/javascript" src="/js/totop.js?v=0.0.0" async></script><script type="text/javascript" src="/js/jquery.fancybox.min.js" async></script><script type="text/javascript" src="/js/fancybox.js?v=0.0.0" async></script><link rel="stylesheet" type="text/css" href="/css/jquery.fancybox.min.css"><script type="text/javascript" src="/js/codeblock-resizer.js?v=0.0.0"></script><script type="text/javascript" src="/js/smartresize.js?v=0.0.0"></script></div></body></html>