<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>go语言开发</title><link>http://go.hh85.com/</link><description>go语言</description><item><title>GORM一对一关系的查询</title><link>http://go.hh85.com/?id=39</link><description>&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;//&amp;nbsp;User&amp;nbsp;有一张&amp;nbsp;CreditCard，UserID&amp;nbsp;是外键
type&amp;nbsp;User&amp;nbsp;struct&amp;nbsp;{
&amp;nbsp;&amp;nbsp;gorm.Model
&amp;nbsp;&amp;nbsp;CreditCard&amp;nbsp;CreditCard
}

type&amp;nbsp;CreditCard&amp;nbsp;struct&amp;nbsp;{
&amp;nbsp;&amp;nbsp;gorm.Model
&amp;nbsp;&amp;nbsp;Number&amp;nbsp;string
&amp;nbsp;&amp;nbsp;UserID&amp;nbsp;uint
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;通过Preload方法可以获取CreditCard 的相关数据&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;//&amp;nbsp;检索用户列表并预加载信用卡
func&amp;nbsp;GetAll(db&amp;nbsp;*gorm.DB)&amp;nbsp;([]User,&amp;nbsp;error)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;users&amp;nbsp;[]User
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;db.Model(&amp;amp;User{}).Preload(&amp;quot;CreditCard&amp;quot;).Find(&amp;amp;users).Error
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;users,&amp;nbsp;err
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;指定外键名称&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-csharp&quot;&gt;type&amp;nbsp;User&amp;nbsp;struct&amp;nbsp;{
&amp;nbsp;&amp;nbsp;gorm.Model
&amp;nbsp;&amp;nbsp;CreditCard&amp;nbsp;CreditCard&amp;nbsp;`gorm:&amp;quot;foreignKey:UserName&amp;quot;`&amp;nbsp;//&amp;nbsp;使用&amp;nbsp;UserName&amp;nbsp;作为外键
}

type&amp;nbsp;CreditCard&amp;nbsp;struct&amp;nbsp;{
&amp;nbsp;&amp;nbsp;gorm.Model
&amp;nbsp;&amp;nbsp;Number&amp;nbsp;&amp;nbsp;&amp;nbsp;string
&amp;nbsp;&amp;nbsp;UserName&amp;nbsp;string
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 26 Apr 2024 13:44:29 +0800</pubDate></item><item><title>GORM使用 SQL 表达式更新</title><link>http://go.hh85.com/?id=38</link><description>&lt;p&gt;通过表达式可以更灵活的更新数据&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;//&amp;nbsp;product&amp;#39;s&amp;nbsp;ID&amp;nbsp;is&amp;nbsp;`3`
db.Model(&amp;amp;product).Update(&amp;quot;price&amp;quot;,&amp;nbsp;gorm.Expr(&amp;quot;price&amp;nbsp;*&amp;nbsp;?&amp;nbsp;+&amp;nbsp;?&amp;quot;,&amp;nbsp;2,&amp;nbsp;100))
//&amp;nbsp;UPDATE&amp;nbsp;&amp;quot;products&amp;quot;&amp;nbsp;SET&amp;nbsp;&amp;quot;price&amp;quot;&amp;nbsp;=&amp;nbsp;price&amp;nbsp;*&amp;nbsp;2&amp;nbsp;+&amp;nbsp;100,&amp;nbsp;&amp;quot;updated_at&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;#39;2013-11-17&amp;nbsp;21:34:10&amp;#39;&amp;nbsp;WHERE&amp;nbsp;&amp;quot;id&amp;quot;&amp;nbsp;=&amp;nbsp;3;

db.Model(&amp;amp;product).Updates(map[string]interface{}{&amp;quot;price&amp;quot;:&amp;nbsp;gorm.Expr(&amp;quot;price&amp;nbsp;*&amp;nbsp;?&amp;nbsp;+&amp;nbsp;?&amp;quot;,&amp;nbsp;2,&amp;nbsp;100)})
//&amp;nbsp;UPDATE&amp;nbsp;&amp;quot;products&amp;quot;&amp;nbsp;SET&amp;nbsp;&amp;quot;price&amp;quot;&amp;nbsp;=&amp;nbsp;price&amp;nbsp;*&amp;nbsp;2&amp;nbsp;+&amp;nbsp;100,&amp;nbsp;&amp;quot;updated_at&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;#39;2013-11-17&amp;nbsp;21:34:10&amp;#39;&amp;nbsp;WHERE&amp;nbsp;&amp;quot;id&amp;quot;&amp;nbsp;=&amp;nbsp;3;

db.Model(&amp;amp;product).UpdateColumn(&amp;quot;quantity&amp;quot;,&amp;nbsp;gorm.Expr(&amp;quot;quantity&amp;nbsp;-&amp;nbsp;?&amp;quot;,&amp;nbsp;1))
//&amp;nbsp;UPDATE&amp;nbsp;&amp;quot;products&amp;quot;&amp;nbsp;SET&amp;nbsp;&amp;quot;quantity&amp;quot;&amp;nbsp;=&amp;nbsp;quantity&amp;nbsp;-&amp;nbsp;1&amp;nbsp;WHERE&amp;nbsp;&amp;quot;id&amp;quot;&amp;nbsp;=&amp;nbsp;3;

db.Model(&amp;amp;product).Where(&amp;quot;quantity&amp;nbsp;&amp;gt;&amp;nbsp;1&amp;quot;).UpdateColumn(&amp;quot;quantity&amp;quot;,&amp;nbsp;gorm.Expr(&amp;quot;quantity&amp;nbsp;-&amp;nbsp;?&amp;quot;,&amp;nbsp;1))
//&amp;nbsp;UPDATE&amp;nbsp;&amp;quot;products&amp;quot;&amp;nbsp;SET&amp;nbsp;&amp;quot;quantity&amp;quot;&amp;nbsp;=&amp;nbsp;quantity&amp;nbsp;-&amp;nbsp;1&amp;nbsp;WHERE&amp;nbsp;&amp;quot;id&amp;quot;&amp;nbsp;=&amp;nbsp;3&amp;nbsp;AND&amp;nbsp;quantity&amp;nbsp;&amp;gt;&amp;nbsp;1;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 26 Apr 2024 13:34:01 +0800</pubDate></item><item><title>[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.</title><link>http://go.hh85.com/?id=37</link><description>&lt;p&gt;&lt;span style=&quot;color: #4D4D4D; font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif, SimHei, SimSun; font-size: 16px; text-wrap: wrap; background-color: #FFFFFF;&quot;&gt;根据warning也就是给gin设置一个信任ip : 127.0.0.1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #4D4D4D; font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif, SimHei, SimSun; font-size: 16px; text-wrap: wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-go&quot;&gt;	router&amp;nbsp;:=&amp;nbsp;gin.Default()
	router.SetTrustedProxies([]string{&amp;quot;127.0.0.1&amp;quot;})&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: #4D4D4D; font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif, SimHei, SimSun; font-size: 16px; text-wrap: wrap; background-color: #FFFFFF;&quot;&gt;&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 25 Apr 2024 10:32:51 +0800</pubDate></item><item><title>chromedp.Nodes方法详情</title><link>http://go.hh85.com/?id=36</link><description>&lt;p&gt;主要功能获取网页的内容保存一个个节点数组，&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;使用方法：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-basic&quot;&gt;chromedp.Nodes(`参数`,&amp;amp;nodes),&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;参数可以class id 如&amp;nbsp;.tableFull &amp;gt; tbody &amp;gt; tr&lt;br/&gt;&lt;/p&gt;&lt;p&gt;也可以name input[name=&amp;quot;xx&amp;quot;] input[tag=&amp;quot;xx&amp;quot;]&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;获取的最终数据如下&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-cpp&quot;&gt;for&amp;nbsp;_,v:=range&amp;nbsp;nodes{

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;len(v.Children)&amp;nbsp;&amp;gt;0{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;------------------------&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(v.Children[0].NodeValue)&amp;nbsp;//这里打印的是最终节点里的内容，如果里面有子节点就会空
&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;

}&lt;/pre&gt;&lt;p&gt;如果内容空&amp;nbsp;v.Children 小于等于0 说明不是内容或则还有子节点&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 28 Feb 2024 16:37:40 +0800</pubDate></item><item><title>git 基本操作</title><link>http://go.hh85.com/?id=35</link><description>&lt;pre class=&quot;prism-highlight prism-language-java&quot;&gt;-&amp;nbsp;创建一个目录也就是本地仓库
-&amp;nbsp;git&amp;nbsp;init&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#告诉git这是本地仓库归你管
-&amp;nbsp;ssh-keygen&amp;nbsp;-t&amp;nbsp;rsa&amp;nbsp;-C注册github用的邮箱&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#生成SSH&amp;nbsp;KEY
-&amp;nbsp;将生成的SSH&amp;nbsp;KEY保存在github的设置中
-&amp;nbsp;git&amp;nbsp;add&amp;nbsp;文件名&amp;nbsp;&amp;nbsp;&amp;nbsp;#将要上传的文件放到缓存空间
-&amp;nbsp;git&amp;nbsp;add&amp;nbsp;.&amp;nbsp;&amp;nbsp;#将当前目录下的所有文件放到缓存空间
-&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;&amp;quot;备注信息&amp;quot;&amp;nbsp;&amp;nbsp;#将缓存空间的所有文件放到仓库
-&amp;nbsp;git&amp;nbsp;remote&amp;nbsp;add&amp;nbsp;origin&amp;nbsp;链接地址&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#连接远程仓库
-&amp;nbsp;git&amp;nbsp;push&amp;nbsp;-u&amp;nbsp;origin&amp;nbsp;master&amp;nbsp;&amp;nbsp;&amp;nbsp;#将仓库里的文件上传到GitHub指定仓库的分支，定义仓库别名为origin，分支名为master
-&amp;nbsp;git&amp;nbsp;pull&amp;nbsp;origin&amp;nbsp;master&amp;nbsp;#将别名为origin仓库下的master分支的文件下载到当前目录
-&amp;nbsp;git&amp;nbsp;clone&amp;nbsp;项目链接&amp;nbsp;#克隆项目到本地&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 27 Feb 2024 08:19:31 +0800</pubDate></item><item><title>chromedp使用入门</title><link>http://go.hh85.com/?id=34</link><description>&lt;p&gt;&lt;span style=&quot;text-wrap: wrap; background-color: #FFFFFF;&quot;&gt;案例演示：&lt;/span&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt; &lt;/span&gt;&lt;a class=&quot;&quot; track-click=&quot;&quot; track-exposure=&quot;&quot; href=&quot;https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fgithub.com%2Fchromedp%2Fexamples&amp;source=article&amp;objectId=2334486&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot; style=&quot;overflow-wrap: break-word; text-decoration-line: none; box-sizing: border-box; list-style: inherit; color: rgb(0, 82, 217); font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: rgb(255, 255, 255);&quot;&gt;https://github.com/chromedp/examples&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt; 这个项目&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一些常见的方法：&lt;/strong&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;chromedp.NewContext()&amp;nbsp;初始化chromedp的上下文，后续这个页面都使用这个上下文进行操作
&amp;nbsp;chromedp.Run()&amp;nbsp;运行一个chrome的一系列操作
&amp;nbsp;chromedp.Navigate()&amp;nbsp;将浏览器导航到某个页面
&amp;nbsp;chromedp.WaitVisible()&amp;nbsp;等候某个元素可见，再继续执行。
&amp;nbsp;chromedp.Click()&amp;nbsp;模拟鼠标点击某个元素
&amp;nbsp;chromedp.Value()&amp;nbsp;获取某个元素的value值
&amp;nbsp;chromedp.ActionFunc()&amp;nbsp;再当前页面执行某些自定义函数
&amp;nbsp;chromedp.Text()&amp;nbsp;读取某个元素的text值
&amp;nbsp;chromedp.Evaluate()&amp;nbsp;执行某个js，相当于控制台输入js
&amp;nbsp;network.SetExtraHTTPHeaders()&amp;nbsp;截取请求，额外增加header头
&amp;nbsp;chromedp.SendKeys()&amp;nbsp;模拟键盘操作，输入字符
&amp;nbsp;chromedp.Nodes()&amp;nbsp;根据xpath获取某些元素，并存储进入数组
&amp;nbsp;chromedp.NewRemoteAllocator
&amp;nbsp;chromedp.OuterHTML()&amp;nbsp;获取元素的outer&amp;nbsp;html
&amp;nbsp;chromedp.Screenshot()&amp;nbsp;根据某个元素截图
&amp;nbsp;page.CaptureScreenshot()&amp;nbsp;截取整个页面的元素
&amp;nbsp;chromedp.Submit()&amp;nbsp;提交某个表单
&amp;nbsp;chromedp.WaitNotPresent()&amp;nbsp;等候某个元素不存在，比如“正在搜索。。。”
&amp;nbsp;chromedp.Tasks{}&amp;nbsp;一系列Action组成的任务&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;简单案例&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-go&quot;&gt;package&amp;nbsp;main
&amp;nbsp;
import&amp;nbsp;(
&amp;nbsp;&amp;quot;context&amp;quot;
&amp;nbsp;&amp;quot;fmt&amp;quot;
&amp;nbsp;&amp;quot;log&amp;quot;
&amp;nbsp;
&amp;nbsp;&amp;quot;github.com/chromedp/cdproto/cdp&amp;quot;
&amp;nbsp;&amp;quot;github.com/chromedp/chromedp&amp;quot;
)
&amp;nbsp;
func&amp;nbsp;main()&amp;nbsp;{
&amp;nbsp;
&amp;nbsp;ctx,&amp;nbsp;cancel&amp;nbsp;:=&amp;nbsp;chromedp.NewContext(
&amp;nbsp;&amp;nbsp;context.Background(),
&amp;nbsp;&amp;nbsp;chromedp.WithLogf(log.Printf),
&amp;nbsp;)
&amp;nbsp;defer&amp;nbsp;cancel()
&amp;nbsp;
&amp;nbsp;var&amp;nbsp;nodes&amp;nbsp;[]*cdp.Node
&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;chromedp.Run(ctx,
&amp;nbsp;&amp;nbsp;chromedp.Navigate(&amp;quot;https://www.cnblogs.com/&amp;quot;),
&amp;nbsp;&amp;nbsp;chromedp.WaitVisible(`#footer`,&amp;nbsp;chromedp.ByID),
&amp;nbsp;&amp;nbsp;chromedp.Nodes(`.//a[@class=&amp;quot;titlelnk&amp;quot;]`,&amp;nbsp;&amp;amp;nodes),
&amp;nbsp;)
&amp;nbsp;if&amp;nbsp;err&amp;nbsp;!=&amp;nbsp;nil&amp;nbsp;{
&amp;nbsp;&amp;nbsp;log.Fatal(err)
&amp;nbsp;}
&amp;nbsp;
&amp;nbsp;fmt.Println(&amp;quot;get&amp;nbsp;nodes:&amp;quot;,&amp;nbsp;len(nodes))
&amp;nbsp;//&amp;nbsp;print&amp;nbsp;titles
&amp;nbsp;for&amp;nbsp;_,&amp;nbsp;node&amp;nbsp;:=&amp;nbsp;range&amp;nbsp;nodes&amp;nbsp;{
&amp;nbsp;&amp;nbsp;fmt.Println(node.Children[0].NodeValue,&amp;nbsp;&amp;quot;:&amp;quot;,&amp;nbsp;node.AttributeValue(&amp;quot;href&amp;quot;))
&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;常用API&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-go&quot;&gt;chromedp.Navigate(&amp;quot;https://xxxx&amp;quot;)&amp;nbsp;//&amp;nbsp;跳转的url
chromedp.WaitVisible(`#username`,&amp;nbsp;chromedp.ByID),&amp;nbsp;//&amp;nbsp;&amp;nbsp;使用chromedp.ByID选择器。所以就是等待id=username的标签元素加载完。
chromedp.SendKeys(`#username`,&amp;nbsp;&amp;quot;username&amp;quot;,&amp;nbsp;chromedp.ByID),&amp;nbsp;//&amp;nbsp;使用chromedp.ByID选择器。向id=username的标签输入username。
chromedp.SetValue&amp;nbsp;设置值，和sendkey不同的是，如果原有的输入框中有内容，sendkey不会清空原来的值，setva
chromedp.Value(`#input1`,&amp;nbsp;val1,&amp;nbsp;chromedp.ByID),&amp;nbsp;//&amp;nbsp;获取id=input1的值，并把值传给val1
chromedp.Click(&amp;quot;btn-submit&amp;quot;,chromedp.Bysearch),&amp;nbsp;//&amp;nbsp;触发点击事件，
chromedp.Screenshot(`#row`,&amp;nbsp;&amp;amp;buf,&amp;nbsp;chromedp.ByID),&amp;nbsp;//&amp;nbsp;截图id=row的标签，把值传入buf&amp;nbsp;需要事先定义var&amp;nbsp;buf&amp;nbsp;[]byte&amp;nbsp;
chromedp.ActionFunc(func(context.Context,&amp;nbsp;cdp.Executor)&amp;nbsp;error&amp;nbsp;{&amp;nbsp;//&amp;nbsp;将图片写入文件
&amp;nbsp;return&amp;nbsp;ioutil.WriteFile(&amp;quot;test.png&amp;quot;,&amp;nbsp;buf,&amp;nbsp;0644)
}),&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;常用选择器&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;pingfang SC&amp;quot;, &amp;quot;helvetica neue&amp;quot;, arial, &amp;quot;hiragino sans gb&amp;quot;, &amp;quot;microsoft yahei ui&amp;quot;, &amp;quot;microsoft yahei&amp;quot;, simsun, sans-serif; white-space: pre-wrap; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-go&quot;&gt;chromedp.BySearch&amp;nbsp;//&amp;nbsp;如果不写，默认会使用这个选择器，类似devtools&amp;nbsp;ctrl+f&amp;nbsp;搜索
chromedp.ByID&amp;nbsp;//&amp;nbsp;只id来选择元素
chromedp.ByQuery&amp;nbsp;//&amp;nbsp;根据document.querySelector的规则选择元素，返回单个节点
chromedp.ByQueryAll&amp;nbsp;//&amp;nbsp;根据document.querySelectorAll返回所有匹配的节点
chromedp.ByNodeIP&amp;nbsp;//&amp;nbsp;检索特定节点(必须先有分配的节点IP)，这个暂时没用过也没看到过例子，如果有例子可以发给我看下&lt;/pre&gt;</description><pubDate>Sat, 24 Feb 2024 10:40:56 +0800</pubDate></item><item><title>gin验证参数</title><link>http://go.hh85.com/?id=33</link><description>&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;//&amp;nbsp;不能为空，并且不能没有这个字段
required：&amp;nbsp;必填字段，如：binding:&amp;quot;required&amp;quot;&amp;nbsp;&amp;nbsp;

//&amp;nbsp;针对字符串的长度
min&amp;nbsp;最小长度，如：binding:&amp;quot;min=5&amp;quot;
max&amp;nbsp;最大长度，如：binding:&amp;quot;max=10&amp;quot;
len&amp;nbsp;长度，如：binding:&amp;quot;len=6&amp;quot;

//&amp;nbsp;针对数字的大小
eq&amp;nbsp;等于，如：binding:&amp;quot;eq=3&amp;quot;
ne&amp;nbsp;不等于，如：binding:&amp;quot;ne=12&amp;quot;
gt&amp;nbsp;大于，如：binding:&amp;quot;gt=10&amp;quot;
gte&amp;nbsp;大于等于，如：binding:&amp;quot;gte=10&amp;quot;
lt&amp;nbsp;小于，如：binding:&amp;quot;lt=10&amp;quot;
lte&amp;nbsp;小于等于，如：binding:&amp;quot;lte=10&amp;quot;

//&amp;nbsp;针对同级字段的
eqfield&amp;nbsp;等于其他字段的值，如：PassWord&amp;nbsp;string&amp;nbsp;`binding:&amp;quot;eqfield=Password&amp;quot;`
nefield&amp;nbsp;不等于其他字段的值


-&amp;nbsp;忽略字段，如：binding:&amp;quot;-&amp;quot;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;演示代码&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;import&amp;nbsp;(
	&amp;quot;fmt&amp;quot;
	&amp;quot;github.com/gin-gonic/gin&amp;quot;
	&amp;quot;github.com/go-playground/validator/v10&amp;quot;
	&amp;quot;reflect&amp;quot;
)

type&amp;nbsp;UserInfo&amp;nbsp;struct&amp;nbsp;{
	Username&amp;nbsp;string&amp;nbsp;`json:&amp;quot;username&amp;quot;&amp;nbsp;binding:&amp;quot;required&amp;quot;&amp;nbsp;msg:&amp;quot;用户名不能为空&amp;quot;`
	Password&amp;nbsp;string&amp;nbsp;`json:&amp;quot;password&amp;quot;&amp;nbsp;binding:&amp;quot;min=3,max=6&amp;quot;&amp;nbsp;msg:&amp;quot;密码长度不能小于3大于6&amp;quot;`
	Email&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string&amp;nbsp;`json:&amp;quot;email&amp;quot;&amp;nbsp;binding:&amp;quot;email&amp;quot;&amp;nbsp;msg:&amp;quot;邮箱地址格式不正确&amp;quot;`
}

func&amp;nbsp;GetValidMsg(err&amp;nbsp;error,&amp;nbsp;obj&amp;nbsp;any)&amp;nbsp;string&amp;nbsp;{
	//&amp;nbsp;使用的时候，需要传obj的指针
	getObj&amp;nbsp;:=&amp;nbsp;reflect.TypeOf(obj)
	//&amp;nbsp;将err接口断言为具体类型
	if&amp;nbsp;errs,&amp;nbsp;ok&amp;nbsp;:=&amp;nbsp;err.(validator.ValidationErrors);&amp;nbsp;ok&amp;nbsp;{
		//&amp;nbsp;断言成功
		for&amp;nbsp;_,&amp;nbsp;e&amp;nbsp;:=&amp;nbsp;range&amp;nbsp;errs&amp;nbsp;{
			//&amp;nbsp;循环每一个错误信息
			//&amp;nbsp;根据报错字段名，获取结构体的具体字段
			if&amp;nbsp;f,&amp;nbsp;exits&amp;nbsp;:=&amp;nbsp;getObj.Elem().FieldByName(e.Field());&amp;nbsp;exits&amp;nbsp;{
				msg&amp;nbsp;:=&amp;nbsp;f.Tag.Get(&amp;quot;msg&amp;quot;)
				return&amp;nbsp;msg
			}
		}
	}

	return&amp;nbsp;err.Error()
}

func&amp;nbsp;main()&amp;nbsp;{
	router&amp;nbsp;:=&amp;nbsp;gin.Default()

	router.POST(&amp;quot;/users&amp;quot;,&amp;nbsp;func(c&amp;nbsp;*gin.Context)&amp;nbsp;{
		var&amp;nbsp;userInfo&amp;nbsp;UserInfo
		err&amp;nbsp;:=&amp;nbsp;c.ShouldBindJSON(&amp;amp;userInfo)
		if&amp;nbsp;err&amp;nbsp;!=&amp;nbsp;nil&amp;nbsp;{
			fmt.Println(err)
			c.JSON(200,&amp;nbsp;gin.H{&amp;quot;msg&amp;quot;:&amp;nbsp;GetValidMsg(err,&amp;nbsp;&amp;amp;userInfo)})
			return
		}
		c.JSON(200,&amp;nbsp;userInfo)
	})

	router.Run(&amp;quot;:8000&amp;quot;)
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 04 Jan 2024 13:57:21 +0800</pubDate></item><item><title>go语言数据类型</title><link>http://go.hh85.com/?id=32</link><description>&lt;p&gt;&lt;strong&gt;一：值类型&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;变量直接存储值，内存通过栈中分配，系统自动回收，不需要初始化&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1：基本数据类型&amp;nbsp;int string bool&lt;/p&gt;&lt;p&gt;&amp;nbsp;var a int var b string&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2: 数组&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;var s [2]int&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3：结构体&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;s:=&amp;nbsp;struct&amp;nbsp;{
&amp;nbsp;Id&amp;nbsp;int
&amp;nbsp;Name&amp;nbsp;string
}{}&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;二：引用类型&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;变量存储的是一个内存地址&amp;nbsp;内存在堆上分配，通过GC回收，使用需要初始化，可以通过make初始化&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1:切片&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;c:=&amp;nbsp;make([]string,0)&lt;/pre&gt;&lt;p&gt;2：管道&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;ch:=&amp;nbsp;make(chan&amp;nbsp;string,5)&lt;/pre&gt;&lt;p&gt;3：Map&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;m:=&amp;nbsp;make(map[string]string)&lt;/pre&gt;&lt;p&gt;4:&amp;nbsp;指针&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-actionscript&quot;&gt;var&amp;nbsp;n&amp;nbsp;=&amp;nbsp;100
var&amp;nbsp;p&amp;nbsp;*int&amp;nbsp;&amp;nbsp;=&amp;nbsp;&amp;amp;n&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sat, 30 Dec 2023 09:58:41 +0800</pubDate></item><item><title>GRPC使用入门</title><link>http://go.hh85.com/?id=31</link><description>&lt;p&gt;1：官网&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://grpc.io/&quot; _src=&quot;https://grpc.io/&quot;&gt;https://grpc.io/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2：go&amp;nbsp;开发文档&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://grpc.io/docs/languages/go/quickstart/&quot; _src=&quot;https://grpc.io/docs/languages/go/quickstart/&quot;&gt;https://grpc.io/docs/languages/go/quickstart/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3：proto文件规范介绍&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://protobuf.dev/programming-guides/proto3/&quot; _src=&quot;https://protobuf.dev/programming-guides/proto3/&quot;&gt;https://protobuf.dev/programming-guides/proto3/&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;4：下载编译器&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;下载地址：&lt;a href=&quot;https://github.com/protocolbuffers/protobuf/releases/&quot; _src=&quot;https://github.com/protocolbuffers/protobuf/releases/&quot;&gt;https://github.com/protocolbuffers/protobuf/releases/&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;下载完成后配置电脑环境变量在path里添加bin位置&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/12/202312291703833617747352.png&quot; title=&quot;微信图片_20231229150639.png&quot; alt=&quot;微信图片_20231229150639.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;测试命令&lt;/p&gt;&lt;p&gt;protoc --version&amp;nbsp;如果正常运行代表配置成功&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;5：配置proto文件&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-cpp&quot;&gt;syntax&amp;nbsp;=&amp;nbsp;&amp;quot;proto3&amp;quot;;

service&amp;nbsp;HelloService{
&amp;nbsp;&amp;nbsp;//定义若干个服务的方法，定义服务接口
&amp;nbsp;&amp;nbsp;//rpc&amp;nbsp;服务名字&amp;nbsp;服务器参数&amp;nbsp;返回参数
&amp;nbsp;&amp;nbsp;rpc&amp;nbsp;hello(LoginRequest)&amp;nbsp;returns(Result){};
}

//自定义消息内容
message&amp;nbsp;LoginRequest{&amp;nbsp;&amp;nbsp;&amp;nbsp;string&amp;nbsp;query&amp;nbsp;=&amp;nbsp;1;&amp;nbsp;&amp;nbsp;&amp;nbsp;int32&amp;nbsp;page_number&amp;nbsp;=&amp;nbsp;2;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Which&amp;nbsp;page&amp;nbsp;number&amp;nbsp;do&amp;nbsp;we&amp;nbsp;want?&amp;nbsp;&amp;nbsp;&amp;nbsp;int32&amp;nbsp;results_per_page&amp;nbsp;=&amp;nbsp;3;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Number&amp;nbsp;of&amp;nbsp;results&amp;nbsp;to&amp;nbsp;return&amp;nbsp;per&amp;nbsp;page.&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 29 Dec 2023 14:59:25 +0800</pubDate></item><item><title>阿里云OSS直传签名Go版</title><link>http://go.hh85.com/?id=30</link><description>&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 36px;&quot;&gt;&lt;strong&gt;1:进入RAM控制台，创建一个RAM用户&amp;nbsp;访问方式一般选择OPenApi就可以了&lt;/strong&gt;&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683166057771832.png&quot; title=&quot;1.png&quot; alt=&quot;1.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;登陆名称自己随意填写不重复就可以，确定后添加成功&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178030787236.png&quot; title=&quot;2.png&quot; alt=&quot;2.png&quot;/&gt;生成的密钥信息可以保存到本地。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 36px;&quot;&gt;&lt;strong&gt;2：为RAM用户添加系统策略&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;添加&lt;span style=&quot;color: #4D4D4D; font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif; font-size: 16px; font-variant-ligatures: no-common-ligatures; background-color: #FFFFFF;&quot;&gt;AliyunSTSAssumeRoleAccess权限&amp;nbsp;这个步骤主要&lt;span style=&quot;color: #4D4D4D; font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif; font-size: 16px; font-variant-ligatures: no-common-ligatures; background-color: #FFFFFF;&quot;&gt;创建了一个用于获取临时访问凭证的角色，获得角色ARN&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683166144534367.png&quot; title=&quot;2.png&quot; alt=&quot;2.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;3：创建角色&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如图：选择角色-&amp;gt; 创建角色&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178078251020.png&quot; title=&quot;7.png&quot; alt=&quot;7.png&quot;/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;类型选择阿里云账户&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178135569902.png&quot; title=&quot;8.png&quot; alt=&quot;8.png&quot;/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178175117075.png&quot; title=&quot;9.png&quot; alt=&quot;9.png&quot;/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;添加角色名创建完成&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178219327971.png&quot; title=&quot;10.png&quot; alt=&quot;10.png&quot;/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这里的角色名称和ARN保存一下后续代码中要用到&lt;/p&gt;&lt;p&gt;&lt;strong style=&quot;font-size: 36px; white-space: normal;&quot;&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 36px;&quot;&gt;&lt;strong&gt;4：创建策略&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;这里主要通过自定义策略实现，选择左边权限管理-》权限策略-》创建策略&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683166422427895.png&quot; title=&quot;5.png&quot; alt=&quot;5.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;切换到脚本编辑模式填写脚本内容&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178322128444.png&quot; title=&quot;12.png&quot; alt=&quot;12.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;主要是设置Rescource配置对资源的访问&amp;nbsp;权限&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178342202888.png&quot; title=&quot;13.png&quot; alt=&quot;13.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre;&quot;&gt;Action：允许的操作&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Version&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Statement&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Effect&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;Allow&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;oss:PutObject&amp;quot; &lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;acs:oss:*:*:oss的&lt;span style=&quot;color: #918B3B; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre;&quot;&gt;bucket名字&lt;/span&gt;/目录&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;acs:oss:*:*:&lt;span style=&quot;color: #918B3B; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre;&quot;&gt;oss的&lt;/span&gt;&lt;span style=&quot;color: #918B3B; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre;&quot;&gt;bucket名字&lt;/span&gt;/目录/*&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;如果不限制目录可以这样写&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;&amp;quot;Resource&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;acs:oss:*:*:oss的bucket名字&amp;quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #918B3B; white-space: pre;&quot;&gt;&amp;quot;acs:oss:*:*:oss的bucket名字/*&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #695D69; font-family: Menlo, Monaco, Consolas, Courier, monospace; white-space: pre; background-color: #F7F7F7;&quot;&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot; style=&quot;box-sizing: border-box; padding: 0px; margin: 0px; font-family: Menlo, Monaco, Consolas, Courier, monospace; color: #695D69; white-space: pre;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;脚本编辑完成后取个名字保存备用&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178374801379.png&quot; title=&quot;15.png&quot; alt=&quot;15.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683166685259797.png&quot; title=&quot;7.png&quot; alt=&quot;7.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 36px;&quot;&gt;&lt;strong&gt;4：为角色添加策略&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;把上面的脚本权限添加给校色，回到角色列表找到对应的用户选择添加权限&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178418719870.png&quot; title=&quot;16.png&quot; alt=&quot;16.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;通过名字查找上面添加的策略，然后保存就完成了整个权限的添加。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;http://go.hh85.com/zb_users/upload/2023/05/202305041683178439376298.png&quot; title=&quot;17.png&quot; alt=&quot;17.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-weight: 600; background-color: #FFFFFF;&quot;&gt;万事俱备接下来是关于Go语言相关的事情。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-weight: 600; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-weight: 600; background-color: #FFFFFF;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;6：Go代码上传案例&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;package&amp;nbsp;main&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;
import&amp;nbsp;(&amp;nbsp;&amp;nbsp;
	&amp;quot;fmt&amp;quot;&amp;nbsp;&amp;nbsp;
	&amp;quot;os&amp;quot;
	&amp;quot;time&amp;quot;
	&amp;quot;strconv&amp;quot;
	&amp;quot;net/http&amp;quot;&amp;nbsp;
	&amp;quot;io&amp;quot;&amp;nbsp;&amp;nbsp;
	&amp;quot;io/ioutil&amp;quot;&amp;nbsp;&amp;nbsp;
	&amp;quot;encoding/base64&amp;quot;
	&amp;quot;encoding/pem&amp;quot;
	&amp;quot;encoding/json&amp;quot;
	&amp;quot;crypto&amp;quot;
	&amp;quot;crypto/md5&amp;quot;
	&amp;quot;crypto/rsa&amp;quot;
	&amp;quot;crypto/x509&amp;quot;
	&amp;quot;crypto/hmac&amp;quot;
	&amp;quot;crypto/sha1&amp;quot;
	&amp;quot;errors&amp;quot;
	&amp;quot;hash&amp;quot;
)

//&amp;nbsp;请填写您的AccessKeyId。
var&amp;nbsp;accessKeyId&amp;nbsp;string&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;lt;yourAccessKeyId&amp;gt;&amp;quot;
//&amp;nbsp;请填写您的AccessKeySecret。
var&amp;nbsp;accessKeySecret&amp;nbsp;string&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;lt;yourAccessKeySecret&amp;gt;&amp;quot;
//&amp;nbsp;host的格式为&amp;nbsp;bucketname.endpoint&amp;nbsp;，请替换为您的真实信息。
var&amp;nbsp;host&amp;nbsp;string&amp;nbsp;=&amp;nbsp;&amp;quot;http://bucket-name.oss-cn-hangzhou.aliyuncs.com&amp;quot;&amp;nbsp;
//&amp;nbsp;callbackUrl为&amp;nbsp;上传回调服务器的URL，请将下面的IP和Port配置为您自己的真实信息。
var&amp;nbsp;callbackUrl&amp;nbsp;string&amp;nbsp;=&amp;nbsp;&amp;quot;http://88.88.88.88:8888&amp;quot;;
//&amp;nbsp;用户上传文件时指定的前缀。
var&amp;nbsp;upload_dir&amp;nbsp;string&amp;nbsp;=&amp;nbsp;&amp;quot;user-dir-prefix/&amp;quot;
var&amp;nbsp;expire_time&amp;nbsp;int64&amp;nbsp;=&amp;nbsp;30

const&amp;nbsp;(&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base64Table&amp;nbsp;=&amp;nbsp;&amp;quot;123QRSTUabcdVWXYZHijKLAWDCABDstEFGuvwxyzGHIJklmnopqr234560178912&amp;quot;&amp;nbsp;&amp;nbsp;
)&amp;nbsp;&amp;nbsp;

var&amp;nbsp;coder&amp;nbsp;=&amp;nbsp;base64.NewEncoding(base64Table)&amp;nbsp;
func&amp;nbsp;base64Encode(src&amp;nbsp;[]byte)&amp;nbsp;[]byte&amp;nbsp;{&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[]byte(coder.EncodeToString(src))&amp;nbsp;&amp;nbsp;
}&amp;nbsp;&amp;nbsp;

func&amp;nbsp;get_gmt_iso8601(expire_end&amp;nbsp;int64)&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;tokenExpire&amp;nbsp;=&amp;nbsp;time.Unix(expire_end,&amp;nbsp;0).UTC().Format(&amp;quot;2006-01-02T15:04:05Z&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;tokenExpire&amp;nbsp;
}

type&amp;nbsp;ConfigStruct&amp;nbsp;struct{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Expiration&amp;nbsp;string&amp;nbsp;`json:&amp;quot;expiration&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Conditions&amp;nbsp;[][]string&amp;nbsp;`json:&amp;quot;conditions&amp;quot;`
}&amp;nbsp;

type&amp;nbsp;PolicyToken&amp;nbsp;struct{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AccessKeyId&amp;nbsp;string&amp;nbsp;`json:&amp;quot;accessid&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Host&amp;nbsp;string&amp;nbsp;`json:&amp;quot;host&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Expire&amp;nbsp;int64&amp;nbsp;`json:&amp;quot;expire&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Signature&amp;nbsp;string&amp;nbsp;`json:&amp;quot;signature&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Policy&amp;nbsp;string&amp;nbsp;`json:&amp;quot;policy&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Directory&amp;nbsp;string&amp;nbsp;`json:&amp;quot;dir&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Callback&amp;nbsp;string&amp;nbsp;`json:&amp;quot;callback&amp;quot;`
}

type&amp;nbsp;CallbackParam&amp;nbsp;struct{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallbackUrl&amp;nbsp;string&amp;nbsp;`json:&amp;quot;callbackUrl&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallbackBody&amp;nbsp;string&amp;nbsp;`json:&amp;quot;callbackBody&amp;quot;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallbackBodyType&amp;nbsp;string&amp;nbsp;`json:&amp;quot;callbackBodyType&amp;quot;`
}

func&amp;nbsp;get_policy_token()&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;now&amp;nbsp;:=&amp;nbsp;time.Now().Unix()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expire_end&amp;nbsp;:=&amp;nbsp;now&amp;nbsp;+&amp;nbsp;expire_time&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;tokenExpire&amp;nbsp;=&amp;nbsp;get_gmt_iso8601(expire_end)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//create&amp;nbsp;post&amp;nbsp;policy&amp;nbsp;json
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;config&amp;nbsp;ConfigStruct
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;config.Expiration&amp;nbsp;=&amp;nbsp;tokenExpire&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;condition&amp;nbsp;[]string
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;condition&amp;nbsp;=&amp;nbsp;append(condition,&amp;nbsp;&amp;quot;starts-with&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;condition&amp;nbsp;=&amp;nbsp;append(condition,&amp;nbsp;&amp;quot;$key&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;condition&amp;nbsp;=&amp;nbsp;append(condition,&amp;nbsp;upload_dir)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;config.Conditions&amp;nbsp;=&amp;nbsp;append(config.Conditions,&amp;nbsp;condition)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//calucate&amp;nbsp;signature
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result,err:=json.Marshal(config)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;debyte&amp;nbsp;:=&amp;nbsp;base64.StdEncoding.EncodeToString(result)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;h&amp;nbsp;:=&amp;nbsp;hmac.New(func()&amp;nbsp;hash.Hash&amp;nbsp;{&amp;nbsp;return&amp;nbsp;sha1.New()&amp;nbsp;},&amp;nbsp;[]byte(accessKeySecret))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;io.WriteString(h,&amp;nbsp;debyte)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signedStr&amp;nbsp;:=&amp;nbsp;base64.StdEncoding.EncodeToString(h.Sum(nil))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;callbackParam&amp;nbsp;CallbackParam
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callbackParam.CallbackUrl&amp;nbsp;=&amp;nbsp;callbackUrl
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callbackParam.CallbackBody&amp;nbsp;=&amp;nbsp;&amp;quot;filename=${object}&amp;amp;size=${size}&amp;amp;mimeType=${mimeType}&amp;amp;height=${imageInfo.height}&amp;amp;width=${imageInfo.width}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callbackParam.CallbackBodyType&amp;nbsp;=&amp;nbsp;&amp;quot;application/x-www-form-urlencoded&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callback_str,err:=json.Marshal(callbackParam)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;err&amp;nbsp;!=&amp;nbsp;nil&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;callback&amp;nbsp;json&amp;nbsp;err:&amp;quot;,&amp;nbsp;err)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callbackBase64&amp;nbsp;:=&amp;nbsp;base64.StdEncoding.EncodeToString(callback_str)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;policyToken&amp;nbsp;PolicyToken
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.AccessKeyId&amp;nbsp;=&amp;nbsp;accessKeyId
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Host&amp;nbsp;=&amp;nbsp;host
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Expire&amp;nbsp;=&amp;nbsp;expire_end
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Signature&amp;nbsp;=&amp;nbsp;string(signedStr)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Directory&amp;nbsp;=&amp;nbsp;upload_dir
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Policy&amp;nbsp;=&amp;nbsp;string(debyte)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;policyToken.Callback&amp;nbsp;=&amp;nbsp;string(callbackBase64)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response,err:=json.Marshal(policyToken)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;err&amp;nbsp;!=&amp;nbsp;nil&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;json&amp;nbsp;err:&amp;quot;,&amp;nbsp;err)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;string(response)
}

func&amp;nbsp;main()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strIPPort&amp;nbsp;:=&amp;nbsp;&amp;quot;:8080&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len(os.Args)==3)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strIPPort&amp;nbsp;=&amp;nbsp;fmt.Sprintf(&amp;quot;%s:%s&amp;quot;,&amp;nbsp;os.Args[1],&amp;nbsp;os.Args[2])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(len(os.Args)!=1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;Usage&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;go&amp;nbsp;run&amp;nbsp;callbackserver.go&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;Usage&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;go&amp;nbsp;run&amp;nbsp;callbackserver.go&amp;nbsp;ip&amp;nbsp;port&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;Example&amp;nbsp;:&amp;nbsp;go&amp;nbsp;run&amp;nbsp;callbackserver.go&amp;nbsp;11.22.33.44&amp;nbsp;80&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;Example&amp;nbsp;:&amp;nbsp;go&amp;nbsp;run&amp;nbsp;callbackserver.go&amp;nbsp;0.0.0.0&amp;nbsp;8080&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;os.Exit(0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\ncallbackserver&amp;nbsp;is&amp;nbsp;running&amp;nbsp;on&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;strIPPort);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;http.HandleFunc(&amp;quot;/&amp;quot;,&amp;nbsp;handlerRequest)&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;http.ListenAndServe(strIPPort,&amp;nbsp;nil)&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strError&amp;nbsp;:=&amp;nbsp;fmt.Sprintf(&amp;quot;http.ListenAndServe&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;panic(strError)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

func&amp;nbsp;handlerRequest(w&amp;nbsp;http.ResponseWriter,&amp;nbsp;r&amp;nbsp;*http.Request)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(r.Method&amp;nbsp;==&amp;nbsp;&amp;quot;GET&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response&amp;nbsp;:=&amp;nbsp;get_policy_token()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Header().Set(&amp;quot;Access-Control-Allow-Methods&amp;quot;,&amp;nbsp;&amp;quot;POST&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Header().Set(&amp;quot;Access-Control-Allow-Origin&amp;quot;,&amp;nbsp;&amp;quot;*&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;io.WriteString(w,&amp;nbsp;response)
		}
		
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(r.Method&amp;nbsp;==&amp;nbsp;&amp;quot;POST&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;\nHandle&amp;nbsp;Post&amp;nbsp;Request&amp;nbsp;...&amp;nbsp;&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Get&amp;nbsp;PublicKey&amp;nbsp;bytes
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bytePublicKey,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;getPublicKey(r)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseFailed(w)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Get&amp;nbsp;Authorization&amp;nbsp;bytes&amp;nbsp;:&amp;nbsp;decode&amp;nbsp;from&amp;nbsp;Base64String
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byteAuthorization,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;getAuthorization(r)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseFailed(w)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Get&amp;nbsp;MD5&amp;nbsp;bytes&amp;nbsp;from&amp;nbsp;Newly&amp;nbsp;Constructed&amp;nbsp;Authrization&amp;nbsp;String.&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byteMD5,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;getMD5FromNewAuthString(r)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseFailed(w)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;verifySignature&amp;nbsp;and&amp;nbsp;response&amp;nbsp;to&amp;nbsp;client&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(verifySignature(bytePublicKey,&amp;nbsp;byteMD5,&amp;nbsp;byteAuthorization))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;do&amp;nbsp;something&amp;nbsp;you&amp;nbsp;want&amp;nbsp;accoding&amp;nbsp;to&amp;nbsp;callback_body&amp;nbsp;...

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseSuccess(w)&amp;nbsp;&amp;nbsp;//&amp;nbsp;response&amp;nbsp;OK&amp;nbsp;:&amp;nbsp;200&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responseFailed(w)&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;response&amp;nbsp;FAILED&amp;nbsp;:&amp;nbsp;400&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&amp;nbsp;&amp;nbsp;

//&amp;nbsp;getPublicKey&amp;nbsp;:&amp;nbsp;Get&amp;nbsp;PublicKey&amp;nbsp;bytes&amp;nbsp;from&amp;nbsp;Request.URL
func&amp;nbsp;getPublicKey(r&amp;nbsp;*http.Request)&amp;nbsp;([]byte,&amp;nbsp;error)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;bytePublicKey&amp;nbsp;[]byte
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;get&amp;nbsp;PublicKey&amp;nbsp;URL
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publicKeyURLBase64&amp;nbsp;:=&amp;nbsp;r.Header.Get(&amp;quot;x-oss-pub-key-url&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(publicKeyURLBase64&amp;nbsp;==&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;GetPublicKey&amp;nbsp;from&amp;nbsp;Request&amp;nbsp;header&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;&amp;nbsp;No&amp;nbsp;x-oss-pub-key-url&amp;nbsp;field.&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;bytePublicKey,&amp;nbsp;errors.New(&amp;quot;no&amp;nbsp;x-oss-pub-key-url&amp;nbsp;field&amp;nbsp;in&amp;nbsp;Request&amp;nbsp;header&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publicKeyURL,&amp;nbsp;_&amp;nbsp;:=&amp;nbsp;base64.StdEncoding.DecodeString(publicKeyURLBase64)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;fmt.Printf(&amp;quot;publicKeyURL={%s}\n&amp;quot;,&amp;nbsp;publicKeyURL)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;get&amp;nbsp;PublicKey&amp;nbsp;Content&amp;nbsp;from&amp;nbsp;URL
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;responsePublicKeyURL,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;http.Get(string(publicKeyURL))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;Get&amp;nbsp;PublicKey&amp;nbsp;Content&amp;nbsp;from&amp;nbsp;URL&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;bytePublicKey,&amp;nbsp;err
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bytePublicKey,&amp;nbsp;err&amp;nbsp;=&amp;nbsp;ioutil.ReadAll(responsePublicKeyURL.Body)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;Read&amp;nbsp;PublicKey&amp;nbsp;Content&amp;nbsp;from&amp;nbsp;URL&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;bytePublicKey,&amp;nbsp;err
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;defer&amp;nbsp;responsePublicKeyURL.Body.Close()&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;fmt.Printf(&amp;quot;publicKey={%s}\n&amp;quot;,&amp;nbsp;bytePublicKey)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;bytePublicKey,&amp;nbsp;nil
}

//&amp;nbsp;getAuthorization&amp;nbsp;:&amp;nbsp;decode&amp;nbsp;from&amp;nbsp;Base64String
func&amp;nbsp;getAuthorization(r&amp;nbsp;*http.Request)&amp;nbsp;([]byte,&amp;nbsp;error)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;byteAuthorization&amp;nbsp;[]byte
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Get&amp;nbsp;Authorization&amp;nbsp;bytes&amp;nbsp;:&amp;nbsp;decode&amp;nbsp;from&amp;nbsp;Base64String
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strAuthorizationBase64&amp;nbsp;:=&amp;nbsp;r.Header.Get(&amp;quot;authorization&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(strAuthorizationBase64&amp;nbsp;==&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&amp;quot;Failed&amp;nbsp;to&amp;nbsp;get&amp;nbsp;authorization&amp;nbsp;field&amp;nbsp;from&amp;nbsp;request&amp;nbsp;header.&amp;nbsp;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;byteAuthorization,&amp;nbsp;errors.New(&amp;quot;no&amp;nbsp;authorization&amp;nbsp;field&amp;nbsp;in&amp;nbsp;Request&amp;nbsp;header&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byteAuthorization,&amp;nbsp;_&amp;nbsp;=&amp;nbsp;base64.StdEncoding.DecodeString(strAuthorizationBase64)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;byteAuthorization,&amp;nbsp;nil
}

//&amp;nbsp;getMD5FromNewAuthString&amp;nbsp;:&amp;nbsp;Get&amp;nbsp;MD5&amp;nbsp;bytes&amp;nbsp;from&amp;nbsp;Newly&amp;nbsp;Constructed&amp;nbsp;Authrization&amp;nbsp;String.&amp;nbsp;
func&amp;nbsp;getMD5FromNewAuthString(r&amp;nbsp;*http.Request)&amp;nbsp;([]byte,&amp;nbsp;error)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;byteMD5&amp;nbsp;[]byte
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Construct&amp;nbsp;the&amp;nbsp;New&amp;nbsp;Auth&amp;nbsp;String&amp;nbsp;from&amp;nbsp;URI+Query+Body
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bodyContent,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;ioutil.ReadAll(r.Body)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r.Body.Close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;Read&amp;nbsp;Request&amp;nbsp;Body&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;byteMD5,&amp;nbsp;err
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strCallbackBody&amp;nbsp;:=&amp;nbsp;string(bodyContent)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;fmt.Printf(&amp;quot;r.URL.RawPath={%s},&amp;nbsp;r.URL.Query()={%s},&amp;nbsp;strCallbackBody={%s}\n&amp;quot;,&amp;nbsp;r.URL.RawPath,&amp;nbsp;r.URL.Query(),&amp;nbsp;strCallbackBody)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strURLPathDecode,&amp;nbsp;errUnescape&amp;nbsp;:=&amp;nbsp;unescapePath(r.URL.Path,&amp;nbsp;encodePathSegment)&amp;nbsp;&amp;nbsp;//url.PathUnescape(r.URL.Path)&amp;nbsp;for&amp;nbsp;Golang&amp;nbsp;v1.8.2+
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(errUnescape&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;url.PathUnescape&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;URL.Path=%s,&amp;nbsp;error=%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;r.URL.Path,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;byteMD5,&amp;nbsp;errUnescape
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Generate&amp;nbsp;New&amp;nbsp;Auth&amp;nbsp;String&amp;nbsp;prepare&amp;nbsp;for&amp;nbsp;MD5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strAuth&amp;nbsp;:=&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(r.URL.RawQuery&amp;nbsp;==&amp;nbsp;&amp;quot;&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strAuth&amp;nbsp;=&amp;nbsp;fmt.Sprintf(&amp;quot;%s\n%s&amp;quot;,&amp;nbsp;strURLPathDecode,&amp;nbsp;strCallbackBody)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strAuth&amp;nbsp;=&amp;nbsp;fmt.Sprintf(&amp;quot;%s?%s\n%s&amp;quot;,&amp;nbsp;strURLPathDecode,&amp;nbsp;r.URL.RawQuery,&amp;nbsp;strCallbackBody)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;fmt.Printf(&amp;quot;NewlyConstructedAuthString={%s}\n&amp;quot;,&amp;nbsp;strAuth)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Generate&amp;nbsp;MD5&amp;nbsp;from&amp;nbsp;the&amp;nbsp;New&amp;nbsp;Auth&amp;nbsp;String&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;md5Ctx&amp;nbsp;:=&amp;nbsp;md5.New()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;md5Ctx.Write([]byte(strAuth))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byteMD5&amp;nbsp;=&amp;nbsp;md5Ctx.Sum(nil)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;byteMD5,&amp;nbsp;nil
}

/*&amp;nbsp;&amp;nbsp;VerifySignature
*&amp;nbsp;&amp;nbsp;&amp;nbsp;VerifySignature需要三个重要的数据信息来进行签名验证：&amp;nbsp;1&amp;gt;获取公钥PublicKey;&amp;nbsp;&amp;nbsp;2&amp;gt;生成新的MD5鉴权串;&amp;nbsp;&amp;nbsp;3&amp;gt;解码Request携带的鉴权串;&amp;nbsp;
*&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;gt;获取公钥PublicKey&amp;nbsp;:&amp;nbsp;从RequestHeader的&amp;quot;x-oss-pub-key-url&amp;quot;字段中获取&amp;nbsp;URL,&amp;nbsp;读取URL链接的包含的公钥内容，&amp;nbsp;进行解码解析，&amp;nbsp;将其作为rsa.VerifyPKCS1v15的入参。&amp;nbsp;
*&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;gt;生成新的MD5鉴权串&amp;nbsp;:&amp;nbsp;把Request中的url中的path部分进行urldecode，&amp;nbsp;加上url的query部分，&amp;nbsp;再加上body，&amp;nbsp;组合之后进行MD5编码，&amp;nbsp;得到MD5鉴权字节串。&amp;nbsp;
*&amp;nbsp;&amp;nbsp;&amp;nbsp;3&amp;gt;解码Request携带的鉴权串&amp;nbsp;：&amp;nbsp;获取RequestHeader的&amp;quot;authorization&amp;quot;字段，&amp;nbsp;对其进行Base64解码，作为签名验证的鉴权对比串。&amp;nbsp;
*&amp;nbsp;&amp;nbsp;&amp;nbsp;rsa.VerifyPKCS1v15进行签名验证，返回验证结果。
*&amp;nbsp;*/
func&amp;nbsp;verifySignature(bytePublicKey&amp;nbsp;[]byte,&amp;nbsp;byteMd5&amp;nbsp;[]byte,&amp;nbsp;authorization&amp;nbsp;[]byte)&amp;nbsp;bool&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pubBlock,&amp;nbsp;_&amp;nbsp;:=&amp;nbsp;pem.Decode(bytePublicKey)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(pubBlock&amp;nbsp;==&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;Failed&amp;nbsp;to&amp;nbsp;parse&amp;nbsp;PEM&amp;nbsp;block&amp;nbsp;containing&amp;nbsp;the&amp;nbsp;public&amp;nbsp;key&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pubInterface,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;x509.ParsePKIXPublicKey(pubBlock.Bytes)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(pubInterface&amp;nbsp;==&amp;nbsp;nil)&amp;nbsp;||&amp;nbsp;(err&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;x509.ParsePKIXPublicKey(publicKey)&amp;nbsp;failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;err.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pub&amp;nbsp;:=&amp;nbsp;pubInterface.(*rsa.PublicKey)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errorVerifyPKCS1v15&amp;nbsp;:=&amp;nbsp;rsa.VerifyPKCS1v15(pub,&amp;nbsp;crypto.MD5,&amp;nbsp;byteMd5,&amp;nbsp;authorization)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(errorVerifyPKCS1v15&amp;nbsp;!=&amp;nbsp;nil)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\nSignature&amp;nbsp;Verification&amp;nbsp;is&amp;nbsp;Failed&amp;nbsp;:&amp;nbsp;%s&amp;nbsp;\n&amp;quot;,&amp;nbsp;errorVerifyPKCS1v15.Error())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//printByteArray(byteMd5,&amp;nbsp;&amp;quot;AuthMd5(fromNewAuthString)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//printByteArray(bytePublicKey,&amp;nbsp;&amp;quot;PublicKeyBase64&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//printByteArray(authorization,&amp;nbsp;&amp;quot;AuthorizationFromRequest&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\nSignature&amp;nbsp;Verification&amp;nbsp;is&amp;nbsp;Successful.&amp;nbsp;\n&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;true
}

//&amp;nbsp;responseSuccess&amp;nbsp;:&amp;nbsp;Response&amp;nbsp;200&amp;nbsp;to&amp;nbsp;client
func&amp;nbsp;responseSuccess(w&amp;nbsp;http.ResponseWriter)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strResponseBody&amp;nbsp;:=&amp;nbsp;&amp;quot;{\&amp;quot;Status\&amp;quot;:\&amp;quot;OK\&amp;quot;}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Header().Set(&amp;quot;Content-Type&amp;quot;,&amp;nbsp;&amp;quot;application/json&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Header().Set(&amp;quot;Content-Length&amp;quot;,&amp;nbsp;strconv.Itoa(len(strResponseBody)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.WriteHeader(http.StatusOK)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.Write([]byte(strResponseBody))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\nPost&amp;nbsp;Response&amp;nbsp;:&amp;nbsp;200&amp;nbsp;OK&amp;nbsp;.&amp;nbsp;\n&amp;quot;)
}

//&amp;nbsp;responseFailed&amp;nbsp;:&amp;nbsp;Response&amp;nbsp;400&amp;nbsp;to&amp;nbsp;client
func&amp;nbsp;responseFailed(w&amp;nbsp;http.ResponseWriter)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;w.WriteHeader(http.StatusBadRequest)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\nPost&amp;nbsp;Response&amp;nbsp;:&amp;nbsp;400&amp;nbsp;BAD&amp;nbsp;.&amp;nbsp;\n&amp;quot;)
}

func&amp;nbsp;printByteArray(byteArrary&amp;nbsp;[]byte&amp;nbsp;,&amp;nbsp;arrName&amp;nbsp;string)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;++++++++&amp;nbsp;printByteArray&amp;nbsp;:&amp;nbsp;&amp;nbsp;ArrayName=%s,&amp;nbsp;ArrayLength=%d&amp;nbsp;\n&amp;quot;,&amp;nbsp;arrName,&amp;nbsp;len(byteArrary))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i:=0;&amp;nbsp;i&amp;lt;len(byteArrary);&amp;nbsp;i++&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;%02x&amp;quot;,&amp;nbsp;byteArrary[i]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Printf(&amp;quot;\n--------&amp;nbsp;printByteArray&amp;nbsp;:&amp;nbsp;&amp;nbsp;End&amp;nbsp;.&amp;nbsp;\n&amp;quot;)&amp;nbsp;&amp;nbsp;
}

type&amp;nbsp;EscapeError&amp;nbsp;string
func&amp;nbsp;(e&amp;nbsp;EscapeError)&amp;nbsp;Error()&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;quot;invalid&amp;nbsp;URL&amp;nbsp;escape&amp;nbsp;&amp;quot;&amp;nbsp;+&amp;nbsp;strconv.Quote(string(e))
}

type&amp;nbsp;InvalidHostError&amp;nbsp;string
func&amp;nbsp;(e&amp;nbsp;InvalidHostError)&amp;nbsp;Error()&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	return&amp;nbsp;&amp;quot;invalid&amp;nbsp;character&amp;nbsp;&amp;quot;&amp;nbsp;+&amp;nbsp;strconv.Quote(string(e))&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;nbsp;in&amp;nbsp;host&amp;nbsp;name&amp;quot;
}
type&amp;nbsp;encoding&amp;nbsp;int
const&amp;nbsp;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodePath&amp;nbsp;encoding&amp;nbsp;=&amp;nbsp;1&amp;nbsp;+&amp;nbsp;iota
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodePathSegment
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeHost
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeZone
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeUserPassword
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeQueryComponent
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeFragment
)

//&amp;nbsp;unescapePath&amp;nbsp;:&amp;nbsp;unescapes&amp;nbsp;a&amp;nbsp;string;&amp;nbsp;the&amp;nbsp;mode&amp;nbsp;specifies,&amp;nbsp;which&amp;nbsp;section&amp;nbsp;of&amp;nbsp;the&amp;nbsp;URL&amp;nbsp;string&amp;nbsp;is&amp;nbsp;being&amp;nbsp;unescaped.
func&amp;nbsp;unescapePath(s&amp;nbsp;string,&amp;nbsp;mode&amp;nbsp;encoding)&amp;nbsp;(string,&amp;nbsp;error)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Count&amp;nbsp;%,&amp;nbsp;check&amp;nbsp;that&amp;nbsp;they&amp;#39;re&amp;nbsp;well-formed.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mode&amp;nbsp;=&amp;nbsp;encodePathSegment
&amp;nbsp;&amp;nbsp;	n&amp;nbsp;:=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;	hasPlus&amp;nbsp;:=&amp;nbsp;false
&amp;nbsp;&amp;nbsp;	for&amp;nbsp;i&amp;nbsp;:=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len(s);&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		switch&amp;nbsp;s[i]&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;&amp;#39;%&amp;#39;:
&amp;nbsp;&amp;nbsp;			n++
&amp;nbsp;&amp;nbsp;			if&amp;nbsp;i+2&amp;nbsp;&amp;gt;=&amp;nbsp;len(s)&amp;nbsp;||&amp;nbsp;!ishex(s[i+1])&amp;nbsp;||&amp;nbsp;!ishex(s[i+2])&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				s&amp;nbsp;=&amp;nbsp;s[i:]
&amp;nbsp;&amp;nbsp;				if&amp;nbsp;len(s)&amp;nbsp;&amp;gt;&amp;nbsp;3&amp;nbsp;{
&amp;nbsp;&amp;nbsp;					s&amp;nbsp;=&amp;nbsp;s[:3]
&amp;nbsp;&amp;nbsp;				}
&amp;nbsp;&amp;nbsp;				return&amp;nbsp;&amp;quot;&amp;quot;,&amp;nbsp;EscapeError(s)
&amp;nbsp;&amp;nbsp;			}
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;Per&amp;nbsp;https://tools.ietf.org/html/rfc3986#page-21
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;in&amp;nbsp;the&amp;nbsp;host&amp;nbsp;component&amp;nbsp;%-encoding&amp;nbsp;can&amp;nbsp;only&amp;nbsp;be&amp;nbsp;used
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;for&amp;nbsp;non-ASCII&amp;nbsp;bytes.
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;But&amp;nbsp;https://tools.ietf.org/html/rfc6874#section-2
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;introduces&amp;nbsp;%25&amp;nbsp;being&amp;nbsp;allowed&amp;nbsp;to&amp;nbsp;escape&amp;nbsp;a&amp;nbsp;percent&amp;nbsp;sign
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;in&amp;nbsp;IPv6&amp;nbsp;scoped-address&amp;nbsp;literals.&amp;nbsp;Yay.
&amp;nbsp;&amp;nbsp;			if&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeHost&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;unhex(s[i+1])&amp;nbsp;&amp;lt;&amp;nbsp;8&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;s[i:i+3]&amp;nbsp;!=&amp;nbsp;&amp;quot;%25&amp;quot;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				return&amp;nbsp;&amp;quot;&amp;quot;,&amp;nbsp;EscapeError(s[i&amp;nbsp;:&amp;nbsp;i+3])
&amp;nbsp;&amp;nbsp;			}
&amp;nbsp;&amp;nbsp;			if&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeZone&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;RFC&amp;nbsp;6874&amp;nbsp;says&amp;nbsp;basically&amp;nbsp;&amp;quot;anything&amp;nbsp;goes&amp;quot;&amp;nbsp;for&amp;nbsp;zone&amp;nbsp;identifiers
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;and&amp;nbsp;that&amp;nbsp;even&amp;nbsp;non-ASCII&amp;nbsp;can&amp;nbsp;be&amp;nbsp;redundantly&amp;nbsp;escaped,
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;but&amp;nbsp;it&amp;nbsp;seems&amp;nbsp;prudent&amp;nbsp;to&amp;nbsp;restrict&amp;nbsp;%-escaped&amp;nbsp;bytes&amp;nbsp;here&amp;nbsp;to&amp;nbsp;those
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;that&amp;nbsp;are&amp;nbsp;valid&amp;nbsp;host&amp;nbsp;name&amp;nbsp;bytes&amp;nbsp;in&amp;nbsp;their&amp;nbsp;unescaped&amp;nbsp;form.
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;That&amp;nbsp;is,&amp;nbsp;you&amp;nbsp;can&amp;nbsp;use&amp;nbsp;escaping&amp;nbsp;in&amp;nbsp;the&amp;nbsp;zone&amp;nbsp;identifier&amp;nbsp;but&amp;nbsp;not
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;to&amp;nbsp;introduce&amp;nbsp;bytes&amp;nbsp;you&amp;nbsp;couldn&amp;#39;t&amp;nbsp;just&amp;nbsp;write&amp;nbsp;directly.
&amp;nbsp;&amp;nbsp;				//&amp;nbsp;But&amp;nbsp;Windows&amp;nbsp;puts&amp;nbsp;spaces&amp;nbsp;here!&amp;nbsp;Yay.
&amp;nbsp;&amp;nbsp;				v&amp;nbsp;:=&amp;nbsp;unhex(s[i+1])&amp;lt;&amp;lt;4&amp;nbsp;|&amp;nbsp;unhex(s[i+2])
&amp;nbsp;&amp;nbsp;				if&amp;nbsp;s[i:i+3]&amp;nbsp;!=&amp;nbsp;&amp;quot;%25&amp;quot;&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;v&amp;nbsp;!=&amp;nbsp;&amp;#39;&amp;nbsp;&amp;#39;&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;shouldEscape(v,&amp;nbsp;encodeHost)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;					return&amp;nbsp;&amp;quot;&amp;quot;,&amp;nbsp;EscapeError(s[i&amp;nbsp;:&amp;nbsp;i+3])
&amp;nbsp;&amp;nbsp;				}
&amp;nbsp;&amp;nbsp;			}
&amp;nbsp;&amp;nbsp;			i&amp;nbsp;+=&amp;nbsp;3
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;&amp;#39;+&amp;#39;:
&amp;nbsp;&amp;nbsp;			hasPlus&amp;nbsp;=&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeQueryComponent
&amp;nbsp;&amp;nbsp;			i++
&amp;nbsp;&amp;nbsp;		default:
&amp;nbsp;&amp;nbsp;			if&amp;nbsp;(mode&amp;nbsp;==&amp;nbsp;encodeHost&amp;nbsp;||&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeZone)&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;s[i]&amp;nbsp;&amp;lt;&amp;nbsp;0x80&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;shouldEscape(s[i],&amp;nbsp;mode)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				return&amp;nbsp;&amp;quot;&amp;quot;,&amp;nbsp;InvalidHostError(s[i&amp;nbsp;:&amp;nbsp;i+1])
&amp;nbsp;&amp;nbsp;			}
&amp;nbsp;&amp;nbsp;			i++
&amp;nbsp;&amp;nbsp;		}
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;	if&amp;nbsp;n&amp;nbsp;==&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;!hasPlus&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;s,&amp;nbsp;nil
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;	t&amp;nbsp;:=&amp;nbsp;make([]byte,&amp;nbsp;len(s)-2*n)
&amp;nbsp;&amp;nbsp;	j&amp;nbsp;:=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;	for&amp;nbsp;i&amp;nbsp;:=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len(s);&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		switch&amp;nbsp;s[i]&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;&amp;#39;%&amp;#39;:
&amp;nbsp;&amp;nbsp;			t[j]&amp;nbsp;=&amp;nbsp;unhex(s[i+1])&amp;lt;&amp;lt;4&amp;nbsp;|&amp;nbsp;unhex(s[i+2])
&amp;nbsp;&amp;nbsp;			j++
&amp;nbsp;&amp;nbsp;			i&amp;nbsp;+=&amp;nbsp;3
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;&amp;#39;+&amp;#39;:
&amp;nbsp;&amp;nbsp;			if&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeQueryComponent&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				t[j]&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;nbsp;&amp;#39;
&amp;nbsp;&amp;nbsp;			}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;				t[j]&amp;nbsp;=&amp;nbsp;&amp;#39;+&amp;#39;
&amp;nbsp;&amp;nbsp;			}
&amp;nbsp;&amp;nbsp;			j++
&amp;nbsp;&amp;nbsp;			i++
&amp;nbsp;&amp;nbsp;		default:
&amp;nbsp;&amp;nbsp;			t[j]&amp;nbsp;=&amp;nbsp;s[i]
&amp;nbsp;&amp;nbsp;			j++
&amp;nbsp;&amp;nbsp;			i++
&amp;nbsp;&amp;nbsp;		}
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;	return&amp;nbsp;string(t),&amp;nbsp;nil
}

//&amp;nbsp;Please&amp;nbsp;be&amp;nbsp;informed&amp;nbsp;that&amp;nbsp;for&amp;nbsp;now&amp;nbsp;shouldEscape&amp;nbsp;does&amp;nbsp;not&amp;nbsp;check&amp;nbsp;all
//&amp;nbsp;reserved&amp;nbsp;characters&amp;nbsp;correctly.&amp;nbsp;See&amp;nbsp;golang.org/issue/5684.
func&amp;nbsp;shouldEscape(c&amp;nbsp;byte,&amp;nbsp;mode&amp;nbsp;encoding)&amp;nbsp;bool&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	//&amp;nbsp;§2.3&amp;nbsp;Unreserved&amp;nbsp;characters&amp;nbsp;(alphanum)
&amp;nbsp;&amp;nbsp;	if&amp;nbsp;&amp;#39;A&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;Z&amp;#39;&amp;nbsp;||&amp;nbsp;&amp;#39;a&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;z&amp;#39;&amp;nbsp;||&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;9&amp;#39;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;	if&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeHost&amp;nbsp;||&amp;nbsp;mode&amp;nbsp;==&amp;nbsp;encodeZone&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;§3.2.2&amp;nbsp;Host&amp;nbsp;allows
&amp;nbsp;&amp;nbsp;		//	sub-delims&amp;nbsp;=&amp;nbsp;&amp;quot;!&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;$&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;&amp;amp;&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;&amp;#39;&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;(&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;)&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;*&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;+&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;,&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;;&amp;quot;&amp;nbsp;/&amp;nbsp;&amp;quot;=&amp;quot;
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;as&amp;nbsp;part&amp;nbsp;of&amp;nbsp;reg-name.
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;We&amp;nbsp;add&amp;nbsp;:&amp;nbsp;because&amp;nbsp;we&amp;nbsp;include&amp;nbsp;:port&amp;nbsp;as&amp;nbsp;part&amp;nbsp;of&amp;nbsp;host.
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;We&amp;nbsp;add&amp;nbsp;[&amp;nbsp;]&amp;nbsp;because&amp;nbsp;we&amp;nbsp;include&amp;nbsp;[ipv6]:port&amp;nbsp;as&amp;nbsp;part&amp;nbsp;of&amp;nbsp;host.
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;We&amp;nbsp;add&amp;nbsp;&amp;lt;&amp;nbsp;&amp;gt;&amp;nbsp;because&amp;nbsp;they&amp;#39;re&amp;nbsp;the&amp;nbsp;only&amp;nbsp;characters&amp;nbsp;left&amp;nbsp;that
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;we&amp;nbsp;could&amp;nbsp;possibly&amp;nbsp;allow,&amp;nbsp;and&amp;nbsp;Parse&amp;nbsp;will&amp;nbsp;reject&amp;nbsp;them&amp;nbsp;if&amp;nbsp;we
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;escape&amp;nbsp;them&amp;nbsp;(because&amp;nbsp;hosts&amp;nbsp;can&amp;#39;t&amp;nbsp;use&amp;nbsp;%-encoding&amp;nbsp;for
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;ASCII&amp;nbsp;bytes).
&amp;nbsp;&amp;nbsp;		switch&amp;nbsp;c&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;&amp;#39;!&amp;#39;,&amp;nbsp;&amp;#39;$&amp;#39;,&amp;nbsp;&amp;#39;&amp;amp;&amp;#39;,&amp;nbsp;&amp;#39;\&amp;#39;&amp;#39;,&amp;nbsp;&amp;#39;(&amp;#39;,&amp;nbsp;&amp;#39;)&amp;#39;,&amp;nbsp;&amp;#39;*&amp;#39;,&amp;nbsp;&amp;#39;+&amp;#39;,&amp;nbsp;&amp;#39;,&amp;#39;,&amp;nbsp;&amp;#39;;&amp;#39;,&amp;nbsp;&amp;#39;=&amp;#39;,&amp;nbsp;&amp;#39;:&amp;#39;,&amp;nbsp;&amp;#39;[&amp;#39;,&amp;nbsp;&amp;#39;]&amp;#39;,&amp;nbsp;&amp;#39;&amp;lt;&amp;#39;,&amp;nbsp;&amp;#39;&amp;gt;&amp;#39;,&amp;nbsp;&amp;#39;&amp;quot;&amp;#39;:
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;		}
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;	switch&amp;nbsp;c&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;-&amp;#39;,&amp;nbsp;&amp;#39;_&amp;#39;,&amp;nbsp;&amp;#39;.&amp;#39;,&amp;nbsp;&amp;#39;~&amp;#39;:&amp;nbsp;//&amp;nbsp;§2.3&amp;nbsp;Unreserved&amp;nbsp;characters&amp;nbsp;(mark)
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;$&amp;#39;,&amp;nbsp;&amp;#39;&amp;amp;&amp;#39;,&amp;nbsp;&amp;#39;+&amp;#39;,&amp;nbsp;&amp;#39;,&amp;#39;,&amp;nbsp;&amp;#39;/&amp;#39;,&amp;nbsp;&amp;#39;:&amp;#39;,&amp;nbsp;&amp;#39;;&amp;#39;,&amp;nbsp;&amp;#39;=&amp;#39;,&amp;nbsp;&amp;#39;?&amp;#39;,&amp;nbsp;&amp;#39;@&amp;#39;:&amp;nbsp;//&amp;nbsp;§2.2&amp;nbsp;Reserved&amp;nbsp;characters&amp;nbsp;(reserved)
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;Different&amp;nbsp;sections&amp;nbsp;of&amp;nbsp;the&amp;nbsp;URL&amp;nbsp;allow&amp;nbsp;a&amp;nbsp;few&amp;nbsp;of
&amp;nbsp;&amp;nbsp;		//&amp;nbsp;the&amp;nbsp;reserved&amp;nbsp;characters&amp;nbsp;to&amp;nbsp;appear&amp;nbsp;unescaped.
&amp;nbsp;&amp;nbsp;		switch&amp;nbsp;mode&amp;nbsp;{
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;encodePath:&amp;nbsp;//&amp;nbsp;§3.3
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;RFC&amp;nbsp;allows&amp;nbsp;:&amp;nbsp;@&amp;nbsp;&amp;amp;&amp;nbsp;=&amp;nbsp;+&amp;nbsp;$&amp;nbsp;but&amp;nbsp;saves&amp;nbsp;/&amp;nbsp;;&amp;nbsp;,&amp;nbsp;for&amp;nbsp;assigning
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;meaning&amp;nbsp;to&amp;nbsp;individual&amp;nbsp;path&amp;nbsp;segments.&amp;nbsp;This&amp;nbsp;package
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;only&amp;nbsp;manipulates&amp;nbsp;the&amp;nbsp;path&amp;nbsp;as&amp;nbsp;a&amp;nbsp;whole,&amp;nbsp;so&amp;nbsp;we&amp;nbsp;allow&amp;nbsp;those
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;last&amp;nbsp;three&amp;nbsp;as&amp;nbsp;well.&amp;nbsp;That&amp;nbsp;leaves&amp;nbsp;only&amp;nbsp;?&amp;nbsp;to&amp;nbsp;escape.
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;?&amp;#39;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;encodePathSegment:&amp;nbsp;//&amp;nbsp;§3.3
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;RFC&amp;nbsp;allows&amp;nbsp;:&amp;nbsp;@&amp;nbsp;&amp;amp;&amp;nbsp;=&amp;nbsp;+&amp;nbsp;$&amp;nbsp;but&amp;nbsp;saves&amp;nbsp;/&amp;nbsp;;&amp;nbsp;,&amp;nbsp;for&amp;nbsp;assigning
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;meaning&amp;nbsp;to&amp;nbsp;individual&amp;nbsp;path&amp;nbsp;segments.
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;/&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;;&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;,&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;?&amp;#39;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;encodeUserPassword:&amp;nbsp;//&amp;nbsp;§3.2.1
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;RFC&amp;nbsp;allows&amp;nbsp;&amp;#39;;&amp;#39;,&amp;nbsp;&amp;#39;:&amp;#39;,&amp;nbsp;&amp;#39;&amp;amp;&amp;#39;,&amp;nbsp;&amp;#39;=&amp;#39;,&amp;nbsp;&amp;#39;+&amp;#39;,&amp;nbsp;&amp;#39;$&amp;#39;,&amp;nbsp;and&amp;nbsp;&amp;#39;,&amp;#39;&amp;nbsp;in
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;userinfo,&amp;nbsp;so&amp;nbsp;we&amp;nbsp;must&amp;nbsp;escape&amp;nbsp;only&amp;nbsp;&amp;#39;@&amp;#39;,&amp;nbsp;&amp;#39;/&amp;#39;,&amp;nbsp;and&amp;nbsp;&amp;#39;?&amp;#39;.
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;parsing&amp;nbsp;of&amp;nbsp;userinfo&amp;nbsp;treats&amp;nbsp;&amp;#39;:&amp;#39;&amp;nbsp;as&amp;nbsp;special&amp;nbsp;so&amp;nbsp;we&amp;nbsp;must&amp;nbsp;escape
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;that&amp;nbsp;too.
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;@&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;/&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;?&amp;#39;&amp;nbsp;||&amp;nbsp;c&amp;nbsp;==&amp;nbsp;&amp;#39;:&amp;#39;
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;encodeQueryComponent:&amp;nbsp;//&amp;nbsp;§3.4
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;RFC&amp;nbsp;reserves&amp;nbsp;(so&amp;nbsp;we&amp;nbsp;must&amp;nbsp;escape)&amp;nbsp;everything.
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;true
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;		case&amp;nbsp;encodeFragment:&amp;nbsp;//&amp;nbsp;§4.1
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;The&amp;nbsp;RFC&amp;nbsp;text&amp;nbsp;is&amp;nbsp;silent&amp;nbsp;but&amp;nbsp;the&amp;nbsp;grammar&amp;nbsp;allows
&amp;nbsp;&amp;nbsp;			//&amp;nbsp;everything,&amp;nbsp;so&amp;nbsp;escape&amp;nbsp;nothing.
&amp;nbsp;&amp;nbsp;			return&amp;nbsp;false
&amp;nbsp;&amp;nbsp;		}
&amp;nbsp;&amp;nbsp;	}

&amp;nbsp;&amp;nbsp;	//&amp;nbsp;Everything&amp;nbsp;else&amp;nbsp;must&amp;nbsp;be&amp;nbsp;escaped.
&amp;nbsp;&amp;nbsp;	return&amp;nbsp;true
}

func&amp;nbsp;ishex(c&amp;nbsp;byte)&amp;nbsp;bool&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	switch&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;9&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;true
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;a&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;f&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;true
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;A&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;F&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;true
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;	return&amp;nbsp;false
}

func&amp;nbsp;unhex(c&amp;nbsp;byte)&amp;nbsp;byte&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	switch&amp;nbsp;{
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;9&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;c&amp;nbsp;-&amp;nbsp;&amp;#39;0&amp;#39;
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;a&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;f&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;c&amp;nbsp;-&amp;nbsp;&amp;#39;a&amp;#39;&amp;nbsp;+&amp;nbsp;10
&amp;nbsp;&amp;nbsp;	case&amp;nbsp;&amp;#39;A&amp;#39;&amp;nbsp;&amp;lt;=&amp;nbsp;c&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;c&amp;nbsp;&amp;lt;=&amp;nbsp;&amp;#39;F&amp;#39;:
&amp;nbsp;&amp;nbsp;		return&amp;nbsp;c&amp;nbsp;-&amp;nbsp;&amp;#39;A&amp;#39;&amp;nbsp;+&amp;nbsp;10
&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;	return&amp;nbsp;0
}&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;&lt;br/&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 04 May 2023 09:38:05 +0800</pubDate></item></channel></rss>