DEV Community

Masui Masanori
Masui Masanori

Posted on

[Nginx][Go] Configurations

Intro

This time, I will try loading configuration data on my Go project and adding more properties into nginx.conf.

Examples

Loading configuration data on Go projects

Last time, I changed the URL of my Go project to access through Nginx.
One problem is that this URL isn't same in all environments.

So I want to get the URL from external configuration data.

Loading files

I can save configuration data as a configuration file at "$HOME/.config"("%APPDATA%" for Windows).
But because I just wanted to load constant texts from an external file in this time, so I decided putting it into my project directory.

appsettings.json

{
    "url": "https://192.168.XX.YYY:443/webrtc"
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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 ""
}
Enter fullscreen mode Exit fullscreen mode

Loading environment variables

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
}
Enter fullscreen mode Exit fullscreen mode

Add more Nginx configurations

Timeout

Last time, I added some properties into the nginx.conf to use SSE and reverse proxy.
I noticed that the application established an SSE connection but automatically disconnected after one minute.

So I added a property to avoid timeout.

And I split the configurations for my Go project into "/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;
    }
}
Enter fullscreen mode Exit fullscreen mode

CORS

I can add CORS headers in the Go project like I tried before.

But I also can do this with 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more