const char * vmod_country(struct sess *sp, const char *ip) { const char *country = NULL; char *cp; if (!gi) { gi = GeoIP_new(GEOIP_STANDARD); if (gi) { WSP(sp, SLT_VCL_Log, "GeoIP database was loaded on request."); } else { WSP(sp, SLT_VCL_Log, "GeoIP database was not loaded on request."); } } if (gi) { country = GeoIP_country_code_by_addr(gi, ip); } if (!country) { country= unknownCountry; } char lowerCountry[2]; strcpy(lowerCountry, country); strtolower(lowerCountry); cp= WS_Dup(sp->wrk->ws, (const char *)lowerCountry); return(cp); }
struct vbe_conn * VBE_GetVbe(struct sess *sp, struct backend *bp) { struct vbe_conn *vc; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); /* first look for vbe_conn's we can recycle */ while (1) { Lck_Lock(&bp->mtx); vc = VTAILQ_FIRST(&bp->connlist); if (vc != NULL) { bp->refcount++; assert(vc->backend == bp); assert(vc->fd >= 0); VTAILQ_REMOVE(&bp->connlist, vc, list); } Lck_Unlock(&bp->mtx); if (vc == NULL) break; if (VBE_CheckFd(vc->fd)) { /* XXX locking of stats */ VSL_stats->backend_reuse += 1; VSL_stats->backend_conn++; WSP(sp, SLT_Backend, "%d %s %s", vc->fd, sp->director->vcl_name, bp->vcl_name); return (vc); } sp->vbe = vc; VBE_ClosedFd(sp); } if (!bp->healthy) { VSL_stats->backend_unhealthy++; return (NULL); } if (bp->max_conn > 0 && bp->n_conn >= bp->max_conn) { VSL_stats->backend_busy++; return (NULL); } vc = VBE_NewConn(); assert(vc->fd == -1); AZ(vc->backend); vc->fd = bes_conn_try(sp, bp); if (vc->fd < 0) { VBE_ReleaseConn(vc); VSL_stats->backend_fail++; return (NULL); } vc->backend = bp; VSL_stats->backend_conn++; WSP(sp, SLT_Backend, "%d %s %s", vc->fd, sp->director->vcl_name, bp->vcl_name); return (vc); }
int cb_check_json_number( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ int err=CBSUCCESS, indx=0; unsigned long int chr=0x20; char state=0, dotcount=0, ecount=0, minuscount=0, firstzero=0, expsigncount=0, atend=0; if( from==NULL || ucsvalue==NULL || *ucsvalue==NULL || cfg==NULL || *cfg==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_number: ucsvalue was null."); return CBERRALLOC; } indx = *from; if(ucsvaluelen<=0) return CBNOTJSONNUMBER; while( indx<ucsvaluelen && indx<CBNAMEBUFLEN && err<CBNEGATION ){ *from = indx; err = cb_get_ucs_chr( &chr, &(*ucsvalue), &indx, ucsvaluelen); //fprintf( stderr, "[%c]", (unsigned char) chr ); if(atend==0){ if( chr=='-' && minuscount==0 && state==0 ){ minuscount=1; state=EXPECTDIGIT; firstzero=0; continue; } if( chr=='0' && ( state==0 || ( firstzero==0 && minuscount==1 && state==EXPECTDIGIT ) ) ){ state=EXPECTDOTOREXP; firstzero=1; continue; } if( chr>='1' && chr<='9' && state==0 ){ state=EXPECTDIGITORDOT; firstzero=2; continue; } if( chr>='0' && chr<='9' && state==EXPECTEND ){ continue; } if( chr>='0' && chr<='9' && ( state==EXPECTDIGIT || state==EXPECTDIGITORDOT || state==EXPECTDIGITBEFOREEXP || state==EXPECTEXP ) ){ if(firstzero==1 && state==EXPECTDIGIT) return CBNOTJSONNUMBER; if( state==EXPECTDIGITBEFOREEXP ) state=EXPECTEXP; if( state==EXPECTDIGIT ) state=EXPECTDIGITORDOT; continue; } if( chr=='.' && dotcount==0 ){ state=EXPECTDIGITBEFOREEXP; dotcount=1; continue; } if( ( chr=='e' || chr=='E' ) && ecount==0 && ( ( dotcount==1 && state!=EXPECTDIGITBEFOREEXP ) || state==EXPECTDOTOREXP || state==EXPECTDIGITORDOT ) ){ state=EXPECTEXP; ecount=1; continue; } if( ( chr=='+' || chr=='-' ) && state==EXPECTEXP ){ expsigncount=1; state=EXPECTEND; continue; } if( WSP( chr ) || CR( chr ) || LF( chr ) ){ atend=1; continue; } if( chr==',' && state!=EXPECTDIGITBEFOREEXP && state!=EXPECTEXP && state!=EXPECTDIGIT ){ //return CBSUCCESS; return CBSUCCESSJSONNUMBER; // 22.8.2016 } if( chr==']' && state!=EXPECTDIGITBEFOREEXP && state!=EXPECTEXP && state!=EXPECTDIGIT ){ //return CBSUCCESS; return CBSUCCESSJSONNUMBER; // 22.8.2016 } return CBNOTJSONNUMBER; }else{ if( ! WSP( chr ) && ! CR( chr ) && ! LF( chr ) && chr!=']' && chr!=',' ) return CBNOTJSONNUMBER; } } //return CBSUCCESS; return CBSUCCESSJSONNUMBER; // 22.8.2016 }
/* * Function reading the white spaces away from the end. * * *from is the current character index. * If *from is not used, cb_compare compares witn -2 the first names length * and *from is updated with the name length. */ int cb_check_json_value( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ int err = CBSUCCESS, wsperr = CBSUCCESS; // 22.8.2016 unsigned long int chr=0x20; if( from==NULL || cfg==NULL || *cfg==NULL || ucsvalue==NULL || *ucsvalue==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_value: ucsvalue was null."); return CBERRALLOC; } err = cb_check_json_value_subfunction( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); /* * Length. */ if(*from>ucsvaluelen){ return CBINDEXOUTOFBOUNDS; }else if(*from<ucsvaluelen){ /* * Last ',' and ']' check missing 10.11.2015 */ /* * Read away white spaces. */ while( *from<ucsvaluelen && ucsvaluelen>0 && *from>0 && *from<CBNAMEBUFLEN && err<CBNEGATION && wsperr<CBNEGATION && \ ( WSP( chr ) || CR( chr ) || LF( chr ) ) ){ wsperr = cb_get_ucs_chr( &chr, &(*ucsvalue), &(*from), ucsvaluelen); //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value: read away white spaces chr [%c]", (char) chr ); } //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value: FROM: %i, UCSVALUELEN: %i, ERR: %i.", *from, ucsvaluelen, err ); if( *from<=ucsvaluelen && err<CBNEGATION ){ // 23.4.2016 //return CBSUCCESS; return err; // 22.8.2016 } }else if( *from==ucsvaluelen ) return err; // 22.8.2016 //return CBSUCCESS; return CBNOTJSONVALUE; }
/* To be used with arrays and objects. */ int cb_check_json_substring( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ if( from==NULL || cfg==NULL || *cfg==NULL || ucsvalue==NULL || *ucsvalue==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_null: ucsvalue was null."); return CBERRALLOC; } int indx=0, err=CBSUCCESS; unsigned long int chr=0x20, chprev=0x20; // chprev is WSP character char quotecount=0; /* * Read until the second quote and pass the value to cb_check_json_string. */ indx = *from; while( indx<ucsvaluelen && indx<CBNAMEBUFLEN && err<CBNEGATION ){ if( chr=='\\' && chprev=='\\' ) chprev = 0x20; // any not bypass else chprev = chr; err = cb_get_ucs_chr( &chr, &(*ucsvalue), &indx, ucsvaluelen); // comment out the next: if(err>=CBERROR){ cb_clog( CBLOGERR, err, "\ncb_check_json_substring: cb_get_ucs_chr, error %i.", err ); } //cb_clog( CBLOGDEBUG, CBNEGATION, "\n\tcb_check_json_substring: [%c]", (char) chr ); if( (unsigned char) chr=='"' && (unsigned char) chprev!='\\' && quotecount>=1 ) ++quotecount; if( quotecount>=2 ){ return cb_check_json_string_content( &(*ucsvalue), indx, &(*from), (**cfg).cf.jsonremovebypassfromcontent ); // updates *from } if( quotecount==0 ){ if( (unsigned char) chr=='"' && ( ! WSP( chprev ) && ! CR( chprev ) && ! LF( chprev ) && chprev!=',' ) ){ *from = indx; return CBNOTJSONSTRING; }else if( (unsigned char) chr=='"' && (unsigned char) chprev!='\\' ){ ++quotecount; } } } *from = indx; return CBNOTJSONSTRING; }
int FetchReqBody(const struct sess *sp) { unsigned long content_length; char buf[8192]; char *ptr, *endp; int rdcnt; if (http_GetHdr(sp->req->http, H_Content_Length, &ptr)) { content_length = strtoul(ptr, &endp, 10); /* XXX should check result of conversion */ while (content_length) { if (content_length > sizeof buf) rdcnt = sizeof buf; else rdcnt = content_length; rdcnt = HTC_Read(sp->wrk, sp->req->htc, buf, rdcnt); if (rdcnt <= 0) return (1); content_length -= rdcnt; if (!sp->req->sendbody) continue; (void)WRW_Write(sp->wrk, buf, rdcnt); /* XXX: stats ? */ if (WRW_Flush(sp->wrk)) return (2); } } if (http_GetHdr(sp->req->http, H_Transfer_Encoding, NULL)) { /* XXX: Handle chunked encoding. */ WSP(sp, SLT_Debug, "Transfer-Encoding in request"); return (1); } return (0); }
static void vep_error(const struct vep_state *vep, const char *p) { intmax_t l; VSC_C_main->esi_errors++; l = (intmax_t)(vep->ver_p - vep->hack_p); WSP(vep->sp, SLT_ESI_xmlerror, "ERR at %jd %s", l, p); }
vfp_nop_begin(struct sess *sp, size_t estimate) { if (fetchfrag > 0) { estimate = fetchfrag; WSP(sp, SLT_Debug, "Fetch %d byte segments:", fetchfrag); } if (estimate > 0) (void)FetchStorage(sp, estimate); }
vmod_log(struct sess *sp, const char *fmt, ...) { char buf[8192], *p; va_list ap; va_start(ap, fmt); p = VRT_StringList(buf, sizeof buf, fmt, ap); va_end(ap); if (p != NULL) WSP(sp, SLT_VCL_Log, "%s", buf); }
static void vep_warn(const struct vep_state *vep, const char *p) { intmax_t l; VSC_C_main->esi_warnings++; l = (intmax_t)(vep->ver_p - vep->hack_p); printf("WARNING at %jd %s\n", l, p); WSP(vep->sp, SLT_ESI_xmlerror, "WARN at %jd %s", l, p); }
void VRT_count(const struct sess *sp, unsigned u) { if (sp == NULL) return; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); if (cache_param->vcl_trace) WSP(sp, SLT_VCL_trace, "%u %u.%u", u, sp->vcl->ref[u].line, sp->vcl->ref[u].pos); }
/* * The only function reading white spaces away from the beginning. */ int cb_check_json_value_subfunction( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ int err=CBSUCCESS; unsigned long int chr=0x20; char atstart=1; unsigned char *chrposition = NULL; if( from==NULL || cfg==NULL || *cfg==NULL || ucsvalue==NULL || *ucsvalue==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_value_subfunction: ucsvalue was null."); return CBERRALLOC; } //cb_clog( CBLOGDEBUG, CBNEGATION, "\n\ncb_check_json_value_subfunction: attribute ["); //cb_print_ucs_chrbuf( CBLOGEMERG, &(*ucsvalue), ucsvaluelen, ucsvaluelen ); //cb_clog( CBLOGDEBUG, CBNEGATION, "], length %i, from %i.", ucsvaluelen, *from); while( *from<ucsvaluelen && *from<CBNAMEBUFLEN && err<CBNEGATION ){ chrposition = &(*ucsvalue)[*from]; err = cb_get_ucs_chr( &chr, &(*ucsvalue), &(*from), ucsvaluelen); if(err>=CBERROR){ cb_clog(CBLOGDEBUG, err, "\ncb_check_json_value_subfunction: cb_get_ucs_chr, error %i.", err ); return err; } //cb_clog(CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: chr [%c].", (char) chr ); if( atstart==1 && ( WSP( chr ) || CR( chr ) || LF( chr ) ) ) continue; atstart=0; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: [%c]", (char) chr ); switch( (unsigned char) chr ){ case '"': *from -= 4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_substring()." ); return cb_check_json_substring( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); // ok case '[': *from -= 4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_array()." ); return cb_check_json_array( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); // ok case '{': *from -= 4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_object()." ); return cb_check_json_object( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); // ok, 12.11.2015 case 't': if(*from>0) *from-=4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_true()." ); return cb_check_json_true( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); case 'n': if(*from>0) *from-=4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_null()." ); return cb_check_json_null( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); case 'f': if(*from>0) *from-=4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_false()." ); return cb_check_json_false( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); default: if(*from>0) *from-=4; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cb_check_json_number()." ); return cb_check_json_number( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); } } //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_value_subfunction: return cbnotjsonvalue." ); return CBNOTJSONVALUE; }
static void cnt_diag(struct sess *sp, const char *state) { if (sp->wrk != NULL) { WSP(sp, SLT_Debug, "thr %p STP_%s sp %p obj %p vcl %p", pthread_self(), state, sp, sp->wrk->obj, sp->vcl); WSL_Flush(sp->wrk, 0); } else { VSL(SLT_Debug, sp->vsl_id, "thr %p STP_%s sp %p obj %p vcl %p", pthread_self(), state, sp, sp->wrk->obj, sp->vcl); } }
static enum pipe_status pie_recv_frombackend(struct pipe *dp) { struct sess *sp; struct vbe_conn *vc; int i; CAST_OBJ_NOTNULL(sp, dp->sess, SESS_MAGIC); CAST_OBJ_NOTNULL(vc, sp->vc, VBE_CONN_MAGIC); i = CFD_read(&vc->fds, dp->buf[1], dp->bufsize); if (i == -2) { SEPTUM_PIPEEVENT(dp, vc->vc_fd, vc->vc_want, CALLOUT_SECTOTICKS(params->pipe_timeout)); return (PIPE_WAIT); } if (i <= 0) { if (i == -1) WSP(sp, SLT_Error, "%s: read(2) %d %s", __func__, errno, strerror(errno)); else WSP(sp, SLT_Error, "%s: read(2) eof", __func__); dp->flags |= PIPE_F_PIPEDONE; if ((dp->flags & PIPE_F_SESSDONE) != 0) { dp->step = PIE_END; return (PIPE_CONTINUE); } (void)shutdown(vc->vc_fd, SHUT_RD); /* XXX */ (void)shutdown(sp->sp_fd, SHUT_WR); /* XXX */ dp->step = PIE_END; return (PIPE_CONTINUE); } assert(i > 0); dp->buflen[1] = i; dp->t_updated = TIM_real(); dp->step = PIE_SEND; return (PIPE_CONTINUE); }
static int fetch_eof(struct sess *sp, struct http_conn *htc) { int i; assert(sp->wrk->body_status == BS_EOF); sp->wrk->vfp->begin(sp, 0); i = sp->wrk->vfp->bytes(sp, htc, SSIZE_MAX); if (i < 0) { WSP(sp, SLT_FetchError, "eof read_error: %d (%s)", errno, htc->error); return (-1); } return (0); }
static int fetch_straight(struct sess *sp, struct http_conn *htc, const char *b) { int i; ssize_t cl; assert(sp->wrk->body_status == BS_LENGTH); cl = fetch_number(b, 10); sp->wrk->vfp->begin(sp, cl > 0 ? cl : 0); if (cl < 0) { WSP(sp, SLT_FetchError, "straight length field bogus"); return (-1); } else if (cl == 0) return (0); i = sp->wrk->vfp->bytes(sp, htc, cl); if (i <= 0) { WSP(sp, SLT_FetchError, "straight read_error: %d %d (%s)", i, errno, htc->error); return (-1); } return (0); }
void HSH_AddString(const struct sess *sp, const char *str) { int l; if (str == NULL) str = ""; l = strlen(str); SHA256_Update(sp->wrk->sha256ctx, str, l); SHA256_Update(sp->wrk->sha256ctx, "#", 1); if (cache_param->log_hash) WSP(sp, SLT_Hash, "%s", str); }
int VRT_re_match(const struct sess *sp, const char *s, void *re) { vre_t *t; int i; if (s == NULL) s = ""; AN(re); t = re; i = VRE_exec(t, s, strlen(s), 0, 0, NULL, 0, ¶ms->vre_limits); if (i >= 0) return (1); if (i < VRE_ERROR_NOMATCH ) WSP(sp, SLT_VCL_Error, "Regexp matching returned %d", i); return (0); }
static int cnt_wait(struct sess *sp) { int i; struct pollfd pfd[1]; struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk = sp->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(sp->vcl); AZ(wrk->obj); AZ(sp->esi_level); assert(sp->xid == 0); i = HTC_Complete(sp->htc); if (i == 0 && cache_param->session_linger > 0) { pfd[0].fd = sp->fd; pfd[0].events = POLLIN; pfd[0].revents = 0; i = poll(pfd, 1, cache_param->session_linger); if (i) i = HTC_Rx(sp->htc); } if (i == 0) { WSP(sp, SLT_Debug, "herding"); wrk->stats.sess_herd++; SES_Charge(sp); Pool_Wait(sp); return (1); } if (i == 1) { sp->step = STP_START; return (0); } if (i == -2) { SES_Close(sp, "overflow"); } else if (i == -1 && Tlen(sp->htc->rxbuf) == 0 && (errno == 0 || errno == ECONNRESET)) SES_Close(sp, "EOF"); else SES_Close(sp, "error"); sp->step = STP_DONE; return (0); }
int cb_check_json_array( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ int err=CBSUCCESS; unsigned long int chr = 0x20; if( cfg==NULL || *cfg==NULL || ucsvalue==NULL || *ucsvalue==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_array: ucsvalue was null."); return CBERRALLOC; } err = cb_get_ucs_chr( &chr, &(*ucsvalue), &(*from), ucsvaluelen); //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: first chr from *from %i is [%c], err %i", (*from-4), (char) chr, err ); if(err>=CBERROR){ cb_clog( CBLOGDEBUG, err, "\ncb_check_json_array: cb_get_ucs_chr, error %i.", err ); return err; } if( (unsigned char) chr == '[' ){ cb_check_json_array_value: /* * First value. */ //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: to cb_check_json_value_subfunction, *from %i.", *from ); err = cb_check_json_value_subfunction( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); if(err>=CBERROR){ cb_clog( CBLOGDEBUG, err, "\ncb_check_json_array: cb_check_json_value_subfunction, error %i.", err ); return err; } //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: after cb_check_json_value_subfunction, %i.", err ); if(err>=CBNEGATION) return err; /* * Read comma or closing bracket. */ while( *from<ucsvaluelen && *from<CBNAMEBUFLEN && err<CBNEGATION ){ err = cb_get_ucs_chr( &chr, &(*ucsvalue), &(*from), ucsvaluelen); if(err>=CBERROR){ cb_clog( CBLOGDEBUG, err, "\ncb_check_json_array: cb_get_ucs_chr, error %i.", err ); return err; } //cb_clog( CBLOGDEBUG, CBNEGATION, "[ chr: %c indx: %i len: %i]", (char) chr, *from, ucsvaluelen ); if( WSP( chr ) || CR( chr ) || LF( chr ) ){ continue; }else if( (unsigned char) chr==']' ){ //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: bracket, CBSUCCESS." ); //return CBSUCCESS; // 10.11.2015 return CBSUCCESSJSONARRAY; // 10.11.2015, 22.8.2016 }else if( (unsigned char) chr==',' ){ //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: comma, next value." ); goto cb_check_json_array_value; }else return CBNOTJSONARRAY; } }else{ //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_array: first char was [%c], NOTJSON.", (char) chr ); return CBNOTJSONARRAY; } return err; }
void VRT_SetHdr(const struct sess *sp , enum gethdr_e where, const char *hdr, const char *p, ...) { struct http *hp; va_list ap; char *b; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); hp = vrt_selecthttp(sp, where); va_start(ap, p); if (p == NULL) { http_Unset(hp, hdr); } else { b = VRT_String(hp->ws, hdr + 1, p, ap); if (b == NULL) { WSP(sp, SLT_LostHeader, "%s", hdr + 1); } else { http_Unset(hp, hdr); http_SetHeader(sp->wrk, sp->vsl_id, hp, b); } } va_end(ap); }
const char * VRT_regsub(const struct sess *sp, int all, const char *str, void *re, const char *sub) { int ovector[30]; vre_t *t; int i, l; txt res; char *b0; const char *s; unsigned u, x; AN(re); if (str == NULL) str = ""; t = re; memset(ovector, 0, sizeof(ovector)); i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30, ¶ms->vre_limits); /* If it didn't match, we can return the original string */ if (i == VRE_ERROR_NOMATCH) return(str); if (i < VRE_ERROR_NOMATCH ) { WSP(sp, SLT_VCL_Error, "Regexp matching returned %d", i); return(str); } u = WS_Reserve(sp->http->ws, 0); res.e = res.b = b0 = sp->http->ws->f; res.e += u; do { /* Copy prefix to match */ Tadd(&res, str, ovector[0]); for (s = sub ; *s != '\0'; s++ ) { if (*s != '\\' || s[1] == '\0') { if (res.b < res.e) *res.b++ = *s; continue; } s++; if (isdigit(*s)) { x = *s - '0'; l = ovector[2*x+1] - ovector[2*x]; Tadd(&res, str + ovector[2*x], l); continue; } else { if (res.b < res.e) *res.b++ = *s; } } str += ovector[1]; if (!all) break; memset(&ovector, 0, sizeof(ovector)); i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30, ¶ms->vre_limits); if (i < VRE_ERROR_NOMATCH ) { WSP(sp, SLT_VCL_Error, "Regexp matching returned %d", i); return(str); } } while (i != VRE_ERROR_NOMATCH); /* Copy suffix to match */ l = strlen(str) + 1; Tadd(&res, str, l); if (res.b >= res.e) { WS_Release(sp->http->ws, 0); return (str); } Tcheck(res); WS_ReleaseP(sp->http->ws, res.b); return (b0); }
void VRT_acl_log(const struct sess *sp, const char *msg) { WSP(sp, SLT_VCL_acl, "%s", msg); }
int main (int argc, char **argv) { int i=-1, u=0, atoms=0, fromend=0, err=CBSUCCESS; unsigned int namearraylen=0, y=0; int bufsize=BUFSIZE, blksize=BLKSIZE, namelen=0, namebuflen=0, count=1, co=0; char list=0, inputenc=CBENC1BYTE, tree=0, uniquenamesandleaves=0; char *str_err, *value, *namearray = NULL; CBFILE *in = NULL; unsigned char *name = NULL; unsigned int chr = ' ', chprev = ' '; unsigned long int endchr = ENDCHR; /* fprintf(stderr,"main: argc=%i", argc ); for(u=0;u<argc;++u) fprintf( stderr,", argv[%i]=%s", u, argv[u] ); fprintf( stderr,".\n" ); */ // Last parameter was null (FreeBSD) atoms=argc; if(argv[(atoms-1)]==NULL && argc>0) --atoms; // Parameters if ( atoms < 2 ){ // no fields usage(&argv[0]); exit(ERRUSAGE); } // // From end fromend = atoms-1; /* * Name */ if ( atoms >= 2 ){ namelen = (int) strlen( argv[fromend] ); namebuflen = NAMEBUFLEN; // 4 * namelen; name = (unsigned char *) malloc( sizeof(unsigned char)*( (unsigned int) namebuflen + 1 ) ); if(name==NULL){ fprintf(stderr,"\nerror in malloc, name was null"); exit(CBERRALLOC); } name[ namelen*4 ] = '\0'; u = 0; for(i=0; i<namelen && u<namebuflen; ++i){ chr = (unsigned long int) argv[fromend][i]; chr = chr & 0x000000FF; err = cb_put_ucs_chr( chr, &name, &u, namebuflen); } if( namebuflen > u ) name[ u ] = '\0'; if(err!=CBSUCCESS){ fprintf(stderr,"\ncbsearch: cb_put_ucs_chr, err=%i.", err); } if( namebuflen>(namelen*4) ) name[ namelen*4 ] = '\0'; }else{ usage(&argv[0]); // not enough parameters exit(ERRUSAGE); } #ifdef DEBUG fprintf(stderr,"\nDebug: name (namelen:%i, namebuflen:%i):", namelen, namebuflen); cb_print_ucs_chrbuf( CBLOGDEBUG, &name, (namelen*4), namebuflen); //fprintf(stderr,"\nDebug: argv[fromend]: %s", argv[fromend]); #endif // Allocate buffer err = cb_allocate_cbfile( &in, 0, bufsize, blksize); if(err>=CBERROR){ fprintf(stderr, "error at cb_allocate_cbfile: %i.", err); } cb_set_to_consecutive_names(&in); //cb_use_as_stream(&in); // BEFORE TEST 11.8.2015 cb_use_as_file(&in); // TEST 11.8.2015 //cb_use_as_seekable_file(&in); // namelist is endless, memory increases cb_set_encoding(&in, CBENC1BYTE); cb_set_search_state(&in, CBSTATETREE); (*in).cf.stopatheaderend=0; (*in).cf.stopatmessageend=0; // 26.3.2016 (*in).cf.leadnames=1; //(*in).cf.leadnames=0; /* * Rest of the fields in between start ( ./progname ) and end ( <name> ) */ for(i=1 ; i<fromend ; ++i){ u = get_option( argv[i], argv[i+1], 'c', &value); // count if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ count = (int) strtol(value,&str_err,10); if(count==0 && errno==EINVAL) count = 1; continue; } u = get_option( argv[i], argv[i+1], 'x', &value); // regular expression search if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE || u == GETOPTSUCCESSNOVALUE){ tree = -10; continue; } u = get_option( argv[i], argv[i+1], 'u', &value); // unique names if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE || u == GETOPTSUCCESSNOVALUE){ uniquenamesandleaves=1; continue; } u = get_option( argv[i], argv[i+1], 'b', &value); // buffer size if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ bufsize = (int) strtol(value,&str_err,10); if(bufsize==0 && errno==EINVAL) bufsize = BUFSIZE; continue; } u = get_option( argv[i], argv[i+1], 'l', &value); // block size if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ blksize = (int) strtol(value,&str_err,10); if(blksize==0 && errno==EINVAL) blksize = BLKSIZE; continue; } u = get_option( argv[i], argv[i+1], 'i', &value); // input encoding number ( from cb_encoding.h ) if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ inputenc = (char) strtol(value,&str_err,10); if(inputenc==0 && errno==EINVAL) inputenc = CBENC1BYTE; cb_set_encoding(&in, inputenc); continue; } u = get_option( argv[i], argv[i+1], 'z', &value); // set double delimiters and configuration file options if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ tree = 1; cb_set_to_conf( &in ); continue; } u = get_option( argv[i], argv[i+1], 't', &value); // traverse the dotted (or primary key-) tree with cb_tree_set_cursor_ucs if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ tree = 1; continue; } u = get_option( argv[i], argv[i+1], 'J', &value); // use JSON if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ tree = 1; cb_set_to_json( &in ); continue; } u = get_option( argv[i], argv[i+1], 'e', &value); // end character if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ if(value!=NULL){ endchr = (unsigned long int) strtol(value,&str_err,16); fprintf(stderr, "\nAfter get_option, value=%s endchr=0x%.6lX.", value, endchr); err = CBSUCCESS; if( ! ( endchr==0 && errno==EINVAL ) ) err = cb_set_rend( &in, endchr); if( err>=CBERROR ){ fprintf(stderr,"\nError ar cb_set_rend, %i.", err); } }else{ err = cb_set_rend( &in, endchr); // set to new line, 0x0A if( err>=CBERROR ){ fprintf(stderr,"\nError ar cb_set_rend, %i.", err); } } continue; } u = get_option( argv[i], argv[i+1], 's', &namearray); // list of names if( u == GETOPTSUCCESS || u == GETOPTSUCCESSATTACHED || u == GETOPTSUCCESSPOSSIBLEVALUE ){ list=1; if(namearray!=NULL) err = CBSUCCESS; else err = CBERRALLOC; continue; } } #ifdef DEBUG // Debug if( name!=NULL ) fprintf(stderr,"\nDebug: Searching ["); cb_print_ucs_chrbuf(CBLOGDEBUG, &name, (namelen*4), namebuflen); if(in!=NULL) fprintf(stderr,"] count [%i] buffer size [%i] block size [%i] encoding [%i]", count, bufsize, blksize, inputenc ); if(in!=NULL) fprintf(stderr," value end [0x%.6lX]", (*in).cf.rend); fprintf(stderr,"\n"); #endif if( uniquenamesandleaves==1 ){ cb_set_to_unique_names(&in); cb_set_to_unique_leaves(&in); } // Program co = count; if(count==-1) co = 10; for(i=0; i<co && err<=CBERROR; ++i){ if(count==-1) i = 0; fprintf(stderr,"\n%i.", (i+1) ); if( list==0 ) // one name err = search_and_print_name(&in, &name, (namelen*4), tree ); else{ // list of names if(namearray!=NULL){ memset( &(*name), (int) 0x20, (unsigned int) namebuflen ); namearraylen = (unsigned int) strnlen( &(*namearray), (unsigned int) namebuflen ); u = 0; chprev = (unsigned long int) 0x0A; namelen=0; for(y=0; y<namearraylen && y<10000; ++y ){ // (if first char in name is sp, possibly prints "null name") chprev = chr; chr = (unsigned long int) namearray[y]; chr = chr & 0x000000FF; if( ! WSP( chr ) ){ err = cb_put_ucs_chr( chr, &name, &u, namebuflen); namelen = u; } if( ( WSP( chr ) && ! WSP( chprev ) && namelen>0 ) || y==(namearraylen-1) || chr=='\0' ){ name[ namelen*4 ] = '\0'; // error here, null is at wrong place 16.7.2015 err = search_and_print_name(&in, &name, namelen, tree ); namelen = 0; u = 0; memset( &(*name), (int) 0x20, (unsigned int) namebuflen ); } } } } } // Debug: cb_print_names(&in, CBLOGDEBUG); memset( &(*name), (int) 0x20, (unsigned int) namebuflen ); name[namebuflen] = '\0'; cb_free_cbfile(&in); free( name ); exit( err ); }
static void parse_addr(char *s, size_t len, int is_from) { size_t pos = 0; int terminal = 0; /* unless this is a continuation... */ if (!WSP(s[pos]) && s[pos] != ',' && s[pos] != ';') { /* ... skip over everything before the ':' */ for (; pos < len && s[pos] != ':'; pos++) ; /* nothing */ /* ... and check & reset parser state */ parse_addr_terminal(is_from); } /* skip over ':' ',' ';' and whitespace */ for (; pos < len && !pstate.quote && (WSP(s[pos]) || s[pos] == ':' || s[pos] == ',' || s[pos] == ';'); pos++) ; /* nothing */ for (; pos < len; pos++) { if (!pstate.esc && !pstate.quote && s[pos] == '(') pstate.comment++; if (!pstate.comment && !pstate.esc && s[pos] == '"') pstate.quote = !pstate.quote; if (!pstate.comment && !pstate.quote && !pstate.esc) { if (s[pos] == ':') { /* group */ for(pos++; pos < len && WSP(s[pos]); pos++) ; /* nothing */ pstate.wpos = 0; } if (s[pos] == '\n' || s[pos] == '\r') break; if (s[pos] == ',' || s[pos] == ';') { terminal = 1; break; } if (s[pos] == '<') { pstate.brackets = 1; pstate.wpos = 0; } if (pstate.brackets && s[pos] == '>') terminal = 1; } if (!pstate.comment && !terminal && (!(!(pstate.quote || pstate.esc) && (s[pos] == '<' || WSP(s[pos]))))) { if (pstate.wpos >= sizeof(pstate.buf)) errx(1, "address exceeds buffer size"); pstate.buf[pstate.wpos++] = s[pos]; } if (!pstate.quote && pstate.comment && s[pos] == ')') pstate.comment--; if (!pstate.esc && !pstate.comment && !pstate.quote && s[pos] == '\\') pstate.esc = 1; else pstate.esc = 0; } if (terminal) parse_addr_terminal(is_from); for (; pos < len && (s[pos] == '\r' || s[pos] == '\n'); pos++) ; /* nothing */ if (pos < len) parse_addr(s + pos, len - pos, is_from); }
static int parse_message(FILE *fin, int get_from, int tflag, FILE *fout) { char *buf; size_t len; u_int i, cur = HDR_NONE; u_int header_seen = 0, header_done = 0; bzero(&pstate, sizeof(pstate)); for (;;) { buf = fgetln(fin, &len); if (buf == NULL && ferror(fin)) err(1, "fgetln"); if (buf == NULL && feof(fin)) break; if (buf == NULL || len < 1) err(1, "fgetln weird"); /* account for \r\n linebreaks */ if (len >= 2 && buf[len - 2] == '\r' && buf[len - 1] == '\n') buf[--len - 1] = '\n'; if (len == 1 && buf[0] == '\n') /* end of header */ header_done = 1; if (!WSP(buf[0])) { /* whitespace -> continuation */ if (cur == HDR_FROM) parse_addr_terminal(1); if (cur == HDR_TO || cur == HDR_CC || cur == HDR_BCC) parse_addr_terminal(0); cur = HDR_NONE; } /* not really exact, if we are still in headers */ if (len + (buf[len - 1] == '\n' ? 0 : 1) >= LINESPLIT) msg.need_linesplit = 1; for (i = 0; !header_done && cur == HDR_NONE && i < nitems(keywords); i++) if (len > strlen(keywords[i].word) && !strncasecmp(buf, keywords[i].word, strlen(keywords[i].word))) cur = keywords[i].type; if (cur != HDR_NONE) header_seen = 1; if (cur != HDR_BCC) { fprintf(fout, "%.*s", (int)len, buf); if (buf[len - 1] != '\n') fputc('\n', fout); if (ferror(fout)) err(1, "write error"); } /* * using From: as envelope sender is not sendmail compatible, * but I really want it that way - maybe needs a knob */ if (cur == HDR_FROM) { msg.saw_from++; if (get_from) parse_addr(buf, len, 1); } if (tflag && (cur == HDR_TO || cur == HDR_CC || cur == HDR_BCC)) parse_addr(buf, len, 0); if (cur == HDR_DATE) msg.saw_date++; if (cur == HDR_MSGID) msg.saw_msgid++; if (cur == HDR_MIME_VERSION) msg.saw_mime_version = 1; if (cur == HDR_CONTENT_TYPE) msg.saw_content_type = 1; if (cur == HDR_CONTENT_DISPOSITION) msg.saw_content_disposition = 1; if (cur == HDR_CONTENT_TRANSFER_ENCODING) msg.saw_content_transfer_encoding = 1; if (cur == HDR_USER_AGENT) msg.saw_user_agent = 1; } return (!header_seen); }
void VEP_parse(const struct sess *sp, const char *p, size_t l) { struct vep_state *vep; const char *e; struct vep_match *vm; int i; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); vep = sp->wrk->vep; CHECK_OBJ_NOTNULL(vep, VEP_MAGIC); assert(l > 0); /* XXX: Really need to fix this */ if (vep->hack_p == NULL) vep->hack_p = p; vep->ver_p = p; e = p + l; while (p < e) { AN(vep->state); i = e - p; if (i > 10) i = 10; Debug("EP %s %d (%.*s) [%.*s]\n", vep->state, vep->remove, vep->tag_i, vep->tag, i, p); assert(p >= vep->ver_p); /****************************************************** * SECTION A */ if (vep->state == VEP_START) { if (params->esi_syntax & 0x1) vep->state = VEP_NEXTTAG; else vep->state = VEP_TESTXML; } else if (vep->state == VEP_TESTXML) { /* * If the first non-whitespace char is different * from '<' we assume this is not XML. */ while (p < e && vct_islws(*p)) p++; vep_mark_verbatim(vep, p); if (p < e && *p == '<') { p++; vep->state = VEP_STARTTAG; } else if (p < e) { WSP(vep->sp, SLT_ESI_xmlerror, "No ESI processing, first char not '<'"); vep->state = VEP_NOTXML; } } else if (vep->state == VEP_NOTXML) { /* * This is not recognized as XML, just skip thru * vfp_esi_end() will handle the rest */ p = e; vep_mark_verbatim(vep, p); /****************************************************** * SECTION B */ } else if (vep->state == VEP_NOTMYTAG) { if (params->esi_syntax & 0x2) { p++; vep->state = VEP_NEXTTAG; } else { vep->tag_i = 0; while (p < e) { if (*p++ == '>') { vep->state = VEP_NEXTTAG; break; } } } if (p == e && !vep->remove) vep_mark_verbatim(vep, p); } else if (vep->state == VEP_NEXTTAG) { /* * Hunt for start of next tag and keep an eye * out for end of EsiCmt if armed. */ vep->emptytag = 0; vep->endtag = 0; vep->attr = NULL; vep->dostuff = NULL; while (p < e && *p != '<') { if (vep->esicmt_p == NULL) { p++; continue; } if (*p != *vep->esicmt_p) { p++; vep->esicmt_p = vep->esicmt; continue; } if (!vep->remove && vep->esicmt_p == vep->esicmt) vep_mark_verbatim(vep, p); p++; if (*++vep->esicmt_p == '\0') { vep->esi_found = 1; vep->esicmt = NULL; vep->esicmt_p = NULL; /* * The end of the esicmt * should not be emitted. * But the stuff before should */ vep_mark_skip(vep, p); } } if (p < e) { if (!vep->remove) vep_mark_verbatim(vep, p); assert(*p == '<'); p++; vep->state = VEP_STARTTAG; } else if (vep->esicmt_p == vep->esicmt && !vep->remove) vep_mark_verbatim(vep, p); /****************************************************** * SECTION C */ } else if (vep->state == VEP_STARTTAG) { /* * Start of tag, set up match table */ if (p < e) { if (*p == '/') { vep->endtag = 1; p++; } vep->match = vep_match_starttag; vep->state = VEP_MATCH; } } else if (vep->state == VEP_COMMENT) { /* * We are in a comment, find out if it is an * ESI comment or a regular comment */ if (vep->esicmt == NULL) vep->esicmt_p = vep->esicmt = "esi"; while (p < e) { if (*p != *vep->esicmt_p) { vep->esicmt_p = vep->esicmt = NULL; vep->until_p = vep->until = "-->"; vep->until_s = VEP_NEXTTAG; vep->state = VEP_UNTIL; vep_mark_verbatim(vep, p); break; } p++; if (*++vep->esicmt_p != '\0') continue; if (vep->remove) vep_error(vep, "ESI 1.0 Nested <!--esi" " element in <esi:remove>"); vep->esicmt_p = vep->esicmt = "-->"; vep->state = VEP_NEXTTAG; vep_mark_skip(vep, p); break; } } else if (vep->state == VEP_CDATA) { /* * Easy: just look for the end of CDATA */ vep->until_p = vep->until = "]]>"; vep->until_s = VEP_NEXTTAG; vep->state = VEP_UNTIL; } else if (vep->state == VEP_ESITAG) { vep->in_esi_tag = 1; vep->esi_found = 1; vep_mark_skip(vep, p); vep->match = vep_match_esi; vep->state = VEP_MATCH; } else if (vep->state == VEP_ESIINCLUDE) { if (vep->remove) { vep_error(vep, "ESI 1.0 <esi:include> element" " nested in <esi:remove>"); vep->state = VEP_TAGERROR; } else if (vep->endtag) { vep_error(vep, "ESI 1.0 </esi:include> illegal end-tag"); vep->state = VEP_TAGERROR; } else { vep->dostuff = vep_do_include; vep->state = VEP_INTAG; vep->attr = vep_match_attr_include; } } else if (vep->state == VEP_ESIREMOVE) { vep->dostuff = vep_do_remove; vep->state = VEP_INTAG; } else if (vep->state == VEP_ESICOMMENT) { if (vep->remove) { vep_error(vep, "ESI 1.0 <esi:comment> element" " nested in <esi:remove>"); vep->state = VEP_TAGERROR; } else if (vep->endtag) { vep_error(vep, "ESI 1.0 </esi:comment> illegal end-tag"); vep->state = VEP_TAGERROR; } else { vep->dostuff = vep_do_comment; vep->state = VEP_INTAG; } } else if (vep->state == VEP_ESIBOGON) { vep_error(vep, "ESI 1.0 <esi:bogus> element"); vep->state = VEP_TAGERROR; /****************************************************** * SECTION D */ } else if (vep->state == VEP_INTAG) { vep->tag_i = 0; while (p < e && vct_islws(*p) && !vep->emptytag) { p++; vep->canattr = 1; } if (p < e && *p == '/' && !vep->emptytag) { p++; vep->emptytag = 1; vep->canattr = 0; } if (p < e && *p == '>') { p++; AN(vep->dostuff); vep_mark_skip(vep, p); vep->dostuff(vep, DO_TAG); vep->in_esi_tag = 0; vep->state = VEP_NEXTTAG; } else if (p < e && vep->emptytag) { vep_error(vep, "XML 1.0 '>' does not follow '/' in tag"); vep->state = VEP_TAGERROR; } else if (p < e && vep->canattr && vct_isxmlnamestart(*p)) { vep->state = VEP_ATTR; } else if (p < e) { vep_error(vep, "XML 1.0 Illegal attribute tart char"); vep->state = VEP_TAGERROR; } } else if (vep->state == VEP_TAGERROR) { while (p < e && *p != '>') p++; if (p < e) { p++; vep_mark_skip(vep, p); vep->in_esi_tag = 0; vep->state = VEP_NEXTTAG; } /****************************************************** * SECTION E */ } else if (vep->state == VEP_ATTR) { AZ(vep->attr_delim); if (vep->attr == NULL) { p++; AZ(vep->attr_vsb); vep->state = VEP_SKIPATTR; } else { vep->match = vep->attr; vep->state = VEP_MATCH; } } else if (vep->state == VEP_SKIPATTR) { while (p < e && vct_isxmlname(*p)) p++; if (p < e && *p == '=') { p++; vep->state = VEP_ATTRDELIM; } else if (p < e && *p == '>') { vep->state = VEP_INTAG; } else if (p < e && *p == '/') { vep->state = VEP_INTAG; } else if (p < e && vct_issp(*p)) { vep->state = VEP_INTAG; } else if (p < e) { vep_error(vep, "XML 1.0 Illegal attr char"); vep->state = VEP_TAGERROR; } } else if (vep->state == VEP_ATTRGETVAL) { vep->attr_vsb = VSB_new_auto(); vep->state = VEP_ATTRDELIM; } else if (vep->state == VEP_ATTRDELIM) { AZ(vep->attr_delim); if (*p == '"' || *p == '\'') { vep->attr_delim = *p++; vep->state = VEP_ATTRVAL; } else if (!vct_issp(*p)) { vep->attr_delim = ' '; vep->state = VEP_ATTRVAL; } else { vep_error(vep, "XML 1.0 Illegal attribute delimiter"); vep->state = VEP_TAGERROR; } } else if (vep->state == VEP_ATTRVAL) { while (p < e && *p != '>' && *p != vep->attr_delim && (vep->attr_delim != ' ' || !vct_issp(*p))) { if (vep->attr_vsb != NULL) VSB_bcat(vep->attr_vsb, p, 1); p++; } if (p < e && *p == '>') { vep_error(vep, "XML 1.0 Missing end attribute delimiter"); vep->state = VEP_TAGERROR; vep->attr_delim = 0; if (vep->attr_vsb != NULL) { AZ(VSB_finish(vep->attr_vsb)); VSB_delete(vep->attr_vsb); vep->attr_vsb = NULL; } } else if (p < e) { vep->attr_delim = 0; p++; vep->state = VEP_INTAG; if (vep->attr_vsb != NULL) { AZ(VSB_finish(vep->attr_vsb)); AN(vep->dostuff); vep->dostuff(vep, DO_ATTR); vep->attr_vsb = NULL; } } /****************************************************** * Utility Section */ } else if (vep->state == VEP_MATCH) { /* * Match against a table */ vm = vep_match(vep, p, e); vep->match_hit = vm; if (vm != NULL) { if (vm->match != NULL) p += strlen(vm->match); vep->state = *vm->state; vep->match = NULL; vep->tag_i = 0; } else { memcpy(vep->tag, p, e - p); vep->tag_i = e - p; vep->state = VEP_MATCHBUF; p = e; } } else if (vep->state == VEP_MATCHBUF) { /* * Match against a table while split over input * sections. */ do { if (*p == '>') { for (vm = vep->match; vm->match != NULL; vm++) continue; AZ(vm->match); } else { vep->tag[vep->tag_i++] = *p++; vm = vep_match(vep, vep->tag, vep->tag + vep->tag_i); if (vm && vm->match == NULL) { vep->tag_i--; p--; } } } while (vm == NULL && p < e); vep->match_hit = vm; if (vm == NULL) { assert(p == e); } else { vep->state = *vm->state; vep->match = NULL; } } else if (vep->state == VEP_UNTIL) { /* * Skip until we see magic string */ while (p < e) { if (*p++ != *vep->until_p++) { vep->until_p = vep->until; } else if (*vep->until_p == '\0') { vep->state = vep->until_s; break; } } if (p == e && !vep->remove) vep_mark_verbatim(vep, p); } else { Debug("*** Unknown state %s\n", vep->state); INCOMPL(); } } /* * We must always mark up the storage we got, try to do so * in the most efficient way, in particular with respect to * minimizing and limiting use of pending. */ if (p == vep->ver_p) ; else if (vep->in_esi_tag) vep_mark_skip(vep, p); else if (vep->remove) vep_mark_skip(vep, p); else vep_mark_pending(vep, p); }
static int cnt_lookup(struct sess *sp) { struct objcore *oc; struct object *o; struct objhead *oh; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); if (sp->obj == NULL) { HSH_BeforeVclHash(sp, sp->vcl->nhashcount); VCL_hash_method(sp); assert(sp->handling == VCL_RET_HASH); HSH_AfterVclHash(sp); } oc = HSH_Lookup(sp, &oh); if (oc == NULL) { /* * We lost the session to a busy object, disembark the * worker thread. The hash code to restart the session, * still in STP_LOOKUP, later when the busy object isn't. */ return (1); } CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); /* If we inserted a new object it's a miss */ if (oc->flags & OC_F_BUSY) { VSL_stats->cache_miss++; AZ(oc->obj); sp->objhead = oh; sp->objcore = oc; sp->step = STP_MISS; return (0); } o = oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); sp->obj = o; if (oc->flags & OC_F_PASS) { VSL_stats->cache_hitpass++; WSP(sp, SLT_HitPass, "%u", sp->obj->xid); HSH_Deref(sp->wrk, &sp->obj); sp->objcore = NULL; sp->objhead = NULL; sp->step = STP_PASS; return (0); } VSL_stats->cache_hit++; WSP(sp, SLT_Hit, "%u", sp->obj->xid); sp->step = STP_HIT; return (0); }
int cb_check_json_object( CBFILE **cfg, unsigned char **ucsvalue, int ucsvaluelen, int *from ){ int openpairs=0, err=CBSUCCESS; unsigned long int chr=0x20; if( from==NULL || cfg==NULL || *cfg==NULL || ucsvalue==NULL || *ucsvalue==NULL ){ cb_clog( CBLOGDEBUG, CBERRALLOC, "\ncb_check_json_null: ucsvalue was null."); return CBERRALLOC; } char state=0; //cb_clog( CBLOGDEBUG, CBNEGATION, "\ncb_check_json_object:" ); while( *from<ucsvaluelen && *from<CBNAMEBUFLEN && err<CBNEGATION ){ err = cb_get_ucs_chr( &chr, &(*ucsvalue), &(*from), ucsvaluelen); //cb_clog( CBLOGDEBUG, CBNEGATION, "[%c]", (char) chr ); if( ( WSP( chr ) || CR( chr ) || LF( chr ) ) ){ continue; }else if( (unsigned char) chr == '{' && state!=EXPECTCOMMA && state!=EXPECTCOLON ){ /* * Read until '{'. */ ++openpairs; cb_check_json_object_read_name: /* * Reads name within the quotes and update *from. Quotes are bypassed. */ err = cb_check_json_substring( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); // comment out the next: if(err>=CBERROR){ cb_clog( CBLOGERR, err, "\ncb_check_json_object: cb_check_json_substring, error %i.", err ); } state = EXPECTCOLON; continue; }else if( state==EXPECTCOLON && (unsigned char) chr == ':' ){ /* * Read colon ':'. */ /* * Read Value. */ err = cb_check_json_value_subfunction( &(*cfg), &(*ucsvalue), ucsvaluelen, &(*from) ); // comment out the next: if(err>=CBERROR){ cb_clog( CBLOGERR, err, "\ncb_check_json_object: cb_check_json_value_subfunction, error %i.", err ); } state = EXPECTCOMMA; continue; }else if( ( state==EXPECTCOMMA || state==EXPECTCOMMAORNAME ) && ( (unsigned char) chr == ',' || (unsigned char) chr == '}' ) ){ /* * Read comma ',' or '}' . */ if( (unsigned char) chr == '}' ){ state = EXPECTCOMMAORNAME; --openpairs; }else{ /* * Read next name. */ goto cb_check_json_object_read_name; } continue; }else if( state==EXPECTCOMMAORNAME && (unsigned char) chr == '"' ){ *from-=4; goto cb_check_json_object_read_name; }else if( (unsigned char) chr == '}' ){ --openpairs; if( state!=EXPECTCOMMA ) err = CBNOTJSONOBJECT; state = 0; continue; }else err = CBNOTJSONOBJECT; } if(openpairs==0) return err; return CBNOTJSONOBJECT; }
struct vsb * VRY_Create(const struct sess *sp, const struct http *hp) { char *v, *p, *q, *h, *e; struct vsb *sb, *sbh; unsigned l; /* No Vary: header, no worries */ if (!http_GetHdr(hp, H_Vary, &v)) return (NULL); /* For vary matching string */ sb = VSB_new_auto(); AN(sb); /* For header matching strings */ sbh = VSB_new_auto(); AN(sbh); if (*v == ':') { WSP(sp, SLT_Error, "Vary header had extra ':', fix backend"); v++; } for (p = v; *p; p++) { /* Find next header-name */ if (vct_issp(*p)) continue; for (q = p; *q && !vct_issp(*q) && *q != ','; q++) continue; /* Build a header-matching string out of it */ VSB_clear(sbh); VSB_printf(sbh, "%c%.*s:%c", (char)(1 + (q - p)), (int)(q - p), p, 0); AZ(VSB_finish(sbh)); if (http_GetHdr(sp->http, VSB_data(sbh), &h)) { AZ(vct_issp(*h)); /* Trim trailing space */ e = strchr(h, '\0'); while (e > h && vct_issp(e[-1])) e--; /* Encode two byte length and contents */ l = e - h; assert(!(l & ~0xffff)); } else { e = h; l = 0xffff; } VSB_printf(sb, "%c%c", (int)(l >> 8), (int)(l & 0xff)); /* Append to vary matching string */ VSB_bcat(sb, VSB_data(sbh), VSB_len(sbh)); if (e != h) VSB_bcat(sb, h, e - h); while (vct_issp(*q)) q++; if (*q == '\0') break; xxxassert(*q == ','); p = q; } /* Terminate vary matching string */ VSB_printf(sb, "%c%c%c", 0xff, 0xff, 0); VSB_delete(sbh); AZ(VSB_finish(sb)); return(sb); }