No description
- Go 65.8%
- TypeScript 28.5%
- Makefile 2.4%
- Shell 1.1%
- CSS 0.9%
- Other 1.3%
| .gitea/workflows | ||
| db | ||
| frontend | ||
| handler | ||
| id | ||
| mime | ||
| model | ||
| packaging/arch | ||
| static | ||
| .gitignore | ||
| config.go | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| Makefile | ||
| README.md | ||
| requirements.md | ||
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 界面
- 访问
http://localhost:4832进入编辑器 - 在编辑器中输入内容(支持 Tab 缩进)
- 底部任务栏可设置:
- 语法类型(留空自动检测)
- 过期时间(无过期 ~ 1个月)
- 私有模式(不生成短链接)
- 点击
paste!获取分享链接 - 查看页(
/?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 防护
- 验证
Origin和Referer头 - 只对修改操作(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