77from http .server import HTTPServer , SimpleHTTPRequestHandler
88import json
99import os
10- from urllib .parse import urlparse
10+ from urllib .parse import urlparse , parse_qs
1111import urllib .request
1212import urllib .error
1313
@@ -45,15 +45,15 @@ def ensure_config_exists():
4545class KaraKeepHandler (SimpleHTTPRequestHandler ):
4646 def do_GET (self ):
4747 """Handle GET requests"""
48+ # Check for API proxy requests first
49+ if self .path .startswith ('/api/karakeep/' ):
50+ self .proxy_to_karakeep ('GET' )
51+ return
52+
4853 # Redirect config.json requests to config/config.json
4954 if self .path == '/config.json' :
5055 self .path = '/config/config.json'
5156
52- # Proxy API requests to KaraKeep
53- elif self .path .startswith ('/api/karakeep/' ):
54- self .proxy_to_karakeep ('GET' )
55- return
56-
5757 # Serve files normally
5858 return super ().do_GET ()
5959
@@ -62,24 +62,31 @@ def proxy_to_karakeep(self, method):
6262 try :
6363 # Load config to get KaraKeep URL and API key
6464 config_path = 'config/config.json'
65+ if not os .path .exists (config_path ):
66+ raise Exception ("Config file not found" )
67+
6568 with open (config_path , 'r' ) as f :
6669 config = json .load (f )
6770
6871 karakeep_url = config .get ('karakeepUrl' , 'http://localhost:3000' )
6972 api_key = config .get ('apiKey' , '' )
7073
74+ if not api_key or api_key == 'YOUR_KARAKEEP_API_KEY_HERE' :
75+ raise Exception ("API key not configured" )
76+
7177 # Remove /api/karakeep prefix and construct the actual API path
7278 api_path = self .path .replace ('/api/karakeep' , '/api' , 1 )
7379 full_url = f"{ karakeep_url } { api_path } "
7480
81+ print (f"Proxying { method } request to: { full_url } " )
82+
7583 # Create request with auth header
76- req = urllib .request .Request (full_url )
84+ req = urllib .request .Request (full_url , method = method )
7785 req .add_header ('Authorization' , f'Bearer { api_key } ' )
7886 req .add_header ('Content-Type' , 'application/json' )
87+ req .add_header ('Accept' , 'application/json' )
7988
8089 # Create SSL context that handles self-signed certificates
81- # Note: This accepts any certificate, including self-signed ones
82- # In production with proper certificates, you may want to remove these lines
8390 ssl_context = None
8491 if SSL_AVAILABLE and full_url .startswith ('https://' ):
8592 ssl_context = ssl .create_default_context ()
@@ -91,23 +98,30 @@ def proxy_to_karakeep(self, method):
9198 response = urllib .request .urlopen (req , context = ssl_context )
9299 else :
93100 response = urllib .request .urlopen (req )
101+
94102 data = response .read ()
95103
96104 # Send response back to client
97105 self .send_response (response .getcode ())
98106 self .send_header ('Content-Type' , 'application/json' )
107+ self .send_header ('Cache-Control' , 'no-cache' )
99108 self .end_headers ()
100109 self .wfile .write (data )
101110
102111 except urllib .error .HTTPError as e :
112+ print (f"HTTP Error: { e .code } - { e .reason } " )
103113 # Forward HTTP errors
104114 self .send_response (e .code )
105115 self .send_header ('Content-Type' , 'application/json' )
106116 self .end_headers ()
107- error_data = e .read ()
108- self .wfile .write (error_data if error_data else json .dumps ({"error" : str (e )}).encode ())
117+ try :
118+ error_data = e .read ()
119+ self .wfile .write (error_data if error_data else json .dumps ({"error" : str (e )}).encode ())
120+ except :
121+ self .wfile .write (json .dumps ({"error" : f"HTTP { e .code } : { e .reason } " }).encode ())
109122
110123 except Exception as e :
124+ print (f"Proxy error: { str (e )} " )
111125 # Handle other errors
112126 self .send_response (500 )
113127 self .send_header ('Content-Type' , 'application/json' )
@@ -159,13 +173,17 @@ def end_headers(self):
159173 """Add CORS headers"""
160174 self .send_header ('Access-Control-Allow-Origin' , '*' )
161175 self .send_header ('Access-Control-Allow-Methods' , 'GET, POST, OPTIONS' )
162- self .send_header ('Access-Control-Allow-Headers' , 'Content-Type' )
176+ self .send_header ('Access-Control-Allow-Headers' , 'Content-Type, Authorization ' )
163177 super ().end_headers ()
164178
165179 def do_OPTIONS (self ):
166180 """Handle OPTIONS requests for CORS"""
167181 self .send_response (200 )
168182 self .end_headers ()
183+
184+ def log_message (self , format , * args ):
185+ """Override to add more detailed logging"""
186+ print (f"{ self .address_string ()} - - [{ self .log_date_time_string ()} ] { format % args } " )
169187
170188if __name__ == '__main__' :
171189 # Ensure config exists before starting server
0 commit comments