import http.server, socketserver, os, re
DIR=os.path.expanduser("~/Projects/lasso-tiles")
CORS=[('Access-Control-Allow-Origin','*'),
      ('Access-Control-Expose-Headers','Content-Range, Content-Length, Accept-Ranges, ETag'),
      ('Cache-Control','public, max-age=600')]
class H(http.server.SimpleHTTPRequestHandler):
    def __init__(self,*a,**k): super().__init__(*a,directory=DIR,**k)
    def end_headers(self):
        for k,v in CORS: self.send_header(k,v)
        super().end_headers()
    def do_OPTIONS(self):
        self.send_response(204)
        self.send_header('Access-Control-Allow-Methods','GET, HEAD, OPTIONS')
        self.send_header('Access-Control-Allow-Headers','Range, If-Match, If-None-Match')
        self.send_header('Access-Control-Max-Age','86400')
        self.end_headers()
    def send_head(self):
        path=self.translate_path(self.path); rng=self.headers.get('Range')
        if not rng or not os.path.isfile(path): return super().send_head()
        m=re.match(r'bytes=(\d+)-(\d*)',rng)
        if not m: return super().send_head()
        size=os.path.getsize(path); start=int(m.group(1)); end=int(m.group(2)) if m.group(2) else size-1
        end=min(end,size-1); length=end-start+1
        f=open(path,'rb'); f.seek(start)
        self.send_response(206)
        self.send_header('Content-Type',self.guess_type(path))
        self.send_header('Accept-Ranges','bytes')
        self.send_header('Content-Range',f'bytes {start}-{end}/{size}')
        self.send_header('Content-Length',str(length)); self.end_headers()
        self._rem=length; return f
    def copyfile(self,src,out):
        rem=getattr(self,'_rem',None)
        if rem is None: return super().copyfile(src,out)
        while rem>0:
            c=src.read(min(65536,rem))
            if not c: break
            out.write(c); rem-=len(c)
    def log_message(self,*a): pass
socketserver.ThreadingTCPServer.allow_reuse_address=True
socketserver.ThreadingTCPServer(("127.0.0.1",9077),H).serve_forever()
