Replace the ClapClientHelper implementation

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Replace the ClapClientHelper implementation

Marais Neethling
Hi Everyone,

I have a restlet application configured via Spring. I'm debugging a problem I'm facing and it is the same as described by a few others:

1. https://stackoverflow.com/questions/26101151/restlet-directory-default-index-html-file-not-being-served?newreg=6f6c60d66f3d4d08a295170d0adc96a7
2. http://restlet-discuss.1400322.n2.nabble.com/Serving-static-files-using-Directory-and-CLAP-from-a-jar-td7578543.html

I've narrowed it down the the ClapClientHelper .

In short, when static resources are served via the CLAP Directory service, requests that does not resolve to specific file, e.g. http://host/public/ should respond with the resource indicated by the indexName property. This works fine when the resources are on a filesystem.
However, when the resources are inside a jar, the ClapClientHelper will try to return a stream pointing to the path it resolved, e.g. jar:file:/filepath/somejar.jar!/web/public/ which is actually results in an HTTP response with empty body and application/octet-stream media type.

In order to change the behaviour I would like to replace the ClapClientHelper with my own implementation say MyClapClientHelper. Where could I register this helper with the Engine and replace the existing one?

Kind regards
Marais

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|

Re: Replace the ClapClientHelper implementation

Thierry Boileau-4
Hello Marais,

there are two ways, one that does not require any code, and the other one.
The first one, is to let the ServiceLoader find your service:
  • add a file called META-INF/services/org.restlet.engine.ClientHelper
  • this file has a single line of text: the full name (including the package) of your helper class

The second one is to add programmatically the helper:

  • Engine.getInstance().getRegisteredClients().add(0, new MyProtocolHelper());


I hope this will help you.


Best regards,

Thierry Boileau


2015-09-12 16:22 GMT+02:00 Marais Neethling <[hidden email]>:
Hi Everyone,

I have a restlet application configured via Spring. I'm debugging a problem I'm facing and it is the same as described by a few others:


I've narrowed it down the the ClapClientHelper .

In short, when static resources are served via the CLAP Directory service, requests that does not resolve to specific file, e.g. http://host/public/ should respond with the resource indicated by the indexName property. This works fine when the resources are on a filesystem.
However, when the resources are inside a jar, the ClapClientHelper will try to return a stream pointing to the path it resolved, e.g. jar:file:/filepath/somejar.jar!/web/public/ which is actually results in an HTTP response with empty body and application/octet-stream media type.

In order to change the behaviour I would like to replace the ClapClientHelper with my own implementation say MyClapClientHelper. Where could I register this helper with the Engine and replace the existing one?

Kind regards
Marais

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
Reply | Threaded
Open this post in threaded view
|

Re: Replace the ClapClientHelper implementation

Marais Neethling
Thanks Thierry,

That helped a lot. I can now share my change that solved the problem.
At around line 74 in the ClapClientHelper file the code checks if the
file url points to a directory as opposed to an actual file. When the
resources are in a jar file, this piece of code is not executed as the
url protocol does not match "file". The below snippet will provide the
same behaviour for resources inside jar files. The new code is
basically the "else if" part.

// The ClassLoader returns a directory listing in some cases.
// As this listing is partial, it is of little value in the context
// of the CLAP client, so we have to ignore them.
if (url != null) {
  if (url.getProtocol().equals("file")) {
    File file = new File(url.getFile());
    modificationDate = new Date(file.lastModified());

    if (file.isDirectory()) {
      url = null;
    }
  } else if (url.getProtocol().equals("jar")) {
    try {
      JarURLConnection conn = (JarURLConnection) url.openConnection();
      modificationDate = new
Date(conn.getJarEntry().getLastModifiedTime().toMillis());
      if (conn.getJarEntry().isDirectory()) {
        url = null;
      }

    } catch (IOException ioe) {
      getLogger().log(Level.WARNING,
              "Unable to open the representation's input stream",
              ioe);
      response.setStatus(Status.SERVER_ERROR_INTERNAL);
    }
  }
}

Regards
Marais

On Sat, Sep 12, 2015 at 6:35 PM, Thierry Boileau <[hidden email]> wrote:

> Hello Marais,
>
> there are two ways, one that does not require any code, and the other one.
> The first one, is to let the ServiceLoader find your service:
>
> add a file called META-INF/services/org.restlet.engine.ClientHelper
> this file has a single line of text: the full name (including the package)
> of your helper class
>
>
> The second one is to add programmatically the helper:
>
> Engine.getInstance().getRegisteredClients().add(0, new MyProtocolHelper());
>
>
> I hope this will help you.
>
>
> Best regards,
>
> Thierry Boileau
>
>
> 2015-09-12 16:22 GMT+02:00 Marais Neethling <[hidden email]>:
>>
>> Hi Everyone,
>>
>> I have a restlet application configured via Spring. I'm debugging a
>> problem I'm facing and it is the same as described by a few others:
>>
>> 1.
>> https://stackoverflow.com/questions/26101151/restlet-directory-default-index-html-file-not-being-served?newreg=6f6c60d66f3d4d08a295170d0adc96a7
>> 2.
>> http://restlet-discuss.1400322.n2.nabble.com/Serving-static-files-using-Directory-and-CLAP-from-a-jar-td7578543.html
>>
>> I've narrowed it down the the ClapClientHelper .
>>
>> In short, when static resources are served via the CLAP Directory service,
>> requests that does not resolve to specific file, e.g. http://host/public/
>> should respond with the resource indicated by the indexName property. This
>> works fine when the resources are on a filesystem.
>> However, when the resources are inside a jar, the ClapClientHelper will
>> try to return a stream pointing to the path it resolved, e.g.
>> jar:file:/filepath/somejar.jar!/web/public/ which is actually results in an
>> HTTP response with empty body and application/octet-stream media type.
>>
>> In order to change the behaviour I would like to replace the
>> ClapClientHelper with my own implementation say MyClapClientHelper. Where
>> could I register this helper with the Engine and replace the existing one?
>>
>> Kind regards
>> Marais
>
>

To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].