static void _check_for_and_handle_json_500(SG_context* pCtx, SG_curl* pCurl, char* buffer, SG_uint32 bufLen)
{
	SG_int32 responseCode = 0;
	_sg_curl* pMe = (_sg_curl*)pCurl;

	SG_ERR_CHECK(  SG_curl__getinfo__int32(pCtx, pCurl, CURLINFO_RESPONSE_CODE, &responseCode)  );
	if (responseCode == 500 || responseCode == 410)
	{
		if (pMe->pstrErr == NULL)
		{
			SG_int32 lenResponse = 0;

			/* We assume an HTTP 500 response will be small enough to fit into an SG_string. */
			SG_ERR_CHECK(  SG_curl__getinfo__int32(pCtx, pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lenResponse)  );
			if (lenResponse > 0)
				SG_ERR_CHECK(  SG_STRING__ALLOC__RESERVE(pCtx, &pMe->pstrErr, (SG_uint32)lenResponse + 1)  );
			else
				SG_ERR_CHECK(  SG_STRING__ALLOC(pCtx, &pMe->pstrErr)  );
		}

		SG_ERR_CHECK(  SG_string__append__buf_len(pCtx, pMe->pstrErr, (const SG_byte*)buffer, bufLen)  );
	}

fail:
	;
}
static void _get_sync_url(SG_context* pCtx, const char* pszBaseUrl, const char* pszUrlSuffix, const char* pszPushId, const char* pszQueryString, char** ppszUrl)
{
    SG_string* pstrUrl = NULL;

    SG_ERR_CHECK(  SG_STRING__ALLOC__RESERVE(pCtx, &pstrUrl, 1024)  );
    SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, pszBaseUrl)  );

    if (pszUrlSuffix)
        SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, pszUrlSuffix)  );

    if (pszPushId)
    {
        SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, "/")  );
        SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, pszPushId)  );
    }
    if (pszQueryString)
    {
        SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, "?")  );
        SG_ERR_CHECK(  SG_string__append__sz(pCtx, pstrUrl, pszQueryString)  );
    }

    SG_ERR_CHECK(  SG_string__sizzle(pCtx, &pstrUrl, (SG_byte**)ppszUrl, NULL)  );

    return;

fail:
    SG_STRING_NULLFREE(pCtx, pstrUrl);
}
void sg_sync_client__http__pull_clone(
    SG_context* pCtx,
    SG_sync_client* pSyncClient,
    SG_vhash* pvh_clone_request,
    const SG_pathname* pStagingPathname,
    char** ppszFragballName)
{
    SG_vhash* pvhRequest = NULL;
    char* pszFragballName = NULL;
    SG_pathname* pPathFragball = NULL;
    SG_string* pstrRequest = NULL;
    char* pszUrl = NULL;

    SG_ERR_CHECK(  SG_log__push_operation(pCtx, "Requesting repository from server", SG_LOG__FLAG__NONE)  );

    SG_NULLARGCHECK_RETURN(pSyncClient);

    SG_ERR_CHECK(  SG_allocN(pCtx, SG_TID_MAX_BUFFER_LENGTH, pszFragballName)  );
    SG_ERR_CHECK(  SG_tid__generate(pCtx, pszFragballName, SG_TID_MAX_BUFFER_LENGTH)  );

    SG_ERR_CHECK(  _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX FRAGBALL_URL_SUFFIX, NULL, NULL, &pszUrl)  );


    SG_ERR_CHECK(  SG_VHASH__ALLOC(pCtx, &pvhRequest)  );
    SG_ERR_CHECK(  SG_vhash__add__null(pCtx, pvhRequest, SG_SYNC_STATUS_KEY__CLONE)  );
    if (pvh_clone_request)
    {
        SG_ERR_CHECK(  SG_vhash__addcopy__vhash(pCtx, pvhRequest, SG_SYNC_STATUS_KEY__CLONE_REQUEST, pvh_clone_request)  );
    }
    SG_ERR_CHECK(  SG_STRING__ALLOC__RESERVE(pCtx, &pstrRequest, 50)  );
    SG_ERR_CHECK(  SG_vhash__to_json(pCtx, pvhRequest, pstrRequest)  );

    SG_ERR_CHECK(  SG_pathname__alloc__pathname_sz(pCtx, &pPathFragball, pStagingPathname, (const char*)pszFragballName)  );
    SG_ERR_CHECK(  do_url(pCtx, pszUrl, "POST", SG_string__sz(pstrRequest), pSyncClient->psz_username, pSyncClient->psz_password, NULL, pPathFragball, SG_TRUE)  );

    SG_RETURN_AND_NULL(pszFragballName, ppszFragballName);

    /* fall through */
