示例#1
0
TEST(Utils, UriCoding) {
    string src1 = "This is a simple & short test.";
    string src2 = "$ & < > ? ; # : = , \" ' ~ + %-_";
    string src3 = "! * ' ( ) ; : @ & = + $ , / ? % # [ ]";
    string src4 =
        "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i "
        "j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 - _ . ~";

    string dst1 = "This%20is%20a%20simple%20%26%20short%20test.";
    string dst2 =
        "%24%20%26%20%3C%20%3E%20%3F%20%3B%20%23%20%3A%20%3D%20%2C%20%22%20%27%"
        "20~%20%2B%20%25-_";
    string dst3 =
        "%21%20%2A%20%27%20%28%20%29%20%3B%20%3A%20%40%20%26%20%3D%20%2B%20%24%"
        "20%2C%20%2F%20%3F%20%25%20%23%20%5B%20%5D";
    string dst4 =
        "A%20B%20C%20D%20E%20F%20G%20H%20I%20J%20K%20L%20M%20N%20O%20P%20Q%20R%"
        "20S%20T%20U%20V%20W%20X%20Y%20Z%20a%20b%20c%20d%20e%20f%20g%20h%20i%"
        "20j%20k%20l%20m%20n%20o%20p%20q%20r%20s%20t%20u%20v%20w%20x%20y%20z%"
        "200%201%202%203%204%205%206%207%208%209%20-%20_%20.%20~";

    EXPECT_STREQ(dst1.c_str(), uri_encode(src1).c_str());
    EXPECT_STREQ(dst2.c_str(), uri_encode(src2).c_str());
    EXPECT_STREQ(dst3.c_str(), uri_encode(src3).c_str());
    EXPECT_STREQ(dst4.c_str(), uri_encode(src4).c_str());

    EXPECT_STREQ(src1.c_str(), uri_decode(dst1).c_str());
    EXPECT_STREQ(src2.c_str(), uri_decode(dst2).c_str());
    EXPECT_STREQ(src3.c_str(), uri_decode(dst3).c_str());
    EXPECT_STREQ(src4.c_str(), uri_decode(dst4).c_str());
}
示例#2
0
文件: call.c 项目: sealaunch/baresip
static int normalize_uri(char **out, const char *uri, const struct uri *luri)
{
	struct uri uri2;
	struct pl pl;
	int err;

	if (!out || !uri || !luri)
		return EINVAL;

	pl_set_str(&pl, uri);

	if (0 == uri_decode(&uri2, &pl)) {

		err = str_dup(out, uri);
	}
	else {
		uri2 = *luri;

		uri2.user     = pl;
		uri2.password = pl_null;
		uri2.params   = pl_null;

		err = re_sdprintf(out, "%H", uri_encode, &uri2);
	}

	return err;
}
示例#3
0
/**
 * Send a SIP request with formatted arguments
 *
 * @param reqp     Pointer to allocated SIP request object
 * @param sip      SIP Stack
 * @param stateful Stateful client transaction
 * @param met      Null-terminated SIP Method string
 * @param uri      Null-terminated Request URI string
 * @param route    Next hop route URI (optional)
 * @param auth     SIP authentication state
 * @param sendh    Send handler
 * @param resph    Response handler
 * @param arg      Handler argument
 * @param fmt      Formatted SIP headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful,
		 const char *met, const char *uri, const struct uri *route,
		 struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
		 void *arg, const char *fmt, ...)
{
	struct uri lroute;
	struct mbuf *mb;
	va_list ap;
	int err;

	if (!sip || !met || !uri || !fmt)
		return EINVAL;

	if (!route) {
		struct pl uripl;

		pl_set_str(&uripl, uri);

		err = uri_decode(&lroute, &uripl);
		if (err)
			return err;

		route = &lroute;
	}

	mb = mbuf_alloc(2048);
	if (!mb)
		return ENOMEM;

	err = mbuf_write_str(mb, "Max-Forwards: 70\r\n");

	if (auth)
		err |= sip_auth_encode(mb, auth, met, uri);

	if (err)
		goto out;

	va_start(ap, fmt);
	err = mbuf_vprintf(mb, fmt, ap);
	va_end(ap);

	if (err)
		goto out;

	mb->pos = 0;

	err = sip_request(reqp, sip, stateful, met, -1, uri, -1, route, mb,
			  sendh, resph, arg);
	if (err)
		goto out;

 out:
	mem_deref(mb);

	return err;
}
示例#4
0
文件: uri.c 项目: brain0/ipxe
/**
 * Decode URI field in-place
 *
 * @v uri		URI
 * @v field		URI field index
 */
static void uri_decode_inplace ( struct uri *uri, unsigned int field ) {
    const char *encoded = uri_field ( uri, field );
    char *decoded = ( ( char * ) encoded );
    size_t len;

    /* Do nothing if field is not present */
    if ( ! encoded )
        return;

    /* Decode field in place */
    len = uri_decode ( encoded, decoded, strlen ( encoded ) );

    /* Terminate decoded string */
    decoded[len] = '\0';
}
示例#5
0
文件: dialog.c 项目: soramimi/qSIP
/**
 * Update an existing SIP Dialog from a SIP Message
 *
 * @param dlg SIP Dialog to update
 * @param msg SIP Message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg)
{
	const struct sip_hdr *contact;
	struct sip_addr addr;
	char *uri;
	int err;

	if (!dlg || !msg)
		return EINVAL;

	contact = sip_msg_hdr(msg, SIP_HDR_CONTACT);
	if (!contact)
		return EBADMSG;

	if (sip_addr_decode(&addr, &contact->val))
		return EBADMSG;

	err = pl_strdup(&uri, &addr.auri);
	if (err)
		return err;

	if (dlg->route.scheme.p == dlg->uri) {

		struct uri tmp;
		struct pl pl;

		pl_set_str(&pl, uri);
		err = uri_decode(&tmp, &pl);
		if (err)
			goto out;

		dlg->route = tmp;
	}

	mem_deref(dlg->uri);
	dlg->uri = mem_ref(uri);

 out:
	mem_deref(uri);

	return err;
}
示例#6
0
文件: uri.c 项目: Prutkov-Alex/gpxe
/**
 * Parse URI
 *
 * @v uri_string	URI as a string
 * @ret uri		URI
 *
 * Splits a URI into its component parts.  The return URI structure is
 * dynamically allocated and must eventually be freed by calling
 * uri_put().
 */
struct uri * parse_uri ( const char *uri_string ) {
	struct uri *uri;
	char *raw;
	char *tmp;
	char *path = NULL;
	char *authority = NULL;
	int i;
	size_t raw_len;

	/* Allocate space for URI struct and a copy of the string */
	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
	uri = zalloc ( sizeof ( *uri ) + raw_len );
	if ( ! uri )
		return NULL;
	raw = ( ( ( char * ) uri ) + sizeof ( *uri ) );

	/* Copy in the raw string */
	memcpy ( raw, uri_string, raw_len );

	/* Start by chopping off the fragment, if it exists */
	if ( ( tmp = strchr ( raw, '#' ) ) ) {
		*(tmp++) = '\0';
		uri->fragment = tmp;
	}

	/* Identify absolute/relative URI.  We ignore schemes that are
	 * apparently only a single character long, since otherwise we
	 * misinterpret a DOS-style path name ("C:\path\to\file") as a
	 * URI with scheme="C",opaque="\path\to\file".
	 */
	if ( ( tmp = strchr ( raw, ':' ) ) && ( tmp > ( raw + 1 ) ) ) {
		/* Absolute URI: identify hierarchical/opaque */
		uri->scheme = raw;
		*(tmp++) = '\0';
		if ( *tmp == '/' ) {
			/* Absolute URI with hierarchical part */
			path = tmp;
		} else {
			/* Absolute URI with opaque part */
			uri->opaque = tmp;
		}
	} else {
		/* Relative URI */
		path = raw;
	}

	/* If we don't have a path (i.e. we have an absolute URI with
	 * an opaque portion, we're already finished processing
	 */
	if ( ! path )
		goto done;

	/* Chop off the query, if it exists */
	if ( ( tmp = strchr ( path, '?' ) ) ) {
		*(tmp++) = '\0';
		uri->query = tmp;
	}

	/* Identify net/absolute/relative path */
	if ( strncmp ( path, "//", 2 ) != 0 ) {
		/* Absolute/relative path */
		uri->path = path;
	} else {
		/* Net path.  If this is terminated by the first '/'
		 * of an absolute path, then we have no space for a
		 * terminator after the authority field, so shuffle
		 * the authority down by one byte, overwriting one of
		 * the two slashes.
		 */
		authority = ( path + 2 );
		if ( ( tmp = strchr ( authority, '/' ) ) ) {
			/* Shuffle down */
			uri->path = tmp;
			memmove ( ( authority - 1 ), authority,
				  ( tmp - authority ) );
			authority--;
			*(--tmp) = '\0';
		}

		/* Split authority into user[:password] and host[:port] portions */
		if ( ( tmp = strchr ( authority, '@' ) ) ) {
			/* Has user[:password] */
			*(tmp++) = '\0';
			uri->host = tmp;
			uri->user = authority;
			if ( ( tmp = strchr ( authority, ':' ) ) ) {
				/* Has password */
				*(tmp++) = '\0';
				uri->password = tmp;
			}
		} else {
			/* No user:password */
			uri->host = authority;
		}

		/* Split host into host[:port] */
		if ( ( tmp = strrchr ( uri->host, ':' ) ) ) {
			/* Make sure an IPv6 address isn't broken up. */
			if ( ( tmp > strchr ( uri->host, ']' ) ) ) {
				*(tmp++) = '\0';
				uri->port = tmp;
			}
		}
		
		/* Handle IPv6 case. */
		if ( ( uri->host <= strchr ( uri->host, '[' ) ) &&
		     ( tmp = strchr ( uri->host, ']' ) ) ) {
			uri->host++;
			*(tmp) = 0;
	        }
	}

