[Nginx][Go] 구성

22540 단어 gonginx

소개



이번에는 Go 프로젝트에서 구성 데이터를 로드하고 nginx.conf에 더 많은 속성을 추가해 보겠습니다.



  • webappsample - GitHub

  • Go 프로젝트에서 구성 데이터 로드



    지난번에는 Go 프로젝트의 URL을 Nginx를 통해 액세스하도록 변경했습니다.
    한 가지 문제는 이 URL이 모든 환경에서 동일하지 않다는 것입니다.

    그래서 외부 구성 데이터에서 URL을 가져오고 싶습니다.

    파일 로드 중



    구성 데이터를 "$HOME/.config"(Windows의 경우 "%APPDATA%")에 구성 파일로 저장할 수 있습니다.
    하지만 이번에는 외부 파일에서 상수 텍스트를 로드하고 싶었기 때문에 프로젝트 디렉토리에 넣기로 결정했습니다.

    appsettings.json




    {
        "url": "https://192.168.XX.YYY:443/webrtc"
    }
    


    appsettings.go




    package main
    
    import (
        "encoding/json"
        "fmt"
        "os"
    )
    
    type AppSettings struct {
        URL string `json:"url"`
    }
    
    func LoadAppSettings() (setting AppSettings, err error) {
        result := &AppSettings{}
        cur, _ := os.Getwd()
        file, err := os.Open(fmt.Sprintf("%s/appsettings.json", cur))
        if err != nil {
            return *result, err
        }
        fileInfo, err := file.Stat()
        if err != nil {
            return *result, err
        }
        // Read the config file
        fileData := make([]byte, fileInfo.Size())
        _, err = file.Read(fileData)
        if err != nil {
            return *result, err
        }
        err = json.Unmarshal(fileData, &result)
        return *result, err
    }
    


    main.go




    ...
    
    func main() {
        settings, _ := LoadAppSettings()
        target := getStrippingTargetPrefix(settings.URL)
    
        hub := *newSSEHub()
        go hub.run()
    
        if len(target) > 0 {
            http.Handle(fmt.Sprintf("/%s/css/", target), http.StripPrefix(fmt.Sprintf("/%s", target), http.FileServer(http.Dir("templates"))))
            http.Handle(fmt.Sprintf("/%s/js/", target), http.StripPrefix(fmt.Sprintf("/%s", target), http.FileServer(http.Dir("templates"))))
    
            http.HandleFunc(fmt.Sprintf("/%s/sse/message", target), func(w http.ResponseWriter, r *http.Request) {
                sendSSEMessage(w, r, &hub)
            })
            http.HandleFunc(fmt.Sprintf("/%s/sse/", target), func(w http.ResponseWriter, r *http.Request) {
                registerSSEClient(w, r, &hub)
            })
        } else {
            http.Handle("/css/", http.FileServer(http.Dir("templates")))
            http.Handle("/js/", http.FileServer(http.Dir("templates")))
    
            http.HandleFunc("/sse/message", func(w http.ResponseWriter, r *http.Request) {
                sendSSEMessage(w, r, &hub)
            })
            http.HandleFunc("/sse/", func(w http.ResponseWriter, r *http.Request) {
                registerSSEClient(w, r, &hub)
            })
        }
        http.Handle("/", &templateHandler{filename: "index.html", serverUrl: settings.URL})
        log.Fatal(http.ListenAndServe("localhost:8080", nil))
    }
    func getStrippingTargetPrefix(url string) string {
        sURL := strings.Split(url, "/")
        if len(sURL) <= 3 {
            return ""
        }
        for i := len(sURL) - 1; i >= 3; i-- {
            if sURL[i] != "" {
                return sURL[i]
            }
        }
        return ""
    }
    


  • How to get file length in Go? - StackOverflow

  • 환경 변수 로드



    appsettings.go




    package main
    
    import (
        "os"
    )
    
    type AppSettings struct {
        URL string `json:"url"`
    }
    
    func LoadAppSettings() (setting AppSettings, err error) {
        result := &AppSettings{}
        result.URL = os.Getenv("WEBRTCAPP_URL")
        if len(result.URL) <= 0 {
            result.URL = "http://localhost:8080"
        }
        return *result, err
    }
    


    더 많은 Nginx 구성 추가



    타임아웃



    지난 시간에 SSE와 리버스 프록시를 사용하기 위해 몇 가지 속성을 nginx.conf에 추가했습니다.
    애플리케이션이 SSE 연결을 설정했지만 1분 후에 자동으로 연결이 끊어지는 것을 확인했습니다.

    그래서 시간 초과를 피하기 위해 속성을 추가했습니다.

    그리고 내 Go 프로젝트의 구성을 "/etc/nginx/conf.d/webrtcapp.conf"로 분할했습니다.

    webrtcapp.conf




    server {
        listen 443 ssl;
        server_name 192.168.XX.YYY;
        proxy_buffering off;
        proxy_cache off;
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
        # The connection times out after 24 hours.
        proxy_read_timeout 24h;
    
        ssl_certificate /home/example/local_cert.pem;
        ssl_certificate_key /home/example/local_key.pem;
        location /webrtc {
    
            proxy_pass http://localhost:8080;
        }
    }
    


    CORS



    이전에 시도한 것처럼 Go 프로젝트에 CORS 헤더를 추가할 수 있습니다.


  • 하지만 Nginx로도 이 작업을 수행할 수 있습니다.

    webrtcapp.conf




    map $http_origin $cors {
        'http://localhost:8080' $http_origin;
        'https://192.168.XX.YYY:443' $http_origin;
    }
    map $request_method $cors_method {
      OPTIONS 11;
      GET  1;
      POST 1; 
      default 0;
    }
    
    server {
    ...
        location /webrtc {
            if ($cors_method ~ '1') {
                add_header 'Access-Control-Allow-Origin' $cors;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
                add_header 'Access-Control-Allow-Headers' '*';
            }
            if ($cors_method = '11') {
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain; charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
            proxy_pass http://localhost:8080;
        }
    }
    


  • Core functionality - Nginx
  • Module ngx_http_proxy_module - Nginx
  • Module ngx_http_core_module - Nginx
  • NGINX Cookbook, 2nd Edition
  • Nginxで複数Originを許可するCORS設定例
  • How to allow access via CORS to multiple domains within nginx - StackOverflow
  • 좋은 웹페이지 즐겨찾기