Skip to content

Commit

Permalink
Merge pull request #25 from nglmq/iter25
Browse files Browse the repository at this point in the history
Iter25
  • Loading branch information
nglmq authored Sep 4, 2024
2 parents c04ee82 + 1e51df0 commit 2ece8c0
Show file tree
Hide file tree
Showing 20 changed files with 2,545 additions and 29 deletions.
30 changes: 30 additions & 0 deletions cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFMDCCAxigAwIBAgICBnowDQYJKoZIhvcNAQELBQAwKDELMAkGA1UEBhMCUlUx
GTAXBgNVBAoTEFlhbmRleC5QcmFrdGlrdW0wHhcNMjQwODE4MTI1MzIwWhcNMzQw
ODE4MTI1MzIwWjAoMQswCQYDVQQGEwJSVTEZMBcGA1UEChMQWWFuZGV4LlByYWt0
aWt1bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMia0+SwQRJrzhax
ZWFuBP13Sz8dC3BeINON4NFxXI1J6xAyNfNBqxXh7pQH0hTmoDBNJ1bdEuQg+td6
CgXFvEjU/ULEJJm+1bJmUvzWr3eiLKFrirHy7gPSupa70nv6wsnFncjwiU3/g2mI
FfP2csqz8e6+UWrsUK3H4l3Mgk8cp+hkADyaAt6WPQjRHG1wYYZPtidUATfYWmXf
XW3bC998XgmENyoVrBMjLNNGkxzb2r+J4RgLm9IZAPUv/wEAcW3Rw4HR/R4X/z1d
IlTWhZYvMu0QO2CBafZbRU5kcRSuM9wcIZ3Xz7fgo2sNTfGeeQJ/dYA1o/RlaYra
lTu3PMC725mOiwq0EqR88uutXd2jLKWLqTmaoxDe4+X19HtdG33SqI5ELrhRfZFR
hTorkuBhYd+2K+/JxaGNqt/fcmSbQOyWsmHDesd4XeRQvjoZLCoGWyVCVDHlckQo
PTXAXmjWAU6fkF7oAe2M8etW4cam2QwjtzJB/0zi/e6FeQkZ450jVgBpb1lHpHB8
sRkpHaAiXK2vQJBaTdVay5yAdQLBVdZmWvxosJhPbmi+qGNjotVtw15sgbzVKm8Z
jVOZFZXJde2wM7PecBRbW7llFgU2PmJIGmbTVkX7t9lhiXpKPEtMfNT6doBLXV6n
PV3I4uRk7y2Lj9aRTglzV2Qpg3VXAgMBAAGjZDBiMA4GA1UdDwEB/wQEAwIHgDAd
BgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0OBAcEBQECAwQGMCEG
A1UdEQQaMBiHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQAD
ggIBAGc8ZguUKw4aa2BmELu1eInY6za5/pWXzXQCx8zWmiWlQAxf13V8Qgto1G8R
uacEHkVx8H3J40Ge7RucdOG5mXnrlW2AgSFqM3MBcqPf7zK01yuq2RZSSitbFWHn
QXTu8WESANRvA5nMaKiBz1j2SH2KaBOkeSiyBnx+WgCqLvzXukZiUFbfiFzizKIc
HQffPRzw0r94j726H+FsdE69qlDGI/nvh0Kew7xs+QNW+F4uwATmPviVBndwaHml
ODKWmON1C1PaIT4BvFnCUAq7HfF0OiKeMPfBaVRCQpj0XBfXG9sDi3cuYgifqzu2
cA9tGyrS/YKlCkYEMk4S/wf7GfVeu6a2zOlCZy4WORljVZy1042zvMDW4SrsDavk
Q31WukUVKYT/RcxvhdYovuYjBZZfIjnI+dZ39uOv2oy9B2JHutY41AzN5ShdkDy6
x2plxZ4iggqs9rEOJ4MYalG2CdHmgPl42tWvuP32LpIEseqUcXjxLv/QN+uIShBa
Pm8jae6HVG6mGgGe1Nq22h/PwoA2NXjH5hiK/oLlzt7aatCVo0enVgzY+02n52WT
Z1f/vwFsOaNrJ4jho96yFsSeoOIhX63mOK1v1JjWZNTxCyKZr2O9uWAqR6pm7JAZ
pdMS74B/Wyko/VzFTTqWeKOqKElrtpdCBlKnJvyp3sNkRVNP
-----END CERTIFICATE-----
59 changes: 58 additions & 1 deletion cmd/shortener/main.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,76 @@
package main

import (
"context"
"errors"
"fmt"
grpcserver "github.com/nglmq/url-shortener/internal/app/grpc/server"
"log"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"syscall"

"github.com/nglmq/url-shortener/internal/app/cert"

"github.com/nglmq/url-shortener/config"
"github.com/nglmq/url-shortener/internal/app/server"
)

var (
buildVersion string = "N/A"
buildDate string = "N/A"
buildCommit string = "N/A"
)

