Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encoding Response as Gzip Causing Cookie to Not Be Set in Browser

I'm trying to reduce the network traffic by Gzipping all responses from backend, but I ran into an issue where cookie is not set in the browser if the login/logout call is being done the same way and I'm not sure why.

This is the backend code in Java.

Cookie cookie = new Cookie("cookie_name", cookieToken);
cookie.setPath("/");
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);

response.setContentType("application/json; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
                    
response.setHeader("Content-Encoding", "gzip");
String json=serviceOutput.toString();
byte[] gzip = Utils.gzip(json.getBytes("UTF-8"));
response.setContentLength(gzip.length);
response.getOutputStream().write(gzip);

Any pointer on why this doesn't work? I'm pretty sure I did the same thing previously without any issues.

--

Added the gzip method just in case it's relevant

public static byte[] gzip(byte[] content) throws IOException    {

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream g = new GZIPOutputStream(baos);

    if (content != null && content.length > 0) {
        g.write(content, 0, content.length);
        g.close();
    }

    return baos.toByteArray();
}
like image 833
juminoz Avatar asked May 24 '17 09:05

juminoz


2 Answers

I have modified your code for mocking data as

package com.mytests.pack;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HomeServlet extends HttpServlet{
    private static final long serialVersionUID = -2638972063792556071L;
    private Cookie[] cookies;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        cookies = request.getCookies();

        System.out.println("----------------------======================-------------------");
        if(null!=cookies){
            for(Cookie c : cookies){
                System.out.println(c.getValue());
            }
        }else {
            System.out.println("First request");
        }
        System.out.println("----------------------======================-------------------");

        Cookie cookie = new Cookie("cookie_name", "cookiecontentishereofname"+LocalDateTime.now().toString());
        cookie.setPath("/");
        cookie.setMaxAge(Integer.MAX_VALUE);

        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        response.addCookie(cookie);

        response.setHeader("Content-Encoding", "gzip");
        String json="{\"keyone\":\"Somestring is here in the point\"}";

        ByteArrayOutputStream obj=new ByteArrayOutputStream();
        GZIPOutputStream gzipstream = new GZIPOutputStream(obj);

        byte[] gzip = json.getBytes("UTF-8");
        gzipstream.write(gzip);
        gzipstream.close();
        response.setContentLength(obj.toByteArray().length);
        response.getOutputStream().write(obj.toByteArray());
    }
}

with above code and jetty-distribution-9.4.0.v20161208

  • Tested Browsers

    -Google Chrome - Version 58.0.3029.110 (64-bit) RESULT :cookie was set

    screenshot

    -Opera - 45.0.2552.812 (PGO) RESULT :cookie was set

    screenshot

    -Mozilla Firefox - 53.0.3 (32-bit)

Important thing to note about FIREFOX
When you open developer tools it doesn't show any cookie set but Practically works fine check screenshots firefox cookie view

Where as

Jetty console output

Jetty console output shows cookie was set successfully!

other change in config I would like to show you

added POM dependency snippet as

  <dependencies>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>compile</scope>
</dependency>
  </dependencies>
like image 156
Arjun Avatar answered Oct 15 '22 09:10

Arjun


Your code looks pretty ok. What I advice you is to show here the response plain text headers using for example curl -v http://your.host/under/test terminal command. If your cookie appears there, then it is a browser's thing

like image 37
Jairo Andres Velasco Romero Avatar answered Oct 15 '22 07:10

Jairo Andres Velasco Romero