Пример #1
0
Файл: ssl.c Проект: Addision/LVS
/* Asynchronous SSL stream reader */
int
ssl_read_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	int r = 0;
	int error;

	/* Handle read timeout */
	if (thread->type == THREAD_READ_TIMEOUT)
		return epilog(thread);

	/*
	 * The design implemented here is a workaround for use
	 * with OpenSSL. This goto loop is a 'read until not
	 * end of stream'. But this break a little our global
	 * I/O multiplexer thread framework because it enter
	 * a synchronous read process for each GET reply.
	 * Sound a little nasty !.
	 * 
	 * Why OpenSSL doesn t handle underlying fd. This
	 * break the I/O (select()) approach !...
	 * If you read this and know the answer, please reply
	 * I am probably missing something... :)
	 * My test show that sometime it return from select,
	 * and sometime not...
	 */

      read_stream:

	/* read the SSL stream */
	memset(sock_obj->buffer, 0, MAX_BUFFER_LENGTH);
	r = SSL_read(sock_obj->ssl, sock_obj->buffer, MAX_BUFFER_LENGTH);
	error = SSL_get_error(sock_obj->ssl, r);

	DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd);

	if (error) {
		/* All the SSL streal has been parsed */
		/* Handle response stream */
		if (error != SSL_ERROR_NONE)
			return finalize(thread);
	} else if (r > 0 && error == 0) {

		/* Handle the response stream */
		http_process_stream(sock_obj, r);

		/*
		 * Register next ssl stream reader.
		 * Register itself to not perturbe global I/O multiplexer.
		 */
		goto read_stream;
	}

	return 0;
}
Пример #2
0
/* Asynchronous HTTP stream reader */
int
http_read_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	int r = 0;

	/* Handle read timeout */
	if (thread->type == THREAD_READ_TIMEOUT)
		return epilog(thread);

	/* read the HTTP stream */
	r = MAX_BUFFER_LENGTH - sock_obj->size;
	if (r <= 0) {
		/* defensive check, should not occur */
		fprintf(stderr, "HTTP socket buffer overflow (not consumed)\n");
		r = MAX_BUFFER_LENGTH;
	}
	memset(sock_obj->buffer + sock_obj->size, 0, r);
	r = read(thread->u.fd, sock_obj->buffer + sock_obj->size, r);

	DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd);

	if (r == -1 || r == 0) {	/* -1:error , 0:EOF */
		if (r == -1) {
			/* We have encourred a real read error */
			DBG("Read error with server [%s]:%d: %s\n",
			    req->ipaddress, ntohs(req->addr_port),
			    strerror(errno));
			return epilog(thread);
		}

		/* All the HTTP stream has been parsed */
		finalize(thread);
	} else {
		/* Handle the response stream */
		http_process_stream(sock_obj, r);

		/*
		 * Register next http stream reader.
		 * Register itself to not perturbe global I/O multiplexer.
		 */
		thread_add_read(thread->master, http_read_thread, sock_obj,
				thread->u.fd, HTTP_CNX_TIMEOUT);
	}

	return 0;
}