
    hD                     b   d dl Zd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZej                  j                  dk(  rej                  j                   dk  rd dlZnd dlZddddZded	efd
Zded	efdZdZdej4                  j6                  fdZ G d dej:                        Zdej>                  d	ej>                  fdZ dej4                  j6                  d	e!ejD                  ef   fdZ#dej4                  j6                  ded	e!e$ef   fdZ%dej4                  j6                  d	e$fdZ& G d d      Z' G d de'ej4                  jP                        Z( G d de'ej4                  jR                        Z)d Z*dej                  d	ejV                  fdZ,d  Z-d! Z.y)"    N      lightz
light darkdarkr   autor   themereturnc                 L    t        dt        j                  |       z   dz   d      S )Nz<!DOCTYPE html>
<html>
<head>
<title>File Upload</title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
<meta name="color-scheme" content="u  ">
</head>
<body>
<h1>File Upload</h1>
<form action="upload" method="POST" enctype="multipart/form-data">
<input name="files" type="file" multiple />
<br />
<br />
<input type="submit" />
</form>
<p id="task"></p>
<p id="status"></p>
</body>
<script>
document.getElementsByTagName('form')[0].addEventListener('submit', async e => {
  e.preventDefault()
  
  const uploadFormData = new FormData(e.target)
  const filenames = uploadFormData.getAll('files').map(v => v.name).join(', ')
  const uploadRequest = new XMLHttpRequest()
  uploadRequest.open(e.target.method, e.target.action)
  uploadRequest.timeout = 3600000
  
  uploadRequest.onreadystatechange = () => {
    if (uploadRequest.readyState === XMLHttpRequest.DONE) {
      let message = `${uploadRequest.status}: ${uploadRequest.statusText}`
      if (uploadRequest.status === 0) message = 'Connection failed'
      if (uploadRequest.status === 204) {
        message = `Success: ${uploadRequest.statusText}`
      }
      document.getElementById('status').textContent = message
    }
  }
  
  uploadRequest.upload.onprogress = e => {
    document.getElementById('status').textContent = (e.loaded === e.total ?
      'Saving…' :
      `${Math.floor(100*e.loaded/e.total)}% ` +
      `[${Math.floor(e.loaded/1024)} / ${Math.floor(e.total/1024)}KiB]`
    )
  }
  
  uploadRequest.send(uploadFormData)
  
  document.getElementById('task').textContent = `Uploading ${filenames}:`
  document.getElementById('status').textContent = '0%'
})
</script>
</html>utf-8bytesCOLOR_SCHEMEgetr	   s    \/root/python_server/python_server_venv/lib/python3.12/site-packages/uploadserver/__init__.pyget_upload_pager      s<     '
 *6)9)9%)@A
0D5j k5 5    c                 L    t        dt        j                  |       z   dz   d      S )Nz{<!-- Injected by uploadserver -->
<meta name="viewport" content="width=device-width" />
<meta name="color-scheme" content="z*">
<!-- End injection by uploadserver -->
r   r   r   s    r   get_directory_head_injectionr   M   s8     ')5)9)9%)@AD 	 r   s   <!-- Injected by uploadserver -->
<a href="/upload">File upload</a>
(provided by uploadserver, all files go to server root)
<hr>
<!-- End injection by uploadserver -->
handlerc                 b   | j                  t        j                  j                         | j	                  dd       | j	                  dt        t        t        j                                     | j                          | j                  j                  t        t        j                               y )NzContent-Typeztext/html; charset=utf-8zContent-Length)send_responsehttp
HTTPStatusOKsend_headerlenr   argsr	   end_headerswfilewrite)r   s    r   send_upload_pager#   [   sq    $//,,-(BC(#odjj.I*JKMM

