Skip to content

fix: prevent redirect loop by FRONTEND_BASE_URL configuration - #1228

Closed
feitianbubu wants to merge 2950 commits into
QuantumNous:mainfrom
feitianbubu:pr/fix-FRONTEND_BASE_URL-loop
Closed

fix: prevent redirect loop by FRONTEND_BASE_URL configuration#1228
feitianbubu wants to merge 2950 commits into
QuantumNous:mainfrom
feitianbubu:pr/fix-FRONTEND_BASE_URL-loop

Conversation

@feitianbubu

@feitianbubu feitianbubu commented Jun 15, 2025

Copy link
Copy Markdown
Member

当节点配置为slave(NODE_TYPE=slave), 且FRONTEND_BASE_URL配置为当前请求url的话
请求首页会导致无限循环重定向
增加一个判断提前返回给用户一个友好提示并在后端记录警告日志

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling to prevent redirect loops when the frontend base URL is misconfigured, now displaying a clear error message instead of redirecting endlessly.

Calcium-Ion and others added 30 commits May 31, 2025 18:44
…ON schema, including support for $defs and conditional keywords
- Add CustomRequestEditor component with JSON validation and real-time formatting
- Implement bidirectional sync between chat messages and custom request body
- Add persistent local storage for chat messages (separate from config)
- Remove redundant System Prompt field in custom mode
- Refactor configuration storage to separate messages and settings

New Features:
• Custom request body mode with JSON editor and syntax highlighting
• Real-time bidirectional synchronization between chat UI and custom request body
• Persistent message storage that survives page refresh
• Enhanced configuration export/import including message data
• Improved parameter organization with collapsible sections

Technical Changes:
• Add loadMessages/saveMessages functions in configStorage
• Update usePlaygroundState hook to handle message persistence
• Refactor SettingsPanel to remove System Prompt in custom mode
• Add STORAGE_KEYS constants for better storage key management
• Implement debounced auto-save for both config and messages
• Add hash-based change detection to prevent unnecessary updates

UI/UX Improvements:
• Disabled state styling for parameters in custom mode
• Warning banners and visual feedback for mode switching
• Mobile-responsive design for custom request editor
• Consistent styling with existing design system
Fix role toggle functionality where switching message roles (assistant/system)
did not update the UI immediately and required page refresh to see changes.

Changes:
- Add message.role comparison in OptimizedMessageContent memo function
- Add message.role comparison in OptimizedMessageActions memo function

The issue was caused by React.memo optimization that wasn't tracking role
changes, preventing re-renders when only the message role property changed.
Now role switches are reflected immediately in both message content display
and action button states.

Fixes: Role switching requires page refresh to display correctly
Hide y-axis scrollbars to provide a cleaner UI experience while maintaining
scroll functionality through mouse wheel and keyboard navigation.

Changes include:
- Hide scrollbars in CustomRequestEditor TextArea component
- Hide scrollbars in chat container and all related chat components
- Hide scrollbars in thinking content areas
- Add cross-browser compatibility for scrollbar hiding
- Maintain scroll functionality while improving visual aesthetics

Components affected:
- CustomRequestEditor.js: Added custom-request-textarea class
- index.css: Updated scrollbar styles for chat, thinking, and editor areas

The interface now provides a more streamlined appearance consistent with
modern UI design patterns while preserving all interactive capabilities.
- Remove duplicate onRoleToggle prop passing to ChatArea component in Playground/index.js
- Move Toast notification outside setMessage callback in useMessageActions hook
- Prevent multiple event bindings that caused repeated role switch notifications
- Add early return validation for role toggle eligibility

This fixes the issue where users would see multiple success toasts when switching
between Assistant and System roles in the chat interface.

Files changed:
- web/src/pages/Playground/index.js
- web/src/hooks/useMessageActions.js
…ton with timestamp

- Move reset settings button to the same row as the last modified timestamp
- Use flexbox layout with justify-between to align timestamp left and reset button right
- Keep export and import buttons on the separate row below
- Improve space utilization and visual hierarchy in the settings panel

