Example #1
0
status_t
WebAppInterface::_SendJsonRequest(BString jsonString, BMessage& reply) const
{
    BUrl url("https://depot.haiku-os.org/api/v1/pkg");

    ProtocolListener listener;
    BUrlContext context;
    BHttpHeaders headers;
    // Content-Type
    headers.AddHeader("Content-Type", "application/json");
    headers.AddHeader("User-Agent", "X-HDS-Client");

    BHttpRequest request(url, true, "HTTP", &listener, &context);

    // Authentication
    if (!fUsername.IsEmpty() && !fPassword.IsEmpty()) {
        request.SetUserName(fUsername);
        request.SetPassword(fPassword);
    }

    request.SetMethod(B_HTTP_POST);
    request.SetHeaders(headers);

    BMemoryIO* data = new BMemoryIO(
        jsonString.String(), jsonString.Length() - 1);

    request.AdoptInputData(data, jsonString.Length() - 1);

    BMallocIO replyData;
    listener.SetDownloadIO(&replyData);
//	listener.SetDebug(true);

    thread_id thread = request.Run();
    wait_for_thread(thread, NULL);

    const BHttpResult& result = dynamic_cast<const BHttpResult&>(
                                    request.Result());

    int32 statusCode = result.StatusCode();
    if (statusCode != 200) {
        printf("Response code: %" B_PRId32 "\n", statusCode);
        return B_ERROR;
    }

    jsonString.SetTo(static_cast<const char*>(replyData.Buffer()),
                     replyData.BufferLength());
    if (jsonString.Length() == 0)
        return B_ERROR;

    BJson parser;
    status_t status = parser.Parse(reply, jsonString);
    if (status == B_BAD_DATA) {
//		printf("Parser choked on JSON:\n%s\n", jsonString.String());
    }
    return status;
}
Example #2
0
void
BHttpRequest::_SendHeaders()
{
	BHttpHeaders outputHeaders;

	// HTTP 1.1 additional headers
	if (fHttpVersion == B_HTTP_11) {
		BString host = Url().Host();
		if (Url().HasPort() && !_IsDefaultPort())
			host << ':' << Url().Port();

		outputHeaders.AddHeader("Host", host);

		outputHeaders.AddHeader("Accept", "*/*");
		outputHeaders.AddHeader("Accept-Encoding", "gzip");
			// Allows the server to compress data using the "gzip" format.
			// "deflate" is not supported, because there are two interpretations
			// of what it means (the RFC and Microsoft products), and we don't
			// want to handle this. Very few websites support only deflate,
			// and most of them will send gzip, or at worst, uncompressed data.

		outputHeaders.AddHeader("Connection", "close");
			// Let the remote server close the connection after response since
			// we don't handle multiple request on a single connection
	}

	// Classic HTTP headers
	if (fOptUserAgent.CountChars() > 0)
		outputHeaders.AddHeader("User-Agent", fOptUserAgent.String());

	if (fOptReferer.CountChars() > 0)
		outputHeaders.AddHeader("Referer", fOptReferer.String());

	// Authentication
	if (fContext != NULL) {
		BHttpAuthentication& authentication = fContext->GetAuthentication(fUrl);
		if (authentication.Method() != B_HTTP_AUTHENTICATION_NONE) {
			if (fOptUsername.Length() > 0) {
				authentication.SetUserName(fOptUsername);
				authentication.SetPassword(fOptPassword);
			}

			BString request(fRequestMethod);
			outputHeaders.AddHeader("Authorization",
				authentication.Authorization(fUrl, request));
		}
	}

	// Required headers for POST data
	if (fOptPostFields != NULL && fRequestMethod == B_HTTP_POST) {
		BString contentType;

		switch (fOptPostFields->GetFormType()) {
			case B_HTTP_FORM_MULTIPART:
				contentType << "multipart/form-data; boundary="
					<< fOptPostFields->GetMultipartBoundary() << "";
				break;

			case B_HTTP_FORM_URL_ENCODED:
				contentType << "application/x-www-form-urlencoded";
				break;
		}

		outputHeaders.AddHeader("Content-Type", contentType);
		outputHeaders.AddHeader("Content-Length",
			fOptPostFields->ContentLength());
	} else if (fOptInputData != NULL
			&& (fRequestMethod == B_HTTP_POST
			|| fRequestMethod == B_HTTP_PUT)) {
		if (fOptInputDataSize >= 0)
			outputHeaders.AddHeader("Content-Length", fOptInputDataSize);
		else
			outputHeaders.AddHeader("Transfer-Encoding", "chunked");
	}

	// Optional headers specified by the user
	if (fOptHeaders != NULL) {
		for (int32 headerIndex = 0; headerIndex < fOptHeaders->CountHeaders();
				headerIndex++) {
			BHttpHeader& optHeader = (*fOptHeaders)[headerIndex];
			int32 replaceIndex = outputHeaders.HasHeader(optHeader.Name());

			// Add or replace the current option header to the
			// output header list
			if (replaceIndex == -1)
				outputHeaders.AddHeader(optHeader.Name(), optHeader.Value());
			else
				outputHeaders[replaceIndex].SetValue(optHeader.Value());
		}
	}

	// Context cookies
	if (fOptSetCookies && fContext != NULL) {
		BString cookieString;

		BNetworkCookieJar::UrlIterator iterator
			= fContext->GetCookieJar().GetUrlIterator(fUrl);
		const BNetworkCookie* cookie = iterator.Next();
		if (cookie != NULL) {
			while (true) {
				cookieString << cookie->RawCookie(false);
				cookie = iterator.Next();
				if (cookie == NULL)
					break;
				cookieString << "; ";
			}

			outputHeaders.AddHeader("Cookie", cookieString);
		}
	}

	// Write output headers to output stream
	BString headerData;

	for (int32 headerIndex = 0; headerIndex < outputHeaders.CountHeaders();
			headerIndex++) {
		const char* header = outputHeaders.HeaderAt(headerIndex).Header();

		headerData << header;
		headerData << "\r\n";

		_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_OUT, "%s", header);
	}

	fSocket->Write(headerData.String(), headerData.Length());
}
Example #3
0
status_t
WebAppInterface::RetrievePackageInfo(const BString& packageName,
	BMessage& message)
{
	BUrl url("https://depot.haiku-os.org/api/v1/pkg");
	
	ProtocolListener listener;
	BUrlContext context;
	BHttpHeaders headers;	
	// Content-Type
	headers.AddHeader("Content-Type", "application/json");

	BHttpRequest request(url, true, "HTTP", &listener, &context);

	// Authentication
	if (!fUsername.IsEmpty() && !fPassword.IsEmpty()) {
		request.SetUserName(fUsername);
		request.SetPassword(fPassword);
	}

	request.SetMethod(B_HTTP_POST);
	request.SetHeaders(headers);

	BString jsonString = JsonBuilder()
		.AddValue("jsonrpc", "2.0")
		.AddValue("id", ++fRequestIndex)
		.AddValue("method", "getPkg")
		.AddArray("params")
			.AddObject()
				.AddValue("name", packageName)
				.AddValue("architectureCode", "x86_gcc2")
				.AddValue("naturalLanguageCode", "en")
				.AddValue("versionType", "NONE")
			.EndObject()
		.EndArray()
	.End();

	printf("Sending JSON:\n%s\n", jsonString.String());
	
	BMemoryIO* data = new BMemoryIO(
		jsonString.String(), jsonString.Length() - 1);

	request.AdoptInputData(data, jsonString.Length() - 1);

	BMallocIO replyData;
	listener.SetDownloadIO(&replyData);
//	listener.SetDebug(true);

	thread_id thread = request.Run();
	wait_for_thread(thread, NULL);

	const BHttpResult& result = dynamic_cast<const BHttpResult&>(
		request.Result());

	int32 statusCode = result.StatusCode();
	
	if (statusCode == 200)
		return B_OK;

       printf("Response code: %" B_PRId32 "\n", statusCode);

	return B_ERROR;
}