After upgrading to 9.4.14.v20181114 getContentAsString() prepends previously fetched strings

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

After upgrading to 9.4.14.v20181114 getContentAsString() prepends previously fetched strings

Alexander Farber
Good afternoon,

I run a custom WebSocketServlet for Jetty, which sends short text push notifications (for an async mobile and desktop word game) to many platforms (Facebook, Vk.com, Mail.ru, Ok.ru also Firebase and Amazon messaging) using a Jetty HttpClient instance:

public class MyServlet extends WebSocketServlet {
    private final SslContextFactory mSslFactory = new SslContextFactory();
    private final HttpClient mHttpClient = new HttpClient(mSslFactory);

    @Override
    public void init() throws ServletException {
        super.init();

        try {
            mHttpClient.start();
        } catch (Exception ex) {
            throw new ServletException(ex);
        }

        mFcm      = new Fcm(mHttpClient);    // Firebase
        mAdm      = new Adm(mHttpClient);    // Amazon
        mApns     = new Apns(mHttpClient);   // Apple
        mFacebook = new Facebook(mHttpClient);
        mMailru   = new Mailru(mHttpClient);
        mOk       = new Ok(mHttpClient);
        mVk       = new Vk(mHttpClient);
    }

This has worked very good for the past year (thank you!), but since I have recently upgraded my WAR-file to use Jetty 9.4.14.v20181114 the trouble has begun -

public class Facebook {
    private final static String APP_ID      = "XXXXX";
    private final static String APP_SECRET  = "XXXXX";
    private final static String MESSAGE_URL = "<a href="https://graph.facebook.com/%s/notifications">https://graph.facebook.com/%s/notifications?" +
            // the app access token is: "app id | app secret"
            "access_token=%s%%7C%s" +
            "&template=%s";

    private final HttpClient mHttpClient;

    public Facebook(HttpClient httpClient) {
        mHttpClient = httpClient;
    }

    private final BufferingResponseListener mMessageListener = new BufferingResponseListener() {
        @Override
        public void onComplete(Result result) {
            if (!result.isSucceeded()) {
                LOG.warn("facebook failure: {}", result.getFailure());
                return;
            }

            try {
                // THE jsonStr SUDDENLY CONTAINS PREVIOUS CONTENT!
                String jsonStr = getContentAsString(StandardCharsets.UTF_8);
                LOG.info("facebook success: {}", jsonStr);
            } catch (Exception ex) {
                LOG.warn("facebook exception: ", ex);
            }
        }
    };

    public void postMessage(int uid, String sid, String body) {
        String url = String.format(MESSAGE_URL, sid, APP_ID, APP_SECRET, UrlEncoded.encodeString(body));
        mHttpClient.POST(url).send(mMessageListener);
    }
}

Suddenly the getContentAsString method called for successful HttpClient invocations started to deliver the strings, which were fetched previously - prepended to the the actual result string.

What could it be please, is it some changed BufferingResponseListener behaviour or maybe some non-obvious Java quirk?

Best regards
Alex


_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: After upgrading to 9.4.14.v20181114 getContentAsString() prepends previously fetched strings

Greg Wilkins

It looks like a change in BufferingResponseListener, which used to allocate a new buffer in onHeaders.   It now will just keep accumulating responses!

A work around until this is fixed is to assign a new BufferingResponseListener for each request.    





On Sun, 2 Dec 2018 at 16:19, Alexander Farber <[hidden email]> wrote:
Good afternoon,

I run a custom WebSocketServlet for Jetty, which sends short text push notifications (for an async mobile and desktop word game) to many platforms (Facebook, Vk.com, Mail.ru, Ok.ru also Firebase and Amazon messaging) using a Jetty HttpClient instance:

public class MyServlet extends WebSocketServlet {
    private final SslContextFactory mSslFactory = new SslContextFactory();
    private final HttpClient mHttpClient = new HttpClient(mSslFactory);

    @Override
    public void init() throws ServletException {
        super.init();

        try {
            mHttpClient.start();
        } catch (Exception ex) {
            throw new ServletException(ex);
        }

        mFcm      = new Fcm(mHttpClient);    // Firebase
        mAdm      = new Adm(mHttpClient);    // Amazon
        mApns     = new Apns(mHttpClient);   // Apple
        mFacebook = new Facebook(mHttpClient);
        mMailru   = new Mailru(mHttpClient);
        mOk       = new Ok(mHttpClient);
        mVk       = new Vk(mHttpClient);
    }

This has worked very good for the past year (thank you!), but since I have recently upgraded my WAR-file to use Jetty 9.4.14.v20181114 the trouble has begun -

public class Facebook {
    private final static String APP_ID      = "XXXXX";
    private final static String APP_SECRET  = "XXXXX";
    private final static String MESSAGE_URL = "<a href="https://graph.facebook.com/%s/notifications" target="_blank">https://graph.facebook.com/%s/notifications?" +
            // the app access token is: "app id | app secret"
            "access_token=%s%%7C%s" +
            "&template=%s";

