Compare commits

...

4 Commits

Author SHA1 Message Date
Captain ALM f5f1625533
Add Gitbucket support. 2023-12-10 14:30:37 +00:00
Captain ALM 2e11c55981
Add setup and deploy support.
Fix readme.
2023-12-01 23:33:31 +00:00
Captain ALM 59b5d686d4
Simple Empty Content Fix.
continuous-integration/drone/push Build is passing Details
2022-07-15 15:33:21 +01:00
Captain ALM 1a48e7815f
Make sure no content length is outputted in non-content circumstances.
continuous-integration/drone/push Build is passing Details
2022-07-15 15:25:50 +01:00
9 changed files with 143 additions and 61 deletions

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SwUserDefinedSpecifications">
<option name="specTypeByUrl">
<map />
</option>
</component>
</project>

View File

@ -1,18 +1,21 @@
SHELL := /bin/bash
BIN := dist/gopkghsrv
ENTRY_POINT := ./cmd/gopkghsrv
PRODUCT_NAME := gopkghsrv
BIN := dist/${PRODUCT_NAME}
DNAME := ${PRODUCT_NAME}_
ENTRY_POINT := ./cmd/${PRODUCT_NAME}
HASH := $(shell git rev-parse --short HEAD)
COMMIT_DATE := $(shell git show -s --format=%ci ${HASH})
BUILD_DATE := $(shell date '+%Y-%m-%d %H:%M:%S')
VERSION := ${HASH}
LD_FLAGS := -s -w -X 'main.buildVersion=${VERSION}' -X 'main.buildDate=${BUILD_DATE}'
LD_FLAGS := -s -w -X 'main.buildVersion=${VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.buildName=${PRODUCT_NAME}'
COMP_BIN := go
ifeq ($(OS),Windows_NT)
BIN := $(BIN).exe
DNAME := $(DNAME).exe
endif
.PHONY: build dev test clean
.PHONY: build dev test clean deploy d setup s
build:
mkdir -p dist/
@ -24,8 +27,30 @@ dev:
./${BIN}
test:
go test
${COMP_BIN} test
clean:
go clean
${COMP_BIN} clean
rm -r -f dist/
setup:
sudo cp "${PRODUCT_NAME}.service" /etc/systemd/system
sudo mkdir -p "/etc/${PRODUCT_NAME}"
sudo touch "/etc/${PRODUCT_NAME}/.env"
sudo systemctl daemon-reload
s:
sudo cp "${DNAME}.service" /etc/systemd/system
sudo mkdir -p "/etc/${DNAME}"
sudo touch "/etc/${DNAME}/.env"
sudo systemctl daemon-reload
deploy: build
sudo systemctl stop "${PRODUCT_NAME}"
sudo cp "${BIN}" /usr/local/bin
sudo systemctl start "${PRODUCT_NAME}"
d: build
sudo systemctl stop "${DNAME}"
sudo cp "${BIN}" "/usr/local/bin/${DNAME}"
sudo systemctl start "${DNAME}"

View File

