No description
  • Go 65.8%
  • TypeScript 28.5%
  • Makefile 2.4%
  • Shell 1.1%
  • CSS 0.9%
  • Other 1.3%
Find a file
liyp 15c917534d
All checks were successful
Release / build (push) Successful in 19m26s
Release / create-release (push) Successful in 59s
Add Arch Linux packaging and simplify binary release
2026-06-19 17:16:36 +08:00
.gitea/workflows Add Arch Linux packaging and simplify binary release 2026-06-19 17:16:36 +08:00
db fix: 修复 Windows 默认数据库路径启动失败,添加拖拽上传功能 2026-06-12 19:17:59 +08:00
frontend feat: 实现优雅关闭,添加 Makefile 2026-06-15 21:29:20 +08:00
handler feat: 优雅关闭、Makefile、Gitea CI/CD、Arch 打包、精简代码 2026-06-19 16:27:35 +08:00
id feat: 初始化 pastego 项目 2026-06-05 21:03:28 +08:00
mime feat: 添加 React 前端,移除服务端高亮,改进 CSRF 配置 2026-06-06 22:08:36 +08:00
model feat: 初始化 pastego 项目 2026-06-05 21:03:28 +08:00
packaging/arch feat: 优雅关闭、Makefile、Gitea CI/CD、Arch 打包、精简代码 2026-06-19 16:27:35 +08:00
static feat: 实现优雅关闭,添加 Makefile 2026-06-15 21:29:20 +08:00
.gitignore feat: 添加 React 前端,移除服务端高亮,改进 CSRF 配置 2026-06-06 22:08:36 +08:00
config.go feat: 全面安全加固,适配公共网络部署 2026-06-06 20:16:43 +08:00
go.mod feat: 优雅关闭、Makefile、Gitea CI/CD、Arch 打包、精简代码 2026-06-19 16:27:35 +08:00
go.sum feat: 优雅关闭、Makefile、Gitea CI/CD、Arch 打包、精简代码 2026-06-19 16:27:35 +08:00
main.go feat: 优雅关闭、Makefile、Gitea CI/CD、Arch 打包、精简代码 2026-06-19 16:27:35 +08:00
Makefile feat: 实现优雅关闭,添加 Makefile 2026-06-15 21:29:20 +08:00
README.md feat: 前端嵌入二进制,改进静态文件服务和 MIME 类型检测 2026-06-06 22:44:44 +08:00
requirements.md feat: 添加 React 前端,移除服务端高亮,改进 CSRF 配置 2026-06-06 22:08:36 +08:00

PasteGo - 轻量级在线剪切板

一个用 Go 编写的轻量级在线剪切板服务,支持文本、代码、图片等任意文件的上传与分享,提供 React Web 界面和终端 CLI 两种交互方式。

特性

  • 多类型支持 - 文本、代码、图片、任意文件
  • 自动语法高亮 - highlight.js 驱动,根据内容自动检测语言
  • 私有模式 - 通过不可猜测的长链接访问敏感内容
  • 定时过期 - 支持 1小时/1天/7天/30天/永久
  • CLI 工具 - 独立二进制,管道友好
  • 零依赖部署 - 单二进制 + SQLite 文件
  • 安全防护 - 速率限制、CSRF 防护、XSS 防护、安全响应头
  • React 前端 - 基于 hastebin 风格的现代化 UI支持二维码

快速开始

安装

# 从源码编译
git clone https://git.liyp.cc/xmengnet/pastego.git
cd pastego
go build -ldflags="-s -w" -o pastego .

# 构建前端
cd frontend && npm install && npm run build

# 或直接下载预编译二进制
# https://git.liyp.cc/xmengnet/pastego/releases

启动服务

# 默认端口 4832
./pastego

# 自定义端口
./pastego -addr :8080

# 自定义数据库路径
./pastego -dsn /data/pastego.db

# 环境变量配置
export CLIP_ADDR=:8080
export CLIP_DSN=/data/pastego.db
./pastego

服务启动后访问 http://localhost:4832 即可使用 Web 界面。

使用指南

