Esempio n. 1
0
void php_yar_error_ex(yar_response_t *response, int type TSRMLS_DC, const char *format, va_list args) /* {{{ */ {
	char *msg;
	uint len;

	len = vspprintf(&msg, 0, format, args);
	php_yar_response_set_error(response, type, msg, len TSRMLS_CC);
	/* intentionally missed
	efree(msg);
	*/

	return;
} /* }}} */
Esempio n. 2
0
yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_request_t *request) /* {{{ */ {
	fd_set rfds;
	struct timeval tv;
	yar_header_t *header;
	yar_response_t *response;
	int fd, retval, recvd;
   	size_t len = 0, total_recvd = 0;
	char *msg, buf[RECV_BUF_SIZE], *payload = NULL;
	yar_socket_data_t *data = (yar_socket_data_t *)self->data;

	response = ecalloc(1, sizeof(yar_response_t));

	FD_ZERO(&rfds);
	if (SUCCESS == php_stream_cast(data->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) && fd >= 0) {
		PHP_SAFE_FD_SET(fd, &rfds);
	} else {
		len = snprintf(buf, sizeof(buf), "Unable cast socket fd form stream (%s)", strerror(errno));
		php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len);
		return response;
	}

	tv.tv_sec = (ulong)(YAR_G(timeout) / 1000);
	tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0);

wait_io:
	retval = php_select(fd+1, &rfds, NULL, NULL, &tv);

	if (retval == -1) {
		len = snprintf(buf, sizeof(buf), "Unable to select %d '%s'", fd, strerror(errno));
		php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len);
		return response;
	} else if (retval == 0) {
		len = snprintf(buf, sizeof(buf), "select timeout %ldms reached", YAR_G(timeout));
		php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len);
		return response;
	}

	if (PHP_SAFE_FD_ISSET(fd, &rfds)) {
		zval *retval, rret;
		if (!payload) {
			if ((recvd = php_stream_xport_recvfrom(data->stream, buf, sizeof(buf), 0, NULL, NULL, NULL)) > 0) {
				if (!(header = php_yar_protocol_parse(buf))) {
					php_yar_error(response, YAR_ERR_PROTOCOL, "malformed response header '%.32s'", payload);
					return response;
				}

				payload = emalloc(header->body_len);
				len = header->body_len;
				total_recvd  = recvd - sizeof(yar_header_t);

				memcpy(payload, buf + sizeof(yar_header_t), total_recvd);

				if (recvd < (sizeof(yar_header_t) + len)) {
					goto wait_io;	
				}
			} else if (recvd < 0) {
				/* this should never happen */
				goto wait_io;
			}
		} else {
			if ((recvd = php_stream_xport_recvfrom(data->stream, payload + total_recvd, len - total_recvd, 0, NULL, NULL, NULL)) > 0) {
				total_recvd += recvd;
			}

			if (total_recvd < len) {
				goto wait_io;
			}
		}

		if (len) {
			if (!(retval = php_yar_packager_unpack(payload, len, &msg, &rret))) {
				php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg));
				efree(msg);
				return response;
			}

			php_yar_response_map_retval(response, retval);

			DEBUG_C(ZEND_ULONG_FMT": server response content packaged by '%.*s', len '%ld', content '%.32s'",
					response->id, 7, payload, header->body_len, payload + 8);

			efree(payload);
			zval_ptr_dtor(retval);
		} else {
			php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response"));
		}
		return response;
	} else {
		goto wait_io;
	}
} /* }}} */