golang模拟web上传

前端之家收集整理的这篇文章主要介绍了golang模拟web上传前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近都在学习golang的内容,今天写了点东西。

学习是基于网上的一些文章。不过功能是全新的

1)实现golang请求Get

2)实现post登陆

3) 实现web上传(基于pp.sohu.com)

代码实现:

package main

import (
	"base"
	"bytes"
	"fmt"
	"io"
	"io/IoUtil"
	"log"
	"mime/multipart"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"regexp"
	"strings"
)

var gCurCookies []*http.Cookie
var gCurCookieJar *cookiejar.Jar
var logger *log.Logger

/*UploadBodyEle struct
--ad36e31ab0e27a44e9038057dc8d0a39aceb12b26f27fd6d375148e6b81a
Content-Disposition: form-data; name="Filename"

test.jpg
*/
type UploadBodyEle struct {
	boundary string
	key      string
	value    string
}

/*
Use these info to construct the whole upload body string
*/
type UploadBodyInfo struct {
	eleMap      map[string]string
	boundary    string
	fileContent string
}

func initAll() {
	gCurCookies = nil
	gCurCookieJar,_ = cookiejar.New(nil)
	logg := base.NewLogger("log","log.")
	logger = logg.Log()
}
func ReadUploadFile(filename string) string {
	buf := new(bytes.Buffer)
	w := multipart.NewWriter(buf)

	fw,err := w.CreateFormFile("file",filename)
	if err != nil {
		fmt.Println("c")
	}

	fd,err := os.Open(filename)
	defer fd.Close()
	if err != nil {
		fmt.Println("d")
	}

	_,err = io.Copy(fw,fd)
	if err != nil {
		fmt.Println("e")
	}
	w.Close()

	return buf.String()
}

func ConstructUploadBodyEleStr(ele *UploadBodyEle) string {
	return fmt.Sprintf("--%s\nContent-Disposition: form-data; name=\"%s\"\n\n%s\n",ele.boundary,ele.key,ele.value)
}
func ConstructUploadBodyStr(info *UploadBodyInfo) string {
	var str string
	for _key,_value := range info.eleMap {
		uploadbodyele := &UploadBodyEle{
			boundary: info.boundary,key:      _key,value:    _value,}
		str += ConstructUploadBodyEleStr(uploadbodyele)
	}
	str += fmt.Sprintf("%s\n",info.fileContent)
	return str
}

func ConstructUploadReq(strUrl string,postDict map[string]string,filename string) *http.Request{
	var httpReq *http.Request
	/*------------------------Content----------------------------*/
	file_content := ReadUploadFile(filename)

	info := &UploadBodyInfo{
		eleMap:      postDict,boundary:    file_content[2:strings.Index(file_content,"\n")],fileContent: file_content,}

	postDataStr := ConstructUploadBodyStr(info)

	postBytesReader := bytes.NewReader([]byte(postDataStr))

	httpReq,_ = http.NewRequest("POST",strUrl,postBytesReader)

	/*------------------------Head----------------------------*/
	httpReq.Header.Add("Content-Type",fmt.Sprintf("multipart/form-data; boundary=%s",info.boundary))

	return httpReq
}

func getUrlRespHtml(httpClient *http.Client,strUrl string,filename string) string {
	var httpReq *http.Request
	if nil == postDict {
        logger.Println("---------------is GET------------------")
		httpReq,_ = http.NewRequest("GET",nil)
		httpReq.Header.Set("Accept","application/json,text/javascript,*/*; q=0.01")
	} else {
		if filename == "" {
            logger.Println("---------------is POST------------------")
			postValues := url.Values{}
			for postKey,PostValue := range postDict {
				postValues.Set(postKey,PostValue)
			}
			postDataStr := postValues.Encode()
			postBytesReader := bytes.NewReader([]byte(postDataStr))
			httpReq,postBytesReader)

			httpReq.Header.Add("Content-Type","application/x-www-form-urlencoded")
		} else {
            logger.Println("---------------is POST Upload------------------")
			httpReq = ConstructUploadReq(strUrl,postDict,filename)
		}
	}

	httpResp,err := httpClient.Do(httpReq)
	if err != nil {
		logger.Println("http get strUrl=%s response error=%s",err.Error())
	}

	//logger.Println("httpResp.Status : %s",httpResp.Status)

	defer httpResp.Body.Close()

	body,errReadAll := IoUtil.ReadAll(httpResp.Body)
	if errReadAll != nil {
		logger.Println("get response for strUrl=%s got error=%s\n",errReadAll.Error())
	}

	gCurCookies = gCurCookieJar.Cookies(httpReq.URL)

	respHtml := string(body)

	return respHtml
}

