示例#1
0
char* parse_fline(char* buffer, char* end, struct msg_start* fl)
{
	if(end<=buffer) {
		/* make it throw error via parse_first_line() for consistency */
		return parse_first_line(buffer, 0, fl);
	}
	return parse_first_line(buffer, (unsigned int)(end-buffer), fl);
}
示例#2
0
/* parse an option */
static int parse_option(char *line)
{
    if (req.method==0)
        return parse_first_line(line);
    else
        return parse_header_line(line);
}
示例#3
0
int tcp_http11_continue(struct tcp_connection *c)
{
	struct dest_info dst;
	char *p;
	struct msg_start fline;
	int ret;
	str msg;

	ret = 0;

	msg.s = c->req.start;
	msg.len = c->req.pos - c->req.start;
#ifdef READ_MSRP
	/* skip if MSRP message */
	if(c->req.flags&F_TCP_REQ_MSRP_FRAME)
		return 0;
#endif
	p = parse_first_line(msg.s, msg.len, &fline);
	if(p==NULL)
		return 0;

	if(fline.type!=SIP_REQUEST)
		return 0;

	/* check if http request */
	if(fline.u.request.version.len < HTTP_VERSION_LEN
			|| strncasecmp(fline.u.request.version.s,
				HTTP_VERSION, HTTP_VERSION_LEN))
		return 0;

	/* check for Expect header */
	if(strfindcasestrz(&msg, "Expect: 100-continue")!=NULL)
	{
		init_dst_from_rcv(&dst, &c->rcv);
		if (tcp_send(&dst, 0, HTTP11CONTINUE, HTTP11CONTINUE_LEN) < 0) {
			LM_ERR("HTTP/1.1 continue failed\n");
		}
	}
	/* check for Transfer-Encoding header */
	if(strfindcasestrz(&msg, "Transfer-Encoding: chunked")!=NULL)
	{
		c->req.flags |= F_TCP_REQ_BCHUNKED;
		ret = 1;
	}
	/* check for HTTP Via header
	 * - HTTP Via format is different that SIP Via
	 * - workaround: replace with Hia to be ignored by SIP parser
	 */
	if((p=strfindcasestrz(&msg, "\nVia:"))!=NULL)
	{
		p++;
		*p = 'H';
		LM_DBG("replaced HTTP Via with Hia [[\n%.*s]]\n", msg.len, msg.s);
	}
	return ret;
}
示例#4
0
void HTTP::update_state()
{
    if (state == 0 && text.find("\r\n") != std::string::npos) {
        state = FIRSTLINE;
        parse_first_line();
    }
    if (state == FIRSTLINE && (body_start == 0 || body_start == std::string::npos)) {
        body_start = text.find("\r\n\r\n");
    }
    if (state == FIRSTLINE && body_start != std::string::npos && body_start != 0) {
        state = HEADERS;
        body_start += 4;
        parse_headers();
    }
    if (state >= HEADERS) {
        check_body();
    }
}
示例#5
0
struct browser_request *parse_browser_request(char *message) {

	struct browser_request *request;

	request = malloc(sizeof(struct browser_request));
	if(request == NULL) {
		perror("memory allocation Failure");
		exit(EXIT_FAILURE);
	}

	char *line, *save_pointer;
	line = strtok_r(message, "\n\r", &save_pointer);
	parse_first_line(line, request);

	while((line = strtok_r(NULL, "\n\r", &save_pointer)) != NULL) {
		parse_request(line, request);
	}

