View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.doc;
16  
17  import java.io.IOException;
18  import java.net.URL;
19  import java.nio.charset.StandardCharsets;
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.List;
23  
24  import org.apache.http.HttpResponse;
25  import org.apache.http.client.methods.HttpUriRequest;
26  import org.htmlunit.BrowserVersion;
27  import org.htmlunit.FrameContentHandler;
28  import org.htmlunit.HttpHeader;
29  import org.htmlunit.HttpWebConnection;
30  import org.htmlunit.MockWebConnection;
31  import org.htmlunit.WebClient;
32  import org.htmlunit.WebRequest;
33  import org.htmlunit.WebResponse;
34  import org.htmlunit.WebResponseData;
35  import org.htmlunit.WebServerTestCase;
36  import org.htmlunit.html.BaseFrameElement;
37  import org.htmlunit.html.HtmlPage;
38  import org.htmlunit.http.HttpStatus;
39  import org.htmlunit.util.ArrayUtils;
40  import org.htmlunit.util.MimeType;
41  import org.htmlunit.util.NameValuePair;
42  import org.htmlunit.util.WebConnectionWrapper;
43  import org.junit.jupiter.api.Test;
44  
45  /**
46   * Tests for the sample code from the documentation to make sure
47   * we adapt the docu or do not break the samples.
48   *
49   * @author Ronald Brill
50   */
51  public class DetailsTest extends WebServerTestCase {
52  
53      /**
54       * @throws Exception if an error occurs
55       */
56      @Test
57      public void contentBlockingRequest() throws Exception {
58          final URL url = new URL("http://localhost/");
59  
60          try (WebClient webClient = new WebClient()) {
61              webClient.getOptions().setThrowExceptionOnScriptError(false);
62              // set more options
63  
64              // create a WebConnectionWrapper with an (subclassed) getResponse() impl
65              new WebConnectionWrapper(webClient) {
66  
67                  @Override
68                  public WebResponse getResponse(final WebRequest request) throws IOException {
69                      final URL requestUrl = request.getUrl();
70                      // check the request url
71                      // if is allowed simple call super.
72  
73                      if (!isBlocked(requestUrl)) {
74                          return super.getResponse(request);
75                      }
76  
77                      // construct alternative response
78                      final String content = "<html><html>";
79                      final WebResponseData data = new WebResponseData(content.getBytes(StandardCharsets.UTF_8),
80                              HttpStatus.OK_200, "blocked", Collections.emptyList());
81                      final WebResponse blocked = new WebResponse(data, request, 0L);
82                      // if you like to check later on for blocked responses
83                      blocked.markAsBlocked("Blocked URL: '" + requestUrl.toExternalForm() + "'");
84                      return blocked;
85                  }
86  
87                  private boolean isBlocked(final URL requestUrl) {
88                      return true;
89                  }
90              };
91  
92              // use the client as usual
93              final HtmlPage page = webClient.getPage(url);
94          }
95      }
96  
97      /**
98       * @throws Exception if an error occurs
99       */
100     @Test
101     public void contentBlockingResponse() throws Exception {
102         final byte[] content = ArrayUtils.EMPTY_BYTE_ARRAY;
103         final List<NameValuePair> headers = new ArrayList<>();
104         headers.add(new NameValuePair(HttpHeader.CONTENT_LENGTH, String.valueOf(content.length)));
105 
106         final MockWebConnection conn = getMockWebConnection();
107         conn.setResponse(URL_FIRST, content, 200, "OK", MimeType.TEXT_HTML, headers);
108 
109         startWebServer(conn);
110         final URL url = URL_FIRST;
111 
112         try (WebClient webClient = new WebClient()) {
113             webClient.getOptions().setThrowExceptionOnScriptError(false);
114             // set more options
115 
116             // use our own sublcass of HttpWebConnection
117             webClient.setWebConnection(new HttpWebConnection(webClient) {
118                 @Override
119                 protected WebResponse downloadResponse(final HttpUriRequest httpMethod,
120                         final WebRequest webRequest, final HttpResponse httpResponse,
121                         final long startTime) throws IOException {
122 
123                     // check content length header
124                     final int contentLength = Integer.parseInt(
125                             httpResponse.getFirstHeader(HttpHeader.CONTENT_LENGTH).getValue());
126 
127                     // if not too big - done
128                     if (contentLength < 1_000) {
129                         return super.downloadResponse(httpMethod, webRequest, httpResponse, startTime);
130                     }
131 
132                     // abort downloading of the content
133                     httpMethod.abort();
134 
135                     // construct alternative response
136                     final String alternativeContent = "<html><html>";
137                     final WebResponseData data = new WebResponseData(
138                             alternativeContent.getBytes(StandardCharsets.UTF_8),
139                             HttpStatus.OK_200, "blocked", Collections.emptyList());
140                     final WebResponse blocked = new WebResponse(data, webRequest, 0L);
141                     // if you like to check later on for blocked responses
142                     blocked.markAsBlocked("Blocked URL: '" + url.toExternalForm()
143                                 + "' content length: " + contentLength);
144                     return blocked;
145                 }
146             });
147 
148             // use the client as usual
149             final HtmlPage page = webClient.getPage(url);
150         }
151     }
152 
153     /**
154      * @throws Exception if an error occurs
155      */
156     @Test
157     public void contentBlockingFrames() throws Exception {
158         final URL url = new URL("https://www.htmlunit.org/");
159 
160         try (WebClient webClient = new WebClient()) {
161             // use our own FrameContentHandler
162             webClient.setFrameContentHandler(new FrameContentHandler() {
163 
164                 @Override
165                 public boolean loadFrameDocument(final BaseFrameElement baseFrameElement) {
166                     final String src = baseFrameElement.getSrcAttribute();
167                     // don't load the content from google
168                     return !src.contains("google");
169                 }
170 
171             });
172 
173             // use the client as usual
174             final HtmlPage page = webClient.getPage(url);
175         }
176     }
177 
178     /**
179      * @throws Exception if the test fails
180      */
181     @Test
182     public void docuPageDetailsCustomizeHeaders() throws Exception {
183         final BrowserVersion browser =
184                 new BrowserVersion.BrowserVersionBuilder(BrowserVersion.FIREFOX)
185                     .setAcceptLanguageHeader("de-CH")
186                     .build();
187 
188 
189         assertEquals("de-CH", browser.getAcceptLanguageHeader());
190     }
191 }