func PrintCurCookies() {
	var cookieNum int = len(gCurCookies)
	logger.Println("cookieNum=%d",cookieNum)
	for i := 0; i < cookieNum; i++ {
		var curCk *http.Cookie = gCurCookies[i]
		logger.Println("------ Cookie [%d]------",i)
		logger.Println("Name\t\t=%s",curCk.Name)
		logger.Println("Value\t=%s",curCk.Value)
		logger.Println("Path\t\t=%s",curCk.Path)
		logger.Println("Domain\t=%s",curCk.Domain)
		logger.Println("Expires\t=%s",curCk.Expires)
		logger.Println("RawExpires\t=%s",curCk.RawExpires)
		logger.Println("MaxAge\t=%d",curCk.MaxAge)
		logger.Println("Secure\t=%t",curCk.Secure)
		logger.Println("HttpOnly\t=%t",curCk.HttpOnly)
		logger.Println("Raw\t\t=%s",curCk.Raw)
		logger.Println("Unparsed\t=%s",curCk.Unparsed)
	}
}

func main() {

	initAll()

	httpClient := &http.Client{
		Jar: gCurCookieJar,}

    //-------------------------------------------页面分割线------------------------------------------
	postDict := map[string]string{}
	postDict["appid"] = "9998"
	postDict["persistentcookie"] = "0"
	postDict["b"] = "7"
	postDict["w"] = "1440"
	postDict["pwdtype"] = "1"
	postDict["v"] = "27"
	postDict["isSLogin"] = "1"
	postDict["ru"] = "https://passport.sohu.com/user/tologin"
	postDict["domain"] = "sohu.com"
	postDict["loginSuccessCallFunction"] = "postLoginSuccessCall"
	postDict["loginFailCallFunction"] = "postLoginFailCall"
	//strUsername := ""
	//strPassword := ""
	//logger.Println("Plese input:")
	//logger.Println("Username:")
	//_,err1 := fmt.Scanln(&strUsername)
	//if nil == err1 {
	//	logger.Println("strUsername=%s",strUsername)
	//}
	//logger.Println("Password:")
	//_,err2 := fmt.Scanln(&strPassword)
	//if nil == err2 {
	//	logger.Println("strPassword=%s",strPassword)
	//}

	//postdict["userid"] = strusername
	//postdict["password"] = strpassword
	postDict["userid"] = "pengnenghui04@sohu.com"
	postDict["password"] = "1775520214"

	logger.Println("postDict=%s",postDict)

	mainLoginUrl := "https://passport.sohu.com/user/login"
	loginRespHtml := getUrlRespHtml(httpClient,mainLoginUrl,"")
	logger.Println("loginRespHtml=%s",loginRespHtml)
	PrintCurCookies()
    //-------------------------------------------页面分割线------------------------------------------

	toUrl_1 := "http://pp.sohu.com/folders"
	toRespHtml_1 := getUrlRespHtml(httpClient,toUrl_1,nil,"")
	logger.Println("toRespHtml=%s",toRespHtml_1)
	PrintCurCookies()

	m := regexp.MustCompile("\"showId\":\".*\",\"name\":\".*\",\"userId\"")
	list := m.FindStringSubmatch(toRespHtml_1)
	logger.Println(list)
	var toUrl_2 string
	for _,str := range list {
		start := len("\"showId\":\"")
		start_ := len("\",\"name\":\"")
		end := strings.Index(str,"\",\"name\":\"")
		end_ := strings.LastIndex(str,\"userId\"")
		//logger.Println(start,start_,end,end_)
		logger.Println(str[start:end])
		logger.Println(str[start_+end : end_])
		toUrl_2 = fmt.Sprintf("http://pp.sohu.com/upload?folder_id=%s",str[start:end])
	}

    //-------------------------------------------页面分割线------------------------------------------
	logger.Println(toUrl_2)

	postDict_2 := map[string]string{}
	postDict_2["Upload"] = "Submit Query"
	postDict_2["Filename"] = "test.jpg"
	toRespHtml_2 := getUrlRespHtml(httpClient,toUrl_2,postDict_2,"test.jpg")
	logger.Println("toRespHtml=%s",toRespHtml_2)
	PrintCurCookies()
}


get请求很简单,post请求用fidder可以截取到包,通过map[string]string构造

post upload上传复杂一点,不过也是构造fidder截取到的封包

猜你在找的Go相关文章