	return request;

}
示例#6
0
static void process_data(struct http_client_request *req)
{
	int bytes_to_commit = 0;

	while (req->state == EINPROGRESS) {
		char *parse_head = req->rcvbuf + req->parse_ptr;
		char *endline;
		int bytes_left;
		int line_size;

		bytes_left = req->read_ptr - req->parse_ptr;

		endline = memchr(parse_head, '\n', bytes_left);
		if (endline == NULL) {
			endline = memchr(parse_head, '\r', bytes_left);
			if (endline == NULL) {
				bytes_to_commit += bytes_left;
				break;
			}
		}

		line_size = endline - parse_head + 1;
		bytes_to_commit += line_size;
		req->parse_ptr += line_size;

		*endline = 0;
		if (parse_head != endline && endline[-1] == '\r')
			endline[-1] = 0;

		if (req->response_code == -1)
			parse_first_line(req, parse_head);
		else
			parse_header_line(req, parse_head);
	}

	commit(req, bytes_to_commit);
}
示例#7
0
/* returns 0 if ok, -1 for errors */
int parse_msg(char* const buf, const unsigned int len, struct sip_msg* const msg)
{

    char *tmp;
    char* rest;
    struct msg_start *fl;
    int offset;
    hdr_flags_t flags;

    /* eat crlf from the beginning */
    for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
            tmp-buf < len ; tmp++);
    offset=tmp-buf;
    fl=&(msg->first_line);
    rest=parse_first_line(tmp, len-offset, fl);
    offset+=rest-tmp;
    tmp=rest;
    switch(fl->type) {
    case SIP_INVALID:
        DBG("parse_msg: invalid message\n");
        goto error;
        break;
    case SIP_REQUEST:
        DBG("SIP Request:\n");
        DBG(" method:  <%.*s>\n",fl->u.request.method.len,
            ZSW(fl->u.request.method.s));
        DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
            ZSW(fl->u.request.uri.s));
        DBG(" version: <%.*s>\n",fl->u.request.version.len,
            ZSW(fl->u.request.version.s));
        flags=HDR_VIA_F;
        break;
    case SIP_REPLY:
        DBG("SIP Reply  (status):\n");
        DBG(" version: <%.*s>\n",fl->u.reply.version.len,
            ZSW(fl->u.reply.version.s));
        DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
            ZSW(fl->u.reply.status.s));
        DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
            ZSW(fl->u.reply.reason.s));
        /* flags=HDR_VIA | HDR_VIA2; */
        /* we don't try to parse VIA2 for local messages; -Jiri */
        flags=HDR_VIA_F;
        break;
    default:
        DBG("unknown type %d\n",fl->type);
        goto error;
    }
    msg->unparsed=tmp;
    /*find first Via: */
    if (parse_headers(msg, flags, 0)==-1) goto error;

#ifdef EXTRA_DEBUG
    /* dump parsed data */
    if (msg->via1) {
        DBG("first via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
            msg->via1->name.len,
            ZSW(msg->via1->name.s),
            msg->via1->version.len,
            ZSW(msg->via1->version.s),
            msg->via1->transport.len,
            ZSW(msg->via1->transport.s),
            msg->via1->host.len,
            ZSW(msg->via1->host.s),
            msg->via1->port_str.len,
            ZSW(msg->via1->port_str.s),
            msg->via1->port);
        if (msg->via1->params.s)  DBG(";<%.*s>",
                                          msg->via1->params.len, ZSW(msg->via1->params.s));
        if (msg->via1->comment.s)
            DBG(" <%.*s>",
                msg->via1->comment.len, ZSW(msg->via1->comment.s));
        DBG ("\n");
    }
    if (msg->via2) {
        DBG("second via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
            msg->via2->name.len,
            ZSW(msg->via2->name.s),
            msg->via2->version.len,
            ZSW(msg->via2->version.s),
            msg->via2->transport.len,
            ZSW(msg->via2->transport.s),
            msg->via2->host.len,
            ZSW(msg->via2->host.s),
            msg->via2->port_str.len,
            ZSW(msg->via2->port_str.s),
            msg->via2->port);
        if (msg->via2->params.s)  DBG(";<%.*s>",
                                          msg->via2->params.len, ZSW(msg->via2->params.s));
        if (msg->via2->comment.s) DBG(" <%.*s>",
                                          msg->via2->comment.len, ZSW(msg->via2->comment.s));
        DBG ("\n");
    }
#endif


#ifdef EXTRA_DEBUG
    DBG("exiting parse_msg\n");
#endif

    return 0;