@ -1,6 +1,6 @@
# GO Package Header Server
[![Build Status](https://ci.mrmelon54.xyz/api/badges/alfred/GOPackageHeaderServer/status.svg)](https://ci.mrmelon54.xyz/alfred/GOPackageHeaderServer)
[![Build Status](https://ci.mrmelon54.com/api/badges/alfred/GOPackageHeaderServer/status.svg)](https://ci.mrmelon54.com/alfred/GOPackageHeaderServer)
This allows for the required meta headers to be outputted in order for the GO package system to find the source files of the package.
@ -8,11 +8,11 @@ The outputter can be configured in runtime, the server has a YAML configuration.
The outputter can be used to add the extra meta tags to the head of the HTML document.
Maintainer:
[Captain ALM](https://code.mrmelon54.xyz/alfred)
[Captain ALM](https://code.mrmelon54.com/alfred)
License:
[BSD 3-Clause](https://code.mrmelon54.xyz/alfred/GOPackageHeaderServer/src/branch/master/LICENSE.md)
[BSD 3-Clause](https://code.mrmelon54.com/alfred/GOPackageHeaderServer/src/branch/master/LICENSE.md)
Example configuration:
[config.example.yml](https://code.mrmelon54.xyz/alfred/GOPackageHeaderServer/src/branch/master/config.example.yml)
[config.example.yml](https://code.mrmelon54.com/alfred/GOPackageHeaderServer/src/branch/master/config.example.yml)
The configuration must by placed in a .data sub-directory from the executable. A .env file must also be generated (Can be empty).

View File

@ -3,19 +3,21 @@ package conf
import "golang.captainalm.com/GOPackageHeaderServer/outputMeta"
type ZoneYaml struct {
Name string `yaml:"name"`
Domains []string `yaml:"domains"`
CssURL string `yaml:"cssURL"`
HavePageContents bool `yaml:"havePageContents"`
BasePath string `yaml:"basePath"`
UsernameProvided bool `yaml:"usernameProvided"` //If set, the outputter will do /{user}/{repo}/ for repos rather than /{repo}/ ; Should really be named usernameProvidedByRequest
Username string `yaml:"username"`
BasePrefixURL string `yaml:"basePrefixURL"`
SuffixDirectoryURL string `yaml:"suffixDirectoryURL"`
SuffixFileURL string `yaml:"suffixFileURL"`
RangeSupported bool `yaml:"rangeSupported"`
PathLengthLimit uint `yaml:"pathLengthLimit"` //The length of the path (Number of entries in the path) to return in the responses; (If 0: defaults to 1, if the username is not expected to be provided by the request, otherwise defaulting to 2)
CacheSettings CacheSettingsYaml `yaml:"cacheSettings"`
Name string `yaml:"name"`
Domains []string `yaml:"domains"`
CssURL string `yaml:"cssURL"`
HavePageContents bool `yaml:"havePageContents"`
BasePath string `yaml:"basePath"`
UsernameProvided bool `yaml:"usernameProvided"` //If set, the outputter will do /{user}/{repo}/ for repos rather than /{repo}/ ; Should really be named usernameProvidedByRequest
Username string `yaml:"username"`
BasePrefixURL string `yaml:"basePrefixURL"`
SuffixDirectoryURL string `yaml:"suffixDirectoryURL"`
SuffixFileURL string `yaml:"suffixFileURL"`
RangeSupported bool `yaml:"rangeSupported"`
PathLengthLimit uint `yaml:"pathLengthLimit"` //The length of the path (Number of entries in the path) to return in the responses; (If 0: defaults to 1, if the username is not expected to be provided by the request, otherwise defaulting to 2)
SuffixImportURL string `yaml:"suffixImportURL"`
BasePrefixSourceURL string `yaml:"basePrefixSourceURL"`
CacheSettings CacheSettingsYaml `yaml:"cacheSettings"`
}
func (zy ZoneYaml) GetPackageMetaTagOutputter() *outputMeta.PackageMetaTagOutputter {
@ -32,11 +34,13 @@ func (zy ZoneYaml) GetPackageMetaTagOutputter() *outputMeta.PackageMetaTagOutput
}
}
return &outputMeta.PackageMetaTagOutputter{
BasePath: zy.BasePath,
Username: theUsername,
BasePrefixURL: zy.BasePrefixURL,
SuffixDirectoryURL: zy.SuffixDirectoryURL,
SuffixFileURL: zy.SuffixFileURL,
PathLengthLimit: pthLength,
BasePath: zy.BasePath,
Username: theUsername,
BasePrefixURL: zy.BasePrefixURL,
SuffixDirectoryURL: zy.SuffixDirectoryURL,
SuffixFileURL: zy.SuffixFileURL,
PathLengthLimit: pthLength,
SuffixImportURL: zy.SuffixImportURL,
BasePrefixSourceURL: zy.BasePrefixSourceURL,
}
}

15
gopkghsrv.service Normal file
View File

@ -0,0 +1,15 @@
# GO PKG Header Service
[Unit]
Description=GO PKG Header Service
[Service]
WorkingDirectory=/etc/gopkghsrv
ExecStart=/usr/local/bin/gopkghsrv
User=www-data
Group=www-data
Type=simple
Restart=on-failure
RestartSec=15
[Install]
WantedBy=multi-user.target

15
gopkghsrv_.service Normal file
View File

@ -0,0 +1,15 @@
# GO PKG Header Service (Dev)
[Unit]
Description=GO PKG Header Service (Dev)
[Service]
WorkingDirectory=/etc/gopkghsrv_
ExecStart=/usr/local/bin/gopkghsrv_
User=www-data
Group=www-data
Type=simple
Restart=on-failure
RestartSec=15
[Install]
WantedBy=multi-user.target

View File

@ -6,12 +6,14 @@ import (
)
type PackageMetaTagOutputter struct {
BasePath string
Username string //If set, the outputter will do /{repo}/ for repos rather than /{user}/{repo}/
BasePrefixURL string
SuffixDirectoryURL string
SuffixFileURL string
PathLengthLimit uint //The number of path entries in the go import paths
BasePath string
Username string //If set, the outputter will do /{repo}/ for repos rather than /{user}/{repo}/
BasePrefixURL string
SuffixDirectoryURL string
SuffixFileURL string
PathLengthLimit uint //The number of path entries in the go import paths
SuffixImportURL string
BasePrefixSourceURL string //If blank, use BasePrefixURL instead
}
func (pkgMTO *PackageMetaTagOutputter) GetMetaTags(pathIn string) string {
@ -21,12 +23,12 @@ func (pkgMTO *PackageMetaTagOutputter) GetMetaTags(pathIn string) string {
func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoImport(pathIn string) string {
pathLoc := pkgMTO.GetPath(pathIn)
return pkgMTO.getPrefix(pathLoc) + " git " + pkgMTO.getHomeURL(pathLoc)
return pkgMTO.getPrefix(pathLoc) + " git " + pkgMTO.getHomeURL(pathLoc, false) + pkgMTO.SuffixImportURL
}
func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoSource(pathIn string) string {
pathLoc := pkgMTO.GetPath(pathIn)
return pkgMTO.getPrefix(pathLoc) + " " + pkgMTO.getHomeURL(pathLoc) + " " +
return pkgMTO.getPrefix(pathLoc) + " " + pkgMTO.getHomeURL(pathLoc, true) + " " +
pkgMTO.getDirectoryURL(pathLoc) + " " + pkgMTO.getFileURL(pathLoc)
}
@ -53,6 +55,19 @@ func (pkgMTO *PackageMetaTagOutputter) assureBasePrefixURL() (failed bool) {
return false
}
func (pkgMTO *PackageMetaTagOutputter) assureBasePrefixSourceURL() (failed bool) {
if pkgMTO.BasePrefixSourceURL == "" {
if pkgMTO.assureBasePrefixURL() {
return true
}
if pkgMTO.BasePrefixURL == "" {
return true
}
pkgMTO.BasePrefixSourceURL = pkgMTO.BasePrefixURL
}
return false
}
func (pkgMTO *PackageMetaTagOutputter) getPrefix(pathIn string) string {
if pkgMTO.BasePath == "" {
return "_"
@ -60,38 +75,48 @@ func (pkgMTO *PackageMetaTagOutputter) getPrefix(pathIn string) string {
return path.Join(pkgMTO.BasePath, pathIn)
}
func (pkgMTO *PackageMetaTagOutputter) getHomeURL(pathIn string) string {
if pkgMTO.assureBasePrefixURL() {
return "_"
}
if pkgMTO.Username == "" {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Clean(pathIn), "/")
func (pkgMTO *PackageMetaTagOutputter) getHomeURL(pathIn string, isSource bool) string {
bpURL := ""
if isSource {
if pkgMTO.assureBasePrefixSourceURL() {
return "_"
} else {
bpURL = pkgMTO.BasePrefixSourceURL
}
} else {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn), "/")
if pkgMTO.assureBasePrefixURL() {
return "_"
} else {
bpURL = pkgMTO.BasePrefixURL
}
}
if pkgMTO.Username == "" {
return bpURL + "/" + strings.TrimLeft(path.Clean(pathIn), "/")
} else {
return bpURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn), "/")
}
}
func (pkgMTO *PackageMetaTagOutputter) getDirectoryURL(pathIn string) string {
if pkgMTO.assureBasePrefixURL() || pkgMTO.SuffixDirectoryURL == "" {
if pkgMTO.assureBasePrefixSourceURL() || pkgMTO.SuffixDirectoryURL == "" {
return "_"
}
if pkgMTO.Username == "" {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixDirectoryURL), "/")
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixDirectoryURL), "/")
} else {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixDirectoryURL), "/")
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixDirectoryURL), "/")
}
}
func (pkgMTO *PackageMetaTagOutputter) getFileURL(pathIn string) string {
if pkgMTO.assureBasePrefixURL() || pkgMTO.SuffixFileURL == "" {
if pkgMTO.assureBasePrefixSourceURL() || pkgMTO.SuffixFileURL == "" {
return "_"
}
if pkgMTO.Username == "" {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixFileURL), "/")
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixFileURL), "/")
} else {
return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixFileURL), "/")
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixFileURL), "/")
}
}

