정상우
hELLO.
정상우
전체 방문자
384,472
오늘
91
어제
1,174
  • hELLO. (121)
    • 컴퓨터과학 (4)
      • 알고리즘 & 자료구조 (4)
    • 언어 & 프레임워크 (63)
      • Go (23)
      • PHP & Laravel (40)
    • 웹 (7)
    • 블록체인 (12)
      • 메인넷 (9)
      • 암호화폐 플랫폼 (3)
    • 포트폴리오 (10)
    • 칼럼 (20)
      • 에세이 (4)
      • 개발자스럽게 살기 (14)
      • 회고 (2)
    • 티스토리 (5)

블로그 메뉴

  • ⚡ 개발자 이력서
  • 🌟 깃허브
  • 💻 강의
  • ✨ 예제코드
  • ⭐ 브런치
  • 태그 클라우드
  • 방명록

공지사항

  • 2차 도메인을 설정했습니다 ✨

인기 글

  • JWT(JSON Web Token)의 개념부⋯
    2021.07.29
    JWT(JSON Web Token)의 개념부⋯
  • 'REST' 를 보다 'RESTful' 하게⋯
    2021.08.14
    'REST' 를 보다 'RESTful' 하게⋯
  • [Laravel] 라라벨 프레임워크⋯
    2021.06.10
    [Laravel] 라라벨 프레임워크⋯
  • 깃허브를 포트폴리오로 쓰려면⋯
    2021.12.25
    깃허브를 포트폴리오로 쓰려면⋯
  • 암호화폐 트레이딩 봇을 만들었⋯
    2021.05.12
    암호화폐 트레이딩 봇을 만들었⋯

태그

  • 라라벨
  • go
  • 포트폴리오
  • 개발 리뷰
  • 개발
  • php
  • 블록체인
  • 프로그래머스
  • Algorithm
  • 코딩테스트

최근 댓글

  • 고맙습니다 ~^^
    정상우
  • 오늘 블로그 만들었는데 검색하⋯
    엥뿌삐
  • 좋은 스킨 정말 감사드립니다.⋯
    이태홍
  • 고맙습니다 ㅎㅎ
    정상우
  • 제가 원하던 최고의 스킨입니다⋯
    _HEON

최근 글

  • 빠르게 성장하는 개발자의 세⋯
    2022.06.08
    빠르게 성장하는 개발자의 세⋯
  • 개발자와 엔지니어, 그 사이에서
    2022.05.10
    개발자와 엔지니어, 그 사이에서
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.03
    아임포트(Iamport)로 결제기능⋯
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.01
    아임포트(Iamport)로 결제기능⋯
  • [Laravel] 카페24 호스팅에 라⋯
    2022.03.29
    [Laravel] 카페24 호스팅에 라⋯

티스토리

hELLO · Designed By 정상우.
정상우

hELLO.

언어 & 프레임워크/Go

Go: 싱글 바이너리로 웹 서비스 제공하기 (go-bindata)

2020. 12. 24. 10:32

Go 를 사용하여 얻을 수 있는 이점 중 하나는, 빌드의 결과로 싱글 바이너리가 나와 간단하게 배포하고 사용자에게 제공할 수 있다는 점이다. 그런데, 이러한 Go 로 작성한 웹 서비스를 제공하려고 하다보면 각종 리소스 파일이 많아지는 것으로 인해 문제가 될 수 있다. 기껏 싱글 바이너리로 어플리케이션을 배포할 수 있는데 리소스 파일로 인해 배포할 파일이 늘어난다면 그건 이점을 살리지 못한 것이 될 지도 모른다.

리소스를 바이너리에 포함시키기

리소스를 별도의 파일로 분리시키지 않고 소스코드에 포함시켜 최종적으로는 바이너리에 포함될 수 있도록 만들 수 있는데, 바로 go-bindata 를 사용하면 그런 행위가 가능하다. go-bindata 를 사용하면 실제 파일시스템 경로와 유사한 사용방법으로 API 를 사용하여 논리적으로 접근할 수 있다.

 