    private final HttpClient mHttpClient;

    public Facebook(HttpClient httpClient) {
        mHttpClient = httpClient;
    }

    private final BufferingResponseListener mMessageListener = new BufferingResponseListener() {
        @Override
        public void onComplete(Result result) {
            if (!result.isSucceeded()) {
                LOG.warn("facebook failure: {}", result.getFailure());
                return;
            }

            try {
                // THE jsonStr SUDDENLY CONTAINS PREVIOUS CONTENT!
                String jsonStr = getContentAsString(StandardCharsets.UTF_8);
                LOG.info("facebook success: {}", jsonStr);
            } catch (Exception ex) {
                LOG.warn("facebook exception: ", ex);
            }
        }
    };

    public void postMessage(int uid, String sid, String body) {
        String url = String.format(MESSAGE_URL, sid, APP_ID, APP_SECRET, UrlEncoded.encodeString(body));
        mHttpClient.POST(url).send(mMessageListener);
    }
}

Suddenly the getContentAsString method called for successful HttpClient invocations started to deliver the strings, which were fetched previously - prepended to the the actual result string.

What could it be please, is it some changed BufferingResponseListener behaviour or maybe some non-obvious Java quirk?

Best regards
Alex

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users


--

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: After upgrading to 9.4.14.v20181114 getContentAsString() prepends previously fetched strings

Simone Bordet-3
In reply to this post by Alexander Farber
Hi,

On Sun, Dec 2, 2018 at 4:19 PM Alexander Farber
<[hidden email]> wrote:

>
> Good afternoon,
>
> I run a custom WebSocketServlet for Jetty, which sends short text push notifications (for an async mobile and desktop word game) to many platforms (Facebook, Vk.com, Mail.ru, Ok.ru also Firebase and Amazon messaging) using a Jetty HttpClient instance:
>
> public class MyServlet extends WebSocketServlet {
>     private final SslContextFactory mSslFactory = new SslContextFactory();
>     private final HttpClient mHttpClient = new HttpClient(mSslFactory);
>
>     @Override
>     public void init() throws ServletException {
>         super.init();
>
>         try {
>             mHttpClient.start();
>         } catch (Exception ex) {
>             throw new ServletException(ex);
>         }
>
>         mFcm      = new Fcm(mHttpClient);    // Firebase
>         mAdm      = new Adm(mHttpClient);    // Amazon
>         mApns     = new Apns(mHttpClient);   // Apple
>         mFacebook = new Facebook(mHttpClient);
>         mMailru   = new Mailru(mHttpClient);
>         mOk       = new Ok(mHttpClient);
>         mVk       = new Vk(mHttpClient);
>     }
>
> This has worked very good for the past year (thank you!), but since I have recently upgraded my WAR-file to use Jetty 9.4.14.v20181114 the trouble has begun -
>
> public class Facebook {
>     private final static String APP_ID      = "XXXXX";
>     private final static String APP_SECRET  = "XXXXX";
>     private final static String MESSAGE_URL = "<a href="https://graph.facebook.com/%s/notifications">https://graph.facebook.com/%s/notifications?" +
>             // the app access token is: "app id | app secret"
>             "access_token=%s%%7C%s" +
>             "&template=%s";
>
>     private final HttpClient mHttpClient;
>
>     public Facebook(HttpClient httpClient) {
>         mHttpClient = httpClient;
>     }
>
>     private final BufferingResponseListener mMessageListener = new BufferingResponseListener() {
>         @Override
>         public void onComplete(Result result) {
>             if (!result.isSucceeded()) {
>                 LOG.warn("facebook failure: {}", result.getFailure());
>                 return;
>             }
>
>             try {
>                 // THE jsonStr SUDDENLY CONTAINS PREVIOUS CONTENT!
>                 String jsonStr = getContentAsString(StandardCharsets.UTF_8);
>                 LOG.info("facebook success: {}", jsonStr);
>             } catch (Exception ex) {
>                 LOG.warn("facebook exception: ", ex);
>             }
>         }
>     };
>
>     public void postMessage(int uid, String sid, String body) {
>         String url = String.format(MESSAGE_URL, sid, APP_ID, APP_SECRET, UrlEncoded.encodeString(body));
>         mHttpClient.POST(url).send(mMessageListener);

You cannot reuse BufferingResponseListener, it was never intended to
work in this way.
It was just a coincidence that it was working before.
Allocate the BufferingResponseListener for each request/response.

--
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.
_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users
Reply | Threaded
Open this post in threaded view
|

Re: After upgrading to 9.4.14.v20181114 getContentAsString() prepends previously fetched strings

Alexander Farber
Hi -

On Mon, Dec 3, 2018 at 10:20 AM Simone Bordet <[hidden email]> wrote:

You cannot reuse BufferingResponseListener, it was never intended to
work in this way.
It was just a coincidence that it was working before.
Allocate the BufferingResponseListener for each request/response.

 
thank you, this has helped!

Regards
Alex

_______________________________________________
jetty-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/jetty-users