Compare commits

..

No commits in common. "master" and "#0d4036d" have entirely different histories.

11 changed files with 59 additions and 179 deletions

8
.idea/misc.xml Normal file
View File

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

View File

@ -1,21 +1,18 @@
SHELL := /bin/bash SHELL := /bin/bash
PRODUCT_NAME := gopkghsrv BIN := dist/gopkghsrv
BIN := dist/${PRODUCT_NAME} ENTRY_POINT := ./cmd/gopkghsrv
DNAME := ${PRODUCT_NAME}_
ENTRY_POINT := ./cmd/${PRODUCT_NAME}
HASH := $(shell git rev-parse --short HEAD) HASH := $(shell git rev-parse --short HEAD)
COMMIT_DATE := $(shell git show -s --format=%ci ${HASH}) COMMIT_DATE := $(shell git show -s --format=%ci ${HASH})
BUILD_DATE := $(shell date '+%Y-%m-%d %H:%M:%S') BUILD_DATE := $(shell date '+%Y-%m-%d %H:%M:%S')
VERSION := ${HASH} VERSION := ${HASH}
LD_FLAGS := -s -w -X 'main.buildVersion=${VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.buildName=${PRODUCT_NAME}' LD_FLAGS := -s -w -X 'main.buildVersion=${VERSION}' -X 'main.buildDate=${BUILD_DATE}'
COMP_BIN := go COMP_BIN := go
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
BIN := $(BIN).exe BIN := $(BIN).exe
DNAME := $(DNAME).exe
endif endif
.PHONY: build dev test clean deploy d setup s .PHONY: build dev test clean
build: build:
mkdir -p dist/ mkdir -p dist/
@ -27,30 +24,8 @@ dev:
./${BIN} ./${BIN}
test: test:
${COMP_BIN} test go test
clean: clean:
${COMP_BIN} clean go clean
rm -r -f dist/ 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 # GO Package Header Server
[![Build Status](https://ci.mrmelon54.com/api/badges/alfred/GOPackageHeaderServer/status.svg)](https://ci.mrmelon54.com/alfred/GOPackageHeaderServer) [![Build Status](https://ci.mrmelon54.xyz/api/badges/alfred/GOPackageHeaderServer/status.svg)](https://ci.mrmelon54.xyz/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. 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. The outputter can be used to add the extra meta tags to the head of the HTML document.
Maintainer: Maintainer:
[Captain ALM](https://code.mrmelon54.com/alfred) [Captain ALM](https://code.mrmelon54.xyz/alfred)
License: License:
[BSD 3-Clause](https://code.mrmelon54.com/alfred/GOPackageHeaderServer/src/branch/master/LICENSE.md) [BSD 3-Clause](https://code.mrmelon54.xyz/alfred/GOPackageHeaderServer/src/branch/master/LICENSE.md)
Example configuration: Example configuration:
[config.example.yml](https://code.mrmelon54.com/alfred/GOPackageHeaderServer/src/branch/master/config.example.yml) [config.example.yml](https://code.mrmelon54.xyz/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). 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

@ -10,7 +10,6 @@ import (
"os" "os"
"os/signal" "os/signal"
"path" "path"
"path/filepath"
"sync" "sync"
"syscall" "syscall"
"time" "time"
@ -49,18 +48,8 @@ func main() {
check(os.MkdirAll(dataDir, 0777)) check(os.MkdirAll(dataDir, 0777))
//Config file processing:
configLocation := os.Getenv("CONFIG_FILE")
if configLocation == "" {
configLocation = path.Join(dataDir, "config.yml")
} else {
if !filepath.IsAbs(configLocation) {
configLocation = path.Join(dataDir, configLocation)
}
}
//Config loading: //Config loading:
configFile, err := os.Open(configLocation) configFile, err := os.Open(path.Join(dataDir, "config.yml"))
if err != nil { if err != nil {
log.Fatalln("Failed to open config.yml") log.Fatalln("Failed to open config.yml")
} }

View File

@ -8,15 +8,12 @@ type ZoneYaml struct {
CssURL string `yaml:"cssURL"` CssURL string `yaml:"cssURL"`
HavePageContents bool `yaml:"havePageContents"` HavePageContents bool `yaml:"havePageContents"`
BasePath string `yaml:"basePath"` 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 UsernameProvided bool `yaml:"usernameProvided"`
Username string `yaml:"username"` Username string `yaml:"username"`
BasePrefixURL string `yaml:"basePrefixURL"` BasePrefixURL string `yaml:"basePrefixURL"`
SuffixDirectoryURL string `yaml:"suffixDirectoryURL"` SuffixDirectoryURL string `yaml:"suffixDirectoryURL"`
SuffixFileURL string `yaml:"suffixFileURL"` SuffixFileURL string `yaml:"suffixFileURL"`
RangeSupported bool `yaml:"rangeSupported"` 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"` CacheSettings CacheSettingsYaml `yaml:"cacheSettings"`
} }
@ -25,22 +22,11 @@ func (zy ZoneYaml) GetPackageMetaTagOutputter() *outputMeta.PackageMetaTagOutput
if !zy.UsernameProvided { if !zy.UsernameProvided {
theUsername = zy.Username theUsername = zy.Username
} }
pthLength := zy.PathLengthLimit
if pthLength == 0 {
if zy.UsernameProvided {
pthLength = 2
} else {
pthLength = 1
}
}
return &outputMeta.PackageMetaTagOutputter{ return &outputMeta.PackageMetaTagOutputter{
BasePath: zy.BasePath, BasePath: zy.BasePath,
Username: theUsername, Username: theUsername,
BasePrefixURL: zy.BasePrefixURL, BasePrefixURL: zy.BasePrefixURL,
SuffixDirectoryURL: zy.SuffixDirectoryURL, SuffixDirectoryURL: zy.SuffixDirectoryURL,
SuffixFileURL: zy.SuffixFileURL, SuffixFileURL: zy.SuffixFileURL,
PathLengthLimit: pthLength,
SuffixImportURL: zy.SuffixImportURL,
BasePrefixSourceURL: zy.BasePrefixSourceURL,
} }
} }

View File

@ -12,12 +12,11 @@ zones: #An array of zones
havePageContents: true #Output a header and link to the target repo havePageContents: true #Output a header and link to the target repo
basePath: "localhost" #The base-path, also known as, package name basePath: "localhost" #The base-path, also known as, package name
basePrefixURL: "http://localhost" #The base git URL basePrefixURL: "http://localhost" #The base git URL
usernameProvided: true #If the username is expected to be provided in requests to the server (When false the value of username can be used) usernameProvided: true #If the username would be provided in requests to the server (When false the value of username can be used)
username: "captain-alm" #The username to append to the start of a path under the prefix username: "captain-alm" #The username to append to the start of a path under the prefix
suffixDirectoryURL: "src/branch/master{/dir}" #The suffix location of the main branch for directory usage suffixDirectoryURL: "src/branch/master{/dir}" #The suffix location of the main branch for directory usage
suffixFileURL: "src/branch/master{/dir}/{file}#L{line}" #The suffix location of the main branch for file usage suffixFileURL: "src/branch/master{/dir}/{file}#L{line}" #The suffix location of the main branch for file usage
rangeSupported: true #Are range requests supported rangeSupported: true #Are range requests supported
pathLengthLimit: 0 #The length of the returned paths in the responses (Number of path entries); (If 0: defaults to 1, if the username is not expected to be provided by the request, otherwise defaulting to 2)
cacheSettings: #Cache settings cacheSettings: #Cache settings
maxAge: 0 #The maximum age of the cache maxAge: 0 #The maximum age of the cache
notModifiedUsingLastModified: true #Are the conditional headers attached to Last-Modified used to work out if to send a 304 Cache Redirect notModifiedUsingLastModified: true #Are the conditional headers attached to Last-Modified used to work out if to send a 304 Cache Redirect

View File

@ -1,15 +0,0 @@
# 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

View File

@ -1,15 +0,0 @@
# 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

@ -11,9 +11,6 @@ type PackageMetaTagOutputter struct {
BasePrefixURL string BasePrefixURL string
SuffixDirectoryURL string SuffixDirectoryURL string
SuffixFileURL 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 { func (pkgMTO *PackageMetaTagOutputter) GetMetaTags(pathIn string) string {
@ -22,27 +19,12 @@ func (pkgMTO *PackageMetaTagOutputter) GetMetaTags(pathIn string) string {
} }
func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoImport(pathIn string) string { func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoImport(pathIn string) string {
pathLoc := pkgMTO.GetPath(pathIn) return pkgMTO.getPrefix(pathIn) + " git " + pkgMTO.getHomeURL(pathIn)
return pkgMTO.getPrefix(pathLoc) + " git " + pkgMTO.getHomeURL(pathLoc, false) + pkgMTO.SuffixImportURL
} }
func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoSource(pathIn string) string { func (pkgMTO *PackageMetaTagOutputter) GetMetaContentForGoSource(pathIn string) string {
pathLoc := pkgMTO.GetPath(pathIn) return pkgMTO.getPrefix(pathIn) + " " + pkgMTO.getHomeURL(pathIn) + " " +
return pkgMTO.getPrefix(pathLoc) + " " + pkgMTO.getHomeURL(pathLoc, true) + " " + pkgMTO.getDirectoryURL(pathIn) + " " + pkgMTO.getFileURL(pathIn)
pkgMTO.getDirectoryURL(pathLoc) + " " + pkgMTO.getFileURL(pathLoc)
}
func (pkgMTO *PackageMetaTagOutputter) GetPath(pathIn string) string {
cleaned := path.Clean(pathIn)
if cleaned == "/" || cleaned == "." {
return cleaned
}
split := strings.Split(cleaned, "/")
toReturn := ""
for i := 1; i < len(split) && i < int(pkgMTO.PathLengthLimit)+1; i++ {
toReturn += split[i] + "/"
}
return toReturn[:len(toReturn)-1]
} }
func (pkgMTO *PackageMetaTagOutputter) assureBasePrefixURL() (failed bool) { func (pkgMTO *PackageMetaTagOutputter) assureBasePrefixURL() (failed bool) {
@ -55,19 +37,6 @@ func (pkgMTO *PackageMetaTagOutputter) assureBasePrefixURL() (failed bool) {
return false 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 { func (pkgMTO *PackageMetaTagOutputter) getPrefix(pathIn string) string {
if pkgMTO.BasePath == "" { if pkgMTO.BasePath == "" {
return "_" return "_"
@ -75,48 +44,38 @@ func (pkgMTO *PackageMetaTagOutputter) getPrefix(pathIn string) string {
return path.Join(pkgMTO.BasePath, pathIn) return path.Join(pkgMTO.BasePath, pathIn)
} }
func (pkgMTO *PackageMetaTagOutputter) getHomeURL(pathIn string, isSource bool) string { func (pkgMTO *PackageMetaTagOutputter) getHomeURL(pathIn string) string {
bpURL := ""
if isSource {
if pkgMTO.assureBasePrefixSourceURL() {
return "_"
} else {
bpURL = pkgMTO.BasePrefixSourceURL
}
} else {
if pkgMTO.assureBasePrefixURL() { if pkgMTO.assureBasePrefixURL() {
return "_" return "_"
} else {
bpURL = pkgMTO.BasePrefixURL
}
} }
if pkgMTO.Username == "" { if pkgMTO.Username == "" {
return bpURL + "/" + strings.TrimLeft(path.Clean(pathIn), "/") return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Clean(pathIn), "/")
} else { } else {
return bpURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn), "/") return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn), "/")
} }
} }
func (pkgMTO *PackageMetaTagOutputter) getDirectoryURL(pathIn string) string { func (pkgMTO *PackageMetaTagOutputter) getDirectoryURL(pathIn string) string {
if pkgMTO.assureBasePrefixSourceURL() || pkgMTO.SuffixDirectoryURL == "" { if pkgMTO.assureBasePrefixURL() || pkgMTO.SuffixDirectoryURL == "" {
return "_" return "_"
} }
if pkgMTO.Username == "" { if pkgMTO.Username == "" {
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixDirectoryURL), "/") return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixDirectoryURL), "/")
} else { } else {
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixDirectoryURL), "/") return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixDirectoryURL), "/")
} }
} }
func (pkgMTO *PackageMetaTagOutputter) getFileURL(pathIn string) string { func (pkgMTO *PackageMetaTagOutputter) getFileURL(pathIn string) string {
if pkgMTO.assureBasePrefixSourceURL() || pkgMTO.SuffixFileURL == "" { if pkgMTO.assureBasePrefixURL() || pkgMTO.SuffixFileURL == "" {
return "_" return "_"
} }
if pkgMTO.Username == "" { if pkgMTO.Username == "" {
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixFileURL), "/") return pkgMTO.BasePrefixURL + "/" + strings.TrimLeft(path.Join(pathIn, pkgMTO.SuffixFileURL), "/")
} else { } else {
return pkgMTO.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(pkgMTO.Username, pathIn, pkgMTO.SuffixFileURL), "/") return pkgMTO.BasePrefixURL + "/" + 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 { func (htm handlerTemplateMarshal) GetLink() string {
if htm.PageHandler.MetaOutput.Username == "" { if htm.PageHandler.MetaOutput.Username == "" {
return htm.PageHandler.MetaOutput.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Clean(htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/") return htm.PageHandler.MetaOutput.BasePrefixURL + "/" + strings.TrimLeft(path.Clean(htm.RequestPath), "/")
} else { } else {
return htm.PageHandler.MetaOutput.BasePrefixSourceURL + "/" + strings.TrimLeft(path.Join(htm.PageHandler.MetaOutput.Username, htm.PageHandler.MetaOutput.GetPath(htm.RequestPath)), "/") return htm.PageHandler.MetaOutput.BasePrefixURL + "/" + strings.TrimLeft(path.Join(htm.PageHandler.MetaOutput.Username, htm.RequestPath), "/")
} }
} }

View File

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