Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookies on WebTextTerminal #32

Open
maxbrito500 opened this issue Jun 18, 2021 · 5 comments
Open

Cookies on WebTextTerminal #32

maxbrito500 opened this issue Jun 18, 2021 · 5 comments

Comments

@maxbrito500
Copy link

Hello,

Was able to make progress quickly, the command line app is looking great thanks to Text-IO.

What is now missing is persistent memory. This can be done on the swing and command line interfaces very easily using files on disk for storage to remember a user that is logged, but not so trivial for the WebTextTerminal because the ContextHandlers don't seem to be exposed for usage. Otherwise would be possible to solve this by extracting URL paths and cookies.

Perhaps exposing the Context object from Ratpack is the simplest way? I imagine it is not easy to create a common mechanism for both spark and ratpack, on this case just needed for RatPack.

How would you recommend that we can access cookies and the URL from within Text-IO for the purpose of persistent user-memory? (to know who is logged inside the app).

Again: many, many thanks. Really good library.

@maxbrito500
Copy link
Author

Found a solution editing file RunnerData.java to include the Context as argument.
In case it helps, these were the changes:

Adding on top:
private Context context;

And then on bottom:

public void setSessionData(Map<String, String> sessionData, Context context) {
        this.context = context;
        this.sessionData = sessionData;
    }

    public Context getContext() {
        return context;
    }

Then finally inside RatPackTextIoApp to modify the createRunnerData method to include the Context as argument on the runnerData.setSession method:

    private RunnerData createRunnerData(String initData, ContextHolder ctxHolder) {
        RunnerData runnerData = new RunnerData(initData);
        Session session = ctxHolder.context.get(Session.class);
        Map<String, String> sessionData = sessionDataProvider.apply(session);
        runnerData.setSessionData(sessionData, ctxHolder.context);
        return runnerData;
    }

From here the forward becomes then possible to read/write the cookies from each web request and generate the memory persistent data. Should also permit to recognize paths and work a bit more as a webpages. Here is an example for writing a cookie from the Weather.java app:

    @Override
    public void accept(TextIO textIO, RunnerData runnerData) {
        
        TextTerminal<?> terminal = textIO.getTextTerminal();
        String initData = (runnerData == null) ? null : runnerData.getInitData();
        AppUtil.printGsonMessage(terminal, initData);
        
        Context context = runnerData.getContext();
        context.getResponse().cookie("whiskey", "make-it-rye");
....
....

Question: Is it worth doing a pull request with these modifications?

On the local command line interfaces is possible to write things on disk, on the web browser we are limited to these methods. An idea could be perhaps to provide a "properties" method that can save these tidybits of data either on disk or as cookies depending on what is used?

Again, thanks for the great library. It is a fantastic piece of work.

@siordache
Copy link
Member

That's a great solution. A pull request is more than welcome. Thanks!

@maxbrito500
Copy link
Author

Will do. If possible, need your opinion. It is possible to set the cookies only until the first terminal command is sent. After that it does not seem possible to send cookies any longer using the context object.

For example:

context.getResponse().cookie("key1", "value1");
terminal.println();
context.getResponse().cookie("key2", "value2");

Key1 gets written to the cookies on the browser page. But key2 will be ignored, albeit still listed inside the context list when applying: Set<Cookie> list = context.getResponse().getCookies();

It seems that after a communication with the browser that the context objects loses "context", and some other object is created instead. I was looking where to catch it but I'm unable to find the right location.

Would you have any ideas where to inject the cookie info for the browser?

@maxbrito500
Copy link
Author

Hello,

I've created a hack. Meaning that a static map list is created with the list of current SESSIONIDs and which cookies should be written. Then before sending a reply the cookies are written back on the proper response object. I've started uploading the code, so this technique is visible here: https://github.com/nya-official/nya-server/blob/main/src/main/java/org2/beryx/textio/web/RatpackDataServer.java#L227-L233

It works albeit not exactly an efficient solution. Just sharing in case you have some thoughts on how to solve this better within textIo.

@siordache
Copy link
Member

I think your hack is ok. I don't have a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants