[haiku-commits] Re: haiku: hrev47060 - src/apps/haikudepot

  • From: Stephan Aßmus <superstippi@xxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 27 Mar 2014 09:55:33 +0100

Hi Adrien,

Am 26.03.2014 23:28, schrieb pulkomandy:
+               char base64[1024];
+               ssize_t base64Size = encode_base64(base64, plain, 
plain.Length(),
+                       false);

This won't work. The "base 64" used for url-encoding isn't the same as
plain base64, as it replaces some characters.

Thanks!

... and anyway, BHttpRequest has SetUserName and SetPassword, which
should do this. The server will request an authentication and decide if
he wants you to use basic or digest.

This is specific to the protocol with the web app. The documentation says this:

  Authentication of invocations uses basic authentication for both
  REST and JSON-RPC. This procedure involves an HTTP header being
  included in each invocation that identies the user and also
  provides their password. The value of the header includes a
  base-64 encoded string of the username and password, separated by
  a colon. This is an example of such a header;

     Authorization: Basic dXNlcjpwYXNzd29yZA

  If the authentication fails then the request will continue
  unauthenticated; there is no `challenge' returned back to the
  caller. As part of the continuation of the invocation, an http
  401 or 403 response maybe returned should authorization checks
  have failed. A special API exists to provide a means to test an
  authentication for the purposes of a login panel or similar.

So when I use BHttpRequest::SetUserName/SetPassword() it will work as the documentation says is required?

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

Using the BUrlProtocolRoster is the preferred way to create requests:
        BUrlProtocolRoster.MakeRequest(url, &listener, &context);

I've looked at that method. I find it cleaner, that when I know I need a BHttpRequest, I just create one directly, instead of trying to cast what the roster gave me.

Note that using NULL as a context is allowed, and results in using the
default context.

Yes, I've used that in the other test.

+       BString jsonString
+               =       "{"
+                               "\"jsonrpc\":\"2.0\","
+                               "\"id\":4143431,"
+                               "\"method\":\"getPkg\","
+                               "\"params\":[{"
+                                       "\"name\":\"apr\","
+                                       "\"architectureCode\":\"x86\","
+                                       "\"versionType\":\"NONE\""
+                               "}]"
+                       "}"
+               ;
+       
+       data->WriteAt(0, jsonString.String(), jsonString.Length());
+       data->Seek(0, SEEK_SET);

You could use a BMemoryIO built around a const char* for this, avoiding
one copy of the data. I guess the proper solution will be a JSONDataIO,
where you can set fields (BMessage like?), and then Read() the
serialized JSON string from it. Such a class could be part of the
Services Kit, to make it easier to use JSON based web services.

What I have in mind is something that converts between JSON and BMessages. I've also looked at porting a library. One JSON library is already in HaikuPorts, but it looked like it would not be the ideal one to use. But there are quite a few to chose from. My thinking is that HaikuDepot communicates with a specific server only, which reduces the requirements with regards to a robust, generic implementation. And I don't need converting between JSON and actual C++ objects based on schemas. Which may or may not require GCC4 anyway, depending on the library. So what I did above is just a first dip into the water and I will refactore the code into a more generic solution which may or may not be re-usable for the Service Kit.

WebKit has something similar for HTTP forms data.

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

If running synchronously, your class could subclass
BUrlSycnhronousRequest, where you can use Perform() and
WaitForCompletion(). Callbacks are the same as what you already
implemented.

Yes, saw that too. Like I said in IRC, I am not sure the API works the right way around. I would make the basic classes work synchronously, and then offer an optional wrapper that makes it asynchronous. Right now, everyone has to live with the draw-backs of creating one thread per request, even when the application already has a dedicated thread for networking. So I am wondering whether the API should be changed first, before it has too many users.

I'd suggest implementing at least RequestCompleted, if you didn't
already. It's the place where you know if the request has failed, and
can get the HttpResult from it.

Thanks. It also looked like the listener already gives this information and is required anyway. For example to capture the data from the server.

Best regards,
-Stephan


Other related posts: