阿里云OSS表单上传签名

/**
 *  阿里云 OSS 密钥
 */
define('AccessKeyId', 'ID');
define('AccessKeySecret', 'SS');
define('OssHost', 'https://bucket.oss-cn-beijing.aliyuncs.com');
define('UploadPrefix', 'files/');

function ossUploadSign($expire = 60) {
    $sign = [];
    $sign['accessid'] = AccessKeyId;
    $sign['host'] = OssHost;
    $sign['expire'] = time() + $expire;
    $sign['policy'] = base64_encode(json_encode(['expiration' => date('Y-m-d\TH:i:s\Z', $sign['expire']), 'conditions' => [['content-length-range', 0, 100 * 1024 * 1024], ['starts-with', '$key', UploadPrefix]]]));
    $sign['signature'] = base64_encode(hash_hmac('sha1', $sign['policy'], AccessKeySecret, true));
    $sign['dir'] = UploadPrefix;
    return json_encode($sign);
}

echo ossUploadSign();
发布日期:
分类:Golang

FRP服务端和客户端配置

一、服务端配置

# frps.ini
[common]
bind_port = 7000
token = 12345678

二、客户端配置

1. 客户端提供服务方

# frpc-01.ini
[common]
server_addr = 1.2.3.4
server_port = 7000
token = 12345678

[service_name]
type = stcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = true

2. 客户端连接方

# frpc-02.ini
[common]
server_addr = 1.2.3.4
server_port = 7000
token = 12345678

[client_name]
role = visitor
type = stcp
server_name = service_name
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 2201
use_encryption = false
use_compression = true
发布日期:
分类:Golang

Go 开发环境配置

以下方式已不建议使用,使用 Go Module 配置的方式

一、安装 govendor 工具

go get -u github.com/kardianos/govendor

二、创建工程

cd $GOPATH/src
mkdir demo
cd demo
govendor init

三、安装依赖

govendor fetch github.com/go-sql-driver/mysql@=v1.4.1
govendor fetch github.com/gin-gonic/gin@=v1.3.0
govendor fetch github.com/gomodule/redigo/redis@=v1.7.0

四、开发

package main

import (
	"database/sql"
	"log"

	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
)

var Database *sql.DB

func main() {
	DatabaseInit()
	defer Database.Close()
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.GET("/", IndexAction)
	r.GET("/user/:name", UserAction)
	r.Run()
}

func DatabaseInit() {
	var err error
	Database, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/wordpress")
	if err != nil {
		log.Fatalln(err)
	}
	Database.SetMaxIdleConns(500)
	Database.SetMaxOpenConns(500)
	err = Database.Ping()
	if err != nil {
		log.Fatalln(err)
	}
}

func IndexAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "index"})
}

func UserAction(c *gin.Context) {
	var ID int
	err := Database.QueryRow("SELECT ID FROM wp_users WHERE user_login = ?", c.Param("name")).Scan(&ID)
	if err == nil {
		c.String(200, "Hello %d", ID)
	} else {
		c.String(200, "Hello nobody")
	}
}

五、gin-app

gin-app-0.1

发布日期:
分类:Golang

golang发送阿里云短信

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "1111"
const TemplateCode = "SMS_2222"
const SignName = "发送测试"

func UrlEncode(in string) string {
	r := strings.NewReplacer("+", "%20", "*", "%2A", "%7E", "~")
	return r.Replace(url.QueryEscape(in))
}

