123123 if os .path .exists (template_dir ):
124124 print (f"Template dir contents: { os .listdir (template_dir )} " )
125125
126+ # Get base_url from settings (used for reverse proxy subpath configurations)
127+ def get_base_url ():
128+ """
129+ Get the configured base URL from general settings.
130+ This allows Huntarr to run under a subpath like /huntarr when behind a reverse proxy.
131+
132+ Returns:
133+ str: The configured base URL (e.g., '/huntarr') or empty string if not configured
134+ """
135+ try :
136+ base_url = settings_manager .get_setting ('general' , 'base_url' , '' )
137+ # Ensure base_url always starts with a / if not empty
138+ if base_url and not base_url .startswith ('/' ):
139+ base_url = f'/{ base_url } '
140+ # Remove trailing slash if present
141+ if base_url and base_url != '/' and base_url .endswith ('/' ):
142+ base_url = base_url .rstrip ('/' )
143+ return base_url
144+ except Exception as e :
145+ print (f"Error getting base_url from settings: { e } " )
146+ return ''
147+
148+ # Define base_url at module level
149+ base_url = ''
150+
126151# Create Flask app with additional debug logging
127152app = Flask (__name__ , template_folder = template_dir , static_folder = static_dir )
128153print (f"Flask app created with template_folder: { app .template_folder } " )
129154print (f"Flask app created with static_folder: { app .static_folder } " )
130155
156+ # Get and apply the base URL setting after app is created
157+ try :
158+ base_url = get_base_url ()
159+ if base_url :
160+ print (f"Configuring base URL: { base_url } " )
161+ app .config ['APPLICATION_ROOT' ] = base_url
162+ # Flask 1.x compatibility - needed for proper URL generation
163+ if not hasattr (app , 'wsgi_app' ) or not hasattr (app .wsgi_app , '__call__' ):
164+ print ("Warning: Unable to configure WSGI middleware for base URL" )
165+ else :
166+ # This ensures static files and other routes respect the base URL
167+ from werkzeug .middleware .dispatcher import DispatcherMiddleware
168+ from werkzeug .exceptions import NotFound
169+ app .wsgi_app = DispatcherMiddleware (
170+ NotFound (), # Default 404 app when accessed without base URL
171+ {base_url : app .wsgi_app } # Main app mounted at base URL
172+ )
173+ print (f"WSGI middleware configured for base URL: { base_url } " )
174+ else :
175+ print ("Running at root URL path (no base URL)" )
176+ except Exception as e :
177+ print (f"Error applying base URL setting: { e } " )
178+ base_url = '' # Fallback to empty string on error
179+
131180# Add debug logging for template rendering
132181def debug_template_rendering ():
133182 """Additional logging for Flask template rendering"""
@@ -198,6 +247,12 @@ def get_source_wrapper(environment, template):
198247# Register the authentication check to run before requests
199248app .before_request (authenticate_request )
200249
250+ # Add base_url to template context so it can be used in templates
251+ @app .context_processor
252+ def inject_base_url ():
253+ """Add base_url to template context for use in templates"""
254+ return {'base_url' : base_url }
255+
201256# Removed MAIN_PID and signal-related code
202257
203258# Lock for accessing the log files
@@ -219,14 +274,19 @@ def get_source_wrapper(environment, template):
219274
220275ALL_APP_LOG_FILES = list (KNOWN_LOG_FILES .values ()) # List of all individual log file paths
221276
277+ # Handle both root path and base URL root path
222278@app .route ('/' )
223279def home ():
280+ """Render the main index page"""
224281 return render_template ('index.html' )
225282
226283@app .route ('/user' )
227284def user ():
228- # User account screen
285+ """Render the user account screen"""
229286 return render_template ('user.html' )
287+
288+ # This section previously contained code for redirecting paths to include the base URL
289+ # It has been removed as Flask's APPLICATION_ROOT setting provides this functionality
230290
231291# Removed /settings and /logs routes if handled by index.html and JS routing
232292# Keep /logs if it's the actual SSE endpoint
0 commit comments