code wiki / _hdl_build / nx_archive_resolve.nx
nx_archive_resolve.nx source
↩ module page · 32 lines · 2738 B
1// nx_archive_resolve.nx -- SERVE-FROM-ARCHIVE, the payoff that connects preservation to the search engine:
2// given a URL whose origin has rotted, build a proper HTTP response serving the PRESERVED copy from the WARC
3// (correct Content-Type, byte-exact body, flagged X-Nishi-Archive: preserved) -- or a 404 if it was never
4// captured. The search engine links results through a resolver endpoint that tries the live origin and falls
5// back to this on 404, so indexed media never dies. Additive: this touches nothing in the search core. ORIGINAL
6import "nx_syscalls.nx"
7import "nx_web_archive.nx"
8
9func ar_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
10func ar_puts(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off]=s[i];off=off+1;i=i+1} return off }
11func ar_putn(dst: *u8, off: i64, v: i64) -> i64 { var m: i64=v; if m==0 { dst[off]=48 as u8; return off+1 } let t: *u8=sys_mmap(24); var k: i64=0; while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } var j: i64=0; while j<k { dst[off]=t[k-1-j]; off=off+1; j=j+1 } return off }
12
13// build the full HTTP response for `url` from the archive into `out`; returns response length.
14func ar_build_response(warc: *u8, warclen: i64, url: *u8, ulen: i64, out: *u8, cap: i64) -> i64 {
15 let op: *i64 = sys_mmap(8) as *i64; let ol: *i64 = sys_mmap(8) as *i64
16 let ct: *u8 = sys_mmap(256)
17 let found: i64 = wa_resolve(warc, warclen, url, ulen, op, ol, ct, 256)
18 var o: i64 = 0
19 if found == 0 {
20 let body: *u8 = "Not preserved in archive.\n" as *u8
21 o = ar_puts(out, o, "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: " as *u8)
22 o = ar_putn(out, o, ar_slen(body)); o = ar_puts(out, o, "\r\nConnection: close\r\n\r\n" as *u8)
23 o = ar_puts(out, o, body)
24 return o
25 }
26 if ct[0] == (0 as u8) { ct[0]=97 as u8; ct[1]=112 as u8; ct[2]=112 as u8; ct[3]=108 as u8; ct[4]=105 as u8; ct[5]=99 as u8; ct[6]=97 as u8; ct[7]=116 as u8; ct[8]=105 as u8; ct[9]=111 as u8; ct[10]=110 as u8; ct[11]=47 as u8; ct[12]=111 as u8; ct[13]=99 as u8; ct[14]=116 as u8; ct[15]=101 as u8; ct[16]=116 as u8; ct[17]=45 as u8; ct[18]=115 as u8; ct[19]=116 as u8; ct[20]=114 as u8; ct[21]=101 as u8; ct[22]=97 as u8; ct[23]=109 as u8; ct[24]=0 as u8 } // "application/octet-stream" default
27 o = ar_puts(out, o, "HTTP/1.1 200 OK\r\nContent-Type: " as *u8); o = ar_puts(out, o, ct)
28 o = ar_puts(out, o, "\r\nContent-Length: " as *u8); o = ar_putn(out, o, ol[0])
29 o = ar_puts(out, o, "\r\nX-Nishi-Archive: preserved\r\nConnection: close\r\n\r\n" as *u8)
30 var i: i64 = 0; while i < ol[0] { out[o] = warc[op[0]+i]; o = o + 1; i = i + 1 } // byte-exact preserved body
31 return o
32}