Beispiel #1
0
/*
 * Parse comma separated list of methods pointed by _body and assign their
 * enum bits to _methods.  Returns 0 on success and -1 on failure.
 */
int parse_methods(str* _body, unsigned int* _methods)
{
	str next;
	char *p;
	char *p0;
	unsigned int method;

	if (!_body || !_methods) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	next.len = _body->len;
	next.s = _body->s;

	trim_leading(&next);

	*_methods = 0;
	if (next.len == 0) {
		goto done;
	}

	method = 0;
	p = next.s;

	while (p<next.s+next.len) {
		if((p0=parse_method(p, next.s+next.len, &method))!=NULL) {
			*_methods |= method;
			p = p0;
		} else {
			LM_ERR("invalid method [%.*s]\n", next.len, next.s);
			return -1;
		}

		while(p<next.s+next.len && (*p==' ' || *p=='\t'
					|| *p=='\r' || *p=='\n'))
			p++;
		if(p>=next.s+next.len || *p == '\0')
			goto done;


		if (*p == ',')
		{
			p++;
			while(p<next.s+next.len && (*p==' ' || *p=='\t'
					|| *p=='\r' || *p=='\n'))
				p++;
			if(p>=next.s+next.len)
				goto done;
		} else {
			LM_ERR("comma expected\n");
			return -1;
		}
	}

done:
	LM_DBG("methods 0x%X\n", *_methods);
	return 0;
}
Beispiel #2
0
int send_leg_msg(struct dlg_cell *dlg,str *method,int src_leg,int dst_leg,
		str *hdrs,str *body,dlg_request_callback func,void *param,dlg_release_func release)
{
	context_p old_ctx;
	dlg_t* dialog_info;
	int result;
	unsigned int method_type;

	if (parse_method(method->s,method->s+method->len,&method_type) == 0)
	{
		LM_ERR("Failed to parse method - [%.*s]\n",method->len,method->s);
		return -1;
	}

	if (method_type == METHOD_INVITE && (body == NULL || body->s == NULL ||
				body->len == 0))
	{
		LM_ERR("Cannot send INVITE without SDP body\n");
		return -1;
	}

	if ((dialog_info = build_dialog_info(dlg, dst_leg, src_leg)) == 0)
	{
		LM_ERR("failed to create dlg_t\n");
		return -1;
	}

	LM_DBG("sending [%.*s] to %s (%d)\n",method->len,method->s,
		(dst_leg==DLG_CALLER_LEG)?"caller":"callee", dst_leg);

	/* set new processing context */
	if (push_new_processing_context( dlg, &old_ctx, NULL)!=0)
		return -1;

	dialog_info->T_flags=T_NO_AUTOACK_FLAG;

	result = d_tmb.t_request_within
		(method,         /* method*/
		hdrs,		    /* extra headers*/
		body,          /* body*/
		dialog_info,   /* dialog structure*/
		func,  /* callback function*/
		param,   /* callback parameter*/
		release);         /* release function*/

	/* reset the processing contect */
	current_processing_ctx = old_ctx;

	if(result < 0)
	{
		LM_ERR("failed to send the in-dialog request\n");
		free_tm_dlg(dialog_info);
		return -1;
	}

	free_tm_dlg(dialog_info);
	return 0;
}
Beispiel #3
0
char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
{
	char *t, *m, *m_end;
	
	cb->error=PARSE_ERROR;
	t=buf;
	
	cb->number.s=t;
	t=eat_token_end(t, end);
	if (t>=end) goto error;
	cb->number.len=t-cb->number.s;

	m=eat_space_end(t, end);
	m_end=eat_token_end(m, end);

	if (m_end>=end) {
			LM_ERR("method terminated unexpectedly\n");
			goto error;
	}
	if (m_end==m){
		/* null method*/
		LM_ERR("no method found\n");
		goto error;
	}
	cb->method.s=m;
	t=m_end;
	cb->method.len=t-cb->method.s;
	
	/* cache the method id */
	if(parse_method(cb->method.s, t, (unsigned int*)&cb->method_id)==0)
	{
		LM_ERR("cannot parse the method\n");
		goto error;
	}
	
	/* there may be trailing LWS 
	 * (it was not my idea to put it in SIP; -jiri )
	 */
	t=eat_lws_end(t, end);
	/*check if the header ends here*/
	if (t>=end) {
		LM_ERR("strange EoHF\n");
		goto error;
	}
	if (*t=='\r' && t+1<end && *(t+1)=='\n') {
			cb->error=PARSE_OK;
			return t+2;
	}
	if (*t=='\n') {
			cb->error=PARSE_OK;
			return t+1;
	}
	LM_ERR("expecting CSeq EoL\n");

error:
	LM_ERR("bad cseq\n");
	return t;
}
Beispiel #4
0
static bool parse_request_line(Iterator& it, Request& request)
{
    bool ret = true;
    ret = ret && parse_method(it, request);
    ret = ret && parse_uri(it, request);
    ret = ret && parse_http_version(it, request);
    ret = ret && expect(it, HTTP_DELIMITER);
    return ret;
}
Beispiel #5
0
void
send_response()
{
	str host = parse_host(client.request,find_header(client.request->headers,_("Host")));
	str method = parse_method(client.request);
	begin_response();
	client.response->status = host && method ? dispatch_method(method) : error_handler(400);
	end_response();
	disconnect();
}
Beispiel #6
0
 /* 
  * Parse comma separated list of methods pointed by _body and assign their
  * enum bits to _methods.  Returns 1 on success and 0 on failure.
  */
 int parse_methods(str* _body, unsigned int* _methods)
 {
 	str next;
 	unsigned int method;
	
	method=0; /* fixes silly gcc 4.x warning */
 
	if (!_body || !_methods) {
		LOG(L_ERR, "parse_methods: Invalid parameter value\n");
		return 0;
	}

	next.len = _body->len;
	next.s = _body->s;
 
 	trim_leading(&next);
 
 	if (next.len == 0) {
 		LOG(L_ERR, "ERROR: parse_methods: Empty body\n");
 		return 0;
 	}

  	*_methods = 0;
 
 	while (1) {
 		if (parse_method(&next, &method)) {
 			*_methods |= method;
 		} else {
 			LOG(L_ERR, "ERROR: parse_methods: Invalid method\n");
 			return 0;
 		}
		
 		trim_leading(&next);
 		if (next.len) {
 			if (next.s[0] == ',') {
 				next.len--;
 				next.s++;
 				trim_leading(&next);
 				if (next.len == 0) {
 					LOG(L_ERR, "ERROR: parse_methods: Method expected\n");
 					return 0;
 				}
 			} else {
 				LOG(L_ERR, "ERROR: parse_methods: Comma expected\n");
 				return 0;
 			}
 		} else {
 			break;
 		}
 	}

 	return 1;
 }