func main() {
fmt.Printf("Build version: %s\n", buildVersion)
fmt.Printf("Build date: %s\n", buildDate)
fmt.Printf("Build commit: %s\n", buildCommit)

r, err := server.Start()
if err != nil {
log.Fatal(err)
}

log.Fatal(http.ListenAndServe(config.FlagRunAddr, r))
if config.GRPCServer {
if err := grpcserver.StartGRPCServer(); err != nil {
log.Fatal(err)
}
} else {
srv := &http.Server{
Addr: config.FlagRunAddr,
Handler: r,
}

idleConnsClosed := make(chan struct{})
sigint := make(chan os.Signal, 3)

signal.Notify(sigint, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

go func() {
<-sigint

if err := srv.Shutdown(context.Background()); err != nil {
log.Printf("HTTP server Shutdown: %v", err)
}
close(idleConnsClosed)
}()

if config.EnableHTTPS {
cert.CertGen()
fmt.Printf("Starting server: %s", config.FlagRunAddr)
err = srv.ListenAndServeTLS("cert.pem", "key.pem")
} else {
err = srv.ListenAndServe()
}

if !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("HTTP server ListenAndServe: %v", err)
}

<-idleConnsClosed
fmt.Println("Server Shutdown gracefully")
}
}
100 changes: 100 additions & 0 deletions cmd/staticlint/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// To start the staticcheck:
//
// 1. go build -o staticlint cmd/staticlint/main.go
// 2. ./staticlint.exe <path to the package>

package main

import (
"go/ast"
"strings"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/multichecker"
"golang.org/x/tools/go/analysis/passes/asmdecl"
"golang.org/x/tools/go/analysis/passes/assign"
"golang.org/x/tools/go/analysis/passes/atomic"
"golang.org/x/tools/go/analysis/passes/bools"
"golang.org/x/tools/go/analysis/passes/buildtag"
"golang.org/x/tools/go/analysis/passes/cgocall"
"golang.org/x/tools/go/analysis/passes/composite"
"golang.org/x/tools/go/analysis/passes/copylock"
"golang.org/x/tools/go/analysis/passes/httpresponse"
"golang.org/x/tools/go/analysis/passes/loopclosure"
"golang.org/x/tools/go/analysis/passes/lostcancel"
"golang.org/x/tools/go/analysis/passes/nilfunc"
"golang.org/x/tools/go/analysis/passes/printf"
"golang.org/x/tools/go/analysis/passes/shadow"
"golang.org/x/tools/go/analysis/passes/shift"
"golang.org/x/tools/go/analysis/passes/stdmethods"
"golang.org/x/tools/go/analysis/passes/structtag"
"golang.org/x/tools/go/analysis/passes/tests"
"golang.org/x/tools/go/analysis/passes/unmarshal"
"golang.org/x/tools/go/analysis/passes/unreachable"
"golang.org/x/tools/go/analysis/passes/unsafeptr"
"golang.org/x/tools/go/analysis/passes/unusedresult"
"honnef.co/go/tools/staticcheck"
)

// ErrCheckOsExit checks os.Exit call in main function
var ErrCheckOsExit = &analysis.Analyzer{
Name: "errcheckosexit",
Doc: "check os.Exit call in main function",
Run: run,
}

func run(pass *analysis.Pass) (interface{}, error) {
for _, file := range pass.Files {
ast.Inspect(file, func(n ast.Node) bool {
if call, ok := n.(*ast.CallExpr); ok {
if s, ok := call.Fun.(*ast.SelectorExpr); ok {
if x, ok := s.X.(*ast.Ident); ok {
if x.Name == "os" && s.Sel.Name == "Exit" {
pass.Reportf(call.Pos(), "os.Exit called")
}
}
}
}

return true
})
}

return nil, nil
}

func main() {
checks := []*analysis.Analyzer{
asmdecl.Analyzer,
assign.Analyzer,
atomic.Analyzer,
bools.Analyzer,
buildtag.Analyzer,
cgocall.Analyzer,
composite.Analyzer,
copylock.Analyzer,
httpresponse.Analyzer,
loopclosure.Analyzer,
lostcancel.Analyzer,
nilfunc.Analyzer,
printf.Analyzer,
shift.Analyzer,
shadow.Analyzer,
stdmethods.Analyzer,
structtag.Analyzer,
tests.Analyzer,
unmarshal.Analyzer,
unreachable.Analyzer,
unsafeptr.Analyzer,
unusedresult.Analyzer,
ErrCheckOsExit,
}

for _, v := range staticcheck.Analyzers {
if strings.HasPrefix(v.Doc.Title, "SA") {
checks = append(checks, v.Analyzer)
}
}

multichecker.Main(checks...)
}
41 changes: 41 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@ package config

import (
"flag"
"log/slog"
"os"
)

