| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.wicket.protocol.http; |
| |
| import java.time.Instant; |
| import jakarta.servlet.http.Cookie; |
| import jakarta.servlet.http.HttpServletResponse; |
| import org.apache.wicket.request.http.WebResponse; |
| import org.apache.wicket.util.lang.Args; |
| |
| /** |
| * Response that keeps headers in buffers until the first content is written. |
| * |
| * This is necessary to get {@link #reset()} working without removing the JSESSIONID cookie. When |
| * {@link HttpServletResponse#reset()} is called it removes all cookies, including the JSESSIONID |
| * cookie - see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=26183">Bug 26183</a>. |
| * |
| * Calling {@link #reset()} on this response clears the buffered meta data, if there is already any |
| * content written it throws {@link IllegalStateException}. |
| * |
| * @author Matej Knopp |
| */ |
| class HeaderBufferingWebResponse extends WebResponse implements IMetaDataBufferingWebResponse |
| { |
| private final WebResponse originalResponse; |
| |
| /** |
| * Buffer of meta data. |
| */ |
| private final BufferedWebResponse bufferedResponse; |
| |
| public HeaderBufferingWebResponse(WebResponse originalResponse) |
| { |
| this.originalResponse = originalResponse; |
| |
| bufferedResponse = new BufferedWebResponse(originalResponse); |
| } |
| |
| private boolean buffering = true; |
| |
| private void stopBuffering() |
| { |
| if (buffering) |
| { |
| bufferedResponse.writeTo(originalResponse); |
| buffering = false; |
| } |
| } |
| |
| /** |
| * The response used for meta data. |
| * |
| * @return buffered response if nothing was written yet, the original response otherwise |
| */ |
| private WebResponse getMetaResponse() |
| { |
| if (buffering) |
| { |
| return bufferedResponse; |
| } |
| else |
| { |
| return originalResponse; |
| } |
| } |
| |
| @Override |
| public void addCookie(Cookie cookie) |
| { |
| getMetaResponse().addCookie(cookie); |
| } |
| |
| @Override |
| public void clearCookie(Cookie cookie) |
| { |
| getMetaResponse().clearCookie(cookie); |
| } |
| |
| @Override |
| public void flush() |
| { |
| stopBuffering(); |
| |
| originalResponse.flush(); |
| } |
| |
| @Override |
| public boolean isRedirect() |
| { |
| return getMetaResponse().isRedirect(); |
| } |
| |
| @Override |
| public void sendError(int sc, String msg) |
| { |
| getMetaResponse().sendError(sc, msg); |
| } |
| |
| @Override |
| public void sendRedirect(String url) |
| { |
| getMetaResponse().sendRedirect(url); |
| } |
| |
| @Override |
| public void setContentLength(long length) |
| { |
| getMetaResponse().setContentLength(length); |
| } |
| |
| @Override |
| public void setContentType(String mimeType) |
| { |
| getMetaResponse().setContentType(mimeType); |
| } |
| |
| @Override |
| public void setDateHeader(String name, Instant date) |
| { |
| Args.notNull(date, "date"); |
| getMetaResponse().setDateHeader(name, date); |
| } |
| |
| @Override |
| public boolean isHeaderSupported() |
| { |
| return getMetaResponse().isHeaderSupported(); |
| } |
| |
| @Override |
| public void setHeader(String name, String value) |
| { |
| getMetaResponse().setHeader(name, value); |
| } |
| |
| @Override |
| public void addHeader(String name, String value) |
| { |
| getMetaResponse().addHeader(name, value); |
| } |
| |
| @Override |
| public void setStatus(int sc) |
| { |
| getMetaResponse().setStatus(sc); |
| } |
| |
| @Override |
| public void disableCaching() { |
| getMetaResponse().disableCaching(); |
| } |
| |
| @Override |
| public String encodeURL(CharSequence url) |
| { |
| return originalResponse.encodeURL(url); |
| } |
| |
| @Override |
| public String encodeRedirectURL(CharSequence url) |
| { |
| return originalResponse.encodeRedirectURL(url); |
| } |
| |
| @Override |
| public void write(CharSequence sequence) |
| { |
| stopBuffering(); |
| |
| originalResponse.write(sequence); |
| } |
| |
| @Override |
| public void write(byte[] array) |
| { |
| stopBuffering(); |
| |
| originalResponse.write(array); |
| } |
| |
| |
| @Override |
| public void write(byte[] array, int offset, int length) |
| { |
| stopBuffering(); |
| |
| originalResponse.write(array, offset, length); |
| } |
| |
| @Override |
| public void reset() |
| { |
| if (buffering) |
| { |
| // still buffering so just reset the buffer of meta data |
| bufferedResponse.reset(); |
| } |
| else |
| { |
| // the original response is never reset (see class javadoc) |
| throw new IllegalStateException("Response is no longer buffering!"); |
| } |
| } |
| |
| @Override |
| public void writeMetaData(WebResponse webResponse) |
| { |
| bufferedResponse.writeMetaData(webResponse); |
| } |
| |
| @Override |
| public Object getContainerResponse() |
| { |
| return originalResponse.getContainerResponse(); |
| } |
| } |