• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.jsoup;
2 
3 import org.jsoup.helper.RequestAuthenticator;
4 import org.jsoup.nodes.Document;
5 import org.jsoup.parser.Parser;
6 import org.jspecify.annotations.Nullable;
7 
8 import javax.net.ssl.SSLSocketFactory;
9 import java.io.BufferedInputStream;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.UncheckedIOException;
13 import java.net.Authenticator;
14 import java.net.CookieStore;
15 import java.net.Proxy;
16 import java.net.URL;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.Map;
20 
21 /**
22  The Connection interface is a convenient HTTP client and session object to fetch content from the web, and parse them
23  into Documents.
24  <p>To start a new session, use either {@link org.jsoup.Jsoup#newSession()} or {@link org.jsoup.Jsoup#connect(String)}.
25  Connections contain {@link Connection.Request} and {@link Connection.Response} objects (once executed). Configuration
26  settings (URL, timeout, useragent, etc) set on a session will be applied by default to each subsequent request.</p>
27  <p>To start a new request from the session, use {@link #newRequest()}.</p>
28  <p>Cookies are stored in memory for the duration of the session. For that reason, do not use one single session for all
29  requests in a long-lived application, or you are likely to run out of memory, unless care is taken to clean up the
30  cookie store. The cookie store for the session is available via {@link #cookieStore()}. You may provide your own
31  implementation via {@link #cookieStore(java.net.CookieStore)} before making requests.</p>
32  <p>Request configuration can be made using either the shortcut methods in Connection (e.g. {@link #userAgent(String)}),
33  or by methods in the {@link Connection.Request} object directly. All request configuration must be made before the request is
34  executed. When used as an ongoing session, initialize all defaults prior to making multi-threaded {@link
35 #newRequest()}s.</p>
36  <p>Note that the term "Connection" used here does not mean that a long-lived connection is held against a server for
37  the lifetime of the Connection object. A socket connection is only made at the point of request execution ({@link
38 #execute()}, {@link #get()}, or {@link #post()}), and the server's response consumed.</p>
39  <p>For multi-threaded implementations, it is important to use a {@link #newRequest()} for each request. The session may
40  be shared across concurrent threads, but a not a specific request.</p>
41  */
42 @SuppressWarnings("unused")
43 public interface Connection {
44 
45     /**
46      * GET and POST http methods.
47      */
48     enum Method {
49         GET(false), POST(true), PUT(true), DELETE(true), PATCH(true), HEAD(false), OPTIONS(false), TRACE(false);
50 
51         private final boolean hasBody;
52 
Method(boolean hasBody)53         Method(boolean hasBody) {
54             this.hasBody = hasBody;
55         }
56 
57         /**
58          * Check if this HTTP method has/needs a request body
59          * @return if body needed
60          */
hasBody()61         public final boolean hasBody() {
62             return hasBody;
63         }
64     }
65 
66     /**
67      Creates a new request, using this Connection as the session-state and to initialize the connection settings (which
68      may then be independently changed on the returned {@link Connection.Request} object).
69      @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request
70      @since 1.14.1
71      */
newRequest()72     Connection newRequest();
73 
74     /**
75      Creates a new request, using this Connection as the session-state and to initialize the connection settings (which
76      may then be independently changed on the returned {@link Connection.Request} object).
77      @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request
78      @param url URL for the new request
79      @since 1.17.1
80      */
newRequest(String url)81     default Connection newRequest(String url) {
82         return newRequest().url(url);
83     }
84 
85     /**
86      Creates a new request, using this Connection as the session-state and to initialize the connection settings (which
87      may then be independently changed on the returned {@link Connection.Request} object).
88      @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request
89      @param url URL for the new request
90      @since 1.17.1
91      */
newRequest(URL url)92     default Connection newRequest(URL url) {
93         return newRequest().url(url);
94     }
95 
96     /**
97      * Set the request URL to fetch. The protocol must be HTTP or HTTPS.
98      * @param url URL to connect to
99      * @return this Connection, for chaining
100      */
url(URL url)101     Connection url(URL url);
102 
103     /**
104      * Set the request URL to fetch. The protocol must be HTTP or HTTPS.
105      * @param url URL to connect to
106      * @return this Connection, for chaining
107      */
url(String url)108     Connection url(String url);
109 
110     /**
111      * Set the proxy to use for this request. Set to <code>null</code> to disable a previously set proxy.
112      * @param proxy proxy to use
113      * @return this Connection, for chaining
114      */
proxy(@ullable Proxy proxy)115     Connection proxy(@Nullable Proxy proxy);
116 
117     /**
118      * Set the HTTP proxy to use for this request.
119      * @param host the proxy hostname
120      * @param port the proxy port
121      * @return this Connection, for chaining
122      */
proxy(String host, int port)123     Connection proxy(String host, int port);
124 
125     /**
126      * Set the request user-agent header.
127      * @param userAgent user-agent to use
128      * @return this Connection, for chaining
129      * @see org.jsoup.helper.HttpConnection#DEFAULT_UA
130      */
userAgent(String userAgent)131     Connection userAgent(String userAgent);
132 
133     /**
134      * Set the total request timeout duration. If a timeout occurs, an {@link java.net.SocketTimeoutException} will be thrown.
135      * <p>The default timeout is <b>30 seconds</b> (30,000 millis). A timeout of zero is treated as an infinite timeout.
136      * <p>Note that this timeout specifies the combined maximum duration of the connection time and the time to read
137      * the full response.
138      * @param millis number of milliseconds (thousandths of a second) before timing out connects or reads.
139      * @return this Connection, for chaining
140      * @see #maxBodySize(int)
141      */
timeout(int millis)142     Connection timeout(int millis);
143 
144     /**
145      * Set the maximum bytes to read from the (uncompressed) connection into the body, before the connection is closed,
146      * and the input truncated (i.e. the body content will be trimmed). <b>The default maximum is 2MB</b>. A max size of
147      * <code>0</code> is treated as an infinite amount (bounded only by your patience and the memory available on your
148      * machine).
149      *
150      * @param bytes number of bytes to read from the input before truncating
151      * @return this Connection, for chaining
152      */
maxBodySize(int bytes)153     Connection maxBodySize(int bytes);
154 
155     /**
156      * Set the request referrer (aka "referer") header.
157      * @param referrer referrer to use
158      * @return this Connection, for chaining
159      */
referrer(String referrer)160     Connection referrer(String referrer);
161 
162     /**
163      * Configures the connection to (not) follow server redirects. By default, this is <b>true</b>.
164      * @param followRedirects true if server redirects should be followed.
165      * @return this Connection, for chaining
166      */
followRedirects(boolean followRedirects)167     Connection followRedirects(boolean followRedirects);
168 
169     /**
170      * Set the request method to use, GET or POST. Default is GET.
171      * @param method HTTP request method
172      * @return this Connection, for chaining
173      */
method(Method method)174     Connection method(Method method);
175 
176     /**
177      * Configures the connection to not throw exceptions when an HTTP error occurs. (4xx - 5xx, e.g. 404 or 500). By
178      * default, this is <b>false</b>; an IOException is thrown if an error is encountered. If set to <b>true</b>, the
179      * response is populated with the error body, and the status message will reflect the error.
180      * @param ignoreHttpErrors - false (default) if HTTP errors should be ignored.
181      * @return this Connection, for chaining
182      */
ignoreHttpErrors(boolean ignoreHttpErrors)183     Connection ignoreHttpErrors(boolean ignoreHttpErrors);
184 
185     /**
186      * Ignore the document's Content-Type when parsing the response. By default, this is <b>false</b>, an unrecognised
187      * content-type will cause an IOException to be thrown. (This is to prevent producing garbage by attempting to parse
188      * a JPEG binary image, for example.) Set to true to force a parse attempt regardless of content type.
189      * @param ignoreContentType set to true if you would like the content type ignored on parsing the response into a
190      * Document.
191      * @return this Connection, for chaining
192      */
ignoreContentType(boolean ignoreContentType)193     Connection ignoreContentType(boolean ignoreContentType);
194 
195     /**
196      * Set custom SSL socket factory
197      * @param sslSocketFactory custom SSL socket factory
198      * @return this Connection, for chaining
199      */
sslSocketFactory(SSLSocketFactory sslSocketFactory)200     Connection sslSocketFactory(SSLSocketFactory sslSocketFactory);
201 
202     /**
203      * Add a request data parameter. Request parameters are sent in the request query string for GETs, and in the
204      * request body for POSTs. A request may have multiple values of the same name.
205      * @param key data key
206      * @param value data value
207      * @return this Connection, for chaining
208      */
data(String key, String value)209     Connection data(String key, String value);
210 
211     /**
212      * Add an input stream as a request data parameter. For GETs, has no effect, but for POSTS this will upload the
213      * input stream.
214      * <p>Use the {@link #data(String, String, InputStream, String)} method to set the uploaded file's mimetype.</p>
215      * @param key data key (form item name)
216      * @param filename the name of the file to present to the remove server. Typically just the name, not path,
217      * component.
218      * @param inputStream the input stream to upload, that you probably obtained from a {@link java.io.FileInputStream}.
219      * You must close the InputStream in a {@code finally} block.
220      * @return this Connection, for chaining
221      * @see #data(String, String, InputStream, String)
222      */
data(String key, String filename, InputStream inputStream)223     Connection data(String key, String filename, InputStream inputStream);
224 
225     /**
226      * Add an input stream as a request data parameter. For GETs, has no effect, but for POSTS this will upload the
227      * input stream.
228      * @param key data key (form item name)
229      * @param filename the name of the file to present to the remove server. Typically just the name, not path,
230      * component.
231      * @param inputStream the input stream to upload, that you probably obtained from a {@link java.io.FileInputStream}.
232      * @param contentType the Content Type (aka mimetype) to specify for this file.
233      * You must close the InputStream in a {@code finally} block.
234      * @return this Connection, for chaining
235      */
data(String key, String filename, InputStream inputStream, String contentType)236     Connection data(String key, String filename, InputStream inputStream, String contentType);
237 
238     /**
239      * Adds all of the supplied data to the request data parameters
240      * @param data collection of data parameters
241      * @return this Connection, for chaining
242      */
data(Collection<KeyVal> data)243     Connection data(Collection<KeyVal> data);
244 
245     /**
246      * Adds all of the supplied data to the request data parameters
247      * @param data map of data parameters
248      * @return this Connection, for chaining
249      */
data(Map<String, String> data)250     Connection data(Map<String, String> data);
251 
252     /**
253      Add one or more request {@code key, val} data parameter pairs.
254      <p>Multiple parameters may be set at once, e.g.:
255      <code>.data("name", "jsoup", "language", "Java", "language", "English");</code> creates a query string like:
256      <code>{@literal ?name=jsoup&language=Java&language=English}</code></p>
257      <p>For GET requests, data parameters will be sent on the request query string. For POST (and other methods that
258      contain a body), they will be sent as body form parameters, unless the body is explicitly set by
259      {@link #requestBody(String)}, in which case they will be query string parameters.</p>
260 
261      @param keyvals a set of key value pairs.
262      @return this Connection, for chaining
263      */
data(String... keyvals)264     Connection data(String... keyvals);
265 
266     /**
267      * Get the data KeyVal for this key, if any
268      * @param key the data key
269      * @return null if not set
270      */
data(String key)271     @Nullable KeyVal data(String key);
272 
273     /**
274      * Set a POST (or PUT) request body. Useful when a server expects a plain request body (such as JSON), and not a set
275      * of URL encoded form key/value pairs. E.g.:
276      * <code><pre>Jsoup.connect(url)
277      * .requestBody(json)
278      * .header("Content-Type", "application/json")
279      * .post();</pre></code>
280      * If any data key/vals are supplied, they will be sent as URL query params.
281      * @return this Request, for chaining
282      */
requestBody(String body)283     Connection requestBody(String body);
284 
285     /**
286      * Set a request header. Replaces any existing header with the same case-insensitive name.
287      * @param name header name
288      * @param value header value
289      * @return this Connection, for chaining
290      * @see org.jsoup.Connection.Request#header(String, String)
291      * @see org.jsoup.Connection.Request#headers()
292      */
header(String name, String value)293     Connection header(String name, String value);
294 
295     /**
296      * Sets each of the supplied headers on the request. Existing headers with the same case-insensitive name will be
297      * replaced with the new value.
298      * @param headers map of headers name {@literal ->} value pairs
299      * @return this Connection, for chaining
300      * @see org.jsoup.Connection.Request#headers()
301      */
headers(Map<String,String> headers)302     Connection headers(Map<String,String> headers);
303 
304     /**
305      * Set a cookie to be sent in the request.
306      * @param name name of cookie
307      * @param value value of cookie
308      * @return this Connection, for chaining
309      */
cookie(String name, String value)310     Connection cookie(String name, String value);
311 
312     /**
313      * Adds each of the supplied cookies to the request.
314      * @param cookies map of cookie name {@literal ->} value pairs
315      * @return this Connection, for chaining
316      */
cookies(Map<String, String> cookies)317     Connection cookies(Map<String, String> cookies);
318 
319     /**
320      Provide a custom or pre-filled CookieStore to be used on requests made by this Connection.
321      @param cookieStore a cookie store to use for subsequent requests
322      @return this Connection, for chaining
323      @since 1.14.1
324      */
cookieStore(CookieStore cookieStore)325     Connection cookieStore(CookieStore cookieStore);
326 
327     /**
328      Get the cookie store used by this Connection.
329      @return the cookie store
330      @since 1.14.1
331      */
cookieStore()332     CookieStore cookieStore();
333 
334     /**
335      * Provide a specific parser to use when parsing the response to a Document. If not set, jsoup defaults to the
336      * {@link Parser#htmlParser() HTML parser}, unless the response content-type is XML, in which case the
337      * {@link Parser#xmlParser() XML parser} is used.
338      * @param parser alternate parser
339      * @return this Connection, for chaining
340      */
parser(Parser parser)341     Connection parser(Parser parser);
342 
343     /**
344      * Set the character-set used to encode for x-www-form-urlencoded post data. Defaults to {@code UTF-8}.
345      * @param charset character set to encode post data
346      * @return this Connection, for chaining
347      */
postDataCharset(String charset)348     Connection postDataCharset(String charset);
349 
350     /**
351      Set the authenticator to use for this connection, enabling requests to URLs, and via proxies, that require
352      authentication credentials.
353      <p>The authentication scheme used is automatically detected during the request execution.
354      Supported schemes (subject to the platform) are {@code basic}, {@code digest}, {@code NTLM},
355      and {@code Kerberos}.</p>
356 
357      <p>To use, supply a {@link RequestAuthenticator} function that:
358      <ol>
359      <li>validates the URL that is requesting authentication, and</li>
360      <li>returns the appropriate credentials (username and password)</li>
361      </ol>
362      </p>
363 
364      <p>For example, to authenticate both to a proxy and a downstream web server:
365      <code><pre>
366      Connection session = Jsoup.newSession()
367          .proxy("proxy.example.com", 8080)
368          .auth(auth -> {
369              if (auth.isServer()) { // provide credentials for the request url
370                  Validate.isTrue(auth.url().getHost().equals("example.com"));
371                  // check that we're sending credentials were we expect, and not redirected out
372                  return auth.credentials("username", "password");
373              } else { // auth.isProxy()
374                  return auth.credentials("proxy-user", "proxy-password");
375              }
376          });
377 
378      Connection.Response response = session.newRequest("https://example.com/adminzone/").execute();
379      </pre></code>
380      </p>
381 
382      <p>The system may cache the authentication and use it for subsequent requests to the same resource.</p>
383 
384      <p><b>Implementation notes</b></p>
385      <p>For compatibility, on a Java 8 platform, authentication is set up via the system-wide default
386      {@link java.net.Authenticator#setDefault(Authenticator)} method via a ThreadLocal delegator. Whilst the
387      authenticator used is request specific and thread-safe, if you have other calls to {@code setDefault}, they will be
388      incompatible with this implementation.</p>
389      <p>On Java 9 and above, the preceding note does not apply; authenticators are directly set on the request. </p>
390      <p>If you are attempting to authenticate to a proxy that uses the {@code basic} scheme and will be fetching HTTPS
391      URLs, you need to configure your Java platform to enable that, by setting the
392      {@code jdk.http.auth.tunneling.disabledSchemes} system property to {@code ""}.
393      This must be executed prior to any authorization attempts. E.g.:
394      <code><pre>
395      static {
396         System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
397         // removes Basic, which is otherwise excluded from auth for CONNECT tunnels
398      }</pre></code>
399      </p>
400      * @param authenticator the authenticator to use in this connection
401      * @return this Connection, for chaining
402      * @since 1.17.1
403      */
auth(@ullable RequestAuthenticator authenticator)404     default Connection auth(@Nullable RequestAuthenticator authenticator) {
405         throw new UnsupportedOperationException();
406     }
407 
408     /**
409      * Execute the request as a GET, and parse the result.
410      * @return parsed Document
411      * @throws java.net.MalformedURLException if the request URL is not an HTTP or HTTPS URL, or is otherwise malformed
412      * @throws HttpStatusException if the response is not OK and HTTP response errors are not ignored
413      * @throws UnsupportedMimeTypeException if the response mime type is not supported and those errors are not ignored
414      * @throws java.net.SocketTimeoutException if the connection times out
415      * @throws IOException on error
416      */
get()417     Document get() throws IOException;
418 
419     /**
420      * Execute the request as a POST, and parse the result.
421      * @return parsed Document
422      * @throws java.net.MalformedURLException if the request URL is not a HTTP or HTTPS URL, or is otherwise malformed
423      * @throws HttpStatusException if the response is not OK and HTTP response errors are not ignored
424      * @throws UnsupportedMimeTypeException if the response mime type is not supported and those errors are not ignored
425      * @throws java.net.SocketTimeoutException if the connection times out
426      * @throws IOException on error
427      */
post()428     Document post() throws IOException;
429 
430     /**
431      * Execute the request.
432      * @return the executed {@link Response}
433      * @throws java.net.MalformedURLException if the request URL is not a HTTP or HTTPS URL, or is otherwise malformed
434      * @throws HttpStatusException if the response is not OK and HTTP response errors are not ignored
435      * @throws UnsupportedMimeTypeException if the response mime type is not supported and those errors are not ignored
436      * @throws java.net.SocketTimeoutException if the connection times out
437      * @throws IOException on error
438      */
execute()439     Response execute() throws IOException;
440 
441     /**
442      * Get the request object associated with this connection
443      * @return request
444      */
request()445     Request request();
446 
447     /**
448      * Set the connection's request
449      * @param request new request object
450      * @return this Connection, for chaining
451      */
request(Request request)452     Connection request(Request request);
453 
454     /**
455      * Get the response, once the request has been executed.
456      * @return response
457      * @throws IllegalArgumentException if called before the response has been executed.
458      */
response()459     Response response();
460 
461     /**
462      * Set the connection's response
463      * @param response new response
464      * @return this Connection, for chaining
465      */
response(Response response)466     Connection response(Response response);
467 
468     /**
469      * Common methods for Requests and Responses
470      * @param <T> Type of Base, either Request or Response
471      */
472     @SuppressWarnings("UnusedReturnValue")
473     interface Base<T extends Base<T>> {
474         /**
475          * Get the URL of this Request or Response. For redirected responses, this will be the final destination URL.
476          * @return URL
477          * @throws IllegalArgumentException if called on a Request that was created without a URL.
478          */
url()479         URL url();
480 
481         /**
482          * Set the URL
483          * @param url new URL
484          * @return this, for chaining
485          */
url(URL url)486         T url(URL url);
487 
488         /**
489          * Get the request method, which defaults to <code>GET</code>
490          * @return method
491          */
method()492         Method method();
493 
494         /**
495          * Set the request method
496          * @param method new method
497          * @return this, for chaining
498          */
method(Method method)499         T method(Method method);
500 
501         /**
502          * Get the value of a header. If there is more than one header value with the same name, the headers are returned
503          * comma separated, per <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">rfc2616-sec4</a>.
504          * <p>
505          * Header names are case-insensitive.
506          * </p>
507          * @param name name of header (case-insensitive)
508          * @return value of header, or null if not set.
509          * @see #hasHeader(String)
510          * @see #cookie(String)
511          */
header(String name)512         @Nullable String header(String name);
513 
514         /**
515          * Get the values of a header.
516          * @param name header name, case-insensitive.
517          * @return a list of values for this header, or an empty list if not set.
518          */
headers(String name)519         List<String> headers(String name);
520 
521         /**
522          * Set a header. This method will overwrite any existing header with the same case-insensitive name. If there
523          * is more than one value for this header, this method will update the first matching header.
524          * <p>For compatibility, if the content of the header includes text that cannot be represented by ISO-8859-1,
525          * then it should be encoded first per <a href="https://www.ietf.org/rfc/rfc2047.txt">RFC 2047</a>.</p>
526          * @param name Name of header
527          * @param value Value of header
528          * @return this, for chaining
529          * @see #addHeader(String, String)
530          */
header(String name, String value)531         T header(String name, String value);
532 
533         /**
534          * Add a header. The header will be added regardless of whether a header with the same name already exists.
535          * <p>For compatibility, if the content of the header includes text that cannot be represented by ISO-8859-1,
536          * then it should be encoded first per <a href="https://www.ietf.org/rfc/rfc2047.txt">RFC 2047</a>.</p>
537          * @param name Name of new header
538          * @param value Value of new header
539          * @return this, for chaining
540          */
addHeader(String name, String value)541         T addHeader(String name, String value);
542 
543         /**
544          * Check if a header is present
545          * @param name name of header (case-insensitive)
546          * @return if the header is present in this request/response
547          */
hasHeader(String name)548         boolean hasHeader(String name);
549 
550         /**
551          * Check if a header is present, with the given value
552          * @param name header name (case-insensitive)
553          * @param value value (case-insensitive)
554          * @return if the header and value pair are set in this req/res
555          */
hasHeaderWithValue(String name, String value)556         boolean hasHeaderWithValue(String name, String value);
557 
558         /**
559          * Remove headers by name. If there is more than one header with this name, they will all be removed.
560          * @param name name of header to remove (case-insensitive)
561          * @return this, for chaining
562          */
removeHeader(String name)563         T removeHeader(String name);
564 
565         /**
566          * Retrieve all of the request/response header names and corresponding values as a map. For headers with multiple
567          * values, only the first header is returned.
568          * <p>Note that this is a view of the headers only, and changes made to this map will not be reflected in the
569          * request/response object.</p>
570          * @return headers
571          * @see #multiHeaders()
572 
573          */
headers()574         Map<String, String> headers();
575 
576         /**
577          * Retreive all of the headers, keyed by the header name, and with a list of values per header.
578          * @return a list of multiple values per header.
579          */
multiHeaders()580         Map<String, List<String>> multiHeaders();
581 
582         /**
583          * Get a cookie value by name from this request/response.
584          * <p>
585          * Response objects have a simplified cookie model. Each cookie set in the response is added to the response
586          * object's cookie key=value map. The cookie's path, domain, and expiry date are ignored.
587          * </p>
588          * @param name name of cookie to retrieve.
589          * @return value of cookie, or null if not set
590          */
cookie(String name)591         @Nullable String cookie(String name);
592 
593         /**
594          * Set a cookie in this request/response.
595          * @param name name of cookie
596          * @param value value of cookie
597          * @return this, for chaining
598          */
cookie(String name, String value)599         T cookie(String name, String value);
600 
601         /**
602          * Check if a cookie is present
603          * @param name name of cookie
604          * @return if the cookie is present in this request/response
605          */
hasCookie(String name)606         boolean hasCookie(String name);
607 
608         /**
609          * Remove a cookie by name
610          * @param name name of cookie to remove
611          * @return this, for chaining
612          */
removeCookie(String name)613         T removeCookie(String name);
614 
615         /**
616          * Retrieve all of the request/response cookies as a map
617          * @return cookies
618          */
cookies()619         Map<String, String> cookies();
620     }
621 
622     /**
623      * Represents a HTTP request.
624      */
625     @SuppressWarnings("UnusedReturnValue")
626     interface Request extends Base<Request> {
627         /**
628          * Get the proxy used for this request.
629          * @return the proxy; <code>null</code> if not enabled.
630          */
proxy()631         @Nullable Proxy proxy();
632 
633         /**
634          * Update the proxy for this request.
635          * @param proxy the proxy ot use; <code>null</code> to disable.
636          * @return this Request, for chaining
637          */
proxy(@ullable Proxy proxy)638         Request proxy(@Nullable Proxy proxy);
639 
640         /**
641          * Set the HTTP proxy to use for this request.
642          * @param host the proxy hostname
643          * @param port the proxy port
644          * @return this Connection, for chaining
645          */
proxy(String host, int port)646         Request proxy(String host, int port);
647 
648         /**
649          * Get the request timeout, in milliseconds.
650          * @return the timeout in milliseconds.
651          */
timeout()652         int timeout();
653 
654         /**
655          * Update the request timeout.
656          * @param millis timeout, in milliseconds
657          * @return this Request, for chaining
658          */
timeout(int millis)659         Request timeout(int millis);
660 
661         /**
662          * Get the maximum body size, in bytes.
663          * @return the maximum body size, in bytes.
664          */
maxBodySize()665         int maxBodySize();
666 
667         /**
668          * Update the maximum body size, in bytes.
669          * @param bytes maximum body size, in bytes.
670          * @return this Request, for chaining
671          */
maxBodySize(int bytes)672         Request maxBodySize(int bytes);
673 
674         /**
675          * Get the current followRedirects configuration.
676          * @return true if followRedirects is enabled.
677          */
followRedirects()678         boolean followRedirects();
679 
680         /**
681          * Configures the request to (not) follow server redirects. By default this is <b>true</b>.
682          * @param followRedirects true if server redirects should be followed.
683          * @return this Request, for chaining
684          */
followRedirects(boolean followRedirects)685         Request followRedirects(boolean followRedirects);
686 
687         /**
688          * Get the current ignoreHttpErrors configuration.
689          * @return true if errors will be ignored; false (default) if HTTP errors will cause an IOException to be
690          * thrown.
691          */
ignoreHttpErrors()692         boolean ignoreHttpErrors();
693 
694         /**
695          * Configures the request to ignore HTTP errors in the response.
696          * @param ignoreHttpErrors set to true to ignore HTTP errors.
697          * @return this Request, for chaining
698          */
ignoreHttpErrors(boolean ignoreHttpErrors)699         Request ignoreHttpErrors(boolean ignoreHttpErrors);
700 
701         /**
702          * Get the current ignoreContentType configuration.
703          * @return true if invalid content-types will be ignored; false (default) if they will cause an IOException to
704          * be thrown.
705          */
ignoreContentType()706         boolean ignoreContentType();
707 
708         /**
709          * Configures the request to ignore the Content-Type of the response.
710          * @param ignoreContentType set to true to ignore the content type.
711          * @return this Request, for chaining
712          */
ignoreContentType(boolean ignoreContentType)713         Request ignoreContentType(boolean ignoreContentType);
714 
715         /**
716          * Get the current custom SSL socket factory, if any.
717          * @return custom SSL socket factory if set, null otherwise
718          */
sslSocketFactory()719         @Nullable SSLSocketFactory sslSocketFactory();
720 
721         /**
722          * Set a custom SSL socket factory.
723          * @param sslSocketFactory SSL socket factory
724          */
sslSocketFactory(SSLSocketFactory sslSocketFactory)725         void sslSocketFactory(SSLSocketFactory sslSocketFactory);
726 
727         /**
728          * Add a data parameter to the request
729          * @param keyval data to add.
730          * @return this Request, for chaining
731          */
data(KeyVal keyval)732         Request data(KeyVal keyval);
733 
734         /**
735          * Get all of the request's data parameters
736          * @return collection of keyvals
737          */
data()738         Collection<KeyVal> data();
739 
740         /**
741          * Set a POST (or PUT) request body. Useful when a server expects a plain request body, not a set of URL
742          * encoded form key/value pairs. E.g.:
743          * <code><pre>Jsoup.connect(url)
744          * .requestBody(json)
745          * .header("Content-Type", "application/json")
746          * .post();</pre></code>
747          * If any data key/vals are supplied, they will be sent as URL query params.
748          * @param body to use as the request body. Set to null to clear a previously set body.
749          * @return this Request, for chaining
750          */
requestBody(@ullable String body)751         Request requestBody(@Nullable String body);
752 
753         /**
754          * Get the current request body.
755          * @return null if not set.
756          */
requestBody()757         @Nullable String requestBody();
758 
759         /**
760          * Specify the parser to use when parsing the document.
761          * @param parser parser to use.
762          * @return this Request, for chaining
763          */
parser(Parser parser)764         Request parser(Parser parser);
765 
766         /**
767          * Get the current parser to use when parsing the document.
768          * @return current Parser
769          */
parser()770         Parser parser();
771 
772         /**
773          * Sets the post data character set for x-www-form-urlencoded post data
774          * @param charset character set to encode post data
775          * @return this Request, for chaining
776          */
postDataCharset(String charset)777         Request postDataCharset(String charset);
778 
779         /**
780          * Gets the post data character set for x-www-form-urlencoded post data
781          * @return character set to encode post data
782          */
postDataCharset()783         String postDataCharset();
784 
785         /**
786          Set the authenticator to use for this request.
787          See {@link Connection#auth(RequestAuthenticator) Connection.auth(authenticator)} for examples and
788          implementation notes.
789          * @param authenticator the authenticator
790          * @return this Request, for chaining.
791          * @since 1.17.1
792          */
auth(@ullable RequestAuthenticator authenticator)793         default Request auth(@Nullable RequestAuthenticator authenticator)  {
794             throw new UnsupportedOperationException();
795         }
796 
797         /**
798          Get the RequestAuthenticator, if any, that will be used on this request.
799          * @return the RequestAuthenticator, or {@code null} if not set
800          * @since 1.17.1
801          */
802         @Nullable
auth()803         default RequestAuthenticator auth() {
804             throw new UnsupportedOperationException();
805         }
806     }
807 
808     /**
809      * Represents a HTTP response.
810      */
811     interface Response extends Base<Response> {
812 
813         /**
814          * Get the status code of the response.
815          * @return status code
816          */
statusCode()817         int statusCode();
818 
819         /**
820          * Get the status message of the response.
821          * @return status message
822          */
statusMessage()823         String statusMessage();
824 
825         /**
826          * Get the character set name of the response, derived from the content-type header.
827          * @return character set name if set, <b>null</b> if not
828          */
charset()829         @Nullable String charset();
830 
831         /**
832          * Set / override the response character set. When the document body is parsed it will be with this charset.
833          * @param charset to decode body as
834          * @return this Response, for chaining
835          */
charset(String charset)836         Response charset(String charset);
837 
838         /**
839          * Get the response content type (e.g. "text/html");
840          * @return the response content type, or <b>null</b> if one was not set
841          */
contentType()842         @Nullable String contentType();
843 
844         /**
845          * Read and parse the body of the response as a Document. If you intend to parse the same response multiple
846          * times, you should {@link #bufferUp()} first.
847          * @return a parsed Document
848          * @throws IOException on error
849          */
parse()850         Document parse() throws IOException;
851 
852         /**
853          * Get the body of the response as a plain string.
854          * @return body
855          */
body()856         String body();
857 
858         /**
859          * Get the body of the response as an array of bytes.
860          * @return body bytes
861          */
bodyAsBytes()862         byte[] bodyAsBytes();
863 
864         /**
865          * Read the body of the response into a local buffer, so that {@link #parse()} may be called repeatedly on the
866          * same connection response. Otherwise, once the response is read, its InputStream will have been drained and
867          * may not be re-read.
868          * <p>Calling {@link #body() } or {@link #bodyAsBytes()} has the same effect.</p>
869          * @return this response, for chaining
870          * @throws UncheckedIOException if an IO exception occurs during buffering.
871          */
bufferUp()872         Response bufferUp();
873 
874         /**
875          Get the body of the response as a (buffered) InputStream. You should close the input stream when you're done
876          with it.
877          <p>Other body methods (like bufferUp, body, parse, etc) will generally not work in conjunction with this method,
878          as it consumes the InputStream.</p>
879          <p>Any configured max size or maximum read timeout applied to the connection will not be applied to this stream,
880          unless {@link #bufferUp()} is called prior.</p>
881          <p>This method is useful for writing large responses to disk, without buffering them completely into memory
882          first.</p>
883          @return the response body input stream
884          */
bodyStream()885         BufferedInputStream bodyStream();
886     }
887 
888     /**
889      * A Key:Value tuple(+), used for form data.
890      */
891     interface KeyVal {
892 
893         /**
894          * Update the key of a keyval
895          * @param key new key
896          * @return this KeyVal, for chaining
897          */
key(String key)898         KeyVal key(String key);
899 
900         /**
901          * Get the key of a keyval
902          * @return the key
903          */
key()904         String key();
905 
906         /**
907          * Update the value of a keyval
908          * @param value the new value
909          * @return this KeyVal, for chaining
910          */
value(String value)911         KeyVal value(String value);
912 
913         /**
914          * Get the value of a keyval
915          * @return the value
916          */
value()917         String value();
918 
919         /**
920          * Add or update an input stream to this keyVal
921          * @param inputStream new input stream
922          * @return this KeyVal, for chaining
923          */
inputStream(InputStream inputStream)924         KeyVal inputStream(InputStream inputStream);
925 
926         /**
927          * Get the input stream associated with this keyval, if any
928          * @return input stream if set, or null
929          */
inputStream()930         @Nullable InputStream inputStream();
931 
932         /**
933          * Does this keyval have an input stream?
934          * @return true if this keyval does indeed have an input stream
935          */
hasInputStream()936         boolean hasInputStream();
937 
938         /**
939          * Set the Content Type header used in the MIME body (aka mimetype) when uploading files.
940          * Only useful if {@link #inputStream(InputStream)} is set.
941          * <p>Will default to {@code application/octet-stream}.</p>
942          * @param contentType the new content type
943          * @return this KeyVal
944          */
contentType(String contentType)945         KeyVal contentType(String contentType);
946 
947         /**
948          * Get the current Content Type, or {@code null} if not set.
949          * @return the current Content Type.
950          */
contentType()951         @Nullable String contentType();
952     }
953 }
954