	/* Decode fields that should be decoded */
	for ( i = URI_FIRST_FIELD; i <= URI_LAST_FIELD; i++ ) {
		const char *field = uri_get_field ( uri, i );
		if ( field && ( URI_ENCODED & ( 1 << i ) ) )
			uri_decode ( field, ( char * ) field,
				     strlen ( field ) + 1 /* NUL */ );
	}

 done:
	DBG ( "URI \"%s\" split into", uri_string );
	dump_uri ( uri );
	DBG ( "\n" );

	return uri;
}
示例#7
0
文件: dialog.c 项目: soramimi/qSIP
/**
 * Initialize a SIP Dialog from an incoming SIP Message
 *
 * @param dlg SIP Dialog to initialize
 * @param msg SIP Message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg)
{
	char *uri = NULL, *rtag = NULL;
	const struct sip_hdr *contact;
	struct route_enc renc;
	struct sip_addr addr;
	struct pl pl;
	int err;

	if (!dlg || dlg->rtag || !dlg->cpos || !msg)
		return EINVAL;

	contact = sip_msg_hdr(msg, SIP_HDR_CONTACT);

	if (!contact)
		return EBADMSG;

	if (sip_addr_decode(&addr, &contact->val))
		return EBADMSG;

	renc.mb = mbuf_alloc(512);
	if (!renc.mb)
		return ENOMEM;

	err = pl_strdup(&uri, &addr.auri);
	if (err)
		goto out;

	err = pl_strdup(&rtag, msg->req ? &msg->from.tag : &msg->to.tag);
	if (err)
		goto out;

	renc.end = 0;

	err |= sip_msg_hdr_apply(msg, msg->req, SIP_HDR_RECORD_ROUTE,
				 record_route_handler, &renc) ? ENOMEM : 0;
	err |= mbuf_printf(renc.mb, "To: %r\r\n",
			   msg->req ? &msg->from.val : &msg->to.val);

	dlg->mb->pos = dlg->cpos;
	err |= mbuf_write_mem(renc.mb, mbuf_buf(dlg->mb),
			      mbuf_get_left(dlg->mb));
	dlg->mb->pos = 0;

	if (err)
		goto out;

	renc.mb->pos = 0;

	if (renc.end) {
		pl.p = (const char *)mbuf_buf(renc.mb) + ROUTE_OFFSET;
		pl.l = renc.end - ROUTE_OFFSET;
		err = sip_addr_decode(&addr, &pl);
		if (err)
			goto out;

		dlg->route = addr.uri;
	}
	else {
		struct uri tmp;

		pl_set_str(&pl, uri);
		err = uri_decode(&tmp, &pl);
		if (err)
			goto out;

		dlg->route = tmp;
	}

	mem_deref(dlg->mb);
	mem_deref(dlg->uri);

	dlg->mb   = mem_ref(renc.mb);
	dlg->rtag = mem_ref(rtag);
	dlg->uri  = mem_ref(uri);
	dlg->rseq = msg->req ? msg->cseq.num : 0;
	dlg->cpos = 0;

 out:
	mem_deref(renc.mb);
	mem_deref(rtag);
	mem_deref(uri);

	return err;
}
示例#8
0
/**
 * Parse URI
 *
 * @v uri_string	URI as a string
 * @ret uri		URI
 *
 * Splits a URI into its component parts.  The return URI structure is
 * dynamically allocated and must eventually be freed by calling
 * uri_put().
 */
struct uri * parse_uri ( const char *uri_string ) {
	struct uri *uri;
	struct parameters *params;
	char *raw;
	char *tmp;
	char *path;
	char *authority;
	size_t raw_len;
	unsigned int field;

