Example #1
0
static int acquire_body_simple(belle_sip_channel_t *obj, int end_of_stream){
	int content_length=obj->input_stream.content_length;
	size_t to_read=obj->input_stream.write_ptr-obj->input_stream.read_ptr;
	belle_sip_message_t *msg=obj->input_stream.msg;
	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
	size_t cursize=belle_sip_body_handler_get_transfered_size(bh);

	if ((cursize == 0) && (to_read == 0)) {
		/**
		 * No data has been received yet, so do not call feed_body() with a size
		 * of 0 that is meaning that the transfer is finished.
		 */
	} else {
		to_read=MIN(content_length-cursize, to_read);
		feed_body(obj,to_read);
	}

	if (end_of_stream ||  belle_sip_body_handler_get_transfered_size(bh)>=content_length){
		/*great body completed*/
		belle_sip_message("channel [%p] read [%i] bytes of body from [%s:%i]"	,obj
			,content_length
			,obj->peer_name
			,obj->peer_port);
		belle_sip_channel_message_ready(obj);
		return BELLE_SIP_CONTINUE;
	}
	/*body is not finished, we need more data*/
	return BELLE_SIP_STOP;
}
Example #2
0
static int acquire_chuncked_body(belle_sip_channel_t *obj){
	belle_sip_channel_input_stream_t *st=&obj->input_stream;
	int readsize;
	do{
		if (st->chunk_size==-1){
			char *tmp;
			/*belle_sip_message("seeing: %s",st->read_ptr);*/
			while ( (tmp=strstr(st->read_ptr,"\r\n"))==st->read_ptr){/*skip \r\n*/
				st->read_ptr+=2;
			}

			if (tmp!=NULL){
				/*the chunk length is there*/
				long chunksize=strtol(st->read_ptr,NULL,16);
				if (chunksize>=0 && chunksize!=LONG_MAX){
					if (chunksize==0){
						belle_sip_message("Got end of chunked body");
						st->read_ptr=tmp+4; /*last chunk indicator finishes with two \r\n*/
						if (st->read_ptr>st->write_ptr) st->read_ptr=st->write_ptr;
						belle_sip_channel_message_ready(obj);
						return BELLE_SIP_CONTINUE;
					}else{
						belle_sip_message("Will get a chunk of %i bytes",(int)chunksize);
						st->chunk_size=chunksize;
						st->chunk_read_size=0;
						st->read_ptr=tmp+2;
					}
				}else{
					belle_sip_error("Chunk parse error");
					belle_sip_channel_input_stream_reset(st);
					return BELLE_SIP_CONTINUE;
				}
			}else{
				/*need more data*/
				return BELLE_SIP_STOP;
			}
		}
		readsize=MIN(st->write_ptr-st->read_ptr,st->chunk_size-st->chunk_read_size);
		if (readsize>0){
			feed_body(obj,readsize);
			st->chunk_read_size+=readsize;
		}
		if (st->chunk_size==st->chunk_read_size){
			/*we have a chunk completed*/
			st->content_length+=st->chunk_size;
			belle_sip_message("Chunk of [%i] bytes completed",st->chunk_size);
			st->chunk_size=-1;/*wait for next chunk indicator*/
		}else{
			/*need more data*/
			return BELLE_SIP_STOP;
		}
	}while(st->write_ptr-st->read_ptr>0); /*no need to continue if nothing to read*/
	return BELLE_SIP_STOP;
}
Example #3
0
static int acquire_body_simple(belle_sip_channel_t *obj, int end_of_stream){
	int content_length=obj->input_stream.content_length;
	size_t to_read=obj->input_stream.write_ptr-obj->input_stream.read_ptr;
	belle_sip_message_t *msg=obj->input_stream.msg;
	belle_sip_body_handler_t *bh=belle_sip_message_get_body_handler(msg);
	size_t cursize=belle_sip_body_handler_get_transfered_size(bh);
	
	to_read=MIN(content_length-cursize, to_read);

	feed_body(obj,to_read);
	if (end_of_stream ||  belle_sip_body_handler_get_transfered_size(bh)>=content_length){
		/*great body completed
		belle_sip_message("channel [%p] read [%i] bytes of body from %s:%i\n%s"	,obj
			,content_length
			,obj->peer_name
			,obj->peer_port
			,obj->input_stream.read_ptr);*/
		belle_sip_channel_message_ready(obj);
		return BELLE_SIP_CONTINUE;
	}
	/*body is not finished, we need more data*/
	return BELLE_SIP_STOP;
}
Example #4
0
void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream){
	int offset;
	size_t read_size=0;
	int num;
	
	while ((num=(obj->input_stream.write_ptr-obj->input_stream.read_ptr))>0){
	
		if (obj->input_stream.state == WAITING_MESSAGE_START) {
			int i;
			/*first, make sure there is \r\n in the buffer, otherwise, micro parser cannot conclude, because we need a complete request or response line somewhere*/
			for (i=0;i<num-1;i++) {
				if ((obj->input_stream.read_ptr[i]=='\r' && obj->input_stream.read_ptr[i+1]=='\n')
						|| belle_sip_channel_input_stream_get_buff_length(&obj->input_stream) <= 1 /*1 because null terminated*/  /*if buffer full try to parse in any case*/) {
					/*good, now we can start searching  for request/response*/
					if ((offset=get_message_start_pos(obj->input_stream.read_ptr,num)) >=0 ) {
						/*message found !*/
						if (offset>0) {
							belle_sip_warning("trashing [%i] bytes in front of sip message on channel [%p]",offset,obj);
							obj->input_stream.read_ptr+=offset;
						}
						obj->input_stream.state=MESSAGE_AQUISITION;
					} else {
						belle_sip_debug("Unexpected [%s] received on channel [%p], trashing",obj->input_stream.read_ptr,obj);
						obj->input_stream.read_ptr=obj->input_stream.write_ptr;
						belle_sip_channel_input_stream_reset(&obj->input_stream);
						continue;
					}
				break;
				}
			}

			if (i >= num-1) {
				belle_sip_debug("[%s] received on channel [%p], cannot determine if expected or not, waiting for new data",obj->input_stream.read_ptr,obj);
				break;
			}
		}

		if (obj->input_stream.state==MESSAGE_AQUISITION) {
			/*search for \r\n\r\n*/
			char* end_of_message=NULL;
			if ((end_of_message=strstr(obj->input_stream.read_ptr,"\r\n\r\n"))){
				int bytes_to_parse;
				char tmp;
				/*end of message found*/
				end_of_message+=4;/*add \r\n\r\n*/
				bytes_to_parse=end_of_message-obj->input_stream.read_ptr;
				tmp=*end_of_message;
				*end_of_message='\0';/*this is in order for the following log to print the message only to its end.*/
				/*belle_sip_message("channel [%p] read message of [%i] bytes:\n%.40s...",obj, bytes_to_parse, obj->input_stream.read_ptr);*/
				obj->input_stream.msg=belle_sip_message_parse_raw(obj->input_stream.read_ptr
										,bytes_to_parse
										,&read_size);
				*end_of_message=tmp;
				obj->input_stream.read_ptr+=read_size;
				if (obj->input_stream.msg && read_size > 0){
					belle_sip_message("channel [%p] [%i] bytes parsed",obj,(int)read_size);
					belle_sip_object_ref(obj->input_stream.msg);
					if (belle_sip_message_is_request(obj->input_stream.msg)) fix_incoming_via(BELLE_SIP_REQUEST(obj->input_stream.msg),obj->current_peer);
					/*check for body*/
					
					if (check_body(obj)){
						obj->input_stream.state=BODY_AQUISITION;
					} else {
						/*no body*/
						belle_sip_channel_message_ready(obj);
						continue;
					}
				}else{
					belle_sip_error("Could not parse [%s], on channel [%p] skipping to [%s]",obj->input_stream.read_ptr
														,obj
														,end_of_message);
					obj->input_stream.read_ptr=end_of_message;
					obj->input_stream.state=WAITING_MESSAGE_START;
					continue;
				}
			}else break; /*The message isn't finished to be receive, we need more data*/
		}

		if (obj->input_stream.state==BODY_AQUISITION) {
			if (acquire_body(obj,end_of_stream)==BELLE_SIP_STOP) break;
		}
	}
}