value_resp(agooReq req, gqlValue result, int status, int indent) {
    agooRes		res = req->res;
    char		buf[256];
    struct _agooErr	err = AGOO_ERR_INIT;
    int			cnt;
    agooText		text = agoo_text_allocate(4094);
    gqlValue		msg = gql_object_create(&err);

    if (NULL == msg) {
	AGOO_ERR_MEM(&err, "response");
	err_resp(res, &err, 500);
	gql_value_destroy(result);
	return;
    }
    if (NULL == result) {
	switch (status) {
	case 101:
	    if (NULL == (text = agoo_text_append(text, ws_up, sizeof(ws_up) - 1)) ||
		NULL == (text = agoo_ws_add_headers(req, text)) ||
		NULL == (text = agoo_text_append(text, "\r\n", 2))) {

		agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
		return;
	    }
	    break;
	case 200:
	    text = agoo_sse_upgrade(req, text);
	    break;
	default:
	    agoo_log_cat(&agoo_error_cat, "Did not expect an HTTP status of %d.", status);
	    agoo_err_set(&err, AGOO_ERR_EVAL, "Did not expect an HTTP status of %d.", status);
	    goto FAILED;
	}
	agoo_res_message_push(res, text);
	return;
    }
    if (AGOO_ERR_OK != gql_object_set(&err, msg, "data", result)) {
	goto FAILED;
    }
    text = gql_value_json(text, msg, indent, 0);
    gql_value_destroy(msg); // also destroys result
    result = NULL;

    cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %ld\r\n\r\n",
		   status, agoo_http_code_message(status), text->len);
    if (NULL != gql_headers || NULL != gql_build_headers) {
	agooText	headers = agoo_text_allocate(4094);

	headers = agoo_text_append(headers, buf, cnt - 2);
	if (NULL == headers) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
	if (NULL != gql_headers) {
	    headers = agoo_text_append(headers, gql_headers->text, (int)gql_headers->len);
	} else {
	    headers = gql_build_headers(&err, req, headers);
	}
	headers = agoo_text_append(headers, "\r\n", 2);
	if (NULL == headers) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
	if (NULL == (text = agoo_text_prepend(text, headers->text, (int)headers->len))) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    agoo_text_release(headers);
	    return;
	}
	agoo_text_release(headers);
    } else {
	if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
    }
    agoo_res_message_push(res, text);

    return;

FAILED:
    err_resp(res, &err, 500);
    if (NULL != result) {
	gql_value_destroy(result);
    }
    return;
}
value_resp(agooReq req, gqlValue result, int status, int indent) {
    agooRes		res = req->res;
    char		buf[256];
    struct _agooErr	err = AGOO_ERR_INIT;
    int			cnt;
    agooText		text = agoo_text_allocate(4094);
    gqlValue		msg = gql_object_create(&err);

    if (NULL == msg) {
	AGOO_ERR_MEM(&err, "response");
	err_resp(res, &err, 500);
	gql_value_destroy(result);
	return;
    }
    if (NULL == result) {
	switch (status) {
	case 101:
	    if (NULL == (text = agoo_text_append(text, ws_up, sizeof(ws_up) - 1)) ||
		NULL == (text = agoo_ws_add_headers(req, text)) ||
		NULL == (text = agoo_text_append(text, "\r\n", 2))) {

		agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
		return;
	    }
	    break;
	case 200:
	    text = agoo_sse_upgrade(req, text);
	    break;
	default:
	    agoo_log_cat(&agoo_error_cat, "Did not expect an HTTP status of %d.", status);
	    agoo_err_set(&err, AGOO_ERR_EVAL, "Did not expect an HTTP status of %d.", status);
	    goto FAILED;
	}
	agoo_res_message_push(res, text);
	return;
    }
    if (AGOO_ERR_OK != gql_object_set(&err, msg, "data", result)) {
	goto FAILED;
    }
    text = gql_value_json(text, msg, indent, 0);
    gql_value_destroy(msg);  
    result = NULL;

    cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %ld\r\n\r\n",
		   status, agoo_http_code_message(status), text->len);
    if (NULL != gql_headers || NULL != gql_build_headers) {
	agooText	headers = agoo_text_allocate(4094);

	headers = agoo_text_append(headers, buf, cnt - 2);
	if (NULL == headers) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
	if (NULL != gql_headers) {
	    headers = agoo_text_append(headers, gql_headers->text, (int)gql_headers->len);
	} else {
	    headers = gql_build_headers(&err, req, headers);
	}
	headers = agoo_text_append(headers, "\r\n", 2);
	if (NULL == headers) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
	if (NULL == (text = agoo_text_prepend(text, headers->text, (int)headers->len))) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    agoo_text_release(headers);
	    return;
	}
	agoo_text_release(headers);
    } else {
	if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
	    agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
	    return;
	}
    }
    agoo_res_message_push(res, text);

    return;

FAILED:
    err_resp(res, &err, 500);
    if (NULL != result) {
	gql_value_destroy(result);
    }
    return;
}