[Go] echo의 파일 업로드 처리(서버 측)

16650 단어 Goechotech

개시하다

  • Go를 통해 이미지 파일을 업로드하는 웹 서버를 간편하게 설치했기 때문에 내용을 요약했다.
  • 이루어지다

  • 이번에는 curl http://localhost:8080/upload -F [email protected]라는 요청을 실행할 때 image_out.png 이미지 파일을 저장하는 처리를 하는 서버를 실시한다.image.pngimage_out.png의 내용은 같다.
  • 이번 웹 서버의 설치는 Go의 웹 프레임워크Echo를 사용했다.설치 예는 다음과 같습니다.
  • main.go
    package main
    
    import (
    	"fmt"
    	"github.com/labstack/echo/v4"
    	"io"
    	"os"
    	"strings"
    )
    
    func upload(c echo.Context) error {
    	file, err := c.FormFile("file")
    	if err != nil {
    		return err
    	}
    	src, err := file.Open()
    	if err != nil {
    		return err
    	}
    	defer src.Close()
    
    	fileModel := strings.Split(file.Filename, ".")
    	fileName := fileModel[0]
    	extension := fileModel[1]
    	dst, err := os.Create(fmt.Sprintf("%s_out.%s", fileName, extension))
    	if err != nil {
    		return err
    	}
    	defer dst.Close()
    
    	if _, err = io.Copy(dst, src); err != nil {
    		return err
    	}
    
    	return c.HTML(200, "Image has been saved.")
    }
    
    func main() {
    	e := echo.New()
    	e.POST("/upload", upload)
    	e.Start(":8080")
    }
    
  • 업로드 처리의 실시에 관해서는 여기.를 참고하십시오.
  • 테스트

  • 업로드된 이미지와 서버 측에서 저장한 이미지 파일의 내용이 일치하는지 확인했습니다.curl에서 실제 요청 확인을 할 수 있으며 이번에 httptest포장을 사용하여 코드를 바탕으로 동작 확인을 진행하였다.httptest 패키지를 사용하면 테스트가 실행될 때 서버를 시작하고 시작된 서버에 대한 요청을 실행하여 API의 행위를 확인할 수 있다.echo를 사용하여 구현된 API도 이 httptest 패키지를 사용하여 테스트할 수 있습니다.설치 예는 다음과 같습니다.
  • main_test.go
    package main
    
    import (
    	"bytes"
    	"github.com/labstack/echo/v4"
    	"github.com/stretchr/testify/assert"
    	"io"
    	"io/ioutil"
    	"mime/multipart"
    	"net/http"
    	"net/http/httptest"
    	"os"
    	"testing"
    )
    
    func TestUpload(t *testing.T) {
    
    	// テストサーバ起動
    	e := echo.New()
    	e.POST("/upload", upload)
    	testServer := httptest.NewServer(e)
    	defer testServer.Close()
    
    	// クライアントの画像ファイルアップロード処理
    	var buffer bytes.Buffer
    	writer := multipart.NewWriter(&buffer)
    	fileWriter, err := writer.CreateFormFile("file", "test.png")
    	if err != nil{
    		t.Fatalf("Failed to create file writer. %s", err)
    	}
    
    	readFile, err := os.Open("test.png")
    	if err != nil {
    		t.Fatalf("Failed to open file. %s", err)
    	}
    	defer readFile.Close()
    	io.Copy(fileWriter, readFile)
    	writer.Close()
    
    	res, err := http.Post(testServer.URL + "/upload", writer.FormDataContentType(), &buffer)
    	if err != nil{
    		t.Fatalf("Failed to POST request. %s", err)
    	}
    
    	// API レスポンス検証
    	message, err := ioutil.ReadAll(res.Body)
    	res.Body.Close()
    	if err != nil {
    		t.Fatalf("Failed to read HTTP response body. %s", err)
    	}
    	assert.Equal(t, "Image has been saved.", string(message))
    
    	// アップロードを行った画像ファイルとサーバ側が保存した画像の内容が一致しているかどうか検証
    	outFile, err := os.Open("test_out.png")
    	if err != nil {
    		t.Fatalf("Failed to open file. %s", err)
    	}
    	defer outFile.Close()
    	var expectedBytes []byte
    	readFile.Write(expectedBytes)
    	var actualBytes []byte
    	outFile.Write(actualBytes)
    	assert.Equal(t, expectedBytes, actualBytes)
    }
    
  • 테스트 실행 결과는 다음과 같다(이번에 진행된 Go 프로젝트의 이름은 go-sample이다).
  • $ go test -run TestUpload
    PASS
    ok      go-sample       0.116s
    

    좋은 웹페이지 즐겨찾기