예제 #1
0
파일: logger.c 프로젝트: BeQ/webserver
static ret_t
parse_x_real_ip (cherokee_logger_t *logger, cherokee_connection_t *conn)
{
	ret_t    ret;
	cuint_t  len  = 0;
	char    *val  = NULL;

	/* Look for the X-Real-IP header
	 */
	ret = cherokee_header_get_known (&conn->header, header_x_real_ip, &val, &len);
	if (ret != ret_ok) {
		char *p;

		/* Look for the X-Forwarded-For header
		 */
		ret = cherokee_header_get_known (&conn->header, header_x_forwarded_for, &val, &len);
		if (ret != ret_ok) {
			return ret_not_found;
		}

		p = val;
		while (*p && (p - val < len)) {
			if ((*p == ' ') || (*p == ',')) {
				len = p - val;
				break;
			}
			p++;
		}
	}

	/* Is the client allowed to use X-Real-IP?
	 */
	ret = cherokee_x_real_ip_is_allowed (&logger->priv->x_real_ip, &conn->socket);
	if (ret != ret_ok) {
		return ret_deny;
	}

	/* Store the X-Real-IP value
	 */
	ret = cherokee_buffer_add (&conn->logger_real_ip, val, len);
	if (unlikely (ret != ret_ok)) {
		return ret_error;
	}

	return ret_ok;
}
예제 #2
0
파일: post.c 프로젝트: Daniel15/webserver
ret_t
cherokee_post_read_header (cherokee_post_t *post,
			   void            *cnt)
{
	ret_t                  ret;
	char                  *info     = NULL;
	cuint_t                info_len = 0;
	cherokee_connection_t *conn     = CONN(cnt);

	switch (post->read_header_phase) {
	case cherokee_post_read_header_init:
		/* Read the header
		 */
		ret = parse_header (post, conn);
		if (unlikely (ret != ret_ok)) {
			return ret;
		}

		post->has_info = true;

		ret = remove_surplus (post, conn);
		if (unlikely (ret != ret_ok)) {
			return ret;
		}

		/* Expect: 100-continue
		 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
		 */
		ret = cherokee_header_get_known (&conn->header, header_expect, &info, &info_len);
		if (likely (ret != ret_ok)) {
			return ret_ok;
		}

		cherokee_buffer_add_str (&post->read_header_100cont, HTTP_100_RESPONSE);
		post->read_header_phase = cherokee_post_read_header_100cont;

	case cherokee_post_read_header_100cont:
		return reply_100_continue (post, conn);
	}

	SHOULDNT_HAPPEN;
	return ret_error;
}
예제 #3
0
static ret_t
match_regex (cherokee_rule_header_t  *rule,
	     cherokee_connection_t   *conn,
	     cherokee_config_entry_t *ret_conf)
{
	int      re;
	ret_t    ret;
	char    *info     = NULL;
	cuint_t  info_len = 0;

	UNUSED(ret_conf);

	/* Find the header
	 */
	ret = cherokee_header_get_known (&conn->header,
					 rule->header,
					 &info, &info_len);

	if ((ret != ret_ok) || (info == NULL)) {
		TRACE (ENTRIES, "Request '%s'; couldn't find header(%d)\n",
		       conn->request.buf, rule->header);
		return ret_not_found;
	}

	/* Check whether it matches
	 */
	re = pcre_exec (rule->pcre, NULL,
			info, info_len,
			0, 0, NULL, 0);

	if (re < 0) {
		TRACE (ENTRIES, "Request '%s' didn't match header(%d) with '%s'\n",
		       conn->request.buf, rule->header, rule->match.buf);
		return ret_not_found;
	}

	TRACE (ENTRIES, "Request '%s' matched header(%d) with '%s'\n",
	       conn->request.buf, rule->header, rule->match.buf);
	return ret_ok;
}
예제 #4
0
파일: post.c 프로젝트: Daniel15/webserver
static ret_t
parse_header (cherokee_post_t       *post,
	      cherokee_connection_t *conn)
{
	ret_t    ret;
	char    *info      = NULL;
	cuint_t  info_len  = 0;
	CHEROKEE_TEMP(buf, 64);

	/* RFC 2616:
	 *
	 * If a message is received with both a Transfer-Encoding
	 * header field and a Content-Length header field, the latter
	 * MUST be ignored.
	 */

	/* Check "Transfer-Encoding"
	 */
	ret = cherokee_header_get_known (&conn->header, header_transfer_encoding, &info, &info_len);
	if (ret == ret_ok) {
		if (strncasecmp (info, "chunked", MIN(info_len, 7)) == 0) {
			TRACE (ENTRIES, "Post type: %s\n", "chunked");
			post->encoding = post_enc_chunked;
			return ret_ok;
		}
	}

	TRACE (ENTRIES, "Post type: %s\n", "plain");

	/* Check "Content-Length"
	 */
	ret = cherokee_header_get_known (&conn->header, header_content_length, &info, &info_len);
	if (unlikely (ret != ret_ok)) {
		conn->error_code = http_length_required;
		return ret_error;
	}

	/* Parse the POST length
	 */
	if (unlikely ((info == NULL)  ||
		      (info_len == 0) ||
		      (info_len >= buf_size)))
	{
		conn->error_code = http_bad_request;
		return ret_error;
	}

	memcpy (buf, info, info_len);
	buf[info_len] = '\0';

	/* Check: Post length >= 0
	 */
	post->len = (off_t) atoll(buf);
	if (unlikely (post->len < 0)) {
		conn->error_code = http_bad_request;
		return ret_error;
	}

	TRACE (ENTRIES, "Post claims to be %llu bytes long\n", post->len);
	return ret_ok;
}