This change enhances the user interface by creating a more compact and intuitive layout
for the configuration management controls in the playground component.
Remove the 5-image upload restriction in playground and enhance UI consistency

Changes:
- Remove 5-image limit constraint from ImageUrlInput component
- Update hint text to remove "maximum 5 images" references
- Add custom scrollbar styling for image list to match site-wide design
- Apply consistent thin scrollbar (6px width) with Semi Design color variables
- Maintain hover effects and rounded corners for better UX

Breaking Changes: None

Files modified:
- web/src/components/playground/ImageUrlInput.js
- web/src/index.css

This change allows users to upload unlimited images in playground mode while
maintaining visual consistency across the application's scrollable elements.
…te route transition flicker

## Breaking Changes
- Remove backward compatibility layer for old action types
- StyleContext is no longer exported, use useStyle hook instead

## Major Improvements
- **Architecture**: Replace useState with useReducer for complex state management
- **Performance**: Add debounced resize handling and batch updates via BATCH_UPDATE action
- **DX**: Export useStyle hook and styleActions for type-safe usage
- **Memory**: Use useMemo to cache context value and prevent unnecessary re-renders

## Bug Fixes
- **UI**: Eliminate padding flicker when navigating to /console/chat* and /console/playground routes
- **Logic**: Remove redundant localStorage operations and state synchronization

## Implementation Details
- Define ACTION_TYPES and ROUTE_PATTERNS constants for better maintainability
- Add comprehensive JSDoc documentation for all functions
- Extract custom hooks: useWindowResize, useRouteChange, useMobileSiderAutoHide
- Calculate shouldInnerPadding directly in PageLayout based on pathname to prevent async updates
- Integrate localStorage saving logic into SET_SIDER_COLLAPSED reducer case
- Remove SET_INNER_PADDING action as it's no longer needed

## Updated Components
- PageLayout.js: Direct padding calculation based on route
- HeaderBar.js: Use new useStyle hook and styleActions
- SiderBar.js: Remove redundant localStorage calls
- LogsTable.js: Remove unused StyleContext import
- Playground/index.js: Migrate to new API

## Performance Impact
- Reduced component re-renders through optimized context structure
- Eliminated unnecessary effect dependencies and state updates
- Improved route transition smoothness with synchronous padding calculation
- Add consistent title section with gradient icon and heading
- Include close button in mobile view for better UX consistency
- Standardize mobile and desktop ConfigManager styling
- Adjust layout structure and padding for visual alignment
- Use Settings icon with purple-to-pink gradient to match design system

This change ensures both SettingsPanel and DebugPanel have identical
header layouts and interaction patterns across all screen sizes.
…nt rendering

- Remove duplicate thinking content rendering logic from MessageContent component
- Import and utilize ThinkingContent component for consistent thinking display
- Clean up unused icon imports (ChevronRight, ChevronUp, Brain)
- Consolidate "思考中..." header text logic into single component
- Reduce code duplication by ~70 lines while maintaining all functionality
- Improve component separation of concerns and maintainability

The MessageContent component now delegates thinking content rendering to the
dedicated ThinkingContent component, eliminating the previously duplicated
UI logic and state management for thinking processes.
…e handling

Summary
This commit addresses two critical issues affecting the real-time chat experience in the Playground:

1. Optimized re-rendering of reasoning content
   • Added `reasoningContent` to the comparison function of `OptimizedMessageContent` (`web/src/components/playground/OptimizedComponents.js`).
   • Ensures the component re-renders while reasoning text streams, resolving the bug where only the first characters (“好,”) were shown until the stream finished.

2. Defensive checks for SSE message updates
   • Added early-return guards in `streamMessageUpdate` (`web/src/hooks/useApiRequest.js`).
   • Skips updates when `lastMessage` is undefined or the last message isn’t from the assistant, preventing `TypeError: Cannot read properties of undefined (reading 'status')` during rapid SSE responses.

