flipped-aurora/gin-vue-admin · error
仅允许 http/https, 实际为 %q
Error message
仅允许 http/https, 实际为 %q
What it means
After parsing, runHTTP enforces a scheme allowlist: only http and https are accepted. Any other scheme (ftp, file, gopher, javascript, empty) is rejected to prevent SSRF/local-file access. The actual scheme is quoted in the error.
Source
Thrown at server/service/system/sys_timed_task_runner.go:132
select {
case err := <-done:
if err != nil && errors.Is(err, context.DeadlineExceeded) {
return "", errTaskTimeout
}
return "", err
case <-ctx.Done():
return "", errTaskTimeout
}
}
// runHTTP 执行 HTTP 回调(SSRF 防护见 sys_timed_task_http.go)
func (s *TimedTaskService) runHTTP(t system.SysTimedTask) (string, error) {
u, err := url.Parse(t.HttpUrl)
if err != nil {
return "", fmt.Errorf("URL 非法: %w", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return "", fmt.Errorf("仅允许 http/https, 实际为 %q", u.Scheme)
}
method := strings.ToUpper(strings.TrimSpace(t.HttpMethod))
if method == "" {
method = http.MethodGet
}
var body io.Reader
if t.HttpBody != "" {
body = strings.NewReader(t.HttpBody)
}
req, err := http.NewRequest(method, t.HttpUrl, body)
if err != nil {
return "", fmt.Errorf("构造请求失败: %w", err)
}
if len(t.HttpHeader) > 0 {
var hdr map[string]string
if err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {
return "", fmt.Errorf("http_header 必须是 JSON 对象: %w", err)
}View on GitHub (pinned to 3136500ef3)
Solutions
- Change the task URL to start with http:// or https://
- Normalize schemeless URLs by prefixing https:// when saving tasks
- Keep the allowlist; do not loosen it for internal schemes
Example fix
// before HttpUrl: "ftp://backup.example.com/ping" // after HttpUrl: "https://backup.example.com/ping"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(httpUrl)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
return errors.New("callback URL must use http or https")
} Type guard
func isHTTPOrHTTPS(s string) bool {
u, err := url.Parse(s)
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
} Try / catch
if err := RunTask(t); err != nil {
if strings.Contains(err.Error(), "仅允许 http/https") {
log.Warnf("task %d rejected scheme in %q", t.ID, t.HttpUrl)
}
} Prevention
- Always include the scheme when entering callback URLs (default to https://)
- Enforce the scheme allowlist in the task-creation API, not only at run time
- Never attempt file:// or internal schemes through this executor
When it happens
Trigger: t.HttpUrl uses a non-http(s) scheme — e.g. 'file:///etc/passwd', 'ftp://...', or a schemeless 'example.com/hook' (empty scheme).
Common situations: Trying to use the HTTP callback for internal file reads; forgetting the 'http://' prefix when entering the URL; probing SSRF protections during security review.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/e307e54fc42800e6.
Report an issue: GitHub.