error:
    /* more debugging, msg->orig is/should be null terminated*/
    LOG(cfg_get(core, core_cfg, corelog), "ERROR: parse_msg: message=<%.*s>\n",
        (int)msg->len, ZSW(msg->buf));
    return -1;
}
示例#8
0
bool jdk_http_request_header::parse_buffer( const char *buf, size_t len )
{
  // return true if an entire http request header is parsed or if a parsing error occurred.
  
  splitter.set_buf( (char *)buf, len );
  
  jdk_str<4096> line;    
  while( splitter.scan_for_line(&line) )
  {
    // found a line!	    
    jdk_log( JDK_LOG_DEBUG4, "jdk_http_request_header::parsing line: '%s'", line.c_str() );
    
    // ignore any initial blank lines.
    if( line.is_clear() && line_count==0 )
    {
      continue;
    }
    
    ++line_count;
    
    // is this our final blank line?
    if( line.is_clear() && line_count>0 )
    {			
      // yup, we are done parsing.
      
      // if we have a valid host name then we have a valid request.
      if( !url.host.is_clear() )
      {
        valid=true;
      }
      jdk_log( JDK_LOG_DEBUG4, "request_header parsed.  buf_pos=%d, buf_len=%d", get_buf_pos(), splitter.get_buf_len() );
      return true;
    }
    
    // is it our first line with the request?
    if( line_count==1 )
    {
      if( !parse_first_line(line) )
      {
        // error parsing first line. return true to stop parsing and is_valid() will be false.
        return true;
      }
      
    }
    else
    {
      // ok, it wasnt the first line. check for Host: and Port: lines
      if( line.nicmp( "Host:", 5 )==0 )
      {
        if( url.host.is_clear() )
        {
          // extract the value of this key
          jdk_str<300> tmp;
          tmp.cpy( line.c_str()+6 );
          tmp.strip_begws();
          tmp.strip_endws();
          
          // is there a : specifying port as well?
          char *p = tmp.chr(':');
          if( p )
          {
            // yup, lets grab it and remove it from the string.
            url.port = strtol(p+1,0,10);
            *p='\0';
          }
          url.host = tmp;
        }
      }
      else // how about a Port: line?
        if( line.nicmp( "Port:", 5 )==0 )
        {
          url.port = strtol( line.c_str()+6, 0, 10 );
        }
        else // we dont need to parse this line, just store it.
        {
          // extract the key, up to first colon
          key_t k;
          int pos = line.extract_token(0,&k,":");
          
          // extract the value, from where key ended, skiping all white space
          value_t v;
          v.cpy( line.c_str() + pos + 1 );
          // remove any trailing white space
          v.strip_begws();
          v.strip_endws();
          k.cat(':'); // add the colon back
          k.lower(); // lowercase the key since it is case insensitive
          // add the key and value to our map
          map.add( k, v );
        }
    }
  }
  
  // return false so the caller knows to grab a new buffer
  // and call us again
  //jdk_log( JDK_LOG_DEBUG4, "jdk_http_request_header parsing not finished yet" );
  return false;
}
示例#9
0
bool jdk_http_response_header::parse_buffer( const char *buf, size_t len )
{
  // return true if an entire http request header is parsed or if a parsing error occurred.
  
  splitter.set_buf( (char *)buf, len );
  
  jdk_str<4096> line;    
  while( splitter.scan_for_line(&line) )
  {
    // found a line!	    
    jdk_log( JDK_LOG_DEBUG4, "jdk_http_response_header::parsing line: '%s'", line.c_str() );
    
    // an initial blank line means the server is f****d and didnt respond with the proper http header.
    if( line.is_clear() && line_count==0 )
    {
      valid=true;
      return true;
    }
    
    ++line_count;
    
    // is this our final blank line?	    
    if( line.is_clear() )
    {
      // yup, we are done parsing.
      
      // if we have a valid http version and code then it is ok
      
      if( !http_version.is_clear() && http_response_code!=0 )
      {
        valid=true;
      }
      
      return true;
    }
    
    // is the server f****d and did not include a blank line before putting a '<' from an html file?
    
    if( !line.is_clear() && line.get(0)=='<' )
    {
      // yup!
      
      // yup, we are done parsing.
      
      valid=true;
      
      return true;				
    }
    
    
    
    // is it our first line with the request?
    if( line_count==1 )
    {
      if( !parse_first_line(line) )
      {
        // error parsing first line. return true to stop parsing and is_valid() will be false.
        return true;
      }
      
    }
    else
    {
      // we dont need to parse this line, just store it.
      // extract the key, up to the first ':'
      key_t k;
      int pos = line.extract_token(0,&k,":");
      k.lower();
      
      // extract the value, from where key ended, skiping the colon and the white space
      value_t v;
      v.cpy( line.c_str() + pos + 1 );
      // remove any trailing white space
      v.strip_begws();
      v.strip_endws();
      
      // put the colon back
      k.cat(':');
      // add the key and value to our map
      map.add( k, v );
    }
  }
  
  
  // return false so the caller knows to grab a new buffer
  // and call us again
  //jdk_log( JDK_LOG_DEBUG4, "jdk_http_response_header parsing not finished yet" );
  return false;
}
示例#10
0
int
parse_msg (struct sip_msg *msg, STRLIST * sender, STRLIST * recipient)
{

  char *tmp;
  char *end;
  int length;
  int offset;
  char *header;
  char address[80] = { 0 };
  char *body;
  int body_length;
  int off;
  int type;
  int evt;



  /* parse the data */
  tmp = msg->buf;
  end = msg->buf + msg->len;

  /* strip the beginning space */
  for (tmp; ((*tmp == '\n') || (*tmp == '\r'))
       && ((tmp - msg->buf) < length); tmp++);

  if (parse_first_line (&tmp, end, &(msg->type)))
    return 1;

  offset = tmp - msg->buf;
  do
    {
      switch (*tmp)
        {
        case 't':
        case 'T':
          {
            if (off = check ("TO", 2, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Header To found in %u\n", tmp - msg->buf);
                offset += off;
                offset += find_end (tmp + off, end);

                /* find the user address */
                tmp += off;
                if (get_address
                    (tmp, address, msg->buf + offset - tmp, &(msg->sips)))
                  {

                    tmp = msg->buf + offset;
                    break;
                  }

                add_to_strlist2 (recipient, address, 0);
                if (LOG_PARSER)
                  log_info ("The address is : %s\n", address);

                /* We only need one to header */
                if (!msg->to)
                  msg->to = parser_create_address (address, 0, msg->sips);
                tmp = msg->buf + offset;

                break;
              }
          }


        case 'f':
        case 'F':
          {
            if (off = check ("FROM", 4, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Header From found in %u\n", tmp - msg->buf);

                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the user address */
                tmp += off;

                if (get_address
                    (tmp, address, msg->buf + offset - tmp, &(msg->sips)))
                  {
                    tmp = msg->buf + offset;
                    break;
                  }

                add_to_strlist2 (sender, address, 0);
                if (LOG_PARSER)
                  log_info ("The address is : %s\n", address);

                /* We only require one from */
                if (!msg->from)
                  {
                    /* copy from header to be used later */
                    msg->from = parser_create_address (address, 1, msg->sips);
                  }
                tmp = msg->buf + offset;


                break;
              }
          }

        case 'v':
        case 'V':
          {
            if (off = check ("VIA", 3, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Header Via found in %u\n", tmp - msg->buf);

                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);
                if (!msg->via1)
                  msg->via1 = tmp;
                else if (!msg->via2)
                  msg->via2 = tmp;
                tmp = msg->buf + offset;
                break;
              }
          }

        case 'e':
        case 'E':
          {
            if (off = check ("Event", 5, tmp, end))
              {
                if (LOG_PARSER)
                  log_info ("Header Event found in %u\n", tmp - msg->buf);

                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);
                tmp += off;
                msg->evt = parse_event (tmp, msg->buf + offset);
                tmp = msg->buf + offset;
                break;
              }
          }

        case 'r':
        case 'R':
          {
            if (off = check ("REQ", 3, tmp, end))
              {

                if (LOG_PARSER)
                  log_info ("Header Requester found in %u\n", tmp - msg->buf);

                offset += off;
                /* find the end of this header */
                offset += find_end (tmp + off, end);

                /* find the user address */
                tmp += off;
                for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++);
                if (!msg->req)
                  msg->req = parser_create_req (tmp);
                tmp = msg->buf + offset;
                break;
              }
          }

        default:
          {
            if (LOG_PARSER)
              log_info ("Other header found in %u\n", tmp - msg->buf);

            offset += find_end (tmp, end);
            tmp = msg->buf + offset;

          }
        }
    }
  while (not_out (&tmp) && tmp < end);

  msg->hdr_len = msg->hdr_len2 = tmp - msg->buf;
  /* We still have data left, it means body */
  if (tmp < end)
    {
      msg->body_len = end - tmp;
      msg->body = tmp;
    }

  return 0;
}
示例#11
0
/* returns 0 if ok, -1 for errors */
int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
{

	char *tmp;
	char* rest;
	struct msg_start *fl;
	int offset;
	hdr_flags_t flags;

	/* eat crlf from the beginning */
	for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
			(unsigned int)(tmp-buf) < len ; tmp++);
	offset=tmp-buf;
	fl=&(msg->first_line);
	rest=parse_first_line(tmp, len-offset, fl);

	offset+=rest-tmp;
	tmp=rest;
	switch(fl->type){
		case SIP_INVALID:
			LM_DBG("invalid message\n");
			/* if failed to parse the first line, we simply consider that the whole
			   buffer was parsed, so that nothing is left to be parsed :) - this will
			   do the trick and make "msg" struct acceptable for following parsing
			   attempts */
			msg->unparsed = msg->buf + msg->len;
			goto error;
			break;
		case SIP_REQUEST:
			LM_DBG("SIP Request:\n");
			LM_DBG(" method:  <%.*s>\n",fl->u.request.method.len,
				ZSW(fl->u.request.method.s));
			LM_DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
				ZSW(fl->u.request.uri.s));
			LM_DBG(" version: <%.*s>\n",fl->u.request.version.len,
				ZSW(fl->u.request.version.s));
			flags=HDR_VIA_F;
			break;
		case SIP_REPLY:
			LM_DBG("SIP Reply  (status):\n");
			LM_DBG(" version: <%.*s>\n",fl->u.reply.version.len,
					ZSW(fl->u.reply.version.s));
			LM_DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
					ZSW(fl->u.reply.status.s));
			LM_DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
					ZSW(fl->u.reply.reason.s));
			flags=HDR_VIA_F;
			break;
		default:
			LM_DBG("unknown type %d\n",fl->type);
			goto error;
	}
	msg->unparsed=tmp;
	/*find first Via: */
	if (parse_headers(msg, flags, 0)==-1) goto error;