fail:
    SG_log__pop_operation(pCtx);
    SG_NULLFREE(pCtx, pszFragballName);
    SG_VHASH_NULLFREE(pCtx, pvhRequest);
    SG_PATHNAME_NULLFREE(pCtx, pPathFragball);
    SG_NULLFREE(pCtx, pszUrl);
    SG_STRING_NULLFREE(pCtx, pstrRequest);
}
Example #4
0
SG_error SG_context__err_to_string(SG_context* pCtx, SG_string** ppErrString)
{
	SG_error err = SG_ERR_OK;
	char szErr[SG_ERROR_BUFFER_SIZE];
	SG_string* pTempStr = NULL;
	SG_uint32 lenRequired;

	SG_ASSERT( pCtx );
//	SG_ASSERT( pCtx->level < SG_CONTEXT_MAX_ERROR_LEVELS );

	if (!ppErrString)
		return SG_ERR_INVALIDARG;

	if (pCtx->level > 0)
	{
		// when in an error-on-error (level > 0), the error string DOES NOT belong to the
		// error context/level that we are in.  The full message is only defined for the
		// original error that triggered things.

		*ppErrString = NULL;
		return SG_ERR_OK;
	}

	SG_error__get_message(pCtx->errValues[pCtx->level], szErr, sizeof(szErr));

	lenRequired = (  strlen(szErr)
					 + strlen(pCtx->szDescription)
					 + pCtx->lenStackTrace
					 + 100);

	// do all of the formatting in an error-on-error context/level
	// so that none of the string allocation/manipulation trashes
	// the current error context.
	//
	// ***DO NOT JUMP OUT OF THIS PUSH..POP BLOCK.***

	SG_context__push_level(pCtx);
	{
		SG_STRING__ALLOC__RESERVE(pCtx,&pTempStr,lenRequired);

		if (SG_IS_OK(pCtx->errValues[pCtx->level]))
		{
			// since we pre-reserved all of the space we require, we
			// don't expect any of the appends to fail.  So we can
			// ignore intermediate errors after each step.  if one of
			// them does have a problem, the subsequent statements will
			// fail because we already have an error at this level.
			// either way, we don't care because we're going to pop the
			// level in a minute anyway.

			if (szErr[0] != 0)
			{
				SG_string__append__sz(pCtx, pTempStr, szErr);
				if (pCtx->szDescription[0] != 0)
					SG_string__append__sz(pCtx, pTempStr, ": ");
				else
					SG_string__append__sz(pCtx, pTempStr, ".");
			}
			if (pCtx->szDescription[0] != 0)
				SG_string__append__sz(pCtx, pTempStr, pCtx->szDescription);
			if (szErr[0] != 0 || pCtx->szDescription[0] != 0)
				SG_string__append__sz(pCtx, pTempStr, "\n");

			SG_string__append__sz(pCtx, pTempStr, pCtx->szStackTrace);

			// if all of the formating works, we return the allocated string.
			// if not, we delete it and return the formatting error.

			if (SG_IS_OK(pCtx->errValues[pCtx->level]))
				*ppErrString = pTempStr;
			else
				SG_STRING_NULLFREE(pCtx, pTempStr);
		}

		err = pCtx->errValues[pCtx->level];		// we return the error value of the allocation/formatting
	}
	SG_context__pop_level(pCtx);

	return err;
}