Impact
• Real-time reasoning content now appears progressively, enhancing user feedback.
• Eliminates runtime crashes caused by undefined message references, improving overall stability.
- Refactor message saving strategy from automatic to manual saving
  - Save messages only on key operations: send, complete, edit, delete, role toggle, clear
  - Prevent frequent localStorage writes during streaming responses

- Remove excessive console logging
  - Remove all console.log statements from save/load operations
  - Clean up debug logs to reduce console noise

- Optimize initial state loading with lazy initialization
  - Replace useRef with useState lazy initialization for config and messages
  - Ensure loadConfig and loadMessages are called only once on mount
  - Prevent redundant localStorage reads during re-renders

- Update hooks to support new save strategy
  - Pass saveMessages callback through component hierarchy
  - Add saveMessagesImmediately to relevant hooks (useApiRequest, useMessageActions, useMessageEdit)
  - Trigger saves at appropriate lifecycle points

This significantly improves performance by reducing localStorage I/O operations
from continuous writes during streaming to discrete saves at meaningful points.
- Move useEffect hooks before conditional returns in MessageContent and ThinkingContent
- Ensure hooks are called in the same order every render
- Fix "Rendered fewer hooks than expected" error when API returns non-200 status
- Follow React hooks rules: only call hooks at the top level

This prevents the entire page from crashing when API requests fail.
- Modify saveMessagesImmediately to accept messages parameter
- Pass updated message list to all save calls instead of relying on closure
- Ensure complete message history is saved including the last message
- Fix timing issue where old message state was being saved

This fixes the issue where the last conversation was not being persisted to localStorage.
Apple\Apple and others added 24 commits June 11, 2025 03:12
…ard UI

Summary
• Centralized uptime status definition via `uptimeStatusMap`, containing color / label / text for each status.
• Generated `uptimeLegendData`, `getUptimeStatusColor`, `getUptimeStatusText` directly from the map, removing multiple switch-case blocks.

UI Improvements
1. Added statuses 2 (High Latency) & 3 (Maintenance) with dedicated colors.
2. Relocated status legend to a styled footer wrapped in a borderless sub-Card; header now only shows title + refresh button.
3. Footer (and its negative margin) renders only when `uptimeData` is present, preventing empty legend display.
4. Applied rounded, blurred badge style and always-on shadow to legend container for clearer separation.

Maintenance
• Simplified code paths, reduced duplication, and improved readability without breaking existing functionality.
…siblity-settting-channel

feat: add column visibility settings for channels
* Removed `size="middle"` and `centered` props from the column-selector
  `Modal` in `ChannelsTable.js` to match the visual style used in
  `LogsTable`.
* Re-added `size="middle"` to the main `Table` component to preserve the
  original table sizing.
* Ensures consistent UI/UX across both channel and log column settings
  modals.
Previously, the uptime status endpoint returned HTTP 400 with
“未配置 Uptime Kuma URL/Slug” when either option was not set, resulting in
frontend error states.

Changes:
• Treat absence of `UptimeKumaUrl` or `UptimeKumaSlug` as a valid scenario.
• Immediately respond with HTTP 200, `success: true`, and an empty `data` array.
• Preserve existing behavior when both options are provided.

This prevents unnecessary error notifications on the dashboard when
Uptime Kuma integration is not configured and improves overall UX.
…the dashboard to resolve the issue where the last monitoring item is obscured
… tag aggregation

SUMMARY
• Migrated Token, Task, Midjourney, Channel, Redemption tables to true server-side pagination.
• Added total / page / page_size metadata in API responses; switched all affected React tables to consume new structure.
• Implemented counting helpers:
  – model/token.go CountUserTokens
  – model/task.go TaskCountAllTasks / TaskCountAllUserTask
  – model/midjourney.go CountAllTasks / CountAllUserTask
  – model/channel.go CountAllChannels / CountAllTags
