chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환 - Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용 - pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관) - worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md) - D:\Rhino-MCP 경로 참조를 새 위치로 치환 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
964a841de1
3978 files changed
+58013356
No files matched your search
@@ -0,0 +1,84 @@
|
||||
"""Deployment-only HTTP prefix adapter; modeling code remains unchanged."""
|
||||
import http.client
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
PREFIX = '/box-sample'
|
||||
UPSTREAM_PORT = 8097
|
||||
HOP = {'connection', 'transfer-encoding', 'keep-alive', 'upgrade',
|
||||
'proxy-authenticate', 'proxy-authorization', 'te', 'trailer'}
|
||||
ROOT_URL = re.compile(rb'''(["'`])/(api/|src/|dxf_rasterizer\.html|model-report\.html)''')
|
||||
|
||||
|
||||
def rewrite(payload):
|
||||
return ROOT_URL.sub(lambda m: m[1] + PREFIX.encode() + b'/' + m[2], payload)
|
||||
|
||||
|
||||
class Gateway(BaseHTTPRequestHandler):
|
||||
def forward(self):
|
||||
parsed = urlsplit(self.path)
|
||||
if parsed.path == PREFIX:
|
||||
self.send_response(308)
|
||||
self.send_header('Location', PREFIX + '/' + ('?' + parsed.query if parsed.query else ''))
|
||||
self.send_header('Content-Length', '0')
|
||||
self.end_headers()
|
||||
return
|
||||
if not parsed.path.startswith(PREFIX + '/'):
|
||||
self.send_error(404)
|
||||
return
|
||||
if self.headers.get('Transfer-Encoding'):
|
||||
self.send_error(411, 'Content-Length required')
|
||||
return
|
||||
target = self.path[len(PREFIX):]
|
||||
connection = http.client.HTTPConnection('127.0.0.1', UPSTREAM_PORT, timeout=600)
|
||||
try:
|
||||
size = int(self.headers.get('Content-Length', '0'))
|
||||
if size < 0 or size > 512 * 1024 * 1024:
|
||||
self.send_error(413)
|
||||
return
|
||||
headers = {k: v for k, v in self.headers.items()
|
||||
if k.lower() not in HOP | {'accept-encoding', 'host'}}
|
||||
headers['Host'] = '127.0.0.1:' + str(UPSTREAM_PORT)
|
||||
connection.request(self.command, target, self.rfile.read(size) if size else None, headers)
|
||||
response = connection.getresponse()
|
||||
content_type = response.getheader('Content-Type', '').lower()
|
||||
text = any(t in content_type for t in ('json', 'javascript', 'text/html', 'text/css'))
|
||||
body = rewrite(response.read()) if text and self.command != 'HEAD' else None
|
||||
self.send_response(response.status)
|
||||
for key, value in response.getheaders():
|
||||
if key.lower() in HOP | {'content-length', 'etag', 'content-md5'}:
|
||||
continue
|
||||
if key.lower() == 'location' and value.startswith('/') and not value.startswith('//'):
|
||||
value = PREFIX + value
|
||||
self.send_header(key, value)
|
||||
self.send_header('X-DMS-Deployment', 'box-sample')
|
||||
self.send_header('Cache-Control', 'no-store')
|
||||
if body is not None:
|
||||
self.send_header('Content-Length', str(len(body)))
|
||||
elif response.getheader('Content-Length') is not None:
|
||||
self.send_header('Content-Length', response.getheader('Content-Length'))
|
||||
self.end_headers()
|
||||
if self.command != 'HEAD':
|
||||
if body is not None:
|
||||
self.wfile.write(body)
|
||||
else:
|
||||
while chunk := response.read(65536):
|
||||
self.wfile.write(chunk)
|
||||
except (ValueError, OSError, http.client.HTTPException):
|
||||
self.send_error(502, 'Application not ready')
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
do_GET = do_POST = do_HEAD = do_PUT = do_DELETE = forward
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
child = subprocess.Popen([sys.executable, 'src/backend/serve.py', '--host', '127.0.0.1', '--port', str(UPSTREAM_PORT)])
|
||||
try:
|
||||
ThreadingHTTPServer(('0.0.0.0', 8080), Gateway).serve_forever()
|
||||
finally:
|
||||
child.terminate()
|
||||
child.wait(timeout=15)
|
||||
Reference in new issue
Block a user