34r   c                       e Zd ZdefdZy)PersistentFieldStorager
   c                     | j                   r&t        j                  dt        j                  d      S t        j                  dt        j                  d| j
                  d      S )Nzwb+F)modedirdeletezw+
)r(   r)   encodingnewline)_binary_filetempfileNamedTemporaryFiler   	directoryr+   selfs    r   	make_filez PersistentFieldStorage.make_filef   sS    ..ennu6 6 ..t4>>4==DJ Jr   N)__name__
__module____qualname__objectr3    r   r   r%   r%   b   s    J6 Jr   r%   pathc                 >   t         j                  j                  |       s| S t         j                  j                  |       \  }}t	        dt
        j                        D ]/  }| d| d| }t         j                  j                  |      r-|c S  t        d|  d      )N   z ()zFile z already exists.)osr9   existssplitextrangesysmaxsizeFileExistsError)r9   baseextirenamed_paths        r   auto_renamerH   p   s    77>>$''""4(KT31ckk"  r!AcU+ww~~l+  E$'78
99r   c                    t         j                  j                  df}d}t        | j                  | j
                  ddi      }d|vrt         j                  j                  dfS |d   }t        |t              s|g}t        d |D              st         j                  j                  d	fS |D ]  }|j                  r6|j                  r*t        j                  |j                        j                  }nd }|sKt        j                  t        j                         |z  }t"        j$                  j'                  |      rRt        j(                  r5t"        j$                  j+                  |      rt#        j,                  |       nt/        |      }d
}t1        |j                  d      rG|j                  j                  }|j                  j3                          t#        j4                  ||       n>t7        |d      5 }	|	j9                  |j                  j;                                d d d        | j=                  d||       t         j                  j>                  |rdndf} |S # 1 sw Y   AxY w)NzServer errorFREQUEST_METHODPOST)fpheadersenvironfileszField "files" not foundc              3   P   K   | ]  }|j                   xr |j                     y wN)filefilename).0fields     r   	<genexpr>z!receive_upload.<locals>.<genexpr>   s      Auzz,enn,As   $&zNo files selectedTnamewbz[Uploaded] "%s" --> %sz-Some filename(s) changed due to name conflictzFiles accepted) r   r   INTERNAL_SERVER_ERRORr%   rfilerM   BAD_REQUEST
isinstancelistallrR   rS   pathlibPathrW   r   r0   r=   r9   r>   allow_replaceisfileremoverH   hasattrcloserenameopenr"   readlog_message
NO_CONTENT)
r   resultname_conflictformfieldsrU   rS   destinationsourcefs
             r   receive_uploadrr   z   s   oo33^DFM!W]]GOO!6*,Dd++-FGG']Ffd#A&AA++-@AA O::%..||ENN388HH!,,t~~6AKww~~k*%%"''..*EIIk*"-k":K$(Muzz6*

  "		&+. +t, /GGEJJOO-./ 8(KPoo00*73'=MOF1O6 M/ /s   6*I  I)	authc                    | j                   j                  d      }|y|j                  d      }t        |      dk7  ry|d   j	                         dk7  ry	 t        j                  |d         j                         }|j                  d	d      \  }}|j                  d	d      \  }}||k7  ry
||k7  ryy# t        j                  $ r Y yw xY w)NAuthorization)FzNo credentials given    )Fz!Credentials incorrectly formattedr   basicr;   :)FzBad username)FzBad password)TN)
rM   r   splitr   lowerbase64	b64decodedecodebinasciiError)	r   rs   auth_headerauth_header_wordshttp_username_passwordhttp_usernamehttp_passwordargs_usernameargs_passwords	            r    check_http_authentication_headerr      s     //%%o6K.#))#.
";!!#w.;<!'!1!12CA2F!G!N!N!P $:#?#?Q#G M=#'::c1#5 M=%.E%.E >> <;<s   &B4 4C
	C
c                 8   t         j                  s/t         j                  syt        | t         j                        \  }}nz| j                  dk(  rt        | t         j                        \  }}nMt         j                  syt        | t         j                        \  }}|st        | t         j                        \  }}|s^| j                  d|       | j                  t        j                  j                  |       | j                  dd       | j                          |S )z
    This function should be called in at the beginning of HTTP method handler.
    It validates Authorization header and sends back 401 response on failure.
    It returns False if this happens.
    T/uploadzRequest rejected (%s)zWWW-AuthenticatezBasic realm="uploadserver")r   basic_auth_upload
basic_authr   r9   ri   r   r   r   UNAUTHORIZEDr   r    )r   validmessages      r   check_http_authenticationr      s     !! :'4??Sw <<9$=g&&(NE7
 ??
 "B'4??![w%EgtOeOe%fNE73W=doo::GD.0LMLr   c                   <    e Zd Zd Zd Zdej                  defdZy)ListDirectoryInterceptionc                 j   t        | j                        D ]r  \  }}|d d dk(  st        |dd        t        t              z   t        t        t        j                              z   }d| dj                  dd      | j                  |<   t t        j                  j                  j                  |        y )N   s   Content-Length:zContent-Length: z
zlatin-1strict)	enumerate_headers_bufferintr   DIRECTORY_BODY_INJECTIONr   r   r	   encoder   serverSimpleHTTPRequestHandlerflush_headers)r2   rF   headerlengths       r   flush_headers_interceptorz3ListDirectoryInterception.flush_headers_interceptor   s    "4#7#78 	1IAvcr{00VBC[)C0H,II4TZZ@AB -=VHD*IVIx0 $$Q'	1 	,,::4@r   c                     |j                         }|j                  dt        t        j                        dz         }|j                  dt
        dz         }|j                  |       y )Ns   </head>s   <ul>)rh   replacer   r   r	   r   r"   )r2   rp   