https://github.com/go-bindata/go-bindata

 

go-bindata/go-bindata

Turn data file into go code. Contribute to go-bindata/go-bindata development by creating an account on GitHub.

github.com

먼저 우리는 data 라는 폴더에 txt, image, html 등 여러 리소스 파일이 있다고 가정해보자. go-bindata 를 설치했다면 go-bindata 바이너리가 설치되어 해당 커맨드를 사용할 수 있게된다.

go-bindata ./data

위와 같이 실행하고나면 bindata.go 라는 파일이 생겨나고 되고 디폴트로 main 패키지에 포함될 것이다. 만약 data 폴더 아래에 hello.txt 파일이 존재한다면 다음과 같이 접근할 수 있다.

b, err := Asset("data/hello.txt")
if err != nil {
	log.Fatal(err)
}

io.Copy(os.Stdout, bytes.NewReader(b))

go-bindata 를 사용하여 bindata.go 를 만들고 나면 해당 파일에는 파일이 바이트 배열로 바뀌어있는 모습을 볼 수 있다. 따라서 새롭게 리소스를 추가하거나 삭제하지 않는 한, 다시 go-bindata 를 실행할 필요는 없어진다.

var _dataHelloTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xf2\x48\xcd\xc9\xc9\xd7\x51\x70\xcf\x57\x04\x04\x00\x00\xff\xff\x6b\x54\x39\x35\x0a\x00\x00\x00")

웹 서버에 정적파일 제공하기

이것을 사용하면 실제 파일시스템에 접근하는 것보다도 안전하게 사용자에게 정적파일 컨텐츠를 제공할 수 있다. 예를 들어 사용자가 /hello.txt 경로에 접근했다면, 소스코드에서는 hello.txt 에 접근하도록 만들면 된다. 리소스 파일은 data 폴더에 있도록 하되 미리 접두사를 만들어 놓고 data/hello.txt 가 아닌 hello.txt 만으로도 접근이 가능하도록 만들자.

go-bindata -prefix data ./data

이제 아래와 같이 웹 서버를 작성하고나면 정적파일에 접근할 수 있다. r.URL.Path 의 경우 요청 URL 이 담기게 될 텐데, http.StripPrefix() 에 의해 / 문자는 제외하고 오게된다.

package main

import (
	"log"
	"mime"
	"net/http"
	"path"
	"strconv"
)

func main() {
	http.Handle("/", http.StripPrefix("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		p := r.URL.Path
		if r.URL.Path == "" {
			p = "index.html"
		}

		b, err := Asset(p)
		if err != nil {
			http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		}

		if ctype := mime.TypeByExtension(path.Ext(r.URL.Path)); ctype != "" {
			w.Header().Set("Content-Type", ctype)
		}
		w.Header().Set("Content-Length", strconv.Itoa(len(b)))

		w.Write(b)
	})))

	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}

본래라면 사용자에게 파일시스템에 접근할 수 있도록 하였을 때, filepath.Base() 와 같은 함수를 사용하여 보안을 신경써야 할 필요가 있었으나, 이와 같이 구성하면 필요한 리소스 파일에 대해서만 접근을 허용하기 때문에 더욱 안전하다고 볼 수 있다.

    '언어 & 프레임워크/Go' 카테고리의 다른 글
    • Go: Switch 를 사용하여 타입 체크하기 (Reflection) [Effective Go]
    • Go: new vs make [Effective Go]
    • Go: 개발 환경과 도구, 크로스 컴파일
    • Go: path vs path/filepath
    go, 싱글바이너리, 웹서버, 정적, 정적파일, 파일, 파일시스템
    정상우
    정상우
    과거의 배움으로 현재를 바꾸고 미래를 만듭니다. #25+2살 #INFJ #개발자 #브런치작가
    댓글쓰기
    다음 글
    Go: new vs make [Effective Go]
    이전 글
    Go: 개발 환경과 도구, 크로스 컴파일
    • 이전
    • 1
    • ···
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • ···
    • 121
    • 다음

    티스토리툴바