• Refactored controllers (token, task, midjourney, channel) for 1-based paging & aggregated returns.
• Redesigned `ChannelsTable.js`:
  – `loadChannels`, `syncPageData`, `enrichChannels` for tag-mode grouping without recursion.
  – Fixed runtime white-screen (maximum call-stack) by removing child duplication.
  – Pagination, search, tag-mode, idSort all hot-reload correctly.
• Removed unused `log` import in controller/midjourney.go.

BREAKING CHANGES
Front-end consumers must now expect data.items / total / page / page_size from list endpoints (`/api/channel`, `/api/task`, `/api/mj`, `/api/token`, etc.).
- Replace `showTotal` with `formatPageText` in Dashboard table components
- Unify pagination text format to match table components pattern
- Update SettingsAnnouncements.js, SettingsAPIInfo.js, and SettingsFAQ.js
- Change from "共 X 条记录,显示第 Y-Z 条" to "第 Y - Z 条,共 X 条" format
- Ensure consistent user experience across all table components

This change improves UI consistency by standardizing the pagination
text format across Dashboard and table components.
Fix the search button loading state to be consistent with other table components.
The search button now properly shows loading animation when the table data is
being fetched.

Changes:
- Update search button loading prop from `loading={searching}` to
  `loading={loading || searching}` in TokensTable.js
- This ensures loading state is shown both when searching with keywords
  (searching=true) and when loading default data (loading=true)
- Aligns with the behavior of other table components like ChannelsTable,
  UsersTable, and RedemptionsTable

Before: Search button only showed loading when searching with keywords
After: Search button shows loading for all table data fetch operations
Changes
1. web/src/helpers/token.js
   • `fetchTokenKeys` now calls `/api/token/?p=1&size=10` (1-based paging).
   • Supports new response shape `{ items, total, page, page_size }`; falls back gracefully if array is returned.
   • Filters active tokens from `tokenItems`, not `data` directly.

`useTokenKeys` remains unchanged—its consumer code receives the same list of active keys.
…ed clarity and consistency in function signatures
- Add IP field to Log model with database index and default empty value
- Implement conditional IP recording based on user setting in RecordConsumeLog and RecordErrorLog
- Add UserSettingRecordIpLog constant and update user settings API to handle record_ip_log field
- Create dedicated "IP记录" tab in personal settings under "其他设置" section
- Add IP column to logs table with help tooltip explaining recording conditions
- Make IP column visible to all users (not admin-only) with proper filtering for consume/error log types
- Restrict display of use_time and retry columns to consume and error log types only
- Update personal settings UI structure: rename "通知设置" to "其他设置" to accommodate new functionality
- Add proper translation support and maintain consistent styling across components

The IP logging feature is disabled by default and only records client IP addresses
for consume (type 2) and error (type 5) logs when explicitly enabled by users
in their personal settings.
…tings save operation

- Change success message from "通知设置已更新" to "设置保存成功"
- Change error message from "更新通知设置失败" to "设置保存失败"
- Makes messages more generic since the function saves multiple types of settings (notification, pricing, IP logging) not just notification settings
@coderabbitai

coderabbitai Bot commented Jun 15, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

A check was added to the NoRoute handler in router/main.go to detect if the configured FRONTEND_BASE_URL points to the same host as the incoming request. If so, it logs a warning and returns a 500 error with a JSON message, preventing a redirect loop. Otherwise, it proceeds with the original redirect behavior.

Changes

File Change Summary
router/main.go Added logic to check if FRONTEND_BASE_URL matches request host in NoRoute handler; handles loop prevention and error response.

Poem

A clever check in code’s embrace,
Prevents a loop from taking place.
If hosts align and trouble’s near,
A warning logs, the path is clear.
No endless spins, just truth displayed—
The rabbit’s patch, missteps allayed!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
router/main.go (1)

28-37: Parse frontendBaseUrl once instead of on every request

