go搭建一个服务器

go(三)

关于go搭建一个服务器
1、导入”net/http”

import "net/http"

2、导入Websocket

import "code.google.com/p/go.net/websocket"

3、导入 html/template

import "html/template"

解析这个包:

template包(html/template)实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。
本包提供了和text/template包相同的接口,无论何时当输出是HTML的时候都应使用本包

本包是对text/template包的包装,两个包提供的模板API几无差别,可以安全的随意替换两包

tmpl, err := template.New("name").Parse(...)
// 省略错误检测
err = tmpl.Execute(out, data)

如果成功创建了tmpl,tmpl现在是注入安全的了。否则err将返回ErrorCode里定义的某个错误。即使成功生成了模板,执行时仍可能导致ErrorCode里定义的错误。

HTML模板将数据视为明文文本,必须经过编码以便安全的嵌入HTML文档。转义操作会参考上下文,因此action可以出现在JavaScript、CSS、URI上下文环境里

本包使用的安全模型假设模板的作者是可信任的,但用于执行的数据不可信

import "text/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

生成:

Hello, <script>alert('you have been pwned')</script>!

但在html/template包里会根据上下文自动转义

import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

生成安全的转义后HTML输出

扫描二维码关注公众号,回复: 1575841 查看本文章
Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!

本包可以理解HTML、CSS、JavaScript和URI。它会给每一个简单的action pipeline都添加处理函数

<a href="/search?q={{.}}">{{.}}</a>

在解析时每个{{.}}都会在必要时重写添加转义函数,会改为:

<a href="/search?q={{. | urlquery}}">{{. | html}}</a>

更为具体的解释请参见https://studygolang.com/pkgdoc
4、实现
绑定端口:

var addr = flag.String("addr",":1718","http service address");

初始化待渲染页面:

var templ = template.Must(template.New("qr").Parse(templateStr))

主函数:

func main() {
    flag.Parse() //参数解析
    http.Handle("/", http.HandlerFunc(QR)) //类似于绑定路由
    err := http.ListenAndServe(*addr, nil) //打开监听的端口
    if err != nil {
        log.Fatal("ListenAndServe:", err) //日志反馈
    }
}

配套渲染页面的代码,总的就是

package main

import (
    "flag"
    "html/template"
    "log"
    "net/http"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18

var templ = template.Must(template.New("qr").Parse(templateStr))

func main() {
    flag.Parse()
    http.Handle("/", http.HandlerFunc(QR))
    err := http.ListenAndServe(*addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

func QR(w http.ResponseWriter, req *http.Request) {
    templ.Execute(w, req.FormValue("s"))
}//处理前端发来的请求

const templateStr = `
<html>
<head>
<title>QR Link Generator</title>
</head>
<body>
{{if .}}
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={{.}}" />
<br>
{{.}}
<br>
<br>
{{end}}
<form action="/" name=f method="GET"><input maxLength=1024 size=70
name=s value="" title="Text to QR Encode"><input type=submit
value="Show QR" name=qr>
</form>
</body>
</html>
`

5、测试
将代码复制到goland中去,然后运行主函数。
windows + R 打开运行,然后输入cmd,使用netstat指令查看刚刚绑定的1718端口是什么状态

C:\Users\laodiao>netstat -ano |findstr "1718"
  TCP    0.0.0.0:1718           0.0.0.0:0              LISTENING       7064
  TCP    [::]:1718              [::]:0                 LISTENING       7064

如果看见端口已经打开了,最后一列代表的是使用这个端口的应用的pid,再使用tasklist指令来查看7064这个pid的运行情况

C:\Users\laodiao>tasklist |findstr "7064"
___go_build_main_go.exe       7064 Console                    1      5,052 K

可以发现是go打开的。现在用telnet指令远程登录该端口,发现返回的是:


HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad Request

但是,这和我远程登录一个本不存在的端口的结果不太一样

C:\Users\laodiao>telnet 192.168.2.103 1719
正在连接192.168.2.103...无法打开到主机的连接。 在端口 1719: 连接失败

也就是说,端口实际上是打开的,但是不能有效的与外界建立起连接。同时,使用浏览器直接打开http://192.168.2.103:1718/会显示

您被禁止访问互联网
防火墙或防病毒软件可能已阻止您连接到网络。
请试试以下办法:

检查网络连接
检查防火墙和防病毒配置
运行 Windows 网络诊断
ERR_NETWORK_ACCESS_DENIED

6、解决访问400的问题
请注意:

http://192.168.2.103:1718/

是本机在内网中的ip地址,这个访问不了,我用本地回环ip:

http://127.0.0.1:1718/
或者
http://localhost:1718/

就可以顺利访问。

7、解决外网访问的问题
经过多方查证,

http://192.168.2.103:1718/

实际上是可以访问的,只不过由于我电脑里有点问题,导致不能访问。

猜你喜欢

转载自blog.csdn.net/xielinrui123/article/details/80623444