Ver Fonte

feat:实现对form-data请求支持

chengjian há 3 anos atrás
pai
commit
c5fb688014
3 ficheiros alterados com 20 adições e 202 exclusões
  1. 0 125
      rpcx-gateway/.idea/workspace.xml
  2. 11 28
      rpcx-gateway/converter.go
  3. 9 49
      rpcx-gateway/gateway.go

+ 0 - 125
rpcx-gateway/.idea/workspace.xml

@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="AutoImportSettings">
-    <option name="autoReloadType" value="SELECTIVE" />
-  </component>
-  <component name="ChangeListManager">
-    <list default="true" id="58f21262-dec0-4388-a049-ec45c7d728fa" name="Changes" comment="">
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/.gitignore" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/compiler.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/golinter.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/micro_gateway.iml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/misc.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/modules.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/../micro_gateway/.idea/vcs.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../micro_gateway/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/../micro_gateway/go.mod" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../micro_gateway/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/../micro_gateway/go.sum" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/../micro_gateway/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/../micro_gateway/main.go" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/converter.go" beforeDir="false" afterPath="$PROJECT_DIR$/converter.go" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/gateway.go" beforeDir="false" afterPath="$PROJECT_DIR$/gateway.go" afterDir="false" />
-    </list>
-    <option name="SHOW_DIALOG" value="false" />
-    <option name="HIGHLIGHT_CONFLICTS" value="true" />
-    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
-    <option name="LAST_RESOLUTION" value="IGNORE" />
-  </component>
-  <component name="GOROOT" url="file:///usr/local/go" />
-  <component name="Git.Settings">
-    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
-  </component>
-  <component name="MarkdownSettingsMigration">
-    <option name="stateVersion" value="1" />
-  </component>
-  <component name="ProjectId" id="2HGnX0ZVeW51i1zflvBXdk8HDdL" />
-  <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
-  <component name="ProjectViewState">
-    <option name="hideEmptyMiddlePackages" value="true" />
-    <option name="showLibraryContents" value="true" />
-  </component>
-  <component name="PropertiesComponent">{
-  &quot;keyToString&quot;: {
-    &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
-    &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
-    &quot;RunOnceActivity.go.formatter.settings.were.checked&quot;: &quot;true&quot;,
-    &quot;RunOnceActivity.go.migrated.go.modules.settings&quot;: &quot;true&quot;,
-    &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
-    &quot;go.import.settings.migrated&quot;: &quot;true&quot;,
-    &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
-    &quot;settings.editor.selected.configurable&quot;: &quot;project.kotlinCompiler&quot;
-  }
-}</component>
-  <component name="RunManager">
-    <configuration default="true" type="GoApplicationRunConfiguration" factoryName="Go Application">
-      <module name="rpcx-gateway" />
-      <working_directory value="$PROJECT_DIR$" />
-      <go_parameters value="-i" />
-      <kind value="FILE" />
-      <directory value="$PROJECT_DIR$" />
-      <filePath value="$PROJECT_DIR$" />
-      <method v="2" />
-    </configuration>
-    <configuration default="true" type="GoTestRunConfiguration" factoryName="Go Test">
-      <module name="rpcx-gateway" />
-      <working_directory value="$PROJECT_DIR$" />
-      <go_parameters value="-i" />
-      <kind value="DIRECTORY" />
-      <directory value="$PROJECT_DIR$" />
-      <filePath value="$PROJECT_DIR$" />
-      <framework value="gotest" />
-      <method v="2" />
-    </configuration>
-  </component>
-  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
-  <component name="TaskManager">
-    <task active="true" id="Default" summary="Default task">
-      <changelist id="58f21262-dec0-4388-a049-ec45c7d728fa" name="Changes" comment="" />
-      <created>1667920330652</created>
-      <option name="number" value="Default" />
-      <option name="presentableId" value="Default" />
-      <updated>1667920330652</updated>
-      <workItem from="1667920337060" duration="720000" />
-      <workItem from="1667921208634" duration="24000" />
-      <workItem from="1667921287454" duration="3112000" />
-      <workItem from="1668041733998" duration="4357000" />
-      <workItem from="1668073732806" duration="479000" />
-      <workItem from="1668140504866" duration="1348000" />
-      <workItem from="1668349196722" duration="5852000" />
-      <workItem from="1668387766123" duration="4592000" />
-      <workItem from="1668529288313" duration="17000" />
-      <workItem from="1668529610531" duration="1264000" />
-      <workItem from="1668558446930" duration="497000" />
-      <workItem from="1668571436655" duration="1001000" />
-      <workItem from="1668585451039" duration="90000" />
-    </task>
-    <servers />
-  </component>
-  <component name="TypeScriptGeneratedFilesManager">
-    <option name="version" value="3" />
-  </component>
-  <component name="Vcs.Log.Tabs.Properties">
-    <option name="TAB_STATES">
-      <map>
-        <entry key="MAIN">
-          <value>
-            <State />
-          </value>
-        </entry>
-      </map>
-    </option>
-  </component>
-  <component name="VgoProject">
-    <settings-migrated>true</settings-migrated>
-  </component>
-  <component name="XDebuggerManager">
-    <breakpoint-manager>
-      <breakpoints>
-        <line-breakpoint enabled="true" type="DlvLineBreakpoint">
-          <url>file://$USER_HOME$/go/pkg/mod/github.com/smallnest/rpcx@v1.6.3-0.20210426142302-97437a82168d/client/xclient.go</url>
-          <line>978</line>
-          <option name="timeStamp" value="1" />
-        </line-breakpoint>
-      </breakpoints>
-    </breakpoint-manager>
-  </component>
-</project>

