golang xml处理函数目前常规的应用没有问题,主要利用xml.Marshal和xml.Unmarshal。
不能生成自关闭标签,能解析自关闭标签。遇到命名空间的时候比较头大,解析和生成xml不能用一个结构,必须定义成2个。

1:获取字段属性

func main() {
    d := `<result code="1000"><msg>Command completed successfully.</msg></result>`
    type result struct {
        Code     int    `xml:"code,attr"`
        Msg      string `xml:"msg"`
    }
    abc := result{}
    xml.Unmarshal([]byte(d),&amp;abc)
    fmt.Printf("%+v\n",abc)
}
    //{Code:1000 Msg:Command completed successfully.}

2:节点带有属性和内容的获取方式

func main() {
    d := `<result code="1000"><period unit="y">1</period></result>`
    type result struct {
        Period struct{
            Unit string `xml:"unit,attr"`
            Value int `xml:",chardata"`
        } `xml:"period"`
    }
    abc := result{}
    xml.Unmarshal([]byte(d),&amp;abc)
    fmt.Printf("%+v\n",abc)
}
    //{Period:{Unit:y Value:1}}

3:如果有节点一样,仅仅是命名空间不一样的处理方式

继续阅读

在用golang处理xml 命名空间属性,可能是个bug,golang 1.10.1

func main() {
 str :=`<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
 <hello />
</epp>`
 doc:=xml.NewDecoder(strings.NewReader(str))
 for {
 t, err := doc.Token()
 if err!=nil{
     print(err.Error())
     break
 }
 switch to := t.(type) {
 case xml.StartElement:
     for _,v:=range to.Copy().Attr{
     fmt.Printf("space:%s--local:%s---value:%s\n",v.Name.Space,v.Name.Local,v.Value)
 }
 default:
 }
 }
}

得到的结果:

space:–local:xmlns—value:urn:ietf:params:xml:ns:epp-1.0
space:xmlns–local:xsi—value:http://www.w3.org/2001/XMLSchema-instance
space:http://www.w3.org/2001/XMLSchema-instance–local:schemaLocation—value:urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd

在解析 xsi:schemaLocation 这个名称的时候返回的不对了。感觉是个BUG,有新的发现在更新。

这里使用的是官方的包管理工具dep  https://github.com/golang/dep

背景 gitlab 10.5.6,gitlab_ci,golang 1.10.1,dep v0.4.1

1:安装,直接在github下载二进制文件,放入系统的path目录即可

2:遇到的问题

2.1 go get gitlab项目失败

git config –global url.”git@git.ciphp.com:”.insteadOf “https://git.ciphp.com/” 使用ssh的方式替代https的模式,这样可以用证书拉项目

2.2 dep init 不能在软链接目录执行

暂时无解,请到gopath非软链接目录执行

2.3 dep ensure is not within a known GOPATH/src

如果登录到gitlab ci机器,能手工执行成功,修改.gitalb-ci.yml执行脚本的pwd环境变量

手头有个乐视的路由器,想着刷个openwrt玩玩插件,参考地址http://www.right.com.cn/forum/thread-172877-1-1.html 还有一些其他资料就准备开刷。

第1步资料已经变动,http://downloads.openwrt.org/attitude_adjustment/12.09-rc1/ar71xx/generic/packages/Packages.gz.
这个地址已经变为http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/Packages.gz. 在安装页面有个配置选项,直接在里面修改就行[不过我后面刷了另一个包,不确认这个是否必须]

继续阅读

php偏移量16个0

openssl_encrypt($xml,’AES-128-CBC’,$key, false, hex2bin(‘00000000000000000000000000000000’));

//java代码是服务提供方写的,目前知道这样写的对方能解出来,不懂java就不写代码了.

golang

package main

import (
“bytes”
“crypto/aes”
“crypto/cipher”
“encoding/base64”
“fmt”
“io”
“log”
“os”
)

var iv = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
//必须这样写,如果写成[]byte(“16个0”)会丢失前面16个字节

func main() {
TestCBCAES()
}

func TestCBCAES() {
key := []byte(“IHqnFXMNhpzYNLOU”)
data := “xmlssssss”
result, err := AesEncrypt([]byte(data), key)
if err != nil {
panic(err)
}
origData, err := AesDecrypt(result, key)
if err != nil {
panic(err)
}
fmt.Println(string(origData))
}

func AesEncrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, iv)
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}

func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, iv)
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
return origData, nil
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize – len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext…)
}

func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// remove the last byte
unpadding := int(origData[length-1])
return origData[:(length – unpadding)]

}

golang代码参考,修改了偏移量的方式,可能跟服务端实现的方式有关系

如何讓 AES 在 Golang 與 Android(Java) 得到一致的加解密結果

GO项目跑整个项目的覆盖率

gitlab-ci.sh 内容如下

set -e echo “mode: atomic” > coverage.txt

for d in $(go list ./… | grep -v vendor | grep -v doc); do
go test -race -coverprofile=profile.out $d
if [ -f profile.out ]; then
cat profile.out | grep -v statements | grep -v atomic >> coverage.txt
rm profile.out
fi done

go tool cover -func=coverage.txt

go 1.10 之后建议使用如下代码

set -e
go test -race -coverprofile=coverage.txt $(go list ./… | grep -v “vendor” | grep -v “doc”)
go tool cover -func=coverage.txt

gitlab页面设置

导航到页面settings/ci_cd 展开节点:General pipelines settings–>Test coverage parsing

输入 total:\s+\(statements\)\s+(\d+.\d+)%

ELK是elasticsearch、kibana、logstas组合的简称,是一套强大的日志处理系统, grafana是一款golang开发的数据显示软件,支持多种数据源,UI漂亮,支持报警

软件下载&安装

es下载地址 https://www.elastic.co/downloads/elasticsearch

kibana https://www.elastic.co/downloads/kibana

logstash https://www.elastic.co/downloads/logstash

filebeat https://www.elastic.co/downloads/beats

grafana https://grafana.com/grafana/download

安装比较简单,直接安装官方说明装就可以了。

继续阅读

刚开始使用gitlab的单元测试覆盖率,测试的代码是golang的,经过摸索如下

total:\s+\(statements\)\s+(\d+.\d+)%

.gitlab-ci.yml 配置文件如下

script:
- go test -coverprofile=coverage.out && go tool cover -func=coverage.out

就是从输出的内容里面用正则匹配,能成功就OK了

服务端

processor := enameepp.NewEppContactProcessor(&EppStruct{})
domainProcessor := enameepp.NewEppDomainProcessor(&EppStructDomain{})
TMultiplexedProcessor := thrift.NewTMultiplexedProcessor()
TMultiplexedProcessor.RegisterProcessor("contact", processor)
TMultiplexedProcessor.RegisterProcessor("domain", domainProcessor)

server := thrift.NewTSimpleServer4(TMultiplexedProcessor, transport, transportFactory, protocolFactory)

fmt.Println("Starting the simple server... on ", addr)
return server.Serve()

客户端

var transport thrift.TTransport
var err error
transport, err = thrift.NewTSocket(addr)
if err != nil {
	fmt.Println("Error opening socket:", err)
	return err
}
transport = transportFactory.GetTransport(transport)
defer transport.Close()
if err := transport.Open(); err != nil {
	return err
}

protocol := thrift.NewTBinaryProtocolTransport(transport)
mp := thrift.NewTMultiplexedProtocol(protocol, "domain")

//client := enameepp.NewEppContactClientProtocol(transport, protocol, mp)
client := enameepp.NewEppDomainClientProtocol(transport, protocol, mp)
return handleClient2(client)