Web 界面

  1. 访问 http://localhost:4832 进入编辑器
  2. 在编辑器中输入内容(支持 Tab 缩进)
  3. 底部任务栏可设置:
    • 语法类型(留空自动检测)
    • 过期时间(无过期 ~ 1个月
    • 私有模式(不生成短链接)
  4. 点击 paste! 获取分享链接
  5. 查看页(/?id=xxx)自动高亮代码,显示二维码

CLI 工具

配置服务器地址

# 方法 1环境变量
export CLIP_SERVER=https://clip.example.com

# 方法 2配置文件
./clip config --server https://clip.example.com

上传内容

# 管道上传(自动检测语言)
echo "SELECT * FROM users" | ./clip

# 指定语法类型
cat query.sql | ./clip -s sql

# 文件上传
./clip -f screenshot.png
./clip -f query.sql -s sql

# 设置过期时间(秒)
echo "临时消息" | ./clip -t 3600

# 私有模式
cat secret.txt | ./clip --private

# 仅输出 URL方便脚本
echo "data" | ./clip -u

查看内容

# 查看原始内容
./clip abc123

# 仅显示元数据JSON
./clip abc123 --meta

# 在浏览器中打开
./clip abc123 --open

更新与删除

# 更新内容(需要 UUID
echo "new content" | ./clip --update <uuid>

# 删除剪切板
./clip --delete <uuid>

API 文档

创建剪切板

POST /
Content-Type: multipart/form-data

Form 字段:
  c        (必填)  内容
  syntax   (可选)  语法类型sql/json/yaml/py/go/sh 等
  sunset   (可选)  过期秒数3600/86400/604800
  p        (可选)  私有模式p=1
  filename (可选)  文件名(自动推断 mimetype

示例:

# 管道上传
echo "Hello World" | curl -F "c=@-" http://localhost:4832/

# 指定语法 + 过期时间
echo '{"key":"value"}' | curl -F "c=@-" -F "syntax=json" -F "sunset=86400" http://localhost:4832/

# 上传图片
curl -F "c=@screenshot.png" http://localhost:4832/

# 私有剪切板
cat secret.txt | curl -F "c=@-" -F "p=1" http://localhost:4832/

响应200

{
  "url": "http://localhost:4832/abc123",
  "short": "abc123",
  "long": "AJJ1vikJUiGkSLlni-aYVR8UrHd5",
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "mimetype": "text/plain",
  "size": 128,
  "status": "created"
}

查看剪切板

GET /:id

Accept 头决定返回格式:
  text/plain       → 原始内容
  application/json → JSON 元数据
  */*              → 根据存储的 mimetype 返回

示例:

# 获取原始内容
curl http://localhost:4832/abc123

# 获取 JSON 元数据
curl -H "Accept: application/json" http://localhost:4832/abc123

更新剪切板

PUT /:id                           ← id 必须是 UUID
Content-Type: multipart/form-data

Form 字段:
  c        (必填) 新内容
  syntax   (可选) 新语法类型
  sunset   (可选) 新过期时间
  filename (可选) 新文件名

响应:

{
  "url": "http://localhost:4832/abc123",
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "updated"
}

删除剪切板

DELETE /:id                        ← id 必须是 UUID

响应:

{
  "url": "http://localhost:4832/abc123",
  "status": "deleted"
}

统计信息

GET /s

响应:

{
  "pastes": 1234
}

数据模型

SQLite 表结构

CREATE TABLE pastes (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    uuid       TEXT    NOT NULL UNIQUE,
    short      TEXT    DEFAULT '',
    long_id    TEXT    NOT NULL UNIQUE,
    content    BLOB    NOT NULL,
    mimetype   TEXT    DEFAULT 'text/plain',
    syntax     TEXT    DEFAULT '',
    filename   TEXT    DEFAULT '',
    size       INTEGER DEFAULT 0,
    private    INTEGER DEFAULT 0,
    sunset     INTEGER,
    created_at INTEGER NOT NULL,
    updated_at INTEGER NOT NULL,
    deleted    INTEGER DEFAULT 0
);

ID 体系

ID 类型 格式 用途 说明
short 6-8 位 base62 公开分享链接 私有模式时为空
long_id 24 位 base62 私有访问链接 不可猜测
uuid UUID v4 更新/删除认证 仅修改操作使用

配置

环境变量

变量 说明 默认值
CLIP_ADDR 监听地址 :4832
CLIP_DSN SQLite 数据库路径 pastego.db
CLIP_MAX_SIZE 单文件最大字节数 10485760 (10MB)
CLIP_SERVER CLI 工具服务器地址 http://localhost:4832
CLIP_ORIGINS CSRF 可信域名(逗号分隔),不设置则禁用 CSRF 防护

命令行参数

./pastego [选项]

选项:
  -addr string      监听地址(默认 ":4832"
  -dsn string       SQLite 数据库路径(默认 "pastego.db"
  -max-size int     单文件最大字节数(默认 10485760
  -origins string   CSRF 可信域名,逗号分隔
  -log-format string 日志格式text 或 json

项目结构

pastego/
├── main.go              # HTTP 服务器入口
├── config.go            # 配置管理
├── go.mod / go.sum      # Go 依赖
├── db/
│   ├── db.go            # SQLite 初始化(连接池配置)
│   └── paste.go         # CRUD 操作
├── handler/
│   ├── paste.go         # HTTP 处理器
│   ├── stat.go          # 统计接口
│   ├── log.go           # 访问日志中间件
│   ├── security.go      # 安全响应头中间件
│   ├── ratelimit.go     # 速率限制中间件
│   ├── csrf.go          # CSRF 防护中间件
│   └── about.go         # 关于页面
├── model/
│   └── paste.go         # 数据模型
├── id/
│   └── id.go            # ID 生成器
├── mime/
│   └── mime.go          # Mimetype 映射
├── frontend/            # React 前端Vite + TypeScript + Tailwind
│   ├── src/
│   │   ├── App.tsx      # 创建页
│   │   ├── View.tsx     # 查看页(语法高亮 + 二维码)
│   │   ├── api/         # API 客户端
│   │   ├── components/  # UI 组件
│   │   └── lib/         # 工具库
│   ├── package.json
│   └── vite.config.ts
├── static/              # 构建产物(前端 + about.md
│   ├── index.html       # SPA 入口
│   ├── assets/          # JS/CSS 资源
│   └── about.md         # 关于页面内容
└── cmd/
    └── clip/
        └── main.go      # CLI 工具

开发

依赖

用途
github.com/mattn/go-sqlite3 SQLite 驱动
github.com/google/uuid UUID v4 生成
github.com/yuin/goldmark Markdown 渲染about 页面)

构建

# 构建后端
go build -o pastego .

# 构建前端
cd frontend && npm install && npm run build

# 交叉编译后端
GOOS=linux GOARCH=amd64 go build -o pastego-linux .
GOOS=darwin GOARCH=arm64 go build -o pastego-mac .
GOOS=windows GOARCH=amd64 go build -o pastego.exe .

运行

./pastego
# 访问 http://localhost:4832

过期清理机制

  • 启动时开启后台 goroutine每 60 秒执行一次
  • sunset <= now()deleted = 0 → 标记为 deleted = 1
  • 物理删除:sunset 距今超过 7 天的已过期记录直接 DELETE

安全说明

安全防护措施

1. 速率限制

  • 基于 IP 的令牌桶算法限流
  • 默认每秒 10 个请求,突发最多 20 个

2. CSRF 防护

  • 验证 OriginReferer
  • 只对修改操作POST/PUT/DELETE生效
  • 不设置 CLIP_ORIGINS 时禁用,设置后只允许指定域名

3. XSS 防护

  • 危险 MIME 类型HTML/SVG/JS以纯文本显示源码

4. 安全响应头

  • Content-Security-Policy: 限制资源加载来源
  • X-Content-Type-Options: nosniff: 防止 MIME 嗅探
  • X-Frame-Options: DENY: 防止点击劫持

生产环境部署建议

# 1. 配置可信域名(启用 CSRF 防护)
export CLIP_ORIGINS="pastego.yourdomain.com"

# 2. 使用反向代理Nginx/Caddy并启用 HTTPS
# 3. 配置防火墙,只开放必要端口
# 4. 定期备份 SQLite 数据库文件

License

MIT License