#ifdef EXTRA_DEBUG
	/* dump parsed data */
	if (msg->via1){
		LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
			msg->via1->name.len,
			ZSW(msg->via1->name.s),
			msg->via1->version.len,
			ZSW(msg->via1->version.s),
			msg->via1->transport.len,
			ZSW(msg->via1->transport.s),
			msg->via1->host.len,
			ZSW(msg->via1->host.s),
			msg->via1->port_str.len,
			ZSW(msg->via1->port_str.s),
			msg->via1->port);
		if (msg->via1->params.s)  LM_DBG(";<%.*s>",
				msg->via1->params.len, ZSW(msg->via1->params.s));
		if (msg->via1->comment.s)
				LM_DBG(" <%.*s>",
					msg->via1->comment.len, ZSW(msg->via1->comment.s));
		LM_DBG ("\n");
	}
	if (msg->via2){
		LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
			msg->via2->name.len,
			ZSW(msg->via2->name.s),
			msg->via2->version.len,
			ZSW(msg->via2->version.s),
			msg->via2->transport.len,
			ZSW(msg->via2->transport.s),
			msg->via2->host.len,
			ZSW(msg->via2->host.s),
			msg->via2->port_str.len,
			ZSW(msg->via2->port_str.s),
			msg->via2->port);
		if (msg->via2->params.s)  LM_DBG(";<%.*s>",
				msg->via2->params.len, ZSW(msg->via2->params.s));
		if (msg->via2->comment.s) LM_DBG(" <%.*s>",
				msg->via2->comment.len, ZSW(msg->via2->comment.s));
		LM_DBG ("\n");
	}
#endif


#ifdef EXTRA_DEBUG
	LM_DBG("exiting\n");
#endif

	return 0;

error:
	/* more debugging, msg->orig is/should be null terminated*/
	LM_ERR("message=<%.*s>\n", (int)len, ZSW(buf));
	return -1;
}