+ 11 - 28
rpcx-gateway/converter.go

@@ -176,53 +176,36 @@ func MultipartRequest2RpcxRequest(r *http.Request) (*protocol.Message, string, e
 
 	multipartReader, readerErr := r.MultipartReader()
 	if readerErr != nil {
-		return nil, "", errors.New("创建form-data报文Reader失败")
+		return nil, "", readerErr
 	}
 
 	form, parseErr := multipartReader.ReadForm(32 << 20)
 	if parseErr != nil {
-		return nil, "", errors.New("解析form-data报文异常")
+		return nil, "", parseErr
 	}
 
-	formParams := make(map[string]string)
+	metaForm := make(map[string]string)
 	for k, v := range form.Value {
-		formParams[k] = v[0]
+		metaForm[k] = v[0]
 	}
-	file := form.File["file"]
+	jstr, _ := json.Marshal(metaForm)
+	req.Payload = jstr
 
-	if len(file) != 1 {
-		return nil, "", errors.New("未上传文件或上传多个文件")
-	}
-
-	fh := file[0]
-	fi, err := fh.Open()
-	if err != nil {
-		return nil, "", errors.New("获取文件失败")
-	}
-	defer fi.Close()
-
-	formParams["file_name"] = fh.Filename
-	formParams["file_size"] = strconv.FormatInt(fh.Size, 10)
-	payload, _ := json.Marshal(formParams)
-	req.Payload = payload
+	fh := form.File["file"][0]
+	fi, _ := fh.Open()
+	buf, _ := ioutil.ReadAll(fi)
 
-	// 获取报文中文件名后缀
 	suffix := path.Ext(fh.Filename)
 
-	// 创建临时文件
 	tmpFile, err := ioutil.TempFile(os.TempDir(), "multipart-*"+suffix)
 	if err != nil {
-		log.Fatal("创建临时文件失败:", err)
+		log.Fatal("Cannot create temporary file", err)
 		return nil, "", err
 	}
 
-	// 一次性
-	buf, _ := ioutil.ReadAll(fi)
-
-	// 将接收文件写入临时文件
 	_, err = tmpFile.Write(buf)
 	if err != nil {
-		log.Fatal("写入临时文件失败:", err)
+		log.Fatal("Failed to write to temporary file", err)
 		return nil, "", err
 	}
 

+ 9 - 49
rpcx-gateway/gateway.go

@@ -5,10 +5,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
-	"github.com/smallnest/rpcx/log"
-	"io"
 	"mime"
-	"net"
 	"net/http"
 	"os"
 	"strings"
@@ -100,35 +97,22 @@ func (g *Gateway) handler(r *http.Request, servicePath string) (meta map[string]
 
 	if mediaType == gin.MIMEMultipartPOSTForm {
 		req, fileName, err := MultipartRequest2RpcxRequest(r)
-
-		formParams := make(map[string]string)
-
-		err = json.Unmarshal(req.Payload, &formParams)
-		if err != nil {
-			return nil, nil, err
-		}
+		formMeta := make(map[string]string)
+		err = json.Unmarshal(req.Payload, formMeta)
 
 		defer os.Remove(fileName)
 
-		conn, callErr := xc.Stream(context.Background(), formParams)
-		if callErr != nil {
-			return nil, nil, err
-		}
-
-		err = sendFile(conn, fileName)
-		if err != nil {
-			log.Errorf("send file err:", err)
-		}
+		err = xc.SendFile(context.Background(), fileName, 0, formMeta)
 
-		resp, err := io.ReadAll(conn)
 		if err != nil {
-			log.Errorf("conn read err:", err)
+			return nil, nil, err
 		}
-		fmt.Println("收到server发来的数据:", string(resp))
-
-		conn.Close()
 
-		return req.Metadata, resp, err
+		resp := make(map[string]interface{})
+		resp["code"] = 200
+		resp["msg"] = "提交成功!"
+		payload, err = json.Marshal(resp)
+		return req.Metadata, payload, err
 	} else {
 		req, err := HttpRequest2RpcxRequest(r)
 		if err != nil {
@@ -182,27 +166,3 @@ func getRequestToken(r *http.Request) string {
 	}
 	return ""
 }
-
-// sendFile
-func sendFile(conn net.Conn, filePath string) error {
-	// 只读打开文件
-	f, err := os.Open(filePath)
-	if err != nil {
-		return err
-	}
-	// 从本文件中,读数据,写给网络接收端。
-	buf := make([]byte, 1024)
-	for {
-		n, err := f.Read(buf)
-		if n == 0 {
-			log.Debug("发送文件完成")
-			return nil
-		}
-		// 写到网络socket中
-		_, err = conn.Write(buf[:n])
-		if err != nil {
-			log.Debug("conn.Write err:", err)
-			return nil
-		}
-	}
-}