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}