Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
FROM golang:1.20-alpine as builder
FROM golang:1.20 as builder
WORKDIR /go/pkg/ocap
COPY . .
ARG build_commit
RUN apk add --no-cache alpine-sdk && go build -ldflags "-X github.com/OCAP2/web/server.BuildDate=`date -u +'%Y-%m-%dT%H:%M:%SZ'` -X github.com/OCAP2/web/server.BuildCommit=$build_commit" -a -o app ./cmd
RUN go build -ldflags "-X github.com/OCAP2/web/server.BuildDate=`date -u +'%Y-%m-%dT%H:%M:%SZ'` -X github.com/OCAP2/web/server.BuildCommit=$build_commit" -a -o app ./cmd

FROM alpine:3.14
FROM debian:bookworm-slim
WORKDIR /usr/local/ocap
RUN mkdir -p /etc/ocap /usr/local/ocap/data /var/lib/ocap/db /var/lib/ocap/maps /var/lib/ocap/data && \
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* && \
mkdir -p /etc/ocap /usr/local/ocap/data /var/lib/ocap/db /var/lib/ocap/maps /var/lib/ocap/data && \
echo '{}' > /etc/ocap/setting.json

ENV OCAP_MARKERS /usr/local/ocap/markers
Expand Down
6 changes: 6 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"log"
"os"
"time"

"github.com/OCAP2/web/server"
"github.com/labstack/echo/v4"
Expand Down Expand Up @@ -40,6 +41,11 @@ func app() error {

e := echo.New()

// Configure server timeouts for large file transfers
// Increased idle timeout to support full-length replay viewing
e.Server.ReadTimeout = 0 // No read timeout for large files
e.Server.WriteTimeout = 0 // No write timeout for large files
e.Server.IdleTimeout = 60 * time.Minute
loggerConfig := middleware.DefaultLoggerConfig
if setting.Logger {
flog, err := os.OpenFile("ocap.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
Expand Down
62 changes: 59 additions & 3 deletions server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,26 @@ func (h *Handler) GetCapture(c echo.Context) error {

upath := filepath.Join(h.setting.Data, filepath.Base(name+".gz"))

c.Response().Header().Set("Content-Encoding", "gzip")
c.Response().Header().Set("Content-Type", "application/json")
// Check if file exists
fileInfo, statErr := os.Stat(upath)
if statErr != nil {
return statErr
}

return c.File(upath)
// Set appropriate headers for large file transfer with better browser compatibility
c.Response().Header().Set("Content-Type", "application/json")
c.Response().Header().Set("Content-Encoding", "gzip")
c.Response().Header().Set("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))
c.Response().Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
c.Response().Header().Set("Pragma", "no-cache")
c.Response().Header().Set("Expires", "0")
c.Response().Header().Set("Connection", "keep-alive")

// Remove Transfer-Encoding header to let Go handle it automatically
// This can help with browser compatibility issues

// Use streaming instead of loading entire file into memory
return h.streamFile(c, upath)
}

func (h *Handler) GetCaptureFile(c echo.Context) error {
Expand Down Expand Up @@ -321,6 +337,46 @@ func (h *Handler) GetAmmo(c echo.Context) error {
return c.File(upath)
}

func (h *Handler) streamFile(c echo.Context, filepath string) error {
// Open the file
file, err := os.Open(filepath)
if err != nil {
return err
}
defer file.Close()

// Get file info for Content-Length header
fileInfo, err := file.Stat()
if err != nil {
return err
}

// Set Content-Length header
c.Response().Header().Set("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))

// Stream the file with better buffer control for browser compatibility
buffer := make([]byte, 32*1024) // 32KB buffer
for {
n, err := file.Read(buffer)
if err != nil && err != io.EOF {
return err
}
if n == 0 {
break
}

// Write to response
if _, writeErr := c.Response().Write(buffer[:n]); writeErr != nil {
return writeErr
}

// Flush the response to ensure data is sent immediately
c.Response().Flush()
}

return nil
}

func paramPath(c echo.Context, param string) (string, error) {
urlPath, err := url.PathUnescape(c.Param(param))
if err != nil {
Expand Down