// server_address": "localhost:8080", // аналог переменной окружения SERVER_ADDRESS или флага -a
// "base_url": "http://localhost", // аналог переменной окружения BASE_URL или флага -b
// "file_storage_path": "/path/to/file.db", // аналог переменной окружения FILE_STORAGE_PATH или флага -f
// "database_dsn": "", // аналог переменной окружения DATABASE_DSN или флага -d
// "enable_https": true // аналог переменной окружения ENABLE_HTTPS или флага -s
// Flags for the server config
var (
FlagRunAddr string
FlagBaseURL string
FlagInMemoryStorage string
DBConnection string
EnableHTTPS bool
ReadConfigFile string
TrustedSubnet string
GRPCServer bool
)

// ParseFlags parses the command line args and ENV variables
Expand All @@ -19,6 +29,10 @@ func ParseFlags() {
flag.StringVar(&FlagBaseURL, "b", "http://localhost:8080", "base url")
flag.StringVar(&FlagInMemoryStorage, "f", "", "in memory storage")
flag.StringVar(&DBConnection, "d", "", "postgres connection url")
flag.BoolVar(&EnableHTTPS, "s", false, "enable https")
flag.StringVar(&ReadConfigFile, "c", "", "read json config from file")
flag.StringVar(&TrustedSubnet, "t", "", "CIDR")
flag.BoolVar(&GRPCServer, "g", false, "run gRPC server")
flag.Parse()

envRunAddr := os.Getenv("SERVER_ADDRESS")
Expand All @@ -40,4 +54,31 @@ func ParseFlags() {
if envDBConnection != "" {
DBConnection = envDBConnection
}

envEnableHTTPS := os.Getenv("ENABLE_HTTPS")
if envEnableHTTPS != "" {
EnableHTTPS = true
}

envTrustedSubnet := os.Getenv("TRUSTED_SUBNET")
if envTrustedSubnet != "" {
TrustedSubnet = envTrustedSubnet
}

envGRPCServer := os.Getenv("GRPC_SERVER")
if envGRPCServer != "" {
GRPCServer = true
}

envReadConfig := os.Getenv("CONFIG")
if envReadConfig != "" {
ReadConfigFile = envReadConfig
}

if ReadConfigFile != "" {
err := ReadJSONConfig(ReadConfigFile)
if err != nil {
slog.Info("error while reading json")
}
}
}
9 changes: 9 additions & 0 deletions config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"server_address": "localhost:8080",
"base_url": "http://localhost:8080",
"file_storage_path": "",
"database_dsn": "postgres://postgres:ANTON_og228@localhost:5432/postgres",
"enable_https": false,
"trusted_subnet": "79.139.178.194/32",
"grpc_server": true
}
56 changes: 56 additions & 0 deletions config/json_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package config

import (
"encoding/json"
"fmt"
"os"
)

// JSONConfig Struct for JSON configuration
type JSONConfig struct {
ServerAddress string `json:"server_address"` // аналог переменной окружения SERVER_ADDRESS или флага -a
BaseURL string `json:"base_url"` // аналог переменной окружения BASE_URL или флага -b
FileStoragePath string `json:"file_storage_path"` // аналог переменной окружения FILE_STORAGE_PATH или флага -f
DatabaseDSN string `json:"database_dsn"` // аналог переменной окружения DATABASE_DSN или флага -d
EnableHTTPS bool `json:"enable_https"` // аналог переменной окружения ENABLE_HTTPS или флага -s
TrustedSubnet string `json:"trusted_subnet"` // аналог переменной окружения TRUSTED_SUBNET или флага -t
GRPCServer bool `json:"grpc_server"` // аналог переменной окружения GRPC_SERVER или флага -g
}

// ReadJSONConfig read config from file
func ReadJSONConfig(filename string) error {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("failed to open file: %v", err)
}

var config JSONConfig

if err := json.NewDecoder(file).Decode(&config); err != nil {
return fmt.Errorf("error decoding json: %v", err)
}

if config.ServerAddress != "" {
FlagRunAddr = config.ServerAddress
}
if config.BaseURL != "" {
FlagBaseURL = config.BaseURL
}
if config.FileStoragePath != "" {
FlagInMemoryStorage = config.FileStoragePath
}
if config.DatabaseDSN != "" {
DBConnection = config.DatabaseDSN
}
if config.EnableHTTPS {
EnableHTTPS = true
}
if config.TrustedSubnet != "" {
TrustedSubnet = config.TrustedSubnet
}
if config.GRPCServer {
GRPCServer = true
}

return nil
}
24 changes: 17 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ go 1.21.9

require (
github.com/go-chi/chi/v5 v5.0.12
github.com/go-playground/validator/v10 v10.19.0
github.com/go-playground/validator/v10 v10.22.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.6.0
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438
github.com/jackc/pgx/v5 v5.5.5
github.com/jackc/pgx/v5 v5.6.0
github.com/lib/pq v1.10.9
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.21.0
golang.org/x/net v0.27.0
google.golang.org/protobuf v1.34.2
)

require (
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
golang.org/x/mod v0.19.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
)

require (
Expand All @@ -27,9 +34,12 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.23.0
google.golang.org/grpc v1.66.0
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.4.7
)
Loading

0 comments on commit 2ece8c0

Please sign in to comment.