View File

@ -20,8 +20,8 @@ func (htm handlerTemplateMarshal) GetGoSourceMetaContent() string {
func (htm handlerTemplateMarshal) GetLink() string {
if htm.PageHandler.MetaOutput.Username == "" {
return htm.PageHandler.MetaOutput.BasePrefixURL + "/" + strings.TrimLeft(path.Clean(htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/")
return htm.PageHandler.MetaOutput.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Clean(htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/")
} else {
return htm.PageHandler.MetaOutput.BasePrefixURL + "/" + strings.TrimLeft(path.Join(htm.PageHandler.MetaOutput.Username, htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/")
return htm.PageHandler.MetaOutput.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(htm.PageHandler.MetaOutput.Username, htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/")
}
}

View File

@ -37,6 +37,8 @@ func ProcessSupportedPreconditionsForNext(rw http.ResponseWriter, req *http.Requ
}
if conditionFailed {
SwitchToNonCachingHeaders(rw.Header())
rw.Header().Del("Content-Type")
rw.Header().Del("Content-Length")
WriteResponseHeaderCanWriteBody(req.Method, rw, http.StatusPreconditionFailed, "")
return false
}
@ -54,6 +56,8 @@ func ProcessSupportedPreconditionsForNext(rw http.ResponseWriter, req *http.Requ
parse, err := time.Parse(http.TimeFormat, req.Header.Get("If-Unmodified-Since"))
if err == nil && modT.After(parse) {
SwitchToNonCachingHeaders(rw.Header())
rw.Header().Del("Content-Type")
rw.Header().Del("Content-Length")
WriteResponseHeaderCanWriteBody(req.Method, rw, http.StatusPreconditionFailed, "")
return false
}
@ -99,6 +103,8 @@ func ProcessRangePreconditions(maxLength int64, rw http.ResponseWriter, req *htt
}
} else {
SwitchToNonCachingHeaders(rw.Header())
rw.Header().Del("Content-Type")
rw.Header().Del("Content-Length")
rw.Header().Set("Content-Range", "bytes */"+strconv.FormatInt(maxLength, 10))
WriteResponseHeaderCanWriteBody(req.Method, rw, http.StatusRequestedRangeNotSatisfiable, "")
return nil