Download linux/responses_http.h from LIghtJUNction/LightNest: direct link, hf CLI and curl.
- Browser
- Download file 15.1 kB
-
https://huggingface.co/LIghtJUNction/LightNest/resolve/main/linux/responses_http.h
- Command line
-
hf download hf://LIghtJUNction/LightNest/linux/responses_http.h
-
curl -L -o responses_http.h https://huggingface.co/LIghtJUNction/LightNest/resolve/main/linux/responses_http.h
15.1 kB
| /* Deliberately small, stateless loopback HTTP adapter. No files or subprocesses. | |
| * Included after lp_predict so the executable uses its embedded model directly. */ | |
| /* A bounded JSON tree: children are linked siblings; decoded strings are UTF-8. */ | |
| typedef struct { int type, child, next; char value[RH_STRING]; } RhToken; | |
| typedef struct { const unsigned char *p; RhToken t[RH_TOKENS]; int count; } RhJson; | |
| static int rh_utf8(const unsigned char *p,size_t n) { | |
| for(size_t i=0;i<n;) { | |
| unsigned c=p[i++],v; int k; | |
| if(!c) return 0; | |
| if(c<128) continue; | |
| if(c>=0xc2 && c<=0xdf) {k=1;v=c&31;} | |
| else if(c>=0xe0 && c<=0xef) {k=2;v=c&15;} | |
| else if(c>=0xf0 && c<=0xf4) {k=3;v=c&7;} else return 0; | |
| if(i+(size_t)k>n) return 0; | |
| for(int j=0;j<k;j++) {unsigned b=p[i++];if((b&0xc0)!=0x80)return 0;v=(v<<6)|(b&63);} | |
| if((k==1&&v<128)||(k==2&&v<2048)||(k==3&&v<65536)||v>0x10ffff||(v>=0xd800&&v<=0xdfff))return 0; | |
| } return 1; | |
| } | |
| static int rh_hex(unsigned c) {if(c>='0'&&c<='9')return (int)c-'0';if(c>='a'&&c<='f')return (int)c-'a'+10;if(c>='A'&&c<='F')return (int)c-'A'+10;return -1;} | |
| static void rh_ws(RhJson *j) {while(*j->p==' '||*j->p=='\t'||*j->p=='\r'||*j->p=='\n')j->p++;} | |
| static int rh_string(RhJson *j,char *out) { | |
| size_t n=0;if(*j->p++!='"')return 0; | |
| while(*j->p && *j->p!='"') { | |
| unsigned c=*j->p++;if(c<32)return 0; | |
| if(c=='\\') { | |
| c=*j->p++;if(!c)return 0; | |
| if(c=='u') { | |
| unsigned v=0;for(int i=0;i<4;i++){int h=rh_hex(*j->p);if(h<0)return 0;j->p++;v=(v<<4)|(unsigned)h;} | |
| if(!v||(v>=0xd800&&v<=0xdfff))return 0; | |
| if(v<128)c=v; | |
| else {if(n+3>=RH_STRING)return 0;if(v<2048)out[n++]=(char)(0xc0|(v>>6));else {out[n++]=(char)(0xe0|(v>>12));out[n++]=(char)(0x80|((v>>6)&63));}c=0x80|(v&63);} | |
| } else if(c=='b')c='\b';else if(c=='f')c='\f';else if(c=='n')c='\n';else if(c=='r')c='\r';else if(c=='t')c='\t';else if(c!='"'&&c!='\\'&&c!='/')return 0; | |
| } | |
| if(n+1>=RH_STRING)return 0;out[n++]=(char)c; | |
| } | |
| if(*j->p!='"')return 0;j->p++;out[n]=0;return 1; | |
| } | |
| static int rh_parse_value(RhJson *j,int depth) { | |
| rh_ws(j);if(depth>8||j->count>=RH_TOKENS)return -1; | |
| int id=j->count++;RhToken *t=&j->t[id];t->child=t->next=-1; | |
| unsigned c=*j->p; | |
| if(c=='"'){t->type='s';return rh_string(j,t->value)?id:-1;} | |
| if(c=='{'||c=='[') { | |
| t->type=(int)c;j->p++;rh_ws(j);unsigned end=c=='{'?'}':']';int last=-1; | |
| if(*j->p==end){j->p++;return id;} | |
| while(1) { | |
| int item; | |
| if(c=='{') { | |
| if(*j->p!='"'||j->count>=RH_TOKENS)return -1; | |
| item=j->count++;RhToken *key=&j->t[item];key->type='k';key->child=key->next=-1; | |
| if(!rh_string(j,key->value))return -1; | |
| for(int k=t->child;k>=0;k=j->t[k].next)if(!strcmp(j->t[k].value,key->value))return -1; | |
| rh_ws(j);if(*j->p++!=':')return -1; | |
| key->child=rh_parse_value(j,depth+1);if(key->child<0)return -1; | |
| } else {item=rh_parse_value(j,depth+1);if(item<0)return -1;} | |
| if(last<0)t->child=item;else j->t[last].next=item;last=item; | |
| rh_ws(j);if(*j->p==end){j->p++;return id;}if(*j->p++!=',')return -1;rh_ws(j); | |
| } | |
| } | |
| if(c>='0'&&c<='9') { | |
| t->type='n';size_t n=0; | |
| do {if(n>=20)return -1;t->value[n++]=(char)*j->p++;}while(*j->p>='0'&&*j->p<='9'); | |
| t->value[n]=0;if(n>1&&c=='0')return -1;return id; | |
| } | |
| const char *literals[]={"false","true","null"}; | |
| for(int i=0;i<3;i++)if(!strncmp((const char*)j->p,literals[i],strlen(literals[i]))) {t->type='l';strcpy(t->value,literals[i]);j->p+=strlen(literals[i]);return id;} | |
| return -1; | |
| } | |
| static int rh_parse(RhJson *j,const char *s) { | |
| memset(j,0,sizeof(*j));j->p=(const unsigned char*)s; | |
| if(!rh_utf8(j->p,strlen(s))||rh_parse_value(j,0)!=0)return 0;rh_ws(j);return !*j->p; | |
| } | |
| static int rh_get(RhJson *j,int obj,const char *name) { | |
| if(obj<0||j->t[obj].type!='{')return -1; | |
| for(int k=j->t[obj].child;k>=0;k=j->t[k].next)if(!strcmp(j->t[k].value,name))return j->t[k].child;return -1; | |
| } | |
| static int rh_fields(RhJson *j,int obj,const char *const *names,int count) { | |
| if(obj<0||j->t[obj].type!='{')return 0; | |
| for(int k=j->t[obj].child;k>=0;k=j->t[k].next){int found=0;for(int n=0;n<count;n++)if(!strcmp(j->t[k].value,names[n]))found=1;if(!found)return 0;}return 1; | |
| } | |
| static int rh_eq(RhJson *j,int id,int type,const char *s){return id>=0&&j->t[id].type==type&&!strcmp(j->t[id].value,s);} | |
| static int rh_uint(const char *s,uint64_t max,uint64_t *out) { | |
| uint64_t n=0;if(!*s)return 0;for(;*s;s++){if(*s<'0'||*s>'9'||n>(max-(unsigned)(*s-'0'))/10)return 0;n=n*10+(unsigned)(*s-'0');}*out=n;return 1; | |
| } | |
| static int64_t rh_now(void){struct timespec t;if(clock_gettime(CLOCK_MONOTONIC,&t))return 0;return (int64_t)t.tv_sec*1000+t.tv_nsec/1000000;} | |
| static ssize_t rh_read(int fd,void *buf,size_t n,int64_t deadline) { | |
| for(;;){int64_t left=deadline-rh_now();if(left<=0)return -1;struct pollfd p={fd,POLLIN,0};int r=poll(&p,1,(int)left);if(r<0&&errno==EINTR)continue;if(r<=0)return -1;return recv(fd,buf,n,0);} | |
| } | |
| static void rh_reply(int fd,int code,const char *body) { | |
| char h[256];const char *reason=code==200?"OK":code==400?"Bad Request":code==404?"Not Found":code==405?"Method Not Allowed":code==413?"Content Too Large":code==415?"Unsupported Media Type":"Request Timeout"; | |
| int n=snprintf(h,sizeof(h),"HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %zu\r\nConnection: close\r\nX-Content-Type-Options: nosniff\r\n\r\n",code,reason,strlen(body)); | |
| const char *parts[]={h,body};size_t sizes[]={(size_t)n,strlen(body)}; | |
| int64_t deadline=rh_now()+5000; | |
| for(int p=0;p<2;p++){size_t off=0;while(off<sizes[p]){int64_t left=deadline-rh_now();if(left<=0)return;struct pollfd f={fd,POLLOUT,0};if(poll(&f,1,(int)left)<=0)return;ssize_t wrote=send(fd,parts[p]+off,sizes[p]-off,MSG_NOSIGNAL|MSG_DONTWAIT);if(wrote<=0)return;off+=(size_t)wrote;}} | |
| } | |
| static void rh_error(int fd,int code,const char *message) {char b[512];snprintf(b,sizeof(b),"{\"error\":{\"message\":\"%s\",\"type\":\"invalid_request_error\",\"param\":null,\"code\":\"unsupported_or_invalid_request\"}}",message);rh_reply(fd,code,b);} | |
| static void rh_response(int fd,const PatchModel *model,const char *body,uint64_t serial) { | |
| RhJson j,e; | |
| if(!rh_parse(&j,body)){rh_error(fd,400,"Malformed JSON, duplicate keys, invalid UTF-8, or JSON exceeds bounded grammar");return;} | |
| const char *root[]={"model","input","stream","store"}; | |
| if(!rh_fields(&j,0,root,4)||!rh_eq(&j,rh_get(&j,0,"model"),'s',"lightnest-patch-v2")){rh_error(fd,400,"Only model lightnest-patch-v2 and input, stream:false, store:false are supported");return;} | |
| int stream=rh_get(&j,0,"stream"),store=rh_get(&j,0,"store"); | |
| if((stream>=0&&!rh_eq(&j,stream,'l',"false"))||(store>=0&&!rh_eq(&j,store,'l',"false"))){rh_error(fd,400,"Streaming and storage are unsupported; use false or omit");return;} | |
| int input=rh_get(&j,0,"input"); | |
| if(input>=0&&j.t[input].type=='[') { | |
| int msg=j.t[input].child;const char *mf[]={"role","content"};const char *cf[]={"type","text"}; | |
| if(msg<0||j.t[msg].next>=0||!rh_fields(&j,msg,mf,2)||!rh_eq(&j,rh_get(&j,msg,"role"),'s',"user")){rh_error(fd,400,"Input must contain exactly one user message");return;} | |
| int content=rh_get(&j,msg,"content"),part=content>=0?j.t[content].child:-1; | |
| if(content<0||j.t[content].type!='['||part<0||j.t[part].next>=0||!rh_fields(&j,part,cf,2)||!rh_eq(&j,rh_get(&j,part,"type"),'s',"input_text")){rh_error(fd,400,"Content must contain exactly one input_text part");return;} | |
| input=rh_get(&j,part,"text"); | |
| } | |
| if(input<0||j.t[input].type!='s'||!rh_parse(&e,j.t[input].value)){rh_error(fd,400,"Input text must be a JSON task envelope");return;} | |
| const char *ef[]={"command","binary_hex","base_offset"};int command=rh_get(&e,0,"command"),hex=rh_get(&e,0,"binary_hex"),base=rh_get(&e,0,"base_offset");uint64_t offset=0; | |
| if(!rh_fields(&e,0,ef,3)||command<0||e.t[command].type!='s'||!strlen(e.t[command].value)||strlen(e.t[command].value)>96||hex<0||e.t[hex].type!='s'||(base>=0&&(e.t[base].type!='n'||!rh_uint(e.t[base].value,UINT64_C(9007199254740736),&offset)))){rh_error(fd,400,"Envelope requires command (1..96 UTF-8 bytes), binary_hex, optional nonnegative bounded integer base_offset");return;} | |
| size_t size=strlen(e.t[hex].value);unsigned char bytes[256]; | |
| if(!size||size>512||size%2){rh_error(fd,400,"binary_hex must encode 1..256 bytes");return;} | |
| for(size_t i=0;i<size/2;i++){int a=rh_hex(e.t[hex].value[2*i]),b=rh_hex(e.t[hex].value[2*i+1]);if(a<0||b<0){rh_error(fd,400,"binary_hex contains non-hex characters");return;}bytes[i]=(unsigned char)((a<<4)|b);} | |
| PatchResult r=lp_predict(model,e.t[command].value,bytes,(int)(size/2)); | |
| char text[1024],escaped[2048],response[4096],absolute[32]; | |
| if(r.proposed)snprintf(absolute,sizeof(absolute),"%" PRIu64,offset+(uint64_t)r.position);else strcpy(absolute,"null"); | |
| snprintf(text,sizeof(text),"{\"result\":\"%s\",\"status\":\"%s\",\"validated\":false,\"proposed\":%s,\"position\":%d,\"replacement\":%d,\"confidence\":%.9g,\"base_offset\":%" PRIu64 ",\"offset\":%s}",r.proposed?"PATCH":"NONE",r.status,r.proposed?"true":"false",r.position,r.replacement,r.confidence,offset,absolute); | |
| size_t n=0;for(size_t i=0;text[i];i++){if(text[i]=='"'||text[i]=='\\')escaped[n++]='\\';escaped[n++]=text[i];}escaped[n]=0; | |
| time_t now=time(NULL); | |
| snprintf(response,sizeof(response),"{\"id\":\"resp_ln_%ld_%ld_%" PRIu64 "\",\"object\":\"response\",\"created_at\":%ld,\"status\":\"completed\",\"error\":null,\"incomplete_details\":null,\"model\":\"lightnest-patch-v2\",\"output\":[{\"id\":\"msg_ln_%" PRIu64 "\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"%s\",\"annotations\":[]}]}],\"usage\":null,\"store\":false,\"instructions\":null,\"metadata\":{},\"parallel_tool_calls\":false,\"tool_choice\":\"none\",\"tools\":[],\"temperature\":null,\"top_p\":null,\"truncation\":\"disabled\"}",(long)now,(long)getpid(),serial,(long)now,serial,escaped); | |
| rh_reply(fd,200,response); | |
| } | |
| static void rh_client(int fd,const PatchModel *model,uint64_t serial,unsigned port) { | |
| char header[RH_HEADER+1],body[RH_BODY+1];size_t n=0;int64_t deadline=rh_now()+5000; | |
| while(n<RH_HEADER){ssize_t got=rh_read(fd,header+n,1,deadline);if(got!=1){rh_error(fd,408,"Request read timeout or premature EOF");return;}if(!header[n]){rh_error(fd,400,"NUL in header");return;}n++;if(n>=4&&!memcmp(header+n-4,"\r\n\r\n",4))break;} | |
| if(n<4||memcmp(header+n-4,"\r\n\r\n",4)){rh_error(fd,400,"Header too large");return;}header[n]=0; | |
| for(size_t i=0;i<n;i++)if(((unsigned char)header[i]<32&&header[i]!='\r'&&header[i]!='\n'&&header[i]!='\t')||(unsigned char)header[i]>=127){rh_error(fd,400,"Invalid header characters");return;} | |
| for(size_t i=0;i<n;i++)if((header[i]=='\r'&&(i+1==n||header[i+1]!='\n'))||(header[i]=='\n'&&(!i||header[i-1]!='\r'))){rh_error(fd,400,"Headers require CRLF");return;} | |
| char *line=strstr(header,"\r\n");*line=0;char method[16],path[128],version[16],extra; | |
| if(sscanf(header,"%15s %127s %15s %c",method,path,version,&extra)!=3||strcmp(version,"HTTP/1.1")){rh_error(fd,400,"Expected HTTP/1.1 request");return;} | |
| int cl=0,ct=0,host=0;uint64_t length=0;char *p=line+2; | |
| while(*p){char *end=strstr(p,"\r\n");if(!end){rh_error(fd,400,"Invalid header line");return;}*end=0;if(!*p)break;char *colon=strchr(p,':');if(!colon||colon==p){rh_error(fd,400,"Invalid header");return;}*colon=0; | |
| for(char *k=p;*k;k++)if(!isalnum((unsigned char)*k)&&!strchr("!#$%&'*+-.^_`|~",*k)){rh_error(fd,400,"Invalid header name");return;} | |
| char *v=colon+1;while(*v==' '||*v=='\t')v++;char *tail=v+strlen(v);while(tail>v&&(tail[-1]==' '||tail[-1]=='\t'))*--tail=0; | |
| if(!strcasecmp(p,"Transfer-Encoding")||!strcasecmp(p,"Expect")||!strcasecmp(p,"Origin")){rh_error(fd,400,"Transfer-Encoding, Expect and browser Origin requests are unsupported");return;} | |
| if(!strcasecmp(p,"Content-Length")){if(cl++||!rh_uint(v,UINT64_MAX,&length)){rh_error(fd,400,"Invalid or duplicate Content-Length");return;}} | |
| if(!strcasecmp(p,"Content-Type")){if(ct++||(strcasecmp(v,"application/json")&&strcasecmp(v,"application/json; charset=utf-8"))){rh_error(fd,415,"Use application/json");return;}} | |
| if(!strcasecmp(p,"Host")){char expected[64];snprintf(expected,sizeof(expected),"127.0.0.1:%u",port);if(host++||strcmp(v,expected)){rh_error(fd,400,"Host must match the loopback listener including port");return;}} | |
| p=end+2; | |
| } | |
| if(!host){rh_error(fd,400,"Host is required");return;} | |
| if(length>RH_BODY){rh_error(fd,413,"Body exceeds 8192 bytes");return;} | |
| if(!strcmp(method,"GET")&&(!strcmp(path,"/health")||!strcmp(path,"/v1/models"))){if(length){rh_error(fd,400,"GET body unsupported");return;}rh_reply(fd,200,!strcmp(path,"/health")?"{\"status\":\"ok\",\"model\":\"lightnest-patch-v2\",\"stateless\":true,\"max_command_utf8_bytes\":96,\"max_binary_bytes\":256,\"streaming\":false,\"semantic_validation\":false}":"{\"object\":\"list\",\"data\":[{\"id\":\"lightnest-patch-v2\",\"object\":\"model\",\"created\":0,\"owned_by\":\"local\"}]}");return;} | |
| if(strcmp(path,"/v1/responses")){rh_error(fd,404,"Unknown route");return;}if(strcmp(method,"POST")){rh_error(fd,405,"Use POST");return;} | |
| if(!cl||!ct||!length){rh_error(fd,400,"JSON Content-Type and nonzero Content-Length are required");return;} | |
| n=0;while(n<(size_t)length){ssize_t got=rh_read(fd,body+n,(size_t)length-n,deadline);if(got<=0){rh_error(fd,408,"Request read timeout or premature EOF");return;}n+=(size_t)got;}body[n]=0; | |
| if(memchr(body,0,n)||!rh_utf8((unsigned char*)body,n)){rh_error(fd,400,"Body must be UTF-8 without NUL");return;}rh_response(fd,model,body,serial); | |
| } | |
| static int rh_serve(const PatchModel *model,const char *port_string) { | |
| uint64_t port;if(!rh_uint(port_string,65535,&port)||!port)die("--serve requires port 1..65535"); | |
| int server=socket(AF_INET,SOCK_STREAM,0);if(server<0)die("cannot create loopback socket"); | |
| struct sockaddr_in addr={0};addr.sin_family=AF_INET;addr.sin_port=htons((uint16_t)port);addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK); | |
| if(bind(server,(struct sockaddr*)&addr,sizeof(addr))||listen(server,8)){close(server);die("cannot bind/listen on 127.0.0.1");} | |
| fprintf(stderr,"LightNest native stateless Responses subset listening on http://127.0.0.1:%u (no authentication; local processes only)\n",(unsigned)port); | |
| uint64_t serial=0;for(;;){int fd=accept(server,NULL,NULL);if(fd<0){if(errno==EINTR)continue;close(server);die("accept failed");}rh_client(fd,model,++serial,(unsigned)port);close(fd);} | |
| } | |