outputfilecontents       r   copyfile_interceptorz.ListDirectoryInterception.copyfile_interceptor   sS    ++-//*(4zAC//'+Cg+MN!r   r9   r
   c                     t        | d| j                         t        | d| j                         t        j                  j
                  j                  | |      S )Nr   copyfile)setattrr   r   r   r   r   list_directory)r2   r9   s     r   r   z(ListDirectoryInterception.list_directory  sE    ot'E'EFj$";";< {{33BB4NNr   N)	r4   r5   r6   r   r   r_   r`   r7   r   r8   r   r   r   r      s'    A"O7<< OF Or   r   c                   *     e Zd Z fdZd Zd Z xZS )r   c                 p    t        |       sy | j                  dk(  rt        |        y t        |           y Nr   r   r9   r#   superdo_GETr2   	__class__s    r   r   zSimpleHTTPRequestHandler.do_GET  +    (.99	!T"GNr   c                 h   t        |       sy | j                  dk(  rmt        |       }|d   t        j                  j
                  k  r)| j                  |d   |d          | j                          y | j                  |d   |d          y | j                  t        j                  j                  d       y )Nr   r   r;   zCan only POST/PUT to /upload)
r   r9   rr   r   r   r[   r   r    
send_error	NOT_FOUND)r2   rk   s     r   do_POSTz SimpleHTTPRequestHandler.do_POST  s    (.99	!#D)Fay4??666""6!9fQi8  "q	6!95OODOO55.0r   c                 $    | j                          y rQ   r   r1   s    r   do_PUTzSimpleHTTPRequestHandler.do_PUT&      r   r4   r5   r6   r   r   r   __classcell__r   s   @r   r   r     s    0r   r   c                   .     e Zd Z fdZ fdZd Z xZS )CGIHTTPRequestHandlerc                 p    t        |       sy | j                  dk(  rt        |        y t        |           y r   r   r   s    r   r   zCGIHTTPRequestHandler.do_GET+  r   r   c                 2   t        |       sy | j                  dk(  rmt        |       }|d   t        j                  j
                  k  r)| j                  |d   |d          | j                          y | j                  |d   |d          y t        | )          y )Nr   r   r;   )r   r9   rr   r   r   r[   r   r    r   r   r   )r2   rk   r   s     r   r   zCGIHTTPRequestHandler.do_POST3  s}    (.99	!#D)Fay4??666""6!9fQi8  "q	6!95GOr   c                 $    | j                          y rQ   r   r1   s    r   r   zCGIHTTPRequestHandler.do_PUTA  r   r   r   r   s   @r   r   r   )  s    r   r   c                  h    t         j                  r!t        j                  fd} | t        _        y y )Nc                  t     | d   j                  dd      j                  dd      fi | t        _        y )Nr   HTTPHTTPSr   https)r   builtinsprint)r   kwargs	old_prints     r   	new_printz(intercept_first_print.<locals>.new_printH  s8    d1goofg6>>vwO &HNr   )r   server_certificater   r   )r   r   s    @r   intercept_first_printr   D  s(    NN		' # r   socketc                 
   t        j                  t         j                  j                        }t	        j
                  t        j                        j                         }t	        j
                  t        j                        j                         }|j                         s$t        d| d       t        j                  d       ||j                  v r't        d| d| d       t        j                  d       	 |j                  |       t        j"                  rt	        j
                  t        j"                        j                         }|j                         s$t        d
| d       t        j                  d       ||j                  v r't        d
| d| d       t        j                  d       |j%                  |       t         j&                  |_        	 |j+                  | d      S # t         j                   $ r/}t        d| d	       t        j                  d       Y d }~"d }~ww xY w# t         j                   $ r9}t        dj-                  |             t        j                  d       Y d }~y d }~ww xY w)NzServer certificate "z" not found, exiting   z" is inside web server root "z
", exitingr   )certfilezUnable to load certificate "z", exiting

NOTE: Certificate must be a single file in .pem format. If you have multiple certificate files, such as Let's Encrypt provides, you can cat them together to get one file.zClient certificate ")cafileT)server_sidezSSL error: "{}", exiting   )sslcreate_default_contextPurposeCLIENT_AUTHr_   r`   r   r0   resolver   is_filer   rA   exitparentsload_cert_chainSSLErrorclient_certificateload_verify_locationsCERT_REQUIREDverify_modewrap_socketformat)r   contextserver_rootr   er   s         r   ssl_wrapr   N  s   (()@)@AG,,t~~.668K !d&=&=>FFH%%'$%7$88LMN(000$%7$8 9 M- 	.);< $\\$*A*ABJJL!))+();(< =  HHQK,444();(< =  +}J8 9HHQK%%-?%@!//""6t"<<3 << ,-?,@ A9 9 	: 	4 << (//23s0   :G1 H6 1H3$H..H36J	/I==Jc                     t        t        d      rt        t        j                        t        u sJ t        t        d      rt        t        j
                        t        u sJ t        t        d      rt        t        j                        t        u sJ t        t        d      sJ t        t        d      sJ t        t        d      sJ t        t        d      sJ t        t        d      sJ t        t        d	      sJ t        t        d
      rt        t        j                        t        u sJ t        j
                  rt        } n)t        j                  t        t        j                        } t        d        G d dt        j                   j"                        }|}t%                t        j                   j'                  | |t        j                  t        j(                         y )Nportcgira   bindr	   r   r   r   r   r0   )r0   z File upload available at /uploadc                        e Zd Z fdZ xZS )&serve_forever.<locals>.DualStackServerc                 F   t        j                  t              5  | j                  j	                  t        j
                  t        j                  d       d d d        t        | !         }t        j                  rt        | j                        | _        |S # 1 sw Y   CxY w)Nr   )
