c5_labsci/zciyon/post.go
2026-01-27 00:52:00 +08:00

199 lines
5.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package zciyon
import (
"io"
"mime/multipart"
"net/http"
"regexp"
"strings"
)
const (
CIYPOST_ALLOW_TEXT = 0 //禁止任何html代码
CIYPOST_ALLOW_HTML = 1 //允许合法html代码但不允许js脚本
CIYPOST_ALLOW_ALL = 2 //全部放行
)
type CiyPost struct {
kv map[string]any
W http.ResponseWriter
R *http.Request
err error
}
func NewCiyPost(w http.ResponseWriter, r *http.Request) *CiyPost {
post := &CiyPost{}
post.W = w
post.R = r
post.kv = map[string]any{}
if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/form-data") {
err := r.ParseMultipartForm(1024 * 5) //1024 * 1024 * 1024 *
if err != nil {
post.err = err
} else {
for k, v := range r.Form {
post.kv[k] = v[0]
}
if r.MultipartForm != nil && r.MultipartForm.File != nil {
for k, files := range r.MultipartForm.File {
post.kv[k] = files[0]
}
}
}
} else if r.Method == "POST" {
body, err := io.ReadAll(r.Body)
if err != nil {
post.err = err
} else {
post.kv = Byte_JSON(body)
if len(post.kv) == 0 {
post.kv = map[string]any{"body": string(body)}
}
}
}
for k, v := range r.URL.Query() {
post.kv[k] = v[0]
}
if len(post.kv) == 0 {
post.kv[""] = r.URL.RawQuery
}
return post
}
func (thos *CiyPost) Is(key string) bool {
_, ok := thos.kv[key]
return ok
}
func (thos *CiyPost) Getany(key string) any {
return thos.kv[key]
}
func (thos *CiyPost) Getobj(key string) map[string]any {
if arr, ok := thos.kv[key].(map[string]any); ok {
return arr
}
return map[string]any{}
}
func (thos *CiyPost) Getint(key string, argdef ...int) int {
return Toint(thos.kv[key], argdef...)
}
func (thos *CiyPost) Getfloat(key string, argdef ...float64) float64 {
return Tofloat(thos.kv[key], argdef...)
}
func (thos *CiyPost) Getbool(key string, argdef ...bool) bool {
return Tobool(thos.kv[key], argdef...)
}
func (thos *CiyPost) Getdate(key string) int {
return Tostamp(Tostr(thos.kv[key]))
}
func (thos *CiyPost) GetIP() string {
xForwardedFor := thos.R.Header.Get("X-Forwarded-For")
if xForwardedFor != "" {
return strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
}
xRealIP := thos.R.Header.Get("X-Real-IP")
if xRealIP != "" {
return xRealIP
}
return thos.R.RemoteAddr
}
func (thos *CiyPost) IsWeixin() bool {
useragent := thos.R.Header.Get("HTTP_USER_AGENT")
useragent = strings.ToLower(useragent)
return strings.Contains(useragent, "micromessenger")
}
func (thos *CiyPost) Get(key string, args ...any) string {
allow := CIYPOST_ALLOW_TEXT
defval := ""
for _, arg := range args {
switch v := arg.(type) {
case int:
allow = v
case string:
defval = v
}
}
str := Tostr(thos.kv[key])
if allow == CIYPOST_ALLOW_TEXT {
str = strings.TrimSpace(thos.triptotext(str))
} else if allow == CIYPOST_ALLOW_HTML {
str = thos.triptohtml(str)
//str = template.HTMLEscapeString(str)
//str = template.JSEscapeString(str)
}
if str == "" {
return defval
}
return str
}
func (thos *CiyPost) Gets(key string, args ...any) []string {
allow := CIYPOST_ALLOW_TEXT
for _, arg := range args {
switch v := arg.(type) {
case int:
allow = v
}
}
switch v := thos.kv[key].(type) {
case []any:
strs := make([]string, len(v))
for i, s := range v {
str := Tostr(s)
if allow == CIYPOST_ALLOW_TEXT {
str = strings.TrimSpace(thos.triptotext(str))
} else if allow == CIYPOST_ALLOW_HTML {
str = thos.triptohtml(str)
}
strs[i] = str
}
return strs
}
return []string{""}
}
func (thos *CiyPost) Getfile(argkey ...string) *multipart.FileHeader {
key := ""
if len(argkey) > 0 {
key = argkey[0]
}
if key != "" {
switch v := thos.kv[key].(type) {
case *multipart.FileHeader:
return v
}
} else {
for _, kv := range thos.kv {
switch v := kv.(type) {
case *multipart.FileHeader:
return v
}
}
}
return nil
}
func (thos *CiyPost) triptotext(str string) string { //去掉所有html标签和控制字符
re, _ := regexp.Compile(`\<[\S\s]+?\>`) //标签小写
str = re.ReplaceAllStringFunc(str, strings.ToLower)
re, _ = regexp.Compile(`\<style[\S\s]+?\</style\>`) //删除style
str = re.ReplaceAllString(str, "")
re, _ = regexp.Compile(`\<script[\S\s]+?\</script\>`) //删除script
str = re.ReplaceAllString(str, "")
re, _ = regexp.Compile(`\<[\S\s]+?\>`) //删除标签
str = re.ReplaceAllString(str, "")
return str
}
func (thos *CiyPost) triptohtml(str string) string { //保留html标签和style属性。去掉所有事件、style、script
re, _ := regexp.Compile(`\<[\S\s]+?\>`) //标签小写
str = re.ReplaceAllStringFunc(str, strings.ToLower)
re, _ = regexp.Compile(`\<style[\S\s]+?\</style\>`) //删除style
str = re.ReplaceAllString(str, "")
re, _ = regexp.Compile(`\<script[\S\s]+?\</script\>`) //删除script
str = re.ReplaceAllString(str, "")
reOnEvent := regexp.MustCompile(` on\w+="[^"]*"`) //删除双引号事件
str = reOnEvent.ReplaceAllString(str, "")
reOnEvent2 := regexp.MustCompile(` on\w+='[^"]*'`) //删除单引号事件
str = reOnEvent2.ReplaceAllString(str, "")
reOnEvent3 := regexp.MustCompile(` on\w+=`) //破坏事件代码
str = reOnEvent3.ReplaceAllString(str, " ")
return str
}