feat: add static files simple server

This commit is contained in:
d3m0k1d
2026-02-15 02:15:05 +03:00
parent 51f8a125e9
commit 482e8571af
6 changed files with 282 additions and 1 deletions

View File

@@ -1,4 +1,4 @@
.PHONY: test build clean lint dev run-docker docs-upd docker .PHONY: test build clean lint dev run-docker docs-upd docker docker-run
test: test:
@@ -29,6 +29,9 @@ docker:
swag init -g ./cmd/main.go --parseDependency --parseInternal swag init -g ./cmd/main.go --parseDependency --parseInternal
docker build -t backend . docker build -t backend .
docker-run:
docker run --rm -p 8080:8080 --env-file .env -v /opt/d3m0k1d.ru/data:/data backend:latest
run-docker: run-docker:
docker build -t backend . docker build -t backend .
docker run --rm -p 8080:8080 --env-file .env backend:latest docker run --rm -p 8080:8080 --env-file .env backend:latest

View File

@@ -412,6 +412,88 @@ const docTemplate = `{
} }
} }
} }
},
"/upload": {
"post": {
"description": "Upload static content to the server",
"produces": [
"application/json"
],
"tags": [
"static"
],
"summary": "Upload static content",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
}
}
}
},
"/upload/{file}": {
"get": {
"description": "Get static content",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"static"
],
"summary": "Get static content",
"parameters": [
{
"type": "string",
"description": "File name",
"name": "file",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Static content",
"schema": {
"allOf": [
{
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "File not found",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
}
}
}
} }
}, },
"definitions": { "definitions": {

View File

@@ -401,6 +401,88 @@
} }
} }
} }
},
"/upload": {
"post": {
"description": "Upload static content to the server",
"produces": [
"application/json"
],
"tags": [
"static"
],
"summary": "Upload static content",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
}
}
}
},
"/upload/{file}": {
"get": {
"description": "Get static content",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"static"
],
"summary": "Get static content",
"parameters": [
{
"type": "string",
"description": "File name",
"name": "file",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Static content",
"schema": {
"allOf": [
{
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "File not found",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse"
}
}
}
}
} }
}, },
"definitions": { "definitions": {

View File

@@ -296,6 +296,57 @@ paths:
summary: Get user session summary: Get user session
tags: tags:
- auth - auth
/upload:
post:
description: Upload static content to the server
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse'
summary: Upload static content
tags:
- static
/upload/{file}:
get:
consumes:
- application/json
description: Get static content
parameters:
- description: File name
in: path
name: file
required: true
type: string
produces:
- application/json
responses:
"200":
description: Static content
schema:
allOf:
- $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse'
- properties:
data:
type: string
type: object
"404":
description: File not found
schema:
$ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse'
summary: Get static content
tags:
- static
securityDefinitions: securityDefinitions:
Bearer: Bearer:
description: Type "Bearer" followed by a space and the JWT token. description: Type "Bearer" followed by a space and the JWT token.

View File

@@ -11,8 +11,12 @@ import (
func Register(router *gin.Engine, db *sql.DB) { func Register(router *gin.Engine, db *sql.DB) {
handler_posts := NewPostHandlers(repositories.NewPostRepository(db)) handler_posts := NewPostHandlers(repositories.NewPostRepository(db))
handler_auth := NewAuthHandlers(repositories.NewAuthRepository(db)) handler_auth := NewAuthHandlers(repositories.NewAuthRepository(db))
handler_static := NewStaticHandlers()
router.GET("/health", func(c *gin.Context) { c.Status(200) }) router.GET("/health", func(c *gin.Context) { c.Status(200) })
v1 := router.Group("api/v1") v1 := router.Group("api/v1")
v1.Static("/uploads", "/data/uploads")
v1.POST("/upload", auth.JWTMiddleware(), auth.RequireAdmin(), handler_static.PostStatic)
v1.GET("/upload/:file", handler_static.GetStatic)
v1.GET("/callback/github", handler_auth.CallbackGithub) v1.GET("/callback/github", handler_auth.CallbackGithub)
v1.GET("/auth/github", handler_auth.LoginGithub) v1.GET("/auth/github", handler_auth.LoginGithub)
v1.GET("/session", auth.JWTMiddleware(), handler_auth.GetSession) v1.GET("/session", auth.JWTMiddleware(), handler_auth.GetSession)

View File

@@ -0,0 +1,59 @@
package handlers
import (
"gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/logger"
"gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/models"
"github.com/gin-gonic/gin"
)
type StaticHandlers struct {
logger *logger.Logger
}
func NewStaticHandlers() *StaticHandlers {
return &StaticHandlers{
logger: logger.New(false),
}
}
// PostStatic godoc
// @Summary Upload static content
// @Description Upload static content to the server
// @Tags static
// @Produce json
// @Success 200 {object} models.SuccessResponse(data=string) "Static content"
// @Failure 500 {object} models.ErrorResponse "Internal server error"
// @Router /upload [post]
func (h *StaticHandlers) PostStatic(c *gin.Context) {
content, err := c.FormFile("file")
if err != nil {
h.logger.Error("error request: " + err.Error())
models.Error(c, 500, "Internal server error", err.Error())
return
}
dst := "/data/upload/" + content.Filename
if err = c.SaveUploadedFile(content, dst); err != nil {
h.logger.Error("error request: " + err.Error())
models.Error(c, 500, "Internal server error", err.Error())
return
}
models.Success(c, "Static content saved")
}
// GetStatic godoc
// @Summary Get static content
// @Description Get static content
// @Tags static
// @Accept json
// @Produce json
// @Param file path string true "File name"
// @Success 200 {object} models.SuccessResponse{data=string} "Static content"
// @Failure 500 {object} models.ErrorResponse "Internal server error"
// @Failure 404 {object} models.ErrorResponse "File not found"
// @Router /upload/{file} [get]
func (h *StaticHandlers) GetStatic(c *gin.Context) {
// TODO: Unsecure handler need to be fixed
c.File("/data/upload/" + c.Param("file"))
}