mirror of
https://gitee.com/johng/gf
synced 2026-06-25 09:15:41 +08:00
完成ghttp客户端测试,文件上传客户端及服务端测试,version 0.90beta -> 0.91beta
This commit is contained in:
@ -8,14 +8,14 @@
|
||||
package ghttp
|
||||
|
||||
import (
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
"bytes"
|
||||
"strings"
|
||||
"net/http"
|
||||
"mime/multipart"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"io"
|
||||
)
|
||||
|
||||
// http客户端
|
||||
@ -46,40 +46,44 @@ func (c *Client) Put(url, data string) (*ClientResponse, error) {
|
||||
// POST请求提交数据
|
||||
// 支持文件上传,需要字段格式为:FieldName=@file:
|
||||
func (c *Client) Post(url, data string) (*ClientResponse, error) {
|
||||
isfile := false
|
||||
buffer := new(bytes.Buffer)
|
||||
writer := multipart.NewWriter(buffer)
|
||||
for _, item := range strings.Split(data, "&") {
|
||||
array := strings.Split(item, "=")
|
||||
// 判断是否文件上传
|
||||
if len(array[1]) > 6 && strings.Compare(array[1][0:6], "@file:") == 0 {
|
||||
isfile = true
|
||||
if file, err := writer.CreateFormFile(array[0], array[1][6:]); err == nil {
|
||||
if f, err := os.Open(array[1][6:]); err == nil {
|
||||
defer f.Close()
|
||||
if _, err = io.Copy(file, f); err != nil {
|
||||
var req *http.Request
|
||||
hasfile := strings.Contains(data, "@file:")
|
||||
if hasfile {
|
||||
buffer := new(bytes.Buffer)
|
||||
writer := multipart.NewWriter(buffer)
|
||||
for _, item := range strings.Split(data, "&") {
|
||||
array := strings.Split(item, "=")
|
||||
if len(array[1]) > 6 && strings.Compare(array[1][0:6], "@file:") == 0 {
|
||||
if file, err := writer.CreateFormFile(array[0], array[1][6:]); err == nil {
|
||||
if f, err := os.Open(array[1][6:]); err == nil {
|
||||
defer f.Close()
|
||||
if _, err = io.Copy(file, f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
writer.WriteField(array[0], array[1])
|
||||
}
|
||||
} else {
|
||||
writer.WriteField(array[0], array[1])
|
||||
}
|
||||
}
|
||||
writer.Close()
|
||||
req, err := http.NewRequest("POST", url, buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 表单类型处理
|
||||
if isfile {
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
writer.Close()
|
||||
if r, err := http.NewRequest("POST", url, buffer); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
req = r
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
}
|
||||
} else {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
if r, err := http.NewRequest("POST", url, bytes.NewReader([]byte(data))); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
req = r
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
}
|
||||
// 执行请求
|
||||
resp, err := c.Do(req)
|
||||
@ -118,9 +122,9 @@ func (c *Client) Trace(url, data string) (*ClientResponse, error) {
|
||||
|
||||
// 请求并返回response对象,该方法支持二进制提交数据
|
||||
func (c *Client) DoRequest(method, url string, data []byte) (*ClientResponse, error) {
|
||||
//if strings.Compare("POST", strings.ToUpper(method)) == 0 {
|
||||
// return c.Post(url, string(data))
|
||||
//}
|
||||
if strings.Compare("POST", strings.ToUpper(method)) == 0 {
|
||||
return c.Post(url, string(data))
|
||||
}
|
||||
fmt.Println(method)
|
||||
req, err := http.NewRequest(strings.ToUpper(method), url, bytes.NewReader(data))
|
||||
if err != nil {
|
||||
|
||||
18
g/net/ghttp/http_func.go
Normal file
18
g/net/ghttp/http_func.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package ghttp
|
||||
|
||||
import "gitee.com/johng/gf/g/encoding/gurl"
|
||||
|
||||
// 构建请求参数,将参数进行urlencode编码
|
||||
func BuildParams(params map[string]string) string {
|
||||
var s string
|
||||
for k, v := range params {
|
||||
s += k + "=" + gurl.Encode(v)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@ -12,26 +12,41 @@ import (
|
||||
"net/url"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/encoding/gjson"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 请求对象
|
||||
type Request struct {
|
||||
http.Request
|
||||
getvals *url.Values // GET参数
|
||||
Id int // 请求id(唯一)
|
||||
Server *Server // 请求关联的服务器对象
|
||||
Cookie *Cookie // 与当前请求绑定的Cookie对象(并发安全)
|
||||
Session *Session // 与当前请求绑定的Session对象(并发安全)
|
||||
Response *Response // 对应请求的返回数据操作对象
|
||||
parsedPost bool // POST参数是否已经解析
|
||||
getvals *url.Values // GET参数
|
||||
Id int // 请求id(唯一)
|
||||
Server *Server // 请求关联的服务器对象
|
||||
Cookie *Cookie // 与当前请求绑定的Cookie对象(并发安全)
|
||||
Session *Session // 与当前请求绑定的Session对象(并发安全)
|
||||
Response *Response // 对应请求的返回数据操作对象
|
||||
}
|
||||
|
||||
// 获得指定名称的get参数列表
|
||||
func (r *Request) GetQuery(k string) []string {
|
||||
// 初始化GET请求参数
|
||||
func (r *Request) initGet() {
|
||||
if r.getvals == nil {
|
||||
values := r.URL.Query()
|
||||
r.getvals = &values
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化POST请求参数
|
||||
func (r *Request) initPost() {
|
||||
if !r.parsedPost {
|
||||
// 快速保存,尽量避免并发问题
|
||||
r.parsedPost = true
|
||||
// MultiMedia表单请求解析允许最大使用内存:1GB
|
||||
r.ParseMultipartForm(1024*1024*1024)
|
||||
}
|
||||
}
|
||||
|
||||
// 获得指定名称的get参数列表
|
||||
func (r *Request) GetQuery(k string) []string {
|
||||
r.initGet()
|
||||
if v, ok := (*r.getvals)[k]; ok {
|
||||
return v
|
||||
}
|
||||
@ -72,14 +87,21 @@ func (r *Request) GetQueryArray(k string) []string {
|
||||
}
|
||||
|
||||
// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
|
||||
func (r *Request) GetQueryMap(defaultMap map[string]string) map[string]string {
|
||||
func (r *Request) GetQueryMap(defaultMap...map[string]string) map[string]string {
|
||||
r.initGet()
|
||||
m := make(map[string]string)
|
||||
for k, v := range defaultMap {
|
||||
v2 := r.GetQueryArray(k)
|
||||
if v2 == nil {
|
||||
m[k] = v
|
||||
} else {
|
||||
m[k] = v2[0]
|
||||
if len(defaultMap) == 0 {
|
||||
for k, v := range *r.getvals {
|
||||
m[k] = v[0]
|
||||
}
|
||||
} else {
|
||||
for k, v := range defaultMap[0] {
|
||||
v2 := r.GetQueryArray(k)
|
||||
if v2 == nil {
|
||||
m[k] = v
|
||||
} else {
|
||||
m[k] = v2[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
return m
|
||||
@ -87,10 +109,7 @@ func (r *Request) GetQueryMap(defaultMap map[string]string) map[string]string {
|
||||
|
||||
// 获得post参数
|
||||
func (r *Request) GetPost(k string) []string {
|
||||
if len(r.PostForm) == 0 {
|
||||
r.ParseForm()
|
||||
fmt.Println(r)
|
||||
}
|
||||
r.initPost()
|
||||
if v, ok := r.PostForm[k]; ok {
|
||||
return v
|
||||
}
|
||||
@ -132,13 +151,20 @@ func (r *Request) GetPostArray(k string) []string {
|
||||
|
||||
// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
|
||||
// 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetPostArray获取特定字段内容
|
||||
func (r *Request) GetPostMap(defaultMap map[string]string) map[string]string {
|
||||
func (r *Request) GetPostMap(defaultMap...map[string]string) map[string]string {
|
||||
r.initPost()
|
||||
m := make(map[string]string)
|
||||
for k, v := range defaultMap {
|
||||
if v2, ok := r.PostForm[k]; ok {
|
||||
m[k] = v2[0]
|
||||
} else {
|
||||
m[k] = v
|
||||
if len(defaultMap) == 0 {
|
||||
for k, v := range r.PostForm {
|
||||
m[k] = v[0]
|
||||
}
|
||||
} else {
|
||||
for k, v := range defaultMap[0] {
|
||||
if v2, ok := r.PostForm[k]; ok {
|
||||
m[k] = v2[0]
|
||||
} else {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return m
|
||||
@ -188,20 +214,28 @@ func (r *Request) GetRequestArray(k string) []string {
|
||||
|
||||
// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
|
||||
// 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetRequestArray获取特定字段内容
|
||||
func (r *Request) GetRequestMap(defaultMap map[string]string) map[string]string {
|
||||
m := make(map[string]string)
|
||||
for k, v := range defaultMap {
|
||||
v2 := r.GetRequest(k)
|
||||
if v2 != nil {
|
||||
m[k] = v2[0]
|
||||
} else {
|
||||
m[k] = v
|
||||
func (r *Request) GetRequestMap(defaultMap...map[string]string) map[string]string {
|
||||
m := r.GetQueryMap()
|
||||
if len(defaultMap) == 0 {
|
||||
for k, v := range r.GetPostMap() {
|
||||
if _, ok := m[k]; !ok {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for k, v := range defaultMap[0] {
|
||||
v2 := r.GetRequest(k)
|
||||
if v2 != nil {
|
||||
m[k] = v2[0]
|
||||
} else {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// 获取原始请求输入字符串
|
||||
// 获取原始请求输入字符串,注意:只能获取一次,读完就没了
|
||||
func (r *Request) GetRaw() []byte {
|
||||
result, _ := ioutil.ReadAll(r.Body)
|
||||
return result
|
||||
|
||||
@ -49,7 +49,7 @@ func Create(path string) error {
|
||||
|
||||
// 打开文件
|
||||
func Open(path string) (*os.File, error) {
|
||||
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0755)
|
||||
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -58,7 +58,7 @@ func Open(path string) (*os.File, error) {
|
||||
|
||||
// 打开文件
|
||||
func OpenWithFlag(path string, flag int) (*os.File, error) {
|
||||
f, err := os.OpenFile(path, flag, 0755)
|
||||
f, err := os.OpenFile(path, flag, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -315,22 +315,22 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
|
||||
// (文本)写入文件内容
|
||||
func PutContents(path string, content string) error {
|
||||
return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
}
|
||||
|
||||
// (文本)追加内容到文件末尾
|
||||
func PutContentsAppend(path string, content string) error {
|
||||
return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
|
||||
return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
}
|
||||
|
||||
// (二进制)写入文件内容
|
||||
func PutBinContents(path string, content []byte) error {
|
||||
return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
}
|
||||
|
||||
// (二进制)追加内容到文件末尾
|
||||
func PutBinContentsAppend(path string, content []byte) error {
|
||||
return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
|
||||
return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ func (p *Pool) File() (*File, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(p.path, p.flag, 0755)
|
||||
file, err := os.OpenFile(p.path, p.flag, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -290,15 +290,15 @@ func (l *Logger) errPrint(s string) {
|
||||
|
||||
// 调用回溯字符串
|
||||
func (l *Logger) backtrace() string {
|
||||
backtraces := []string{"Trace:"}
|
||||
for i := 1; i < 100; i++ {
|
||||
backtrace := "Trace:\n"
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, cfile, cline, ok := runtime.Caller(i + 3); ok {
|
||||
backtraces = append(backtraces, strconv.Itoa(i) + ". " + cfile + ":" + strconv.Itoa(cline) + "\n")
|
||||
backtrace += strconv.Itoa(i) + ". " + cfile + ":" + strconv.Itoa(cline) + "\n"
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(backtraces[0 : len(backtraces) -2 ], "\n")
|
||||
return backtrace
|
||||
}
|
||||
|
||||
func (l *Logger) format(s string) string {
|
||||
|
||||
35
geg/frame/mvc/controller/demo/form.go
Normal file
35
geg/frame/mvc/controller/demo/form.go
Normal file
@ -0,0 +1,35 @@
|
||||
package demo
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/net/ghttp"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Form(r *ghttp.Request) {
|
||||
fmt.Println(r.GetPostMap())
|
||||
fmt.Println(r.GetPostString("name"))
|
||||
fmt.Println(r.GetPostString("age"))
|
||||
|
||||
}
|
||||
|
||||
func FormShow(r *ghttp.Request) {
|
||||
r.Response.WriteString(`
|
||||
<html>
|
||||
<head>
|
||||
<title>表单提交</title>
|
||||
</head>
|
||||
<body>
|
||||
<form enctype="application/x-www-form-urlencoded" action="/form" method="post">
|
||||
<input type="input" name="name" />
|
||||
<input type="input" name="age" />
|
||||
<input type="submit" value="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
||||
func init() {
|
||||
ghttp.GetServer().BindHandler("/form", Form)
|
||||
ghttp.GetServer().BindHandler("/form/show", FormShow)
|
||||
}
|
||||
@ -8,16 +8,13 @@ import (
|
||||
)
|
||||
|
||||
func Upload(r *ghttp.Request) {
|
||||
fmt.Println(r.GetPostMap(nil))
|
||||
fmt.Println(r.GetPostString("name"))
|
||||
//fmt.Println(string(r.GetRaw()))
|
||||
return
|
||||
if f, h, e := r.FormFile("upload-file"); e == nil {
|
||||
defer f.Close()
|
||||
fname := gfile.Basename(h.Filename)
|
||||
buffer := make([]byte, h.Size)
|
||||
f.Read(buffer)
|
||||
gfile.PutBinContents("/tmp/" + h.Filename, buffer)
|
||||
r.Response.WriteString(fmt.Sprintf("%s upload success, input value:%s", h.Filename, r.GetPostString("name")))
|
||||
gfile.PutBinContents("/tmp/" + fname, buffer)
|
||||
r.Response.WriteString(fmt.Sprintf("%s upload success, input value:%s", fname, r.GetPostString("name")))
|
||||
} else {
|
||||
glog.Error(e)
|
||||
}
|
||||
|
||||
@ -3,9 +3,16 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/net/ghttp"
|
||||
"gitee.com/johng/gf/g/os/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, e := ghttp.Post("http://127.0.0.1:8199/upload", "name=john&age=18")
|
||||
fmt.Println(e)
|
||||
path := "/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/version.go"
|
||||
r, e := ghttp.Post("http://127.0.0.1:8199/upload?page=1", "name=john&upload-file=@file:" + path)
|
||||
if e != nil {
|
||||
glog.Error(e)
|
||||
} else {
|
||||
fmt.Println(string(r.ReadAll()))
|
||||
r.Close()
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/glog"
|
||||
"gitee.com/johng/gf/g/encoding/gurl"
|
||||
)
|
||||
|
||||
|
||||
@ -15,5 +15,5 @@ func (t *T)Test() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
glog.Error("test")
|
||||
fmt.Println(gurl.Encode("@123"))
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
package gf
|
||||
|
||||
// 框架信息
|
||||
const VERSION = "0.90 beta"
|
||||
const VERSION = "0.91 beta"
|
||||
const AUTHORS = "john<john@johng.cn>"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user