MESSAGE
metautils_message_create(void)
{
	const char *id = oio_ext_get_reqid ();
	MESSAGE result = calloc(1, sizeof(Message_t));
	if (id)
		metautils_message_set_ID (result, id, strlen(id));
	return result;
}
GByteArray*
message_marshall_gba(MESSAGE m, GError **err)
{
	asn_enc_rval_t encRet;

	/*sanity check */
	if (!m) {
		GSETERROR(err, "Invalid parameter");
		return NULL;
	}

	/*set an ID if it is not present */
	if (!metautils_message_has_ID(m)) {
		const char *reqid = oio_ext_get_reqid ();
		if (!reqid)
			oio_ext_set_random_reqid ();
		reqid = oio_ext_get_reqid ();
		metautils_message_set_ID(m, (guint8*)reqid, strlen(reqid));
	}

	metautils_message_add_field_strint(m, NAME_MSGKEY_ADMIN_COMMAND,
			oio_ext_is_admin());

	/*try to encode */
	guint32 u32 = 0;
	GByteArray *result = g_byte_array_sized_new(256);
	g_byte_array_append(result, (guint8*)&u32, sizeof(u32));
	encRet = der_encode(&asn_DEF_Message, m, metautils_asn1c_write_gba, result);

	if (encRet.encoded < 0) {
		g_byte_array_free(result, TRUE);
		GSETERROR(err, "Encoding error (Message)");
		return NULL;
	}

	guint32 s32 = result->len - 4;
	*((guint32*)(result->data)) = g_htonl(s32);
	return result;
}
Exemple #3
0
void
oio_headers_common (struct oio_headers_s *h)
{
	oio_headers_add (h, "Expect", "");
	oio_headers_add (h, PROXYD_HEADER_REQID, oio_ext_get_reqid());
}
Exemple #4
0
static GError *
_proxy_call_notime (CURL *h, const char *method, const char *url,
		struct http_ctx_s *in, struct http_ctx_s *out)
{
	g_assert (h != NULL);
	g_assert (method != NULL);
	g_assert (url != NULL);
	struct view_GString_s view_input = {.data=NULL, .done=0};

	GError *err = NULL;
	curl_easy_setopt (h, CURLOPT_URL, url);
	curl_easy_setopt (h, CURLOPT_CUSTOMREQUEST, method);

	/* Populate the request headers */
	struct oio_headers_s headers = {NULL,NULL};
	oio_headers_common (&headers);
	curl_easy_setopt (h, CURLOPT_HTTPHEADER, headers.headers);
	if (in && in->headers) {
		for (gchar **p=in->headers; *p && *(p+1) ;p+=2)
			oio_headers_add (&headers, *p, *(p+1));
	}

	/* Intercept the headers from the response */
	if (out) {
		curl_easy_setopt (h, CURLOPT_HEADERDATA, out);
		curl_easy_setopt (h, CURLOPT_HEADERFUNCTION, _header_callback);
	} else {
		curl_easy_setopt (h, CURLOPT_HEADERDATA, NULL);
		curl_easy_setopt (h, CURLOPT_HEADERFUNCTION, NULL);
	}

	if (in && in->body) {
		view_input.data = in->body;
		gint64 len = in->body->len;
		curl_easy_setopt (h, CURLOPT_READFUNCTION, _read_GString);
		curl_easy_setopt (h, CURLOPT_READDATA, &view_input);
		curl_easy_setopt (h, CURLOPT_UPLOAD, 1L);
		curl_easy_setopt (h, CURLOPT_INFILESIZE_LARGE, len);
	} else {
		curl_easy_setopt (h, CURLOPT_READFUNCTION, NULL);
		curl_easy_setopt (h, CURLOPT_READDATA, NULL);
		curl_easy_setopt (h, CURLOPT_UPLOAD, 0L);
		curl_easy_setopt (h, CURLOPT_INFILESIZE, 0L);
	}

	if (out && out->body) {
		curl_easy_setopt (h, CURLOPT_WRITEFUNCTION, _write_GString);
		curl_easy_setopt (h, CURLOPT_WRITEDATA, out->body);
	} else {
		curl_easy_setopt (h, CURLOPT_WRITEFUNCTION, _write_NOOP);
	}

	CURLcode rc = curl_easy_perform (h);
	if (CURLE_OK != rc)
		err = NEWERROR(0, "Proxy error: (%d) %s", rc, curl_easy_strerror(rc));
	else {
		long code = 0;
		rc = curl_easy_getinfo (h, CURLINFO_RESPONSE_CODE, &code);
		if (2 != (code/100)) {
			if (out && out->body) {
				err = _body_parse_error (out->body);
				g_prefix_error (&err, "Request error (%ld): ", code);
			} else {
				err = NEWERROR(code, "Request error (%ld)", code);
			}
		}
	}
	oio_headers_clear (&headers);
	return err;
}

static GError *
_proxy_call (CURL *h, const char *method, const char *url,
		struct http_ctx_s *in, struct http_ctx_s *out)
{
	if (!oio_ext_get_reqid ())
		oio_ext_set_random_reqid();

	gint64 t = g_get_monotonic_time ();
	GError *err = _proxy_call_notime (h, method, url, in, out);
	t = g_get_monotonic_time () - t;
	GRID_TRACE("proxy: %s %s took %"G_GINT64_FORMAT"us", method, url, t);
	return err;
}

/* -------------------------------------------------------------------------- */

GError *
oio_proxy_call_container_create (CURL *h, struct oio_url_s *u)
{
	GString *http_url = _curl_container_url (u, "create");
	gchar *hdrin[] = {PROXYD_HEADER_MODE, "autocreate", NULL};
	struct http_ctx_s i = { .headers = hdrin, .body = NULL };
	GError *err = _proxy_call (h, "POST", http_url->str, &i, NULL);
	g_string_free(http_url, TRUE);
	return err;
}