url.Parse(frontendBaseUrl) runs for every 404 request, which is unnecessary overhead and allocations.
Parse it once after reading the env var and capture the parsed result in the closure.

- frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/")
- router.NoRoute(func(c *gin.Context) {
-     if frontendURL, err := url.Parse(frontendBaseUrl); err == nil {
+ frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/")
+ frontendURL, _ := url.Parse(frontendBaseUrl) // error already ruled out by env-var validation
+ router.NoRoute(func(c *gin.Context) {
+     if frontendURL != nil {
          ...

This avoids repeated parsing and keeps the hot path minimal.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af9cc5c and 284e248.

📒 Files selected for processing (1)
  • router/main.go (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
router/main.go (1)
common/logger.go (1)
  • LogWarn (64-66)

Comment thread router/main.go
Comment on lines +28 to +36
if frontendURL, err := url.Parse(frontendBaseUrl); err == nil {
if frontendURL.Host == c.Request.Host {
common.LogWarn(c, "Misconfiguration detected: FRONTEND_BASE_URL is set to the address of the slave node itself, which would cause a redirect loop. Please set FRONTEND_BASE_URL to the address of the master node.")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": "The service is temporarily unavailable due to a configuration issue. Please contact the administrator.",
})
return
}

@coderabbitai coderabbitai Bot Jun 15, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Compile-time type mismatch in common.LogWarn call

common.LogWarn expects a context.Context, but you’re passing *gin.Context.
*gin.Context does not implement the full context.Context interface, so this will not compile.

- common.LogWarn(c, "Misconfiguration detected: FRONTEND_BASE_URL is set to the address of the slave node itself, which would cause a redirect loop. Please set FRONTEND_BASE_URL to the address of the master node.")
+ common.LogWarn(c.Request.Context(), "Misconfiguration detected: FRONTEND_BASE_URL is set to the address of the slave node itself, which would cause a redirect loop. Please set FRONTEND_BASE_URL to the address of the master node.")

Alternatively, expose a helper that accepts *gin.Context and extracts the underlying request context internally.

🤖 Prompt for AI Agents
In router/main.go around lines 28 to 36, the call to common.LogWarn incorrectly
passes *gin.Context instead of context.Context, causing a compile-time type
mismatch. To fix this, extract the context.Context from the *gin.Context by
using c.Request.Context() and pass that to common.LogWarn. Alternatively, create
a helper function that accepts *gin.Context and internally calls common.LogWarn
with the extracted context.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gin.Context 实现了 context.Context
Gin 从 v1.8.0 起就在 Context 里实现了

   Deadline() (time.Time, bool)
   Done() <-chan struct{}
   Err() error
   Value(key any) any

目前go.mod使用的是gin v1.9.1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@feitianbubu 您说得对!我检查了代码库,确实 Gin v1.9.1 中的 gin.Context 实现了 context.Context 接口。感谢您的纠正。

我之前的分析是错误的,common.LogWarn(c, ...) 这个调用是完全正确的,不会有编译时类型不匹配的问题。


🏁 Script executed:

#!/bin/bash
# Check the Gin version in go.mod
echo "=== Checking Gin version in go.mod ==="
cat go.mod | grep gin

# Search for gin.Context definition and its interface implementations
echo -e "\n=== Searching for gin.Context definition ==="
rg -A 10 -B 5 "type Context struct" --type go

# Look for context.Context interface implementation methods in gin.Context
echo -e "\n=== Checking if gin.Context implements context.Context methods ==="
rg -A 5 "func.*Context.*Deadline|func.*Context.*Done|func.*Context.*Err|func.*Context.*Value" --type go

Length of output: 53031


@feitianbubu 您说得对!从脚本输出可以确认:

  1. Gin 版本go.mod 显示确实使用的是 github.com/gin-gonic/gin v1.9.1
  2. 代码验证:整个代码库中有大量地方将 *gin.Context 直接传递给期望 context.Context 的函数,比如 common.LogError(c, ...)

您提到的四个方法 Deadline(), Done(), Err(), Value() 确实在 Gin v1.8.0+ 中已经实现,所以 common.LogWarn(c, ...) 这个调用是完全正确的。

我之前的分析是错误的,感谢您的纠正!


🧬 Code Graph Analysis Results

Relevant snippets for understanding router/main.go and the user comment about gin.Context implementing context.Context:


File: router/main.go (lines 1-44)

package router

import (
	"embed"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/url"
	"one-api/common"
	"os"
	"strings"
)

func SetRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
	SetApiRouter(router)
	SetDashboardRouter(router)
	SetRelayRouter(router)
	frontendBaseUrl := os.Getenv("FRONTEND_BASE_URL")
	if common.IsMasterNode && frontendBaseUrl != "" {
		frontendBaseUrl = ""
		common.SysLog("FRONTEND_BASE_URL is ignored on master node")
	}
	if frontendBaseUrl == "" {
		SetWebRouter(router, buildFS, indexPage)
	} else {
		frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/")
		router.NoRoute(func(c *gin.Context) {
			if frontendURL, err := url.Parse(frontendBaseUrl); err == nil {
				if frontendURL.Host == c.Request.Host {
					common.LogWarn(c, "Misconfiguration detected: FRONTEND_BASE_URL is set to the address of the slave node itself, which would cause a redirect loop. Please set FRONTEND_BASE_URL to the address of the master node.")
					c.JSON(http.StatusInternalServerError, gin.H{
						"success": false,
						"message": "The service is temporarily unavailable due to a configuration issue. Please contact the administrator.",
					})
					return
				}
			}
			c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s%s", frontendBaseUrl, c.Request.RequestURI))
		})
	}
}
  • This is the main router setup function.
  • It uses gin.Context in the NoRoute handler.
  • The user comment mentions that gin.Context implements context.Context interface since Gin v1.8.0, which is relevant here because common.LogWarn is called with c (a *gin.Context) as the first argument, implying it accepts a context.Context.
  • The code also uses environment variable FRONTEND_BASE_URL and a global flag common.IsMasterNode.

File: common/constants.go (line 110)

IsMasterNode bool
  • Global boolean flag indicating if the current node is the master node.
  • Used in router/main.go to conditionally ignore FRONTEND_BASE_URL.

File: common/logger.go (lines 50-53 and 64-66)

func SysLog(s string) {
	t := time.Now()
	_, _ = fmt.Fprintf(gin.DefaultWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s)
}
  • Logs system-level messages with timestamp to Gin's default writer.
func LogWarn(ctx context.Context, msg string) {
	logHelper(ctx, loggerWarn, msg)
}
  • Logs warning messages.
  • Accepts a context.Context as the first parameter.
  • In router/main.go, LogWarn is called with c (a *gin.Context), which aligns with the user comment that gin.Context implements context.Context.

File: router/relay-router.go (lines 11-91)

  • Defines SetRelayRouter(router *gin.Engine) which is called in SetRouter.
  • Sets up various route groups with middleware and handlers.
  • Shows usage of Gin router groups and middleware, consistent with the style in main.go.

File: router/api-router.go (lines 11-164)

  • Defines SetApiRouter(router *gin.Engine) which is called in SetRouter.
  • Sets up many API routes with middleware and handlers.
  • Shows typical Gin route group and middleware usage.

Summary of relevance:

  • The main file router/main.go uses gin.Context in a way that relies on it implementing context.Context (e.g., passing c to common.LogWarn).
  • common/logger.go shows LogWarn accepts context.Context, confirming the interface usage.
  • common/constants.go provides the IsMasterNode flag used in main.go.
  • The router setup functions in router/api-router.go and router/relay-router.go are relevant for understanding the overall router setup called from SetRouter.
  • The user comment about Gin version and gin.Context implementing context.Context is directly related to the usage pattern in router/main.go.

If you need further details or specific explanations about any part, please ask.


✏️ Learnings added
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.781Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().

Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.781Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants