整个儿的¶
最终,完成所有功能的配置和代码:
- 版本仓库: https://github.com/ZoomQuiet/urisaok/tree/GAE
- 应用发布: urisago1.appsp0t.com/
app.yaml¶
application: urisago1
version: 3
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
urisa.go¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | package urisa
import (
"fmt"
"net/http"
"encoding/json"
"io"
"io/ioutil"
"time"
"strconv"
"encoding/base64"
"encoding/hex"
"crypto/md5"
"appengine"
"appengine/urlfetch"
"appengine/datastore"
)
func init() {
http.HandleFunc("/", help)
http.HandleFunc("/chk", chk)
http.HandleFunc("/qchk", qchk)
}
func help(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, usageHelp)
}
const usageHelp = `
URIsA ~ KSC 4 GAE powdered by go1
{v12.05.4}
usage:
$ curl -d "uri=http://sina.com" urisago1.appsp0t.com/chk
or with GAE Datastore quick resp. if ahd checked:
$ curl -d "uri=http://sina.com" urisago1.appsp0t.com/qchk
`
var APPKEY = "k-60666"
var SECRET = "99fc9fdbc6761f7d898ad25762407373"
var APIHOST = "open.pc120.com"
var APITYPE = "/phish/"
var PHISHID = map[int] string {
-1: "未知",
0: "好站",
1: "钓鱼!",
2: "也许...",
}
type KSC struct {
Success int //`json:"success"`
Phish int //`json:"phish"`
Msg string //`json:"msg"`
}
func _genKSCuri(url string) string {
println("url len~\t ", len(url))
maxEncLen := base64.URLEncoding.EncodedLen(len([]byte(url)))
println("maxEncLen~\t ", maxEncLen)
//dst := make([]byte, 256) //<~ 整来的代码,不理解,就一定会出问题...
dst := make([]byte, maxEncLen) //<~ 整来的代码,不理解,就一定会出问题...
base64.URLEncoding.Encode(dst, []byte(url))
println("base64~\t", string(dst))
args := "appkey=" + APPKEY
args += "&q=" + string(dst)
now := time.Now()
nano := strconv.FormatInt(now.UnixNano(),10)
//c.Infof("timestamp ~ %v.%v", nano[0:10],nano[10:13])
args += "×tamp=" + nano[0:10] + "." + nano[10:13]
sign_base_string := APITYPE + "?" + args
println("sign_base_string~\t ", sign_base_string)
//md5 hash 严格参数顺序:: appkey -> q -> timestamp
h := md5.New()
io.WriteString(h, sign_base_string + SECRET)
args += "&sign=" + hex.EncodeToString(h.Sum(nil))
println("sign~\t ", hex.EncodeToString(h.Sum(nil)))
println("args~\t ", args)
api_url := "http://"+ APIHOST + APITYPE + "?" + args
println("api_url~ ", api_url)
return api_url
}
func _asKSC(uri string, r *http.Request) (int, int) {
c := appengine.NewContext(r)
client := urlfetch.Client(c)
resp, err := client.Get(uri)
if err != nil {
panic(err)
//http.Error(w, err.Error(), http.StatusInternalServerError)
//return
}
c.Infof("HTTP GET returned status %v", resp.Status)
if resp.StatusCode != 200 {
panic(err)
c.Infof("couldn't get sale data %v", http.StatusInternalServerError)
//http.Error(w, "couldn't get sale data", http.StatusInternalServerError)
//return
}
defer resp.Body.Close()
c.Infof("resp.ContentLength %v", resp.ContentLength)
var buf []byte
buf, _ = ioutil.ReadAll(resp.Body)
c.Infof("resp.Body %v", string(buf))
result := &KSC{}
err = json.Unmarshal(buf, result)
if err != nil {
panic(err)
//http.Error(w, err.Error(), http.StatusInternalServerError)
//return
}
return result.Success, result.Phish
}
type Chked struct {
Uri string
Phish int
Tstamp time.Time
Cip string
}
func qchk(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
url := r.FormValue("uri")
ukey := datastore.NewKey(c, "Uri", url, 0, nil)
var e2 Chked
if err := datastore.Get(c, ukey, &e2); err != nil {
fmt.Fprint(w, "~ ", err.Error() , "\n")
//panic(err)
c.Infof("Get Err.~\n\t !!! %v", err.Error())
//http.Error(w, err.Error(), http.StatusInternalServerError)
//return
api_url := _genKSCuri(url)
_,p := _asKSC(api_url, r)
e1 := Chked{
Uri: url,
Phish: p,
Tstamp: time.Now(),
Cip: r.RemoteAddr,
}
//key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "chked", nil), &e1)
ukey, err = datastore.Put(c, ukey, &e1)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
//c.Infof("datastore key=%v", key.String())
fmt.Fprint(w, "ask KCS API srv.\n")
fmt.Fprint(w, "/qchk(KCS):\t" + PHISHID[p])
}else{
c.Infof("datastore ukey=%v", ukey.String())
fmt.Fprint(w, "datastore Get OK;-) \n")
c.Infof("co4 datastore:%v \t Phish:%s", e2.Phish ,PHISHID[e2.Phish])
fmt.Fprint(w, "/qchk(GAE):\t" + PHISHID[e2.Phish])
}
}
func chk(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
url := r.FormValue("uri")
api_url := _genKSCuri(url)
s,p := _asKSC(api_url, r)
c.Infof("Success:%v \t Phish:%s", s ,PHISHID[p])
fmt.Fprint(w, "/chk(KCS):\t" + PHISHID[p])
}
|