	/* Allocate space for URI struct and a copy of the string */
	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
	uri = zalloc ( sizeof ( *uri ) + raw_len );
	if ( ! uri )
		return NULL;
	ref_init ( &uri->refcnt, uri_free );
	raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );

	/* Copy in the raw string */
	memcpy ( raw, uri_string, raw_len );

	/* Identify the parameter list, if present */
	if ( ( tmp = strstr ( raw, "##params" ) ) ) {
		*tmp = '\0';
		tmp += 8 /* "##params" */;
		params = find_parameters ( *tmp ? ( tmp + 1 ) : NULL );
		if ( params ) {
			uri->params = claim_parameters ( params );
		} else {
			/* Ignore non-existent submission blocks */
		}
	}

	/* Chop off the fragment, if it exists */
	if ( ( tmp = strchr ( raw, '#' ) ) ) {
		*(tmp++) = '\0';
		uri->fragment = tmp;
	}

	/* Identify absolute/relative URI */
	if ( ( tmp = strchr ( raw, ':' ) ) ) {
		/* Absolute URI: identify hierarchical/opaque */
		uri->scheme = raw;
		*(tmp++) = '\0';
		if ( *tmp == '/' ) {
			/* Absolute URI with hierarchical part */
			path = tmp;
		} else {
			/* Absolute URI with opaque part */
			uri->opaque = tmp;
			path = NULL;
		}
	} else {
		/* Relative URI */
		path = raw;
	}

	/* If we don't have a path (i.e. we have an absolute URI with
	 * an opaque portion, we're already finished processing
	 */
	if ( ! path )
		goto done;

	/* Chop off the query, if it exists */
	if ( ( tmp = strchr ( path, '?' ) ) ) {
		*(tmp++) = '\0';
		uri->query = tmp;
	}

	/* If we have no path remaining, then we're already finished
	 * processing.
	 */
	if ( ! path[0] )
		goto done;

	/* Identify net/absolute/relative path */
	if ( strncmp ( path, "//", 2 ) == 0 ) {
		/* Net path.  If this is terminated by the first '/'
		 * of an absolute path, then we have no space for a
		 * terminator after the authority field, so shuffle
		 * the authority down by one byte, overwriting one of
		 * the two slashes.
		 */
		authority = ( path + 2 );
		if ( ( tmp = strchr ( authority, '/' ) ) ) {
			/* Shuffle down */
			uri->path = tmp;
			memmove ( ( authority - 1 ), authority,
				  ( tmp - authority ) );
			authority--;
			*(--tmp) = '\0';
		}
	} else {
		/* Absolute/relative path */
		uri->path = path;
		authority = NULL;
	}

	/* If we don't have an authority (i.e. we have a non-net
	 * path), we're already finished processing
	 */
	if ( ! authority )
		goto done;

	/* Split authority into user[:password] and host[:port] portions */
	if ( ( tmp = strchr ( authority, '@' ) ) ) {
		/* Has user[:password] */
		*(tmp++) = '\0';
		uri->host = tmp;
		uri->user = authority;
		if ( ( tmp = strchr ( authority, ':' ) ) ) {
			/* Has password */
			*(tmp++) = '\0';
			uri->password = tmp;
		}
	} else {
		/* No user:password */
		uri->host = authority;
	}

	/* Split host into host[:port] */
	if ( ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) &&
	     ( tmp = strrchr ( uri->host, ':' ) ) ) {
		*(tmp++) = '\0';
		uri->port = tmp;
	}

	/* Decode fields in-place */
	for ( field = 0 ; field < URI_FIELDS ; field++ ) {
		if ( uri_field ( uri, field ) )
			uri_decode ( ( char * ) uri_field ( uri, field ) );
	}

 done:
	DBGC ( uri, "URI parsed \"%s\" to", uri_string );
	uri_dump ( uri );
	DBGC ( uri, "\n" );

	return uri;
}
示例#9
0
void Cconnection::read(const std::string& v)
{
#ifndef NDEBUG
	std::cout << v << std::endl;
#endif
	if (srv_config().m_log_access)
	{
		static std::ofstream f("xbt_tracker_raw.log");
		f << srv_time() << '\t' << inet_ntoa(m_a.sin_addr) << '\t' << ntohs(m_a.sin_port) << '\t' << v << std::endl;
	}
	Ctracker_input ti;
	size_t e = v.find('?');
	if (e == std::string::npos)
		e = v.size();
	else
	{
		size_t a = e + 1;
		size_t b = v.find(' ', a);
		if (b == std::string::npos)
			return;
		while (a < b)
		{
			size_t c = v.find('=', a);
			if (c++ == std::string::npos)
				break;
			size_t d = v.find_first_of(" &", c);
			if (d == std::string::npos)
				break;
			ti.set(v.substr(a, c - a - 1), uri_decode(v.substr(c, d - c)));
			a = d + 1;
		}
	}
	if (!ti.m_ipa || !is_private_ipa(m_a.sin_addr.s_addr))
		ti.m_ipa = m_a.sin_addr.s_addr;
	str_ref torrent_pass;
	size_t a = 4;
	if (a < e && v[a] == '/')
	{
		a++;
		if (a + 32 < e && v[a + 32] == '/')
		{
			torrent_pass.assign(&v[a], 32);
			a += 33;
		}
	}
	std::string h = "HTTP/1.0 200 OK\r\n";
	std::string s;
	bool gzip = true;
	switch (a < v.size() ? v[a] : 0)
	{
	case 'a':
		if (ti.valid())
		{
			gzip = false;
			std::string error = srv_insert_peer(ti, false, find_user_by_torrent_pass(torrent_pass, ti.m_info_hash));
			s = error.empty() ? srv_select_peers(ti) : (boost::format("d14:failure reason%d:%se") % error.size() % error).str();
		}
		break;
	case 'd':
		if (srv_config().m_debug)
		{
			h += "Content-Type: text/html; charset=us-ascii\r\n";
			s = srv_debug(ti);
		}
		break;
	case 's':
		if (v.size() >= 7 && v[6] == 't')
		{
			h += "Content-Type: text/html; charset=us-ascii\r\n";
			s = srv_statistics();
		}
		else if (srv_config().m_full_scrape || !ti.m_info_hash.empty())
		{
			gzip = srv_config().m_gzip_scrape && ti.m_info_hash.empty();
 			s = srv_scrape(ti, find_user_by_torrent_pass(torrent_pass, ti.m_info_hash));
		}
		break;
	}
	if (s.empty())
	{
		if (!ti.m_info_hash.empty() || srv_config().m_redirect_url.empty())
			h = "HTTP/1.0 404 Not Found\r\n";
		else
		{
			h = "HTTP/1.0 302 Found\r\n"
				"Location: " + srv_config().m_redirect_url + (ti.m_info_hash.empty() ? "" : "?info_hash=" + uri_encode(ti.m_info_hash)) + "\r\n";
		}
	}
	else if (gzip)
	{
		shared_data s2 = xcc_z::gzip(s);
#ifndef NDEBUG
		static std::ofstream f("xbt_tracker_gzip.log");
		f << srv_time() << '\t' << v[5] << '\t' << s.size() << '\t' << s2.size() << std::endl;
#endif
		if (s2.size() + 24 < s.size())
		{
			h += "Content-Encoding: gzip\r\n";
			s = to_string(s2);
		}
	}
	h += "\r\n";
#ifdef WIN32
	m_write_b = shared_data(h.size() + s.size());
	memcpy(m_write_b.data(), h);
	memcpy(m_write_b.data() + h.size(), s);
	int r = m_s.send(m_write_b);
#else
	std::array<iovec, 2> d;
	d[0].iov_base = const_cast<char*>(h.data());
	d[0].iov_len = h.size();
	d[1].iov_base = const_cast<char*>(s.data());
	d[1].iov_len = s.size();
	msghdr m;
	m.msg_name = NULL;
	m.msg_namelen = 0;
	m.msg_iov = const_cast<iovec*>(d.data());
	m.msg_iovlen = d.size();
	m.msg_control = NULL;
	m.msg_controllen = 0;
	m.msg_flags = 0;
	int r = sendmsg(m_s, &m, MSG_NOSIGNAL);
#endif
	if (r == SOCKET_ERROR)
	{
		if (WSAGetLastError() != WSAECONNRESET)
			std::cerr << "send failed: " << Csocket::error2a(WSAGetLastError()) << std::endl;
	}
	else if (r != h.size() + s.size())
	{
#ifndef WIN32
		if (r < h.size())
		{
			m_write_b = shared_data(h.size() + s.size());
			memcpy(m_write_b.data(), h);
			memcpy(m_write_b.data() + h.size(), s);
		}
		else
		{
			m_write_b = make_shared_data(s);
			r -= h.size();
		}
#endif
		m_r = m_write_b;
		m_r.advance_begin(r);
	}
	if (m_r.empty())
		m_write_b.clear();
}
示例#10
0
文件: wizd_http.c 项目: birkirb/wizd
// **************************************************************************
// HTTPヘッダを受信して解析する。
//
// 処理するのはGETのみ。GET以外のメソッドが来たらエラー
// 今のところ、URIとuser_agent、Range、Hostを解析。
// URIは、URIデコードもやる。
//
//	return: 0 		正常終了
//	return: 0以外 	エラー
// **************************************************************************
static int http_header_receive(int accept_socket, HTTP_RECV_INFO *http_recv_info_p)
{
	int result = 0;
	int	recv_len;
	unsigned char	line_buf[1024];	// 大きめに。
	unsigned char 	work_buf[1024];
	unsigned char 	work_buf2[1024];
	unsigned char 	split1[1024];
	unsigned char 	split2[1024];

	int		ret;
	int		i;
	int		j;

	// ================================
	// 1行づつ HTTPヘッダを受信
	// ================================
	for (i=0;;i++)
	{
		// 1行受信 実行。
		memset(line_buf, '\0', sizeof(line_buf));
		recv_len = line_receive(accept_socket, line_buf, sizeof(line_buf));

		// debug. 受信したヘッダ表示
		debug_log_output("'%s'(%d byte)\n", line_buf, recv_len );

		// 受信した内容をチェック。
		if ( i != 0 && recv_len == 0 ) // 空行検知。ヘッダ受信終了。
		{
			break;
		}
		else if ( recv_len < 0 ) // 受信失敗
		{
			return ( -1 );
		}

		// --------------------------
		// GETメッセージチェック
		// --------------------------
		if ( i == 0 ) // 1行目のみチェック
		{
			debug_log_output("URI Check start.'%s'\n", line_buf);

			// GET/POSTある?
			if (strncmp(line_buf, "GET ", 4) && strncmp(line_buf, "POST ", 5))
			{
				debug_log_output("'GET' or 'POST' not found. error.");
				return ( -1 );
			}
			strncpy(http_recv_info_p->request_method, line_buf, sizeof(http_recv_info_p->request_method));
			cut_after_character(http_recv_info_p->request_method, ' ');

			// 最初のスペースまでを削除。
			cut_before_character(line_buf, ' ');

			// 次にスペースが出てきたところの後ろまでを削除。
			cut_after_character(line_buf, ' ');

			// ===========================
			// GETオプション部解析
			// ===========================

			// REQUEST_URI用・Proxy用に値を保存
			strncpy(http_recv_info_p->request_uri, line_buf, sizeof(http_recv_info_p->request_uri));

			// '?'が存在するかチェック。
			if ( strchr(line_buf, '?') != NULL )
			{

				strncpy(work_buf, line_buf, sizeof(work_buf));

				// '?'より前をカット
				cut_before_character(work_buf, '?' );
				debug_log_output("work_buf = '%s'", work_buf );

				while ( 1 )
				{
					memset(split1, '\0', sizeof(split1));
					memset(split2, '\0', sizeof(split2));

					uri_decode(split1, sizeof(split1), work_buf, sizeof(work_buf) );
					strcpy(work_buf, split1);

					// 最初に登場する'&'で分割
					ret = sentence_split(work_buf, '&', split1, split2 );
					if ( ret == 0 ) // 分割成功
					{
						strncpy(work_buf, split2, sizeof(work_buf));
					}
					else if (strlen(work_buf) > 0) // まだwork_bufに中身ある?
					{
						strncpy( split1, work_buf, sizeof(split1));
						strncpy( work_buf, "", sizeof(work_buf));
					}
					else // 処理終了
					{
						break;
					}

					// -------------------------------------
					// GETした内容 解析開始
					// 超安直。いいのかこんな比較で。
					// -------------------------------------

					// URIデコード
					// uri_decode(work_buf2, sizeof(work_buf2), split1, sizeof(split1) );
					strcpy(work_buf2, split1);

					// "page="あるか調査。
					if (strncasecmp( work_buf2, "page=", strlen("page=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');
						if ( strlen(work_buf2) > 0 )
						{
							// 構造体に値を保存。
							http_recv_info_p->page = atoi(work_buf2);
						}

						continue;
					}

					// "menupage="あるか調査。
					if (strncasecmp( work_buf2, "menupage=", strlen("menupage=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');
						if ( strlen(work_buf2) > 0 )
						{
							// 構造体に値を保存。
							http_recv_info_p->menupage = atoi(work_buf2);
						}

						continue;
					}

					// "title=" DVD title selection
					if (strncasecmp( work_buf2, "title=", strlen("title=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');
						if ( strlen(work_buf2) > 0 )
						{
							// 構造体に値を保存。
							http_recv_info_p->title = atoi(work_buf2);
						}

						continue;
					}

					if (strncasecmp( work_buf2, "width=", strlen("width=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');
						if ( strlen(work_buf2) > 0 )
						{
							// 構造体に値を保存。
							global_param.target_jpeg_width = atoi(work_buf2);
						}

						continue;
					}

					if (strncasecmp( work_buf2, "height=", strlen("height=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');
						if ( strlen(work_buf2) > 0 )
						{
							// 構造体に値を保存。
							global_param.target_jpeg_height = atoi(work_buf2);
						}

						continue;
					}

					// "action="あるか調査。
					if (strncasecmp( work_buf2, "action=", strlen("action=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->action, work_buf2, sizeof(http_recv_info_p->action));
						continue;
					}

					// "type=" allplay list type
					if (strncasecmp( work_buf2, "type=movie", strlen("type=movie") ) == 0 )
					{
						http_recv_info_p->default_file_type = TYPE_MOVIE;
						continue;
					}
					if (strncasecmp( work_buf2, "type=music", strlen("type=music") ) == 0 )
					{
						http_recv_info_p->default_file_type = TYPE_MUSIC;
						continue;
					}
					if (strncasecmp( work_buf2, "type=photo", strlen("type=photo") ) == 0 )
					{
						http_recv_info_p->default_file_type = TYPE_JPEG;
						continue;
					}
					if (strncasecmp( work_buf2, "type=soundtrack", strlen("type=soundtrack") ) == 0 )
					{
						http_recv_info_p->default_file_type = TYPE_MUSICLIST;
						continue;
					}
					if (strncasecmp( work_buf2, "type=slideshow", strlen("type=slideshow") ) == 0 )
					{
						http_recv_info_p->default_file_type = TYPE_PLAYLIST;
						continue;
					}
					
					// "option="あるか調査
					if (strncasecmp( work_buf2, "option=", strlen("option=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->option, work_buf2, sizeof(http_recv_info_p->option));
						continue;
					}

					// "alias="あるか調査
					if (strncasecmp( work_buf2, "alias=", strlen("alias=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->alias, work_buf2, sizeof(http_recv_info_p->alias));

						if (strncasecmp(http_recv_info_p->alias, "movie", strlen("movie")) == 0)
							http_recv_info_p->default_file_type = TYPE_MOVIE;
						else if (strncasecmp(http_recv_info_p->alias, "music", strlen("music")) == 0)
							http_recv_info_p->default_file_type = TYPE_MUSIC;
						else if (strncasecmp(http_recv_info_p->alias, "photo", strlen("photo")) == 0)
							http_recv_info_p->default_file_type = TYPE_JPEG;
						else
							http_recv_info_p->default_file_type = TYPE_UNKNOWN;

						continue;
					}

					if (strncasecmp( work_buf2, "lsearch=", strlen("lsearch=") ) == 0 )
					{
						cut_before_character(work_buf2, '=');

						strcpy(http_recv_info_p->lsearch, work_buf2);
						strcpy(http_recv_info_p->recv_uri, work_buf2);
						continue;
					}

					// "search=
					if (strncasecmp( work_buf2, "search", strlen("search") ) == 0 )
					{
						if (strncasecmp(work_buf2, "search_movie", strlen("search_movie")) == 0) {
							http_recv_info_p->search_type = TYPE_MOVIE;
							strcpy(http_recv_info_p->search_str, "_movie");
							http_recv_info_p->default_file_type = TYPE_MOVIE;
							// printf("search movie for ");
						} else if (strncasecmp(work_buf2, "search_music", strlen("search_music")) == 0) {
							http_recv_info_p->search_type = TYPE_MUSIC;
							strcpy(http_recv_info_p->search_str, "_music");
							http_recv_info_p->default_file_type = TYPE_MUSIC;
							// printf("search music for ");
						} else if (strncasecmp(work_buf2, "search_photo", strlen("search_photo")) == 0) {
							http_recv_info_p->search_type = TYPE_JPEG;
							strcpy(http_recv_info_p->search_str, "_photo");
							http_recv_info_p->default_file_type = TYPE_JPEG;
							// printf("search photo for ");
						} else if (strncasecmp(work_buf2, "search_all", strlen("search_all")) == 0) {
							http_recv_info_p->search_type = TYPE_UNKNOWN;
							strcpy(http_recv_info_p->search_str, "_all");
							http_recv_info_p->default_file_type = TYPE_UNKNOWN;
							// printf("search all for ");
						} else
							continue;

						cut_before_character(work_buf2, '=');

						strncpy(http_recv_info_p->search, work_buf2, sizeof(http_recv_info_p->search));
						if (http_recv_info_p->search[0] == '\0')
							// everything qualifies
							strcpy(http_recv_info_p->search, ".*");

						// printf("%s\n", http_recv_info_p->search);
						continue;
					}

					// "sort="あるか調査
					if (strncasecmp( work_buf2, "sort=", strlen("sort=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->sort, work_buf2, sizeof(http_recv_info_p->sort));
						continue;
					}


					// "dvdopt="あるか調査
					if (strncasecmp( work_buf2, "dvdopt=", strlen("dvdopt=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->dvdopt, work_buf2, sizeof(http_recv_info_p->dvdopt));
						continue;
					}

					// "focus="あるか調査
					if (strncasecmp( work_buf2, "focus=", strlen("focus=") ) == 0 )
					{
						// = より前を削除
						cut_before_character(work_buf2, '=');

						// 構造体に値を保存。
						strncpy(http_recv_info_p->focus, work_buf2, sizeof(http_recv_info_p->focus));
						continue;
					}




				}
			}

			debug_log_output("http_recv_info_p->page = '%d'", http_recv_info_p->page);
			debug_log_output("http_recv_info_p->title = '%d'", http_recv_info_p->title);
			debug_log_output("http_recv_info_p->action = '%s'", http_recv_info_p->action);
			debug_log_output("http_recv_info_p->option = '%s'", http_recv_info_p->option);
			debug_log_output("http_recv_info_p->dvdopt = '%s'", http_recv_info_p->dvdopt);

			// URIデコード
			cut_after_character(line_buf, '?');
			uri_decode(work_buf, sizeof(work_buf), line_buf, sizeof(line_buf) );
			strncpy(line_buf, work_buf, sizeof(line_buf));
			debug_log_output("URI(decoded):'%s'\n", line_buf);

			convert_language_code(line_buf, work_buf, sizeof(work_buf), CODE_AUTO, CODE_EUC);
			debug_log_output("URI(decoded,euc,FYI):'%s'\n", work_buf);


			// 構造体に保存
			if (http_recv_info_p->lsearch[0] == '\0')
				strncpy(http_recv_info_p->recv_uri, line_buf, sizeof(http_recv_info_p->recv_uri));

			continue;

		}

		// User-agent切り出し
		if ( strncasecmp(line_buf, HTTP_USER_AGENT, strlen(HTTP_USER_AGENT) ) == 0 )
		{
			// ':'より前を切る
			cut_before_character(line_buf, ':');
			cut_first_character(line_buf, ' ');

			// 構造体に保存
			strncpy( http_recv_info_p->user_agent, line_buf, sizeof(http_recv_info_p->user_agent));

			// Set the skin name based on user agent, if desired
			for(j=0; j<global_param.alternate_skin_count; j++) {
				debug_log_output("Checking for '%s'", global_param.alternate_skin_match[j]);
				if(strstr(line_buf, global_param.alternate_skin_match[j]) != NULL) {
					strcpy(global_param.skin_name, global_param.alternate_skin_name[j]);
					debug_log_output("User agent matches alternate skin '%s'", global_param.skin_name); 
					break;
				}
			}
			continue;
		}

		// Rangeあるかチェック
		if ( strncasecmp(line_buf, HTTP_RANGE,	strlen(HTTP_RANGE) ) == 0 )
		{
			debug_log_output("%s Detect.\n", HTTP_RANGE);
			// ':' より前を切る。
			cut_before_character(line_buf, ':');
			cut_first_character(line_buf, ' ');

			// recv_range にRangeの中身保存
			strncpy(http_recv_info_p->recv_range, line_buf, sizeof(http_recv_info_p->recv_range));

			// '=' より前を切る
			cut_before_character(line_buf, '=');


			// '-'で前後に分割。
			sentence_split(line_buf, '-', work_buf, work_buf2);

			debug_log_output("work_buf='%s'\n", work_buf);
			debug_log_output("work_buf2='%s'\n", work_buf2);

			// 値を文字列→数値変換
			http_recv_info_p->range_start_pos  = strtoull(work_buf, NULL, 10);

			if ( strlen(work_buf2) > 0 )
			{
				http_recv_info_p->range_end_pos = strtoull(work_buf2, NULL, 10);
			}


			debug_log_output("range_start_pos=%d\n", http_recv_info_p->range_start_pos);
			debug_log_output("range_end_pos=%d\n", http_recv_info_p->range_end_pos);

			continue;
		}

		// Hostあるかチェック
		if ( strncasecmp(line_buf, HTTP_HOST,	strlen(HTTP_HOST) ) == 0 )
		{
			debug_log_output("%s Detect.\n", HTTP_HOST);
			// ':' より前を切る。
			cut_before_character(line_buf, ':');
			cut_first_character(line_buf, ' ');

			strncpy(http_recv_info_p->recv_host, line_buf, sizeof(http_recv_info_p->recv_host));
			if(NULL == strchr(http_recv_info_p->recv_host, ':')) {
				debug_log_output("CLIENT BUG: Host header field was missing port number - fixing");
				snprintf(http_recv_info_p->recv_host + strlen(http_recv_info_p->recv_host), sizeof(http_recv_info_p->recv_host)-1, ":%d", global_param.server_port);
				debug_log_output("%s '%s'", HTTP_HOST, http_recv_info_p->recv_host);
			}

			continue;
		}

		if (strncasecmp(line_buf, HTTP_AUTHORIZATION, strlen(HTTP_AUTHORIZATION)) == 0) {
			debug_log_output("%s Detect.\n", HTTP_AUTHORIZATION);
			// ':' より前を切る。
			cut_before_character(line_buf, ':');
			cut_first_character(line_buf, ' ');
			if (strncmp(line_buf, "Basic ", 6)) {
				debug_log_output("received '%s', is not supported.", line_buf);
				continue;
			}

			strncpy(http_recv_info_p->passwd, line_buf + 6, sizeof(http_recv_info_p->passwd));

			continue;
		}

		// Content-Lengthあるかチェック
		if ( strncasecmp(line_buf, HTTP_CONTENT_LENGTH_STR,	strlen(HTTP_CONTENT_LENGTH_STR) ) == 0 )
		{
			debug_log_output("%s Detect.\n", HTTP_CONTENT_LENGTH_STR);
			// ':' より前を切る。
			cut_before_character(line_buf, ':');
			cut_first_character(line_buf, ' ');
			/* recv_content_length は わざと long です. */
			http_recv_info_p->recv_content_length = strtol(line_buf, NULL, 10);
			debug_log_output("Content-Length: %ld", http_recv_info_p->recv_content_length);
			continue;
		}

	}

	return result;
}
示例#11
0
void Cconnection::read(const std::string& v)
{
#ifndef NDEBUG
	std::cout << v << std::endl;
#endif
	if (m_server->config().m_log_access)
	{
		static std::ofstream f("xbt_tracker_raw.log");
		f << m_server->time() << '\t' << inet_ntoa(m_a.sin_addr) << '\t' << ntohs(m_a.sin_port) << '\t' << v << std::endl;
	}
	Ctracker_input ti;
	size_t e = v.find('?');
	if (e == std::string::npos)
		e = v.size();
	else
	{
		size_t a = e + 1;
		size_t b = v.find(' ', a);
		if (b == std::string::npos)
			return;
		while (a < b)
		{
			size_t c = v.find('=', a);
			if (c++ == std::string::npos)
				break;
			size_t d = v.find_first_of(" &", c);
			if (d == std::string::npos)
				break;
			ti.set(v.substr(a, c - a - 1), uri_decode(v.substr(c, d - c)));
			a = d + 1;
		}
	}
	if (!ti.m_ipa || !is_private_ipa(m_a.sin_addr.s_addr))
		ti.m_ipa = m_a.sin_addr.s_addr;
	std::string torrent_pass0;
	size_t a = 4;
	if (a < e && v[a] == '/')
	{
		a++;
		if (a + 1 < e && v[a + 1] == '/')
			a += 2;
		if (a + 32 < e && v[a + 32] == '/')
		{
			torrent_pass0 = v.substr(a, 32);
			a += 33;
			if (a + 40 < e && v[a + 40] == '/')
				a += 41;
		}
	}
	std::string h = "HTTP/1.0 200 OK\r\n";
	Cvirtual_binary s;
	bool gzip = true;
	switch (a < v.size() ? v[a] : 0)
	{
	case 'a':
		if (!ti.valid())
			break;
		gzip = false;
		if (0)
			s = Cbvalue().d(bts_failure_reason, bts_banned_client).read();
		else
		{
			std::string error = m_server->insert_peer(ti, false, m_server->find_user_by_torrent_pass(torrent_pass0, ti.m_info_hash));
			s = error.empty() ? m_server->select_peers(ti) : Cbvalue().d(bts_failure_reason, error).read();
		}
		break;
	case 'd':
		if (m_server->config().m_debug)
		{
			gzip = m_server->config().m_gzip_debug;
			h += "Content-Type: text/html; charset=us-ascii\r\n";
			s = Cvirtual_binary(m_server->debug(ti));
		}
		break;
	case 's':
		if (v.size() >= 7 && v[6] == 't')
		{
			gzip = m_server->config().m_gzip_debug;
			h += "Content-Type: text/html; charset=us-ascii\r\n";
			s = Cvirtual_binary(m_server->statistics());
		}
		else if (m_server->config().m_full_scrape || ti.m_compact || !ti.m_info_hash.empty())
		{
			gzip = m_server->config().m_gzip_scrape && !ti.m_compact && ti.m_info_hash.empty();
			s = m_server->scrape(ti);
		}
		break;
	}
	if (s.empty())
	{
		if (!ti.m_peer_id.empty() || m_server->config().m_redirect_url.empty())
			h = "HTTP/1.0 404 Not Found\r\n";
		else
		{
			h = "HTTP/1.0 302 Found\r\n"
				"Location: " + m_server->config().m_redirect_url + (ti.m_info_hash.empty() ? "" : "?info_hash=" + uri_encode(ti.m_info_hash)) + "\r\n";
		}
	}
	else if (gzip)
	{
		Cvirtual_binary s2 = xcc_z::gzip(s);
#ifndef NDEBUG
		static std::ofstream f("xbt_tracker_gzip.log");
		f << m_server->time() << '\t' << v[5] << '\t' << s.size() << '\t' << s2.size() << std::endl;
#endif
		if (s2.size() + 24 < s.size())
		{
			h += "Content-Encoding: gzip\r\n";
			s = s2;
		}
	}
	h += "\r\n";
#ifdef WIN32
	m_write_b.resize(h.size() + s.size());
	memcpy(m_write_b.data_edit(), h.data(), h.size());
	s.read(m_write_b.data_edit() + h.size());
	int r = m_s.send(m_write_b);
#else
	boost::array<iovec, 2> d;
	d[0].iov_base = const_cast<char*>(h.data());
	d[0].iov_len = h.size();
	d[1].iov_base = const_cast<unsigned char*>(s.data());
	d[1].iov_len = s.size();
	msghdr m;
	m.msg_name = NULL;
	m.msg_namelen = 0;
	m.msg_iov = const_cast<iovec*>(d.data());
	m.msg_iovlen = d.size();
	m.msg_control = NULL;
	m.msg_controllen = 0;
	m.msg_flags = 0;
	int r = sendmsg(m_s, &m, MSG_NOSIGNAL);
#endif
	if (r == SOCKET_ERROR)
	{
		if (WSAGetLastError() != WSAECONNRESET)
			std::cerr << "send failed: " << Csocket::error2a(WSAGetLastError()) << std::endl;
	}
	else if (r != h.size() + s.size())
	{
#ifndef WIN32
		if (r < h.size())
		{
			m_write_b.resize(h.size() + s.size());
			memcpy(m_write_b.data_edit(), h.data(), h.size());
			s.read(m_write_b.data_edit() + h.size());
		}
		else
		{
			m_write_b = s;
			r -= h.size();
		}
#endif
		m_r = m_write_b;
		m_r += r;
	}
	if (m_r.empty())
		m_write_b.clear();
}
示例#12
0
TEST(uri, test_uri_decode)
{
    lwm2m_uri_t* uri;
    multi_option_t extraID = { .next = nullptr, .is_static = 1, .len = 3, .data = (uint8_t *) "555" };
    multi_option_t rID = { .next = nullptr, .is_static = 1, .len = 1, .data = (uint8_t *) "0" };
    multi_option_t iID = { .next = &rID, .is_static = 1, .len = 2, .data = (uint8_t *) "11" };
    multi_option_t oID = { .next = &iID, .is_static = 1, .len = 4, .data = (uint8_t *) "9050" };
    multi_option_t location = { .next = nullptr, .is_static = 1, .len = 4, .data = (uint8_t *) "5a3f" };
    multi_option_t locationDecimal = { .next = nullptr, .is_static = 1, .len = 4, .data = (uint8_t *) "5312" };
    multi_option_t reg = { .next = nullptr, .is_static = 1, .len = 2, .data = (uint8_t *) "rd" };
    multi_option_t boot = { .next = nullptr, .is_static = 1, .len = 2, .data = (uint8_t *) "bs" };

    memoryObserver.reset();

    /* "/rd" */
    uri = uri_decode(nullptr, &reg);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_REGISTRATION);
    lwm2m_free(uri);

    /* "/rd/5a3f" */
    reg.next = &location;
    uri = uri_decode(nullptr, &reg);
    /* should not fail, error in uri_parse */
    /* ASSERT_TRUE(uri); */
    lwm2m_free(uri);

    /* "/rd/5312" */
    reg.next = &locationDecimal;
    uri = uri_decode(nullptr, &reg);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_REGISTRATION | LWM2M_URI_FLAG_OBJECT_ID);
    ASSERT_EQ(uri->objectId, 5312);
    lwm2m_free(uri);

    /* "/bs" */
    uri = uri_decode(nullptr, &boot);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_BOOTSTRAP);
    lwm2m_free(uri);

    /* "/bs/5a3f" */
    boot.next = &location;
    uri = uri_decode(nullptr, &boot);
    ASSERT_FALSE(uri);
    lwm2m_free(uri);

    /* "/9050/11/0" */
    uri = uri_decode(nullptr, &oID);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_DM | LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID | LWM2M_URI_FLAG_RESOURCE_ID);
    ASSERT_EQ(uri->objectId, 9050);
    ASSERT_EQ(uri->instanceId, 11);
    ASSERT_EQ(uri->resourceId, 0);
    lwm2m_free(uri);

    /* "/11/0" */
    uri = uri_decode(nullptr, &iID);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_DM | LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID);
    ASSERT_EQ(uri->objectId, 11);
    ASSERT_EQ(uri->instanceId, 0);
    lwm2m_free(uri);

    /* "/0" */
    uri = uri_decode(nullptr, &rID);
    ASSERT_TRUE(uri);
    ASSERT_EQ(uri->flag, LWM2M_URI_FLAG_DM | LWM2M_URI_FLAG_OBJECT_ID);
    ASSERT_EQ(uri->objectId, 0);
    lwm2m_free(uri);

    /* "/9050/11/0/555" */
    rID.next = &extraID;
    uri = uri_decode(nullptr, &oID);
    ASSERT_FALSE(uri);
    lwm2m_free(uri);

    /* "/0/5a3f" */
    rID.next = &location;
    uri = uri_decode(nullptr, &rID);
    ASSERT_FALSE(uri);
    lwm2m_free(uri);

    MEMEVAL(FAIL());
}

TEST(uri, test_string_to_uri)
{
    int result;
    lwm2m_uri_t uri;
    memoryObserver.reset();
    result = lwm2m_stringToUri("", 0, &uri);
    ASSERT_EQ(result, 0);
    result = lwm2m_stringToUri("no_uri", 6, &uri);
    ASSERT_EQ(result, 0);
    result = lwm2m_stringToUri("/1", 2, &uri);
    ASSERT_EQ(result, 2);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_OBJECT_ID), LWM2M_URI_FLAG_OBJECT_ID);
    ASSERT_EQ(uri.objectId, 1);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_INSTANCE_ID), 0);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_RESOURCE_ID), 0);

    result = lwm2m_stringToUri("/1/2", 4, &uri);
    ASSERT_EQ(result, 4);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_OBJECT_ID), LWM2M_URI_FLAG_OBJECT_ID);
    ASSERT_EQ(uri.objectId, 1);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_INSTANCE_ID), LWM2M_URI_FLAG_INSTANCE_ID);
    ASSERT_EQ(uri.instanceId, 2);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_RESOURCE_ID), 0);

    result = lwm2m_stringToUri("/1/2/3", 6, &uri);
    ASSERT_EQ(result, 6);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_OBJECT_ID), LWM2M_URI_FLAG_OBJECT_ID);
    ASSERT_EQ(uri.objectId, 1);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_INSTANCE_ID), LWM2M_URI_FLAG_INSTANCE_ID);
    ASSERT_EQ(uri.instanceId, 2);
    ASSERT_EQ((uri.flag & LWM2M_URI_FLAG_RESOURCE_ID), LWM2M_URI_FLAG_RESOURCE_ID);
    ASSERT_EQ(uri.resourceId, 3);

    MEMEVAL(FAIL());
}
示例#13
0
文件: msg.c 项目: Issic47/libre
/**
 * Decode a SIP message
 *
 * @param msgp Pointer to allocated SIP Message
 * @param mb   Buffer containing SIP Message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb)
{
	struct pl x, y, z, e, name;
	const char *p, *v, *cv;
	struct sip_msg *msg;
	bool comsep, quote;
	enum sip_hdrid id = SIP_HDR_NONE;
	uint32_t ws, lf;
	size_t l;
	int err;

	if (!msgp || !mb)
		return EINVAL;

	p = (const char *)mbuf_buf(mb);
	l = mbuf_get_left(mb);

	if (re_regex(p, l, "[^ \t\r\n]+ [^ \t\r\n]+ [^\r\n]*[\r]*[\n]1",
		     &x, &y, &z, NULL, &e) || x.p != (char *)mbuf_buf(mb))
		return (l > STARTLINE_MAX) ? EBADMSG : ENODATA;

	msg = mem_zalloc(sizeof(*msg), destructor);
	if (!msg)
		return ENOMEM;

	err = hash_alloc(&msg->hdrht, HDR_HASH_SIZE);
	if (err)
		goto out;

	msg->tag = rand_u64();
	msg->mb  = mem_ref(mb);
	msg->req = (0 == pl_strcmp(&z, "SIP/2.0"));

	if (msg->req) {

		msg->met = x;
		msg->ruri = y;
		msg->ver = z;

		if (uri_decode(&msg->uri, &y)) {
			err = EBADMSG;
			goto out;
		}
	}
	else {
		msg->ver    = x;
		msg->scode  = pl_u32(&y);
		msg->reason = z;

		if (!msg->scode) {
			err = EBADMSG;
			goto out;
		}
	}

	l -= e.p + e.l - p;
	p = e.p + e.l;

	name.p = v = cv = NULL;
	name.l = ws = lf = 0;
	comsep = false;
	quote = false;

	for (; l > 0; p++, l--) {

		switch (*p) {

		case ' ':
		case '\t':
			lf = 0; /* folding */
			++ws;
			break;

		case '\r':
			++ws;
			break;

		case '\n':
			++ws;

			if (!lf++)
				break;

			++p; --l; /* eoh */

			/*@fallthrough@*/

		default:
			if (lf || (*p == ',' && comsep && !quote)) {

				if (!name.l) {
					err = EBADMSG;
					goto out;
				}

				err = hdr_add(msg, &name, id, cv ? cv : p,
					      cv ? p - cv - ws : 0,
					      true, cv == v && lf);
				if (err)
					goto out;

				if (!lf) { /* comma separated */
					cv = NULL;
					break;
				}

				if (cv != v) {
					err = hdr_add(msg, &name, id,
						      v ? v : p,
						      v ? p - v - ws : 0,
						      false, true);
					if (err)
						goto out;
				}

				if (lf > 1) { /* eoh */
					err = 0;
					goto out;
				}

				comsep = false;
				name.p = NULL;
				cv = v = NULL;
				lf = 0;
			}

			if (!name.p) {
				name.p = p;
				name.l = 0;
				ws = 0;
			}

			if (!name.l) {
				if (*p != ':') {
					ws = 0;
					break;
				}

				name.l = MAX((int)(p - name.p - ws), 0);
				if (!name.l) {
					err = EBADMSG;
					goto out;
				}

				id = hdr_hash(&name);
				comsep = hdr_comma_separated(id);
				break;
			}

			if (!cv) {
				quote = false;
				cv = p;
			}

			if (!v) {
				v = p;
			}

			if (*p == '"')
				quote = !quote;

			ws = 0;
			break;
		}
	}

	err = ENODATA;

 out:
	if (err)
		mem_deref(msg);
	else {
		*msgp = msg;
		mb->pos = mb->end - l;
	}

	return err;
}
示例#14
0
// **************************************************************************
// HTTPヘッダを受信して解析する。
//
// 処理するのはGETのみ。GET以外のメソッドが来たらエラー
// 今のところ、URIとuser_agent、Range、Hostを解析。
// URIは、URIデコードもやる。
//
//	return: 0 		正常終了
//	return: 0以外 	エラー
// **************************************************************************
static int http_header_receive(int accept_socket, HTTP_RECV_INFO *http_recv_info_p)
{
    int result = 0;
    int	recv_len;
    char	line_buf[1024];	// 大きめに。
    char 	work_buf[1024];
    char 	work_buf2[1024];
    char 	split1[1024];
    char 	split2[1024];
    int		ret;
    int		i;
    // ================================
    // 1行づつ HTTPヘッダを受信
    // ================================
    for (i=0;;i++){
        // 1行受信 実行。
        recv_len = line_receive(accept_socket, line_buf, sizeof(line_buf));
        // 受信した内容をチェック。
        if ( recv_len == 0 ){ // 空行検知。ヘッダ受信終了。
            break;
        }else if ( recv_len < 0 ){ // 受信失敗
            return ( -1 );
        }
        // debug. 受信したヘッダ表示
        debug_log_output("'%s'(%d byte)\n", line_buf, recv_len );
        // --------------------------
        // GETメッセージチェック
        // --------------------------
        if ( i == 0 ){ // 1行目のみチェック
            debug_log_output("%d:URI Check start.'%s'\n", accept_socket,line_buf);
            // GETある?
            if       ( strstr(line_buf, "GET") != NULL ){
                http_recv_info_p->isGet = 1;
            }else if ( strstr(line_buf, "HEAD") != NULL ){
                http_recv_info_p->isGet = 2;
            }else if ( strstr(line_buf, "POST") != NULL ){
                http_recv_info_p->isGet = 3;
            }else{
                debug_log_output("'GET' not found. error.%d",accept_socket);
                return ( -1 );
            }
            // 最初のスペースまでを削除。
            cut_before_character(line_buf, ' ');
            // 次にスペースが出てきたところの後ろまでを削除。
            cut_after_character(line_buf, ' ');
            // ===========================
            // GETオプション部解析
            // ===========================
            // REQUEST_URI用・Proxy用に値を保存
            strncpy(http_recv_info_p->request_uri, line_buf, sizeof(http_recv_info_p->request_uri));
            // '?'が存在するかチェック。
            if ( strchr(line_buf, '?') != NULL ){
                strncpy(work_buf, line_buf, sizeof(work_buf));
                // '?'より前をカット
                cut_before_character(work_buf, '?' );
                while ( 1 ){
                    memset(split1, 0, sizeof(split1));
                    memset(split2, 0, sizeof(split2));
                    // 最初に登場する'&'で分割
                    ret = sentence_split(work_buf, '&', split1, split2 );
                    if ( ret == 0 ){ // 分割成功
                        strncpy(work_buf, split2, sizeof(work_buf));
                    }else if (strlen(work_buf) > 0){ // まだwork_bufに中身ある?
                        strncpy( split1, work_buf, sizeof(split1));
                        strncpy( work_buf, "", sizeof(work_buf));
                    }else{ // 処理終了
                        break;
                    }
                    // -------------------------------------
                    // GETした内容 解析開始
                    // 超安直。いいのかこんな比較で。
                    // -------------------------------------
                    // URIデコード
                    uri_decode(work_buf2, sizeof(work_buf2), split1, sizeof(split1) );
                    // "action="あるか調査。
                    if (strncasecmp( work_buf2, "action=", strlen("action=") ) == 0 ){
                        // = より前を削除
                        cut_before_character(work_buf2, '=');
                        // 構造体に値を保存。
                        strncpy(http_recv_info_p->action, work_buf2, sizeof(http_recv_info_p->action));
                        continue;
                    }
                }
            }
            debug_log_output("http_recv_info_p->action = '%s'", http_recv_info_p->action);
            // URIデコード
            cut_after_character(line_buf, '?');
            uri_decode(work_buf, sizeof(work_buf), line_buf, sizeof(line_buf) );
            strncpy(line_buf, work_buf, sizeof(line_buf));
            debug_log_output("URI(decoded):'%s'\n", line_buf);
            convert_language_code(line_buf, work_buf, sizeof(work_buf), CODE_AUTO, CODE_EUC);
            debug_log_output("URI(decoded,euc,FYI):'%s'\n", work_buf);
            // 構造体に保存
            strncpy(http_recv_info_p->recv_uri, line_buf, sizeof(http_recv_info_p->recv_uri));
            //httpから始まってる場合には、http://以降の最初の'/'の前でカット
            if( strncmp(http_recv_info_p->recv_uri,"http://",7)==0){
                char* ptr = strstr(http_recv_info_p->recv_uri+7,"/");
                if( ptr ){
                    strcpy(http_recv_info_p->recv_uri,ptr);
                }
            }
            continue;
        }
        // User-agent切り出し
        if ( strncasecmp(line_buf, HTTP_USER_AGENT, strlen(HTTP_USER_AGENT) ) == 0 ){
            debug_log_output("User-agent: Detect.\n");
            // ':'より前を切る
            cut_before_character(line_buf, ':');
            cut_first_character(line_buf, ' ');
            // 構造体に保存
            strncpy( http_recv_info_p->user_agent, line_buf, sizeof(http_recv_info_p->user_agent));
            continue;
        }
        // Rangeあるかチェック
        if ( strncasecmp(line_buf, HTTP_RANGE,	strlen(HTTP_RANGE) ) == 0 ){
            debug_log_output("%s Detect.\n", HTTP_RANGE);
            // ':' より前を切る。
            cut_before_character(line_buf, ':');
            cut_first_character(line_buf, ' ');
            // recv_range にRangeの中身保存
            strncpy(http_recv_info_p->recv_range, line_buf, sizeof(http_recv_info_p->recv_range));
            // '=' より前を切る
            cut_before_character(line_buf, '=');
            // '-'で前後に分割。
            sentence_split(line_buf, '-', work_buf, work_buf2);
            debug_log_output("wrok_buf='%s'\n", work_buf);
            debug_log_output("wrok_buf2='%s'\n", work_buf2);
            // 値を文字列→数値変換
            http_recv_info_p->range_start_pos  = strtoull(work_buf, NULL, 10);
            if ( strlen(work_buf2) > 0 ){
                http_recv_info_p->range_end_pos = strtoull(work_buf2, NULL, 10);
            }
            debug_log_output("range_start_pos=%d\n", http_recv_info_p->range_start_pos);
            debug_log_output("range_end_pos=%d\n", http_recv_info_p->range_end_pos);
            continue;
        }
        // Hostあるかチェック
        if ( strncasecmp(line_buf, HTTP_HOST,	strlen(HTTP_HOST) ) == 0 ){
            // ':' より前を切る。
            cut_before_character(line_buf, ':');
            cut_first_character(line_buf, ' ');
            strncpy(http_recv_info_p->recv_host, line_buf, sizeof(http_recv_info_p->recv_host));
            debug_log_output("%s Detect. %s '%s'", HTTP_HOST, HTTP_HOST, http_recv_info_p->recv_host);
            continue;
        }
        // Content-Lengthあるかチェック
        if ( strncasecmp(line_buf, HTTP_CONTENT_LENGTH1, strlen(HTTP_CONTENT_LENGTH1) ) == 0 ){
            // ':' より前を切る。
            cut_before_character(line_buf, ':');
            cut_first_character(line_buf, ' ');
            strncpy(http_recv_info_p->content_length, line_buf, sizeof(http_recv_info_p->content_length));
            debug_log_output("%s Detect. %s '%s'", HTTP_CONTENT_LENGTH1, HTTP_CONTENT_LENGTH1, http_recv_info_p->content_length);
            continue;
        }
        // Content-TYPEあるかチェック
        if ( strncasecmp(line_buf, HTTP_CONTENT_TYPE1, strlen(HTTP_CONTENT_TYPE1) ) == 0 ){
            // ':' より前を切る。
            cut_before_character(line_buf, ':');
            cut_first_character(line_buf, ' ');
            strncpy(http_recv_info_p->content_type, line_buf, sizeof(http_recv_info_p->content_type));
            debug_log_output("%s Detect. %s '%s'", HTTP_CONTENT_TYPE1, HTTP_CONTENT_TYPE1, http_recv_info_p->content_type);
            continue;
        }
    }
    return result;
}
示例#15
0
static coap_status_t handle_request(lwm2m_context_t * contextP,
                                    void * fromSessionH,
                                    coap_packet_t * message,
                                    coap_packet_t * response)
{
    lwm2m_uri_t * uriP;
    coap_status_t result = COAP_IGNORE;

#ifdef LWM2M_CLIENT_MODE
    uriP = uri_decode(contextP->altPath, message->uri_path);
#else
    uriP = uri_decode(NULL, message->uri_path);
#endif

    if (uriP == NULL) return COAP_400_BAD_REQUEST;

    switch(uriP->flag & LWM2M_URI_MASK_TYPE)
    {
#ifdef LWM2M_CLIENT_MODE
    case LWM2M_URI_FLAG_DM:
    {
        lwm2m_server_t * serverP;

        serverP = utils_findServer(contextP, fromSessionH);
        if (serverP != NULL)
        {
            result = dm_handleRequest(contextP, uriP, serverP, message, response);
        }
#ifdef LWM2M_BOOTSTRAP
        else
        {
            serverP = utils_findBootstrapServer(contextP, fromSessionH);
            if (serverP != NULL)
            {
                result = bootstrap_handleCommand(contextP, uriP, serverP, message, response);
            }
        }
#endif
    }
    break;

#ifdef LWM2M_BOOTSTRAP
    case LWM2M_URI_FLAG_DELETE_ALL:
        if (COAP_DELETE != message->code)
        {
            result = COAP_400_BAD_REQUEST;
        }
        else
        {
            result = bootstrap_handleDeleteAll(contextP, fromSessionH);
        }
        break;

    case LWM2M_URI_FLAG_BOOTSTRAP:
        if (message->code == COAP_POST)
        {
            result = bootstrap_handleFinish(contextP, fromSessionH);
        }
        break;
#endif
#endif

#ifdef LWM2M_SERVER_MODE
    case LWM2M_URI_FLAG_REGISTRATION:
        result = registration_handleRequest(contextP, uriP, fromSessionH, message, response);
        break;
#endif
#ifdef LWM2M_BOOTSTRAP_SERVER_MODE
    case LWM2M_URI_FLAG_BOOTSTRAP:
        result = bootstrap_handleRequest(contextP, uriP, fromSessionH, message, response);
        break;
#endif
    default:
        result = COAP_IGNORE;
        break;
    }

    coap_set_status_code(response, result);

    if (COAP_IGNORE < result && result < COAP_400_BAD_REQUEST)
    {
        result = NO_ERROR;
    }

    lwm2m_free(uriP);
    return result;
}
示例#16
0
int location_update(struct list *locl, const struct sip_msg *msg,
                    const struct sip_addr *contact, uint32_t expires)
{
    struct location *loc, *loc_new = NULL;
    struct loctmp *tmp;
    struct pl pl;
    int err;

    if (!locl || !msg || !contact)
        return EINVAL;

    loc = list_ledata(list_apply(locl, true, cmp_handler,
                                 (void *)&contact->uri));
    if (!loc) {
        if (expires == 0)
            return 0;

        loc = loc_new = mem_zalloc(sizeof(*loc), destructor_location);
        if (!loc)
            return ENOMEM;

        list_append(locl, &loc->le, loc);
    }
    else {
        if (!pl_strcmp(&msg->callid, loc->callid) &&
                msg->cseq.num <= loc->cseq)
            return EPROTO;

        if (expires == 0) {
            loc->rm = true;
            return 0;
        }
    }

    tmp = mem_zalloc(sizeof(*tmp), destructor_loctmp);
    if (!tmp) {
        err = ENOMEM;
        goto out;
    }

    err = pl_strdup(&tmp->uri, &contact->auri);
    if (err)
        goto out;

    pl_set_str(&pl, tmp->uri);

    if (uri_decode(&tmp->duri, &pl)) {
        err = EBADMSG;
        goto out;
    }

    err = pl_strdup(&tmp->callid, &msg->callid);
    if (err)
        goto out;


    if (!msg_param_decode(&contact->params, "q", &pl))
        tmp->q = pl_float(&pl);
    else
        tmp->q = 1;

    tmp->cseq    = msg->cseq.num;
    tmp->expires = expires;
    tmp->src     = msg->src;

out:
    if (err) {
        mem_deref(loc_new);
        mem_deref(tmp);
    }
    else {
        mem_deref(loc->tmp);
        loc->tmp = tmp;
    }

    return err;
}
示例#17
0
文件: dialog.c 项目: soramimi/qSIP
/**
 * Allocate a SIP Dialog
 *
 * @param dlgp      Pointer to allocated SIP Dialog
 * @param uri       Target URI
 * @param to_uri    To URI
 * @param from_name From displayname (optional)
 * @param from_uri  From URI
 * @param routev    Route vector
 * @param routec    Route count
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_dialog_alloc(struct sip_dialog **dlgp,
		     const char *uri, const char *to_uri,
		     const char *from_name, const char *from_uri,
		     const char *routev[], uint32_t routec)
{
	const uint64_t ltag = rand_u64();
	struct sip_dialog *dlg;
	struct sip_addr addr;
	size_t rend = 0;
	struct pl pl;
	uint32_t i;
	int err;

	if (!dlgp || !uri || !to_uri || !from_uri)
		return EINVAL;

	dlg = mem_zalloc(sizeof(*dlg), destructor);
	if (!dlg)
		return ENOMEM;

	dlg->lseq = rand_u16();

	err = str_dup(&dlg->uri, uri);
	if (err)
		goto out;

	err = x64_strdup(&dlg->callid, rand_u64());
	if (err)
		goto out;

	err = x64_strdup(&dlg->ltag, ltag);
	if (err)
		goto out;

	dlg->mb = mbuf_alloc(512);
	if (!dlg->mb) {
		err = ENOMEM;
		goto out;
	}

	for (i=0; i<routec; i++) {
		err |= mbuf_printf(dlg->mb, "Route: <%s;lr>\r\n", routev[i]);
		if (i == 0)
			rend = dlg->mb->pos - 2;
	}
	err |= mbuf_printf(dlg->mb, "To: <%s>\r\n", to_uri);
	dlg->cpos = dlg->mb->pos;
	err |= mbuf_printf(dlg->mb, "From: %s%s%s<%s>;tag=%016llx\r\n",
			   from_name ? "\"" : "", from_name,
			   from_name ? "\" " : "",
			   from_uri, ltag);
	if (err)
		goto out;

	dlg->mb->pos = 0;

	if (rend) {
		pl.p = (const char *)mbuf_buf(dlg->mb) + ROUTE_OFFSET;
		pl.l = rend - ROUTE_OFFSET;
		err = sip_addr_decode(&addr, &pl);
		dlg->route = addr.uri;
	}
	else {
		pl_set_str(&pl, dlg->uri);
		err = uri_decode(&dlg->route, &pl);
	}

 out:
	if (err)
		mem_deref(dlg);
	else
		*dlgp = dlg;

	return err;
}
示例#18
0
int stun_uri_decode(struct stun_uri *stun_uri, const char *str)
{
	struct uri uri;
	struct pl pl_uri;
	uint16_t port;
	struct pl transp;
	int err;

	if (!stun_uri || !str)
		return EINVAL;

	pl_set_str(&pl_uri, str);

	err = uri_decode(&uri, &pl_uri);
	if (err) {
		warning("cannot decode URI (%r)\n", &pl_uri);
		return err;
	}

	if (0 == pl_strcasecmp(&uri.scheme, "stun") ||
	    0 == pl_strcasecmp(&uri.scheme, "stuns")) {

		stun_uri->scheme = STUN_SCHEME_STUN;
	}
	else if (0 == pl_strcasecmp(&uri.scheme, "turn") ||
		 0 == pl_strcasecmp(&uri.scheme, "turns")) {

		stun_uri->scheme = STUN_SCHEME_TURN;
	}
	else {
		warning("unsupported stun scheme (%r)\n", &uri.scheme);
		return ENOTSUP;
	}

	stun_uri->secure = 's' == tolower(uri.scheme.p[uri.scheme.l-1]);

	if (uri.port)
		port = uri.port;
	else if (stun_uri->secure)
		port = 5349;
	else
		port = 3478;

	err = sa_set(&stun_uri->addr, &uri.host, port);
	if (err) {
		warning("invalid stun address (%r)\n", &uri.host);
		return err;
	}

	if (0 == re_regex(str, strlen(str), "?transport=[a-z]+", &transp)) {

		if (0 == pl_strcasecmp(&transp, "udp"))
			stun_uri->proto = IPPROTO_UDP;
		else if (0 == pl_strcasecmp(&transp, "tcp"))
			stun_uri->proto = IPPROTO_TCP;
		else {
			warning("unsupported stun transport (%r)\n", &transp);
			return ENOTSUP;
		}

	}
	else {
		stun_uri->proto = IPPROTO_UDP;
	}

	return 0;
}
示例#19
0
文件: packet.c 项目: eclipse/wakaama
static uint8_t handle_request(lwm2m_context_t * contextP,
                              void * fromSessionH,
                              coap_packet_t * message,
                              coap_packet_t * response)
{
    lwm2m_uri_t uri;
    lwm2m_request_type_t requestType;
    uint8_t result = COAP_IGNORE;

    LOG("Entering");
	
#ifdef LWM2M_CLIENT_MODE
    requestType = uri_decode(contextP->altPath, message->uri_path, &uri);
#else
    requestType = uri_decode(NULL, message->uri_path, &uri);
#endif

    switch(requestType)
    {
    case LWM2M_REQUEST_TYPE_UNKNOWN:
        return COAP_400_BAD_REQUEST;

#ifdef LWM2M_CLIENT_MODE
    case LWM2M_REQUEST_TYPE_DM:
    {
        lwm2m_server_t * serverP;

        serverP = utils_findServer(contextP, fromSessionH);
        if (serverP != NULL)
        {
            result = dm_handleRequest(contextP, &uri, serverP, message, response);
        }
#ifdef LWM2M_BOOTSTRAP
        else
        {
            serverP = utils_findBootstrapServer(contextP, fromSessionH);
            if (serverP != NULL)
            {
                result = bootstrap_handleCommand(contextP, &uri, serverP, message, response);
            }
        }
#endif
    }
    break;

#ifdef LWM2M_BOOTSTRAP
    case LWM2M_REQUEST_TYPE_DELETE_ALL:
        if (COAP_DELETE != message->code)
        {
            result = COAP_400_BAD_REQUEST;
        }
        else
        {
            result = bootstrap_handleDeleteAll(contextP, fromSessionH);
        }
        break;

    case LWM2M_REQUEST_TYPE_BOOTSTRAP:
        if (message->code == COAP_POST)
        {
            result = bootstrap_handleFinish(contextP, fromSessionH);
        }
        break;
#endif
#endif

#ifdef LWM2M_SERVER_MODE
    case LWM2M_REQUEST_TYPE_REGISTRATION:
        result = registration_handleRequest(contextP, &uri, fromSessionH, message, response);
        break;
#endif
#ifdef LWM2M_BOOTSTRAP_SERVER_MODE
    case LWM2M_REQUEST_TYPE_BOOTSTRAP:
        result = bootstrap_handleRequest(contextP, &uri, fromSessionH, message, response);
        break;
#endif
    default:
        result = COAP_IGNORE;
        break;
    }

    coap_set_status_code(response, result);

    if (COAP_IGNORE < result && result < COAP_400_BAD_REQUEST)
    {
        result = NO_ERROR;
    }

    return result;
}
示例#20
0
文件: e-url.c 项目: Pecisk/eds-gtasks
/**
 * e_uri_new:
 * @uri_string: The uri to represent as an #EUri.
 *
 * Creates an #EUri representation of the uri given in @uri_string.
 *
 * Returns: The newly-allocated #EUri structure.
 **/
