Esempio n. 1
0
/** @return -2 if no data was read but the caller should retry;
 * -1 if an error occurred and *@a error was set; 0 at end of data;
 * a positive number if that many bytes were read.
 *
 * @relates http_post */
static int
read_http_post_inline(struct http_post *http_post,
		      unsigned char buffer[], int max,
		      struct connection_state *error)
{
	const unsigned char *post = http_post->post_data;
	const unsigned char *end = (const unsigned char *)strchr((char *)post, FILE_CHAR);
	int total = 0;

	assert(http_post->post_fd < 0);
	if_assert_failed { *error = connection_state(S_INTERNAL); return -1; }

	if (!end)
		end = (const unsigned char *)strchr((char *)post, '\0');

	while (post < end && total < max) {
		int h1, h2;

		h1 = unhx(post[0]);
		assertm(h1 >= 0 && h1 < 16, "h1 in the POST buffer is %d (%d/%c)", h1, post[0], post[0]);
		if_assert_failed h1 = 0;

		h2 = unhx(post[1]);
		assertm(h2 >= 0 && h2 < 16, "h2 in the POST buffer is %d (%d/%c)", h2, post[1], post[1]);
		if_assert_failed h2 = 0;

		buffer[total++] = (h1<<4) + h2;
		post += 2;
	}
	if (post != end || *end != FILE_CHAR) {
		http_post->post_data = post;
		return total;
	}

	http_post->file_read = 0;
	end = (const unsigned char *)strchr((char *)(post + 1), FILE_CHAR);
	assert(end);
	http_post->post_fd = open((const char *)http_post->files[http_post->file_index].name,
				  O_RDONLY);
	/* Be careful not to change errno here.  */
	if (http_post->post_fd < 0) {
		http_post->post_data = post;
		if (total > 0)
			return total; /* retry the open on the next call */
		else {
			*error = connection_state_for_errno(errno);
			return -1;
		}
	}
	http_post->post_data = end + 1;
	return total ? total : -2;
}
Esempio n. 2
0
static void
decode_q_segment(struct string *str, unsigned char *in, unsigned char *end)
{
	int c;

	while ((c = *in++) != 0 && (in <= end)) {
		if (c == '=') {
			int d = *in++;

			if (d == '\n' || !d)
				break; /* drop trailing newline */
			d = (unhx(d) << 4) | unhx(*in++);
			add_format_to_string(str, "&#%d;", d);
			continue;
		}

		if (c == '_') /* rfc2047 4.2 (2) */
			c = 0x20;
		add_char_to_string(str, c);
	}
}