Ejemplo n.º 1
0
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);
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
/*
 * 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;
}
Ejemplo n.º 5
0
/* 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;
}
Ejemplo n.º 6
0
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);

}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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);

}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
/*
 * 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;
}
Ejemplo n.º 13
0
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);
    }
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
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, &params->vre_limits);
	if (i >= 0)
		return (1);
	if (i < VRE_ERROR_NOMATCH )
		WSP(sp, SLT_VCL_Error, "Regexp matching returned %d", i);
	return (0);
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 20
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; 
}
Ejemplo n.º 21
0
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);
}
Ejemplo n.º 22
0
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,
	    &params->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,
		    &params->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);
}
Ejemplo n.º 23
0
void
VRT_acl_log(const struct sess *sp, const char *msg)
{

	WSP(sp, SLT_VCL_acl, "%s", msg);
}
Ejemplo n.º 24
0
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 );
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
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);
}