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.MimeType;
40  import org.htmlunit.util.NameValuePair;
41  import org.htmlunit.util.WebConnectionWrapper;
42  import org.junit.Test;
43  
44  /**
45   * Tests for the sample code from the documentation to make sure
46   * we adapt the docu or do not break the samples.
47   *
48   * @author Ronald Brill
49   */
50  public class DetailsTest extends WebServerTestCase {
51  
52      /**
53       * @throws Exception if an error occurs
54       */
55      @Test
56      public void contentBlockingRequest() throws Exception {
57          final URL url = new URL("http://localhost/");
58  
59          try (WebClient webClient = new WebClient()) {
60              webClient.getOptions().setThrowExceptionOnScriptError(false);
61              // set more options
62  
63              // create a WebConnectionWrapper with an (subclassed) getResponse() impl
64              new WebConnectionWrapper(webClient) {
65  
66                  @Override
67                  public WebResponse getResponse(final WebRequest request) throws IOException {
68                      final URL requestUrl = request.getUrl();
69                      // check the request url
70                      // if is allowed simple call super.
71  
72                      if (!isBlocked(requestUrl)) {
73                          return super.getResponse(request);
74                      }
75  
76                      // construct alternative response
77                      final String content = "<html><html>";
78                      final WebResponseData data = new WebResponseData(content.getBytes(StandardCharsets.UTF_8),
79                              HttpStatus.OK_200, "blocked", Collections.emptyList());
80                      final WebResponse blocked = new WebResponse(data, request, 0L);
81                      // if you like to check later on for blocked responses
82                      blocked.markAsBlocked("Blocked URL: '" + requestUrl.toExternalForm() + "'");
83                      return blocked;
84                  }
85  
86                  private boolean isBlocked(final URL requestUrl) {
87                      return true;
88                  }
89              };
90  
91              // use the client as usual
92              final HtmlPage page = webClient.getPage(url);
93          }
94      }
95  
96      /**
97       * @throws Exception if an error occurs
98       */
99      @Test
100     public void contentBlockingResponse() throws Exception {
101         final byte[] content = new byte[] {};
102         final List<NameValuePair> headers = new ArrayList<>();
103         headers.add(new NameValuePair(HttpHeader.CONTENT_LENGTH, String.valueOf(content.length)));
104 
105         final MockWebConnection conn = getMockWebConnection();
106         conn.setResponse(URL_FIRST, content, 200, "OK", MimeType.TEXT_HTML, headers);
107 
108         startWebServer(conn);
109         final URL url = URL_FIRST;
110 
111         try (WebClient webClient = new WebClient()) {
112             webClient.getOptions().setThrowExceptionOnScriptError(false);
113             // set more options
114 
115             // use our own sublcass of HttpWebConnection
116             webClient.setWebConnection(new HttpWebConnection(webClient) {
117                 @Override
118                 protected WebResponse downloadResponse(final HttpUriRequest httpMethod,
119                         final WebRequest webRequest, final HttpResponse httpResponse,
120                         final long startTime) throws IOException {
121 
122                     // check content length header
123                     final int contentLenght = Integer.parseInt(
124                             httpResponse.getFirstHeader(HttpHeader.CONTENT_LENGTH).getValue());
125 
126                     // if not too big - done
127                     if (contentLenght < 1_000) {
128                         return super.downloadResponse(httpMethod, webRequest, httpResponse, startTime);
129                     }
130 
131                     // abort downloading of the content
132                     httpMethod.abort();
133 
134                     // construct alternative response
135                     final String alternativeContent = "<html><html>";
136                     final WebResponseData data = new WebResponseData(
137                             alternativeContent.getBytes(StandardCharsets.UTF_8),
138                             HttpStatus.OK_200, "blocked", Collections.emptyList());
139                     final WebResponse blocked = new WebResponse(data, webRequest, 0L);
140                     // if you like to check later on for blocked responses
141                     blocked.markAsBlocked("Blocked URL: '" + url.toExternalForm()
142                                 + "' content length: " + contentLenght);
143                     return blocked;
144                 }
145             });
146 
147             // use the client as usual
148             final HtmlPage page = webClient.getPage(url);
149         }
150     }
151 
152     /**
153      * @throws Exception if an error occurs
154      */
155     @Test
156     public void contentBlockingFrames() throws Exception {
157         final URL url = new URL("https://www.htmlunit.org/");
158 
159         try (WebClient webClient = new WebClient()) {
160             // use our own FrameContentHandler
161             webClient.setFrameContentHandler(new FrameContentHandler() {
162 
163                 @Override
164                 public boolean loadFrameDocument(final BaseFrameElement baseFrameElement) {
165                     final String src = baseFrameElement.getSrcAttribute();
166                     // don't load the content from google
167                     return !src.contains("google");
168                 }
169 
170             });
171 
172             // use the client as usual
173             final HtmlPage page = webClient.getPage(url);
174         }
175     }
176 
177     /**
178      * @throws Exception if the test fails
179      */
180     @Test
181     public void docuPageDetailsCustomizeHeaders() throws Exception {
182         final BrowserVersion browser =
183                 new BrowserVersion.BrowserVersionBuilder(BrowserVersion.FIREFOX)
184                     .setAcceptLanguageHeader("de-CH")
185                     .build();
186 
187 
188         assertEquals("de-CH", browser.getAcceptLanguageHeader());
189     }
190 }