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.attachment;
16  
17  import org.htmlunit.HttpHeader;
18  import org.htmlunit.Page;
19  import org.htmlunit.WebResponse;
20  
21  /**
22   * An attachment represents a page received from the server which contains a
23   * {@code Content-Disposition=attachment} header.
24   *
25   * @author Bruce Chapman
26   * @author Sudhan Moghe
27   * @author Daniel Gredler
28   * @author Ronald Brill
29   * @author Lai Quang Duong
30   */
31  public class Attachment {
32  
33      /** The attached page. */
34      private final Page page_;
35  
36      /** The file name of this attachment. */
37      private final String attachmentFilename_;
38  
39      /**
40       * Creates a new attachment for the specified page.
41       * @param page the attached page
42       */
43      public Attachment(final Page page) {
44          this(page, null);
45      }
46  
47      /**
48       * Creates a new attachment for the specified page.
49       * @param page the attached page
50       * @param attachmentFilename the file name of this attachment
51       */
52      public Attachment(final Page page, final String attachmentFilename) {
53          page_ = page;
54          attachmentFilename_ = attachmentFilename;
55      }
56  
57      /**
58       * Returns the attached page.
59       * @return the attached page
60       */
61      public Page getPage() {
62          return page_;
63      }
64  
65      /**
66       * Returns the attachment's filename, as suggested by the <code>Content-Disposition</code>
67       * header, or {@code null} if no filename was suggested.
68       * @return the attachment's suggested filename, or {@code null} if none was suggested
69       */
70      public String getSuggestedFilename() {
71          if (attachmentFilename_ != null) {
72              return attachmentFilename_;
73          }
74  
75          final WebResponse response = page_.getWebResponse();
76          final String disp = response.getResponseHeaderValue(HttpHeader.CONTENT_DISPOSITION);
77          return getSuggestedFilename(disp);
78      }
79  
80      /**
81       * Returns the attachment's filename, as suggested by the <code>Content-Disposition</code>
82       * header, or {@code null} if no filename was suggested.
83       * @param contentDispositionHeader the <code>Content-Disposition</code> header
84       *
85       * @return the attachment's suggested filename, or {@code null} if none was suggested
86       */
87      public static String getSuggestedFilename(final String contentDispositionHeader) {
88          if (contentDispositionHeader == null) {
89              return null;
90          }
91  
92          int start = contentDispositionHeader.indexOf("filename=");
93          if (start == -1) {
94              return null;
95          }
96          start += "filename=".length();
97          if (start >= contentDispositionHeader.length()) {
98              return null;
99          }
100 
101         int end = contentDispositionHeader.indexOf(';', start);
102         if (end == -1) {
103             end = contentDispositionHeader.length();
104         }
105         if (contentDispositionHeader.charAt(start) == '"' && contentDispositionHeader.charAt(end - 1) == '"') {
106             start++;
107             end--;
108         }
109         return contentDispositionHeader.substring(start, end);
110     }
111 }