contextlibsuppress	Exceptionr   
setsockoptIPPROTO_IPV6IPV6_V6ONLYr   server_bindr   r   r   )r2   r   r   s     r   r   z2serve_forever.<locals>.DualStackServer.server_bind  s}    $$Y/ @&&''););Q@@ 7&(D&&&t{{3K@ @s   :BB )r4   r5   r6   r   r   r   s   @r   DualStackServerr     s    	 	r   r   )HandlerClassServerClassr   r   )rd   r   typer   r   r   boolra   r0   strr   	functoolspartialr   r   r   r   ThreadingHTTPServerr   testr   )handler_classr   server_classs      r   serve_foreverr  ~  sd   4 T$))_%;;;4DNd$:::4)d43E3E.F$.NNN4   4!!!4-...4-...4&&&4,---4%$t~~*>#*EEExx-!))*Bnn& 

,-	$++99 	 #LKK" YYYY	  r   c                     t        j                         } | j                  dt        ddd       | j                  ddd	       | j                  d
ddd       | j                  dddd       | j                  ddt	        j
                         d       | j                  dt        dg dd       | j                  dddd        | j                  d!d"        | j                  d#d$        | j                  d%d&        | j                         at        t        d'      st	        j
                         t        _
        t                y )(Nr   i@  ?z&Specify alternate port [default: 8000])r   defaultnargshelpz--cgi
store_truezRun as CGI Server)actionr	  z--allow-replaceFzQReplace existing file if uploaded file has the same name. Auto rename by default.)r  r  r	  z--bindz-bADDRESSz8Specify alternate bind address [default: all interfaces])metavarr	  z--directoryz-dz9Specify alternative directory [default:current directory])r  r	  z--themer   r   zASpecify a light or dark theme for the upload page [default: auto])r   r  choicesr	  z--server-certificatez--certificatez-cz7Specify HTTPS server certificate to use [default: none])r	  z--client-certificatezISpecify HTTPS client certificate to accept for mutual TLS [default: none]z--basic-authzBSpecify user:pass for basic authentication (downloads and uploads)z--basic-auth-uploadz9Specify user:pass for basic authentication (uploads only)r0   )argparseArgumentParseradd_argumentr   r=   getcwdr   
parse_argsr   rd   r0   r  )parsers    r   mainr    sj    $$&F
S$c5  7
   "
),   $	G  I
tRYY[H  J
	V)   .F  H
.      -H  J D4%		t~Or   )/http.serverr   r_   rA   r  r   r=   r   r.   r|   r   r   r   r   version_infomajorminorr   uploadserver.cgiuploadserverr   r   r   r   r   r   r   BaseHTTPRequestHandlerr#   FieldStorager%   r`   rH   tupler   rr   r   r   r   r   r   r   r   	SSLSocketr   r  r  r8   r   r   <module>r      s   M M M M M . .  Q3#3#3#9#9B#> 63 65 6p   5dkk@@ 5
JS-- 
J:gll :w|| :,DKK>> ,
4??C ,^		+	+36
494't{{'I'I '	'VO O>8KK((85KK%%6#.V]] .s}} .`'R!r   