func Sign(stringToSign string) string {
	h := hmac.New(sha1.New, []byte(fmt.Sprintf("%s&", AccessKeySecret)))
	h.Write([]byte(stringToSign))
	return UrlEncode(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func Keys(data map[string]string) []string {
	var keys []string
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return keys
}

func SortedString(data map[string]string) string {
	var sortQueryString string
	for _, v := range Keys(data) {
		sortQueryString = fmt.Sprintf("%s&%s=%s", sortQueryString, v, UrlEncode(data[v]))
	}
	return sortQueryString
}

func AliyunSendSMS(PhoneNumber string, code string) string {

	rand.Seed(time.Now().UnixNano())

	data := map[string]string{
		"SignatureMethod":  "HMAC-SHA1",
		"SignatureNonce":   strconv.FormatFloat(rand.Float64(), 'f', 6, 64),
		"AccessKeyId":      AccessKeyID,
		"SignatureVersion": "1.0",
		"Timestamp":        time.Now().UTC().Format("2006-01-02T15:04:05Z"),
		"Format":           "JSON",

		"RegionId":      "cn-hangzhou",
		"Action":        "SendSms",
		"Version":       "2017-05-25",
		"PhoneNumbers":  PhoneNumber,
		"SignName":      SignName,
		"TemplateCode":  TemplateCode,
		"TemplateParam": `{"code":"` + code + `"}`,
	}

	sortQueryString := SortedString(data)
	stringToSign := "GET&%2F&" + UrlEncode(sortQueryString[1:])
	url := fmt.Sprintf("https://dysmsapi.aliyuncs.com/?Signature=%s%s", Sign(stringToSign), sortQueryString)

	r, err := http.Get(url)
	if err != nil {
		return ""
	}
	defer r.Body.Close()

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return ""
	}

	return string(b)
}

func main() {
	html := AliyunSendSMS("18611112222", "123456")
	fmt.Println(html)
}
发布日期:
分类:Golang

golang发送阿里云邮件

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "1111"
const AccountName = "admin@sendmail.aliyun.com"

func UrlEncode(in string) string {
	r := strings.NewReplacer("+", "%20", "*", "%2A", "%7E", "~")
	return r.Replace(url.QueryEscape(in))
}

func Sign(stringToSign string) string {
	h := hmac.New(sha1.New, []byte(fmt.Sprintf("%s&", AccessKeySecret)))
	h.Write([]byte(stringToSign))
	return UrlEncode(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func Keys(data map[string]string) []string {
	var keys []string
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return keys
}

func SortedString(data map[string]string) string {
	var sortQueryString string
	for _, v := range Keys(data) {
		sortQueryString = fmt.Sprintf("%s&%s=%s", sortQueryString, v, UrlEncode(data[v]))
	}
	return sortQueryString
}

func AliyunSendMail(email string, subject string, body string) string {

	rand.Seed(time.Now().UnixNano())

	data := map[string]string{
		"SignatureMethod":  "HMAC-SHA1",
		"SignatureNonce":   fmt.Sprintf("%s", rand.Int63()),
		"AccessKeyId":      AccessKeyID,
		"SignatureVersion": "1.0",
		"Timestamp":        time.Now().UTC().Format("2006-01-02T15:04:05Z"),
		"Format":           "JSON",

		"Action":         "SingleSendMail",
		"Version":        "2015-11-23",
		"AccountName":    AccountName,
		"ReplyToAddress": "true",
		"AddressType":    "1",
		"ToAddress":      email,
		"Subject":        subject,
		"TextBody":       body,
	}

	sortQueryString := SortedString(data)
	stringToSign := fmt.Sprintf("GET&%s&%s", UrlEncode("/"), UrlEncode(sortQueryString[1:]))
	url := fmt.Sprintf("http://dm.aliyuncs.com/?Signature=%s%s", Sign(stringToSign), sortQueryString)

	r, err := http.Get(url)
	if err != nil {
		return ""
	}
	defer r.Body.Close()

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return ""
	}

	return string(b)
}

func main() {
	html := AliyunSendMail("123456@qq.com", "Database Backup Email", "Database Backup Completed")
	fmt.Println(html)
}
发布日期:
分类:Golang

golang上传文件到OSS

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "0000"

const Bucket = "bbbb"
const BucketUrl = "https://bbbb.oss-cn-beijing.aliyuncs.com"

var datetime string = time.Now().UTC().Format(http.TimeFormat)

func Sign(dest string) string {
	h := hmac.New(sha1.New, []byte(AccessKeySecret))
	h.Write([]byte("PUT\n\napplication/octet-stream\n" + datetime + "\n/" + Bucket + dest))
	return "OSS " + AccessKeyID + ":" + base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func Upload(file string, dest string) error {

	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	request, err := http.NewRequest("PUT", BucketUrl+dest, f)
	if err != nil {
		return err
	}

	request.Header.Add("Date", datetime)
	request.Header.Add("Authorization", Sign(dest))
	request.Header.Add("Content-Type", "application/octet-stream")

	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}

	if response.StatusCode == 200 {
		return nil
	} else {
		return errors.New(string(body))
	}

}

func main() {
	up := Upload("02.zip", "/08.zip")
	fmt.Println(up)
}
发布日期:
分类:Golang

golang使用协程和管道的例子

1. 协程和管道

package main

import (
	"fmt"
	"time"
)

func write(ch chan int) {
	for i := 0; i < 10; i++ {
		ch <- i
		fmt.Println("write data: ", i)
	}
}

func read(ch chan int) {
	for {
		var b int
		b = <-ch
		fmt.Println("read data: ", b)
		time.Sleep(time.Second)
	}
}

func main() {
	intChan := make(chan int, 5)
	go write(intChan)
	go read(intChan)

	time.Sleep(10 * time.Second)
}

2. 使用 WaitGroup 控制协程

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func write(ch chan int) {
	for i := 0; i < 10; i++ {
		ch <- i
		fmt.Println("write data: ", i)
	}
}

func read(ch chan int) {
	for {
		fmt.Println("read data: ", <-ch)
		wg.Done()
	}
}

func main() {
	ch := make(chan int, 5)
	wg.Add(10)

	go write(ch)
	go read(ch)

	wg.Wait()
}
发布日期:
分类:Golang

Golang使用zip压缩文件


package main

import (
	"archive/zip"
	"io"
	"os"
)

func main() {
	compress("01.png", "01.zip")
}

func compress(file string, dest string) error {
        f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	d, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer d.Close()

	wr := zip.NewWriter(d)
	defer wr.Close()

	w, err := wr.Create(file)
	if err != nil {
		return err
	}

	_, err = io.Copy(w, f)
	if err != nil {
		return err
	}

	return nil
}
发布日期:
分类:Golang

Golang使用tar压缩文件


package main

import (
	"archive/tar"
	"compress/gzip"
	"io"
	"os"
)

func main() {
	Compress("01.png", "02.tar.gz")
}

func Compress(file string, dest string) error {
	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()
	d, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer d.Close()
	gw := gzip.NewWriter(d)
	defer gw.Close()
	tw := tar.NewWriter(gw)
	defer tw.Close()
	info, err := f.Stat()
	if err != nil {
		return err
	}
	header, err := tar.FileInfoHeader(info, "")
	if err != nil {
		return err
	}
	err = tw.WriteHeader(header)
	if err != nil {
		return err
	}
	_, err = io.Copy(tw, f)
	if err != nil {
		return err
	}
	return nil
}
发布日期:
分类:Golang

golang模拟浏览器请求


import (
	"io/ioutil"
	"net/http"
)

func httpRequest(url string) []byte {
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return []byte{}
	}

	request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
	request.Header.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
	request.Header.Add("Connection", "keep-alive")
	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36")

	client := http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return []byte{}
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return []byte{}
	}

	return body
}
发布日期:
分类:Golang