Beispiel #7
0
// Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
const char* parse_request_line(unsigned char** p)
{
	if (parse_method(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_request_uri(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_http_version(p))
		return ERR;
	return parse_crlf(p);
}
Beispiel #8
0
void ProguardMap::parse_line(const std::string& line) {
  if (parse_class(line)) {
    return;
  }
  if (parse_field(line)) {
    return;
  }
  if (parse_method(line)) {
    return;
  }
  always_assert_log(false,
                    "Bogus line encountered in proguard map: %s\n",
                    line.c_str());
}
Beispiel #9
0
http_request_t *parse_http_request(http_parser_t *parser, const char *data, size_t len)
{
    if (!parser || !data || !len)
        return NULL;

    parser->data = data;
    parser->len = len;

    parser->parse_ptr = (char*)data;

    parse_method(parser);
    parse_char(parser, ' ');
    parse_absolute_path(parser);
    parse_params(parser);
    parse_char(parser, ' ');
    parse_http_version(parser);
    parse_crlf(parser);
    while (parse_message_header(parser) == 0)
        ;

    return &parser->req;
}
Beispiel #10
0
// Parse message populating fields and return Method
Method Parser::parse(char* buffer, int buffer_size) {
    data.clear();
    tokenize(buffer, buffer_size);
    Errcode errcode = parse_method(_lines[0]);
    for (unsigned int line = 1; line < _lines.size(); ++line) {
        Errcode ec = parse_field(_lines[line]);
        // We always throw the first error we find
        if (errcode == OK)
            errcode = ec;
    }
    switch (_state) {
        case INIT:      if (data.method == SETUP)    _state = READY;     
                   else if (data.method == PLAY)     throw METHOD_NOT_VALID_IN_THIS_STATE;
                        break;
        case READY:     if (data.method == PLAY)     _state = PLAYING;
                   else if (data.method == TEARDOWN) _state = INIT;      break;
        case PLAYING:   if (data.method == TEARDOWN) _state = INIT;      break;
    }
    if (errcode != OK)
        throw errcode;
    return data.method;
}
Beispiel #11
0
static int
parse_icap_startline(char *line,struct pollfd_state *pfd,icap_status *istat){
	icap_state *is = get_pfd_icap(pfd);
	const char *method;

	is->method = parse_method(&line);
	if(is->method == ICAP_METHOD_COUNT){
		*istat = ICAPSTATUS_METHOD_NOT_IMPLEMENTED;
		return -1;
	}
	if((method = name_icap_method(is->method)) == NULL){
		bitch("Couldn't stringize method %d\n",is->method);
		*istat = ICAPSTATUS_INTERNAL_ERROR;
		return -1;
	}
	// nag("Valid method: %s\n",method);
	inc_method_begun(is->method);
	if((is->icapuri = extract_uri(ICAP_URI_SCHEME,&line)) == NULL){
		*istat = ICAPSTATUS_BAD_REQUEST;
		return -1;
	}
	if(verify_icap_uri(is->icapuri,is)){
		bitch("Bad URI for %s\n",method);
		free_uri(&is->icapuri);
		*istat = ICAPSTATUS_METHOD_BAD_SERVICE;
		return -1;
	}
	if(parse_icap_version(&line)){
		*istat = ICAPSTATUS_VERSION_NOT_SUPPORTED;
		return -1;
	}
	if(strcmp(line,CRLF)){
		bitch("Excess data after ICAP version (%zu/%zu)\n",
				strlen(line),__builtin_strlen(CRLF));
		*istat = ICAPSTATUS_BAD_REQUEST;
		return -1;
	}
	return 0;
}
Beispiel #12
0
/* `struct` , `table`, or 'rpc_service' must already be matched. */
static void parse_compound_type(fb_parser_t *P, fb_compound_type_t *ct, long token)
{
    fb_token_t *t = 0;

    if (!(t = match(P, LEX_TOK_ID, "Declaration expected an identifier"))) {
        goto fail;
    }
    ct->symbol.ident = t;
    ct->metadata = parse_metadata(P);
    if (!(match(P, '{', "Declaration expected '{'"))) {
        goto fail;
    }
    t = P->token;

/* Allow empty tables and structs. */
#if 0
    if (P->token->id == '}') {
        error_tok(P, t, "table / struct declaration cannot be empty");
    }
#endif
    while (P->token->id != '}') {
        if (token == tok_kw_rpc_service) {
            parse_method(P, fb_add_member(P, &ct->members));
        } else {
            parse_field(P, fb_add_member(P, &ct->members));
        }
        if (P->failed >= FLATCC_MAX_ERRORS) {
            goto fail;
        }
    }
    if (!optional(P, '}') && t) {
        error_tok_2(P, P->token, "Declaration missing closing '}' to match", t);
    }
    revert_symbols(&ct->members);
    return;
fail:
    recover(P, '}', 1);
}
Beispiel #13
0
str* client_new(client_info_t* ci,b2b_notify_t b2b_cback,
		b2b_add_dlginfo_t add_dlginfo, str* param)
{
	int result;
	b2b_dlg_t* dlg;
	unsigned int hash_index;
	str* callid = NULL;
	int size;
	str ehdr = {0, 0};
	str* b2b_key_shm = NULL;
	dlg_t td;
	str from_tag;
	str random_info = {0, 0};

	if(ci == NULL || b2b_cback == NULL || param== NULL)
	{
		LM_ERR("Wrong parameters.\n");
		return NULL;
	}
	if(param && param->len > B2BL_MAX_KEY_LEN)
	{
		LM_ERR("parameter too long, received [%d], maximum [%d]\n",
				param->len, B2BL_MAX_KEY_LEN);
		return 0;
	}

	hash_index = core_hash(&ci->from_uri, &ci->to_uri, client_hsize);

	if(ci->from_tag)
		from_tag = *ci->from_tag;
	else
		generate_tag(&from_tag, &ci->from_uri, ci->extra_headers);

	/* create a dummy b2b dialog structure to be inserted in the hash table*/
	size = sizeof(b2b_dlg_t) + ci->to_uri.len + ci->from_uri.len
		+ ci->from_dname.len + ci->to_dname.len +
		from_tag.len + ci->local_contact.len + B2B_MAX_KEY_SIZE + B2BL_MAX_KEY_LEN;

	/* create record in hash table */
	dlg = (b2b_dlg_t*)shm_malloc(size);
	if(dlg == NULL)
	{
		LM_ERR("No more shared memory\n");
		return 0;
	}
	memset(dlg, 0, size);
	size = sizeof(b2b_dlg_t);

	CONT_COPY(dlg, dlg->from_uri, ci->from_uri);
	CONT_COPY(dlg, dlg->to_uri, ci->to_uri);
	if(ci->to_dname.s)
		CONT_COPY(dlg, dlg->to_dname, ci->to_dname);
	if(ci->from_dname.s)
		CONT_COPY(dlg, dlg->from_dname, ci->from_dname);
	CONT_COPY(dlg, dlg->tag[CALLER_LEG], from_tag);
	CONT_COPY(dlg, dlg->contact[CALLER_LEG], ci->local_contact);

	if(param && param->s)
	{
		dlg->param.s = (char*)dlg + size;
		memcpy(dlg->param.s, param->s, param->len);
		dlg->param.len = param->len;
		size+= B2BL_MAX_KEY_LEN;
	}
	dlg->b2b_cback = b2b_cback;
	dlg->add_dlginfo = add_dlginfo;
	if(parse_method(ci->method.s, ci->method.s+ci->method.len, &dlg->last_method)< 0)
	{
		LM_ERR("wrong method %.*s\n", ci->method.len, ci->method.s);
		shm_free(dlg);
		goto error;
	}
	dlg->state = B2B_NEW;
	dlg->cseq[CALLER_LEG] =(ci->cseq?ci->cseq:1);
	dlg->send_sock = ci->send_sock;

	/* if the callid should be the same in more instances running at the same time (replication)*/
	if(!replication_mode)
	{
		srand(get_uticks());
		random_info.s = int2str(rand(), &random_info.len);
	}

	dlg->send_sock = ci->send_sock;
	dlg->id = core_hash(&from_tag, random_info.s?&random_info:0, HASH_SIZE);

	/* callid must have the special format */
	dlg->db_flag = NO_UPDATEDB_FLAG;
	callid = b2b_htable_insert(client_htable, dlg, hash_index, B2B_CLIENT, 0);
	if(callid == NULL)
	{
		LM_ERR("Inserting new record in hash table failed\n");
		shm_free(dlg);
		goto error;
	}

	if(b2breq_complete_ehdr(ci->extra_headers, &ehdr, ci->body,
				&ci->local_contact)< 0)
	{
		LM_ERR("Failed to complete extra headers\n");
		goto error;
	}

	/* copy the key in shared memory to transmit it as a parameter to the tm callback */
	b2b_key_shm = b2b_key_copy_shm(callid);
	if(b2b_key_shm== NULL)
	{
		LM_ERR("no more shared memory\n");
		goto error;
	}
	CONT_COPY(dlg, dlg->callid, (*callid));

	/* create the tm dialog structure with the a costum callid */
	memset(&td, 0, sizeof(dlg_t));
	td.loc_seq.value = dlg->cseq[CALLER_LEG];
	dlg->last_invite_cseq = dlg->cseq[CALLER_LEG];
	td.loc_seq.is_set = 1;

	td.id.call_id = *callid;
	td.id.loc_tag = from_tag;
	td.id.rem_tag.s = 0;
	td.id.rem_tag.len = 0;

	td.rem_uri = ci->to_uri;
	if(ci->req_uri.s)
		td.rem_target    = ci->req_uri;
	else
		td.rem_target    = ci->to_uri;
	if(td.rem_target.s[0] == '<')
	{
		td.rem_target.s++;
		td.rem_target.len-=2;
	}

	td.rem_dname  = ci->to_dname;

	td.loc_uri    = ci->from_uri;
	td.loc_dname  = ci->from_dname;

	td.state= DLG_CONFIRMED;
	td.T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;

	td.send_sock = ci->send_sock;

	if(ci->dst_uri.len)
		td.obp = ci->dst_uri;

	td.avps = ci->avps;

	tmb.setlocalTholder(&dlg->uac_tran);

	/* send request */
	result= tmb.t_request_within
		(&ci->method,          /* method*/
		&ehdr,                 /* extra headers*/
		ci->body,              /* body*/
		&td,                   /* dialog structure*/
		b2b_client_tm_cback,   /* callback function*/
		b2b_key_shm,
		shm_free_param);       /* function to release the parameter*/

	if(td.route_set)
		pkg_free(td.route_set);
	if(result< 0)
	{
		LM_ERR("while sending request with t_request\n");
		pkg_free(callid);
		shm_free(b2b_key_shm);
		return NULL;
	}
	tmb.setlocalTholder(NULL);

	LM_DBG("new client entity [%p] callid=[%.*s] tag=[%.*s] param=[%.*s]"
			" last method=[%d] dlg->uac_tran=[%p]\n",
			dlg, callid->len, callid->s,
			dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s,
			dlg->param.len, dlg->param.s, dlg->last_method, dlg->uac_tran);

	return callid;

error:
	if(callid)
		pkg_free(callid);
	return NULL;
}
Beispiel #14
0
int parse_cseq(sip_cseq* cseq, const char* beg, int len)
{
    enum {
	C_NUM=0,
	C_NUM_SWS,
	C_METHOD
    };


    const char* c = beg;
    const char* end = c+len;

    int saved_st=0, st=C_NUM;

    for(;c!=end;c++){

	switch(st){

	case C_NUM:
	    switch(*c){

	    case_CR_LF;

	    case SP:
	    case HTAB:
		st = C_NUM_SWS;
		cseq->num_str.set(beg, c-beg);
		break;
		
	    default:
		if(!IS_DIGIT(*c)){
		    return MALFORMED_SIP_MSG;
		}
		cseq->num = cseq->num*10 + *c - '0';
		break;
	    }
	    break;

	case C_NUM_SWS:
	    switch(*c){

	    case_CR_LF;

	    case SP:
	    case HTAB:
		break;
		
	    default:
		st = C_METHOD;
		beg = c;
		break;
	    }
	    break;

	case C_METHOD:
	    switch(*c){

	    case_CR_LF;

	    case SP:
	    case HTAB:
		cseq->method_str.set(beg,c-beg);
		return 0;
	    }
	    break;

	case_ST_CR(*c);

	case ST_LF:
	case ST_CRLF:
	    switch(saved_st){
	    case C_NUM:
		cseq->num_str.set(beg,c-(st==ST_CRLF?2:1)-beg);
		break;
	    case C_METHOD:
		cseq->method_str.set(beg,c-beg);
		return 0;
	    }
	    st = saved_st;
	    break;
	}
    }

    if(st != C_METHOD){
	return MALFORMED_SIP_MSG;
    }

    cseq->method_str.set(beg,c-beg);
    if(parse_method(&cseq->method, cseq->method_str.s, cseq->method_str.len) < 0){
	
	DBG("Cseq method parsing failed\n");
	return MALFORMED_SIP_MSG;
    }

    return 0;
}
Beispiel #15
0
/* parses the first line, returns pointer to  next line  & fills fl;
   also  modifies buffer (to avoid extra copy ops) */
char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
{

	char *tmp;
	char* second;
	char* third;
	char* nl;
	unsigned int offset;
	/* int l; */
	char* end;
	char s1,s2,s3;
	char *prn;
	unsigned int t;

	/* grammar:
		request  =  method SP uri SP version CRLF
		response =  version SP status  SP reason  CRLF
		(version = "SIP/2.0")
	*/


	end=buffer+len;
	/* see if it's a reply (status) */

	/* jku  -- parse well-known methods */

	/* drop messages which are so short they are for sure useless;
           utilize knowledge of minimum size in parsing the first
	   token
        */
	if (len <=16 ) {
		LM_INFO("message too short: %d\n", len);
		goto error1;
	}

	tmp=buffer;
  	/* is it perhaps a reply, ie does it start with "SIP...." ? */
	if ( 	(*tmp=='S' || *tmp=='s') &&
		strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
		(*(tmp+SIP_VERSION_LEN)==' ')) {
			fl->type=SIP_REPLY;
			fl->u.reply.version.len=SIP_VERSION_LEN;
			tmp=buffer+SIP_VERSION_LEN;
	} else IFISMETHOD( INVITE, 'I' )
	else IFISMETHOD( CANCEL, 'C')
	else IFISMETHOD( ACK, 'A' )
	else IFISMETHOD( BYE, 'B' )
	else IFISMETHOD( INFO, 'I' )
	/* if you want to add another method XXX, include METHOD_XXX in
           H-file (this is the value which you will take later in
           processing and define XXX_LEN as length of method name;
	   then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
	   latter; everything must be capitals
	*/
	else {
		/* neither reply, nor any of known method requests,
		   let's believe it is an unknown method request
        	*/
		tmp=eat_token_end(buffer,buffer+len);
		if ((tmp==buffer)||(tmp>=end)){
			LM_INFO("empty  or bad first line\n");
			goto error1;
		}
		if (*tmp!=' ') {
			LM_INFO("method not followed by SP\n");
			goto error1;
		}
		fl->type=SIP_REQUEST;
		/* see if it is another known method */
		/* fl->u.request.method_value=METHOD_OTHER; */
		if(parse_method(buffer, tmp,
				(unsigned int*)&fl->u.request.method_value)==0)
		{
			LM_INFO("failed to parse the method\n");
			goto error1;
		}
		fl->u.request.method.len=tmp-buffer;
	}


	/* identifying type of message over now;
	   tmp points at space after; go ahead */

	fl->u.request.method.s=buffer;  /* store ptr to first token */
	second=tmp+1;			/* jump to second token */
	offset=second-buffer;

/* EoJku */

	/* next element */
	tmp=eat_token_end(second, second+len-offset);
	if (tmp>=end){
		goto error;
	}
	offset+=tmp-second;
	third=eat_space_end(tmp, tmp+len-offset);
	offset+=third-tmp;
	if ((third==tmp)||(tmp>=end)){
		goto error;
	}
	fl->u.request.uri.s=second;
	fl->u.request.uri.len=tmp-second;

	/* jku: parse status code */
	if (fl->type==SIP_REPLY) {
		if (fl->u.request.uri.len!=3) {
			LM_INFO("len(status code)!=3: %.*s\n",
				fl->u.request.uri.len, ZSW(second) );
			goto error;
		}
		s1=*second; s2=*(second+1);s3=*(second+2);
		if (s1>='0' && s1<='9' &&
		    s2>='0' && s2<='9' &&
		    s3>='0' && s3<='9' ) {
			fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
		} else {
			LM_INFO("status_code non-numerical: %.*s\n",
				fl->u.request.uri.len, ZSW(second) );
			goto error;
		}
	}
	/* EoJku */

	/*  last part: for a request it must be the version, for a reply
	 *  it can contain almost anything, including spaces, so we don't care
	 *  about it*/
	if (fl->type==SIP_REQUEST){
		tmp=eat_token_end(third,third+len-offset);
		offset+=tmp-third;
		if ((tmp==third)||(tmp>=end)){
			goto error;
		}
		if (! is_empty_end(tmp, tmp+len-offset)){
			goto error;
		}
	}else{
		tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line
												  ('\n' or '\r') */
		if (tmp>=end){ /* no crlf in packet => invalid */
			goto error;
		}
		offset+=tmp-third;
	}
	nl=eat_line(tmp,len-offset);
	if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
		goto error;
	}
	fl->u.request.version.s=third;
	fl->u.request.version.len=tmp-third;
	fl->len=nl-buffer;

	return nl;

error:
	LM_ERR("bad %s first line\n",
		(fl->type==SIP_REPLY)?"reply(status)":"request");

	LM_ERR("at line 0 char %d: \n", offset );
	prn=pkg_malloc( offset );
	if (prn) {
		for (t=0; t<offset; t++)
			if (*(buffer+t)) *(prn+t)=*(buffer+t);
			else *(prn+t)='°';
		LM_ERR("parsed so far: %.*s\n", offset, ZSW(prn) );
		pkg_free( prn );
	};
error1:
	fl->type=SIP_INVALID;
	LM_INFO("bad message\n");
	/* skip  line */
	nl=eat_line(buffer,len);
	return nl;
}
Beispiel #16
0
/*
 * main function to parse the http request header.
 */
int parse_request(struct http_header *header, char *request, size_t len)
{
        char ch, *p = request;
        int tmp;

        while (p < request + len)
        // for(p = request; p < request + len; p++)
        {
                ch = *p;

                switch (GET_HEADER_STATE(header)) {

                // some error happened,
                // and then ignore all data left in the buffer.
                case s_dead:
                        return -1;

                // finshed parsing http request header,
                // but there are still some data in the buffer.
                case s_done:
                        return p - request;

                // start to parse METHOD
                case s_request_start:
                case s_method_start:
                {
                        // skip space at the beginning
                        if (CR == ch || LF == ch || SP == ch) {
                                p++;
                                break;
                        }
                        
                        // when match the first non-space character
                        // parse the http method
                        tmp = parse_method(header, p);
                        if (tmp == -1) {
                                // failed
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_invalid_method);
                                return -1;
                        } else if (tmp == E_INTERRUPT) {
                                SET_HEADER_ERROR(header, e_again);
                                return -1;
                        } else {
                                // success
                                SET_HEADER_STATE(header, s_method_end);
                                p += tmp; p++;
                                break;
                        }
                }

                // after found out the http method
                // there is an SP between METHOD and URL
                case s_method_end:
                {
                        if (SP != ch) {
                                // failed
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_invalid_method);
                                return -1;
                        } else {
                                // success
                                SET_HEADER_STATE(header, s_url_start);
                                p++;
                                break;
                        }
                }

                // start to parse URL
                case s_url_start:
                case s_path_start:
                case s_query_start:
                {
                        // TODO 
                        // handle the CONNECT and OPTION method

                        tmp = parse_url(header, p, len - (p - request));
                        if (tmp == -1) {
                                // failed
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_invalid_url);
                                return -1;
                        } else if (tmp == E_INTERRUPT) {
                                SET_HEADER_ERROR(header, e_again);
                                return -1;
                        } else {
                                SET_HEADER_STATE(header, s_version_start);
                                p += tmp; p++;
                                break;
                        }
                }

                // http version, only support HTTP/1.0 and HTTP/1.1
                case s_version_start:
                {
                        int tmp = parse_version(header, p);
                        if (tmp == -1) {
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_invalid_version);
                                return -1;
                        } else if (tmp == E_INTERRUPT) {
                                SET_HEADER_ERROR(header, e_again);
                                return -1;
                        } else {
                                SET_HEADER_STATE(header, s_line_cr);
                                p += HTTP_VERSION_LENGTH;
                                break;
                        }
                }

                // CR character in the end of line
                case s_line_cr:
                {
                        if (CR == ch) {
                                SET_HEADER_STATE(header, s_line_lf);
                                p++;
                                break;
                        } else {
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_eol);
                                return -1;
                        }
                }

                // LF character in the end of line
                case s_line_lf:
                {
                        if (LF == ch) {
                                SET_HEADER_STATE(header, s_done);
                                break;
                        } else {
                                SET_HEADER_STATE(header, s_dead);
                                SET_HEADER_ERROR(header, e_eol);
                                return -1;
                        }
                }

                // header field start
                case s_field_start:
                {
                        SET_HEADER_STATE(header, s_done);
                        break;
                }

                default:
                        SET_HEADER_STATE(header, s_dead);

                }

        }

        // three results 
        // dead, done, again
        switch (GET_HEADER_STATE(header)) {
        // error
        case s_dead:    return s_dead;
        // finished
        case s_done:    return s_done;
        // again
        default:        
                SET_HEADER_ERROR(header, e_again);
                return s_dead;

        }
}
Beispiel #17
0
struct node *parse_factor(struct compiler *compiler)
{
    switch (lexer_current(compiler))
    {
    case T_BEGIN:
        return parse_begin(compiler);

    case T_IF:
        return parse_if(compiler);

    case T_UNLESS:
        return parse_unless(compiler);

    case T_CASE:
        return parse_case(compiler);

    case T_CLASS:
        return parse_class(compiler);

    case T_MODULE:
        return parse_module(compiler);

    case T_DEF:
        return parse_method(compiler);

    case T_YIELD:
        return parse_yield(compiler);

    case T_RETURN:
        return parse_return(compiler);

    case T_BREAK:
        return parse_break(compiler);

    case T_NEXT:
        return parse_next(compiler);

    case T_REDO:
        return parse_redo(compiler);

    case T_SQUARE_OPEN:
    {
        struct node *result = alloc_node(compiler, N_ARRAY);

        lexer_next(compiler);

        if(lexer_current(compiler) == T_SQUARE_CLOSE)
            result->left  = 0;
        else
            result->left = parse_array_element(compiler);

        lexer_match(compiler, T_SQUARE_CLOSE);

        return result;
    }

    case T_STRING:
    {
        struct node *result = alloc_node(compiler, N_STRING);

        result->left = (void *)lexer_token(compiler)->start;

        lexer_next(compiler);

        return result;
    }

    case T_STRING_START:
    {
        struct node *result = alloc_node(compiler, N_STRING_CONTINUE);

        result->left = 0;
        result->middle = (void *)lexer_token(compiler)->start;

        lexer_next(compiler);

        result->right = parse_statements(compiler);

        while(lexer_current(compiler) == T_STRING_CONTINUE)
        {
            struct node *node = alloc_node(compiler, N_STRING_CONTINUE);

            node->left = result;
            node->middle = (void *)lexer_token(compiler)->start;

            lexer_next(compiler);

            node->right = parse_statements(compiler);

            result = node;
        }

        if(lexer_require(compiler, T_STRING_END))
        {
            struct node *node = alloc_node(compiler, N_STRING_START);

            node->left = result;
            node->right = (void *)lexer_token(compiler)->start;

            lexer_next(compiler);

            return node;
        }

        return result;
    }

    case T_SELF:
    {
        lexer_next(compiler);

        return &self_node;
    }

    case T_TRUE:
    {
        lexer_next(compiler);

        return alloc_node(compiler, N_TRUE);
    }

    case T_FALSE:
    {
        lexer_next(compiler);

        return alloc_node(compiler, N_FALSE);
    }

    case T_NIL:
    {
        lexer_next(compiler);

        return &nil_node;
    }

    case T_NUMBER:
    {
        struct node *result = alloc_node(compiler, N_NUMBER);

        char *text = get_token_str(lexer_token(compiler));

        result->left = (void* )atoi(text);

        lexer_next(compiler);

        return result;
    }

    case T_IVAR:
    {
        rt_value symbol = rt_symbol_from_lexer(compiler);

        lexer_next(compiler);

        switch (lexer_current(compiler))
        {
        case T_ASSIGN_ADD:
        case T_ASSIGN_SUB:
        case T_ASSIGN_MUL:
        case T_ASSIGN_DIV:
        {
            struct node *result;

            enum token_type op_type = lexer_current(compiler) - OP_TO_ASSIGN;

            lexer_next(compiler);

            result = alloc_node(compiler, N_IVAR_ASSIGN);

            result->right = alloc_node(compiler, N_BINARY_OP);
            result->right->op = op_type;
            result->right->left = alloc_node(compiler, N_IVAR);
            result->right->left->left = (void *)symbol;
            result->right->right = parse_expression(compiler);

            result->left = (void *)symbol;

            return result;
        }

        case T_ASSIGN:
        {
            struct node *result;

            lexer_next(compiler);

            result = alloc_node(compiler, N_IVAR_ASSIGN);
            result->left = (void *)symbol;
            result->right = parse_expression(compiler);

            return result;
        }

        default:
        {
            struct node *result = alloc_node(compiler, N_IVAR);

            result->left = (void *)symbol;

            return result;
        }
        }
    }

    case T_IDENT:
        return parse_identifier(compiler);

    case T_EXT_IDENT:
        return parse_call(compiler, 0, &self_node, false);

    case T_PARAM_OPEN:
    {
        lexer_next(compiler);

        struct node *result = parse_statements(compiler);

        lexer_match(compiler, T_PARAM_CLOSE);

        return result;
    }

    default:
    {
        COMPILER_ERROR(compiler, "Expected expression but found %s", token_type_names[lexer_current(compiler)]);

        lexer_next(compiler);

        return 0;
    }
    }
}
Beispiel #18
0
int COMPRESSION_METHOD::server()
{
  char *service = p._str("service");

  // Global services
  if (strequ (service, "register"))               return FREEARC_OK; //to do: Register();

  // Invocation-specific services
  if (strequ (service, "decompress"))             {parse_method(); return decompress (p._callback("callback"), p);}
#ifndef FREEARC_DECOMPRESS_ONLY
  if (strequ (service, "compress"))               {parse_method(); return compress   (p._callback("callback"), p);}
  if (strequ (service, "canonize"))               {parse_method();                                     char a[1000]; ShowCompressionMethod(a); return p._return(a);}
  if (strequ (service, "SetCompressionMem"))      {parse_method(); SetCompressionMem  (p._int("mem")); char a[1000]; ShowCompressionMethod(a); return p._return(a);}
  if (strequ (service, "SetDictionary"))          {parse_method(); SetDictionary      (p._int("mem")); char a[1000]; ShowCompressionMethod(a); return p._return(a);}
  if (strequ (service, "SetBlockSize"))           {parse_method(); SetBlockSize       (p._int("mem")); char a[1000]; ShowCompressionMethod(a); return p._return(a);}
  if (strequ (service, "SetDecompressionMem"))    {parse_method(); SetDecompressionMem(p._int("mem")); char a[1000]; ShowCompressionMethod(a); return p._return(a);}
  if (strequ (service, "GetCompressionMem"))      {parse_method(); return p._return (GetCompressionMem());}
  if (strequ (service, "GetDictionary"))          {parse_method(); return p._return (GetDictionary());}
  if (strequ (service, "GetBlockSize"))           {parse_method(); return p._return (GetBlockSize());}
#endif
  if (strequ (service, "GetDecompressionMem"))    {parse_method(); return p._return (GetDecompressionMem());}

  return FREEARC_ERRCODE_NOT_IMPLEMENTED;
}