EUri *
e_uri_new (const gchar *uri_string)
{
	EUri *uri;
	const gchar *end, *hash, *colon, *semi, *at, *slash, *question;
	const gchar *p;

	if (!uri_string)
		return NULL;

	uri = g_new0 (EUri, 1);

	/* find fragment */
	end = hash = strchr (uri_string, '#');
	if (hash && hash[1]) {
		uri->fragment = g_strdup (hash + 1);
		uri_decode (uri->fragment);
	}
	else
		end = uri_string + strlen (uri_string);

	/* find protocol: initial [a-z+.-]* substring until ":" */
	p = uri_string;
	while (p < end && (isalnum ((guchar) *p) ||
			   *p == '.' || *p == '+' || *p == '-'))
		p++;

	if (p > uri_string && *p == ':') {
		uri->protocol = g_ascii_strdown (uri_string, p - uri_string);
		uri_string = p + 1;
	}
	else
		uri->protocol = g_strdup ("file");

	if (!*uri_string)
		return uri;

	/* check for authority */
	if (strncmp (uri_string, "//", 2) == 0) {
		uri_string += 2;

		slash = uri_string + strcspn (uri_string, "/#");
		at = strchr (uri_string, '@');
		if (at && at < slash) {
			const gchar *at2;
			/* this is for cases where username contains '@' at it, like:
			 * http://[email protected]@server.addr.com/path
			 * We skip all at-s before the slash here. */

			while (at2 = strchr (at + 1, '@'), at2 && at2 < slash) {
				at = at2;
			}
		}
		if (at && at < slash) {
			colon = strchr (uri_string, ':');
			if (colon && colon < at) {
				uri->passwd = g_strndup (colon + 1, at - colon - 1);
				uri_decode (uri->passwd);
			}
			else {
				uri->passwd = NULL;
				colon = at;
			}

			semi = strchr (uri_string, ';');
			if (semi && semi < colon &&
			    !g_ascii_strncasecmp (semi, ";auth=", 6)) {
				uri->authmech = g_strndup (semi + 6, colon - semi - 6);
				uri_decode (uri->authmech);
			}
			else {
				uri->authmech = NULL;
				semi = colon;
			}

			uri->user = g_strndup (uri_string, semi - uri_string);
			uri_decode (uri->user);
			uri_string = at + 1;
		}
		else
			uri->user = uri->passwd = uri->authmech = NULL;

		/* find host and port */
		colon = strchr (uri_string, ':');
		if (colon && colon < slash) {
			uri->host = g_strndup (uri_string, colon - uri_string);
			uri->port = strtoul (colon + 1, NULL, 10);
		}
		else {
			uri->host = g_strndup (uri_string, slash - uri_string);
			uri_decode (uri->host);
			uri->port = 0;
		}

		uri_string = slash;
	}

	/* find query */
	question = memchr (uri_string, '?', end - uri_string);
	if (question) {
		if (question[1]) {
			uri->query = g_strndup (question + 1, end - (question + 1));
			uri_decode (uri->query);
		}
		end = question;
	}

	/* find parameters */
	semi = memchr (uri_string, ';', end - uri_string);
	if (semi) {
		if (semi[1]) {
			const gchar *cur, *ptr, *eq;
			gchar *name, *value;

			for (cur = semi + 1; cur < end; cur = ptr + 1) {
				ptr = memchr (cur, ';', end - cur);
				if (!ptr)
					ptr = end;
				eq = memchr (cur, '=', ptr - cur);
				if (eq) {
					name = g_strndup (cur, eq - cur);
					value = g_strndup (eq + 1, ptr - (eq + 1));
					uri_decode (value);
				} else {
					name = g_strndup (cur, ptr - cur);
					value = g_strdup ("");
				}
				uri_decode (name);
				g_datalist_set_data_full (
					&uri->params, name,
					value, g_free);
				g_free (name);
			}
		}
		end = semi;
	}

	if (end != uri_string) {
		uri->path = g_strndup (uri_string, end - uri_string);
		uri_decode (uri->path);
	}

	return uri;
}
示例#21
0
文件: dialog.c 项目: soramimi/qSIP
/**
 * Fork a SIP Dialog from an incoming SIP Message
 *
 * @param dlgp Pointer to allocated SIP Dialog
 * @param odlg Original SIP Dialog
 * @param msg  SIP Message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg,
		    const struct sip_msg *msg)
{
	const struct sip_hdr *contact;
	struct sip_dialog *dlg;
	struct route_enc renc;
	struct sip_addr addr;
	struct pl pl;
	int err;

	if (!dlgp || !odlg || !odlg->cpos || !msg)
		return EINVAL;

	contact = sip_msg_hdr(msg, SIP_HDR_CONTACT);

	if (!contact || !msg->callid.p)
		return EBADMSG;

	if (sip_addr_decode(&addr, &contact->val))
		return EBADMSG;

	dlg = mem_zalloc(sizeof(*dlg), destructor);
	if (!dlg)
		return ENOMEM;

	dlg->callid = mem_ref(odlg->callid);
	dlg->ltag   = mem_ref(odlg->ltag);
	dlg->lseq   = odlg->lseq;
	dlg->rseq   = msg->req ? msg->cseq.num : 0;

	err = pl_strdup(&dlg->uri, &addr.auri);
	if (err)
		goto out;

	err = pl_strdup(&dlg->rtag, msg->req ? &msg->from.tag : &msg->to.tag);
	if (err)
		goto out;

	dlg->mb = mbuf_alloc(512);
	if (!dlg->mb) {
		err = ENOMEM;
		goto out;
	}

	renc.mb  = dlg->mb;
	renc.end = 0;

	err |= sip_msg_hdr_apply(msg, msg->req, SIP_HDR_RECORD_ROUTE,
				 record_route_handler, &renc) ? ENOMEM : 0;
	err |= mbuf_printf(dlg->mb, "To: %r\r\n",
			   msg->req ? &msg->from.val : &msg->to.val);

	odlg->mb->pos = odlg->cpos;
	err |= mbuf_write_mem(dlg->mb, mbuf_buf(odlg->mb),
			      mbuf_get_left(odlg->mb));
	odlg->mb->pos = 0;

	if (err)
		goto out;

	dlg->mb->pos = 0;

	if (renc.end) {
		pl.p = (const char *)mbuf_buf(dlg->mb) + ROUTE_OFFSET;
		pl.l = renc.end - ROUTE_OFFSET;
		err = sip_addr_decode(&addr, &pl);
		dlg->route = addr.uri;
	}
	else {
		pl_set_str(&pl, dlg->uri);
		err = uri_decode(&dlg->route, &pl);
	}

 out:
	if (err)
		mem_deref(dlg);
	else
		*dlgp = dlg;

	return err;
}