001package org.jsoup; 002 003import org.jsoup.helper.RequestAuthenticator; 004import org.jsoup.nodes.Document; 005import org.jsoup.parser.Parser; 006import org.jspecify.annotations.Nullable; 007 008import javax.net.ssl.SSLSocketFactory; 009import java.io.BufferedInputStream; 010import java.io.IOException; 011import java.io.InputStream; 012import java.io.UncheckedIOException; 013import java.net.Authenticator; 014import java.net.CookieStore; 015import java.net.Proxy; 016import java.net.URL; 017import java.util.Collection; 018import java.util.List; 019import java.util.Map; 020 021/** 022 The Connection interface is a convenient HTTP client and session object to fetch content from the web, and parse them 023 into Documents. 024 <p>To start a new session, use either {@link org.jsoup.Jsoup#newSession()} or {@link org.jsoup.Jsoup#connect(String)}. 025 Connections contain {@link Connection.Request} and {@link Connection.Response} objects (once executed). Configuration 026 settings (URL, timeout, useragent, etc) set on a session will be applied by default to each subsequent request.</p> 027 <p>To start a new request from the session, use {@link #newRequest()}.</p> 028 <p>Cookies are stored in memory for the duration of the session. For that reason, do not use one single session for all 029 requests in a long-lived application, or you are likely to run out of memory, unless care is taken to clean up the 030 cookie store. The cookie store for the session is available via {@link #cookieStore()}. You may provide your own 031 implementation via {@link #cookieStore(java.net.CookieStore)} before making requests.</p> 032 <p>Request configuration can be made using either the shortcut methods in Connection (e.g. {@link #userAgent(String)}), 033 or by methods in the {@link Connection.Request} object directly. All request configuration must be made before the request is 034 executed. When used as an ongoing session, initialize all defaults prior to making multi-threaded {@link 035#newRequest()}s.</p> 036 <p>Note that the term "Connection" used here does not mean that a long-lived connection is held against a server for 037 the lifetime of the Connection object. A socket connection is only made at the point of request execution ({@link 038#execute()}, {@link #get()}, or {@link #post()}), and the server's response consumed.</p> 039 <p>For multi-threaded implementations, it is important to use a {@link #newRequest()} for each request. The session may 040 be shared across concurrent threads, but a not a specific request.</p> 041 */ 042@SuppressWarnings("unused") 043public interface Connection { 044 045 /** 046 * GET and POST http methods. 047 */ 048 enum Method { 049 GET(false), POST(true), PUT(true), DELETE(true), PATCH(true), HEAD(false), OPTIONS(false), TRACE(false); 050 051 private final boolean hasBody; 052 053 Method(boolean hasBody) { 054 this.hasBody = hasBody; 055 } 056 057 /** 058 * Check if this HTTP method has/needs a request body 059 * @return if body needed 060 */ 061 public final boolean hasBody() { 062 return hasBody; 063 } 064 } 065 066 /** 067 Creates a new request, using this Connection as the session-state and to initialize the connection settings (which 068 may then be independently changed on the returned {@link Connection.Request} object). 069 @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request 070 @since 1.14.1 071 */ 072 Connection newRequest(); 073 074 /** 075 Creates a new request, using this Connection as the session-state and to initialize the connection settings (which 076 may then be independently changed on the returned {@link Connection.Request} object). 077 @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request 078 @param url URL for the new request 079 @since 1.17.1 080 */ 081 default Connection newRequest(String url) { 082 return newRequest().url(url); 083 } 084 085 /** 086 Creates a new request, using this Connection as the session-state and to initialize the connection settings (which 087 may then be independently changed on the returned {@link Connection.Request} object). 088 @return a new Connection object, with a shared Cookie Store and initialized settings from this Connection and Request 089 @param url URL for the new request 090 @since 1.17.1 091 */ 092 default Connection newRequest(URL url) { 093 return newRequest().url(url); 094 } 095 096 /** 097 * Set the request URL to fetch. The protocol must be HTTP or HTTPS. 098 * @param url URL to connect to 099 * @return this Connection, for chaining 100 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 439 Response execute() throws IOException; 440 441 /** 442 * Get the request object associated with this connection 443 * @return request 444 */ 445 Request request(); 446 447 /** 448 * Set the connection's request 449 * @param request new request object 450 * @return this Connection, for chaining 451 */ 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 */ 459 Response response(); 460 461 /** 462 * Set the connection's response 463 * @param response new response 464 * @return this Connection, for chaining 465 */ 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 */ 479 URL url(); 480 481 /** 482 * Set the URL 483 * @param url new URL 484 * @return this, for chaining 485 */ 486 T url(URL url); 487 488 /** 489 * Get the request method, which defaults to <code>GET</code> 490 * @return method 491 */ 492 Method method(); 493 494 /** 495 * Set the request method 496 * @param method new method 497 * @return this, for chaining 498 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 613 T removeCookie(String name); 614 615 /** 616 * Retrieve all of the request/response cookies as a map 617 * @return cookies 618 */ 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 */ 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 */ 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 */ 646 Request proxy(String host, int port); 647 648 /** 649 * Get the request timeout, in milliseconds. 650 * @return the timeout in milliseconds. 651 */ 652 int timeout(); 653 654 /** 655 * Update the request timeout. 656 * @param millis timeout, in milliseconds 657 * @return this Request, for chaining 658 */ 659 Request timeout(int millis); 660 661 /** 662 * Get the maximum body size, in bytes. 663 * @return the maximum body size, in bytes. 664 */ 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 */ 672 Request maxBodySize(int bytes); 673 674 /** 675 * Get the current followRedirects configuration. 676 * @return true if followRedirects is enabled. 677 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 719 @Nullable SSLSocketFactory sslSocketFactory(); 720 721 /** 722 * Set a custom SSL socket factory. 723 * @param sslSocketFactory SSL socket factory 724 */ 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 */ 732 Request data(KeyVal keyval); 733 734 /** 735 * Get all of the request's data parameters 736 * @return collection of keyvals 737 */ 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 */ 751 Request requestBody(@Nullable String body); 752 753 /** 754 * Get the current request body. 755 * @return null if not set. 756 */ 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 */ 764 Request parser(Parser parser); 765 766 /** 767 * Get the current parser to use when parsing the document. 768 * @return current Parser 769 */ 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 */ 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 */ 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 */ 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 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 */ 817 int statusCode(); 818 819 /** 820 * Get the status message of the response. 821 * @return status message 822 */ 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 */ 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 */ 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 */ 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 */ 850 Document parse() throws IOException; 851 852 /** 853 * Get the body of the response as a plain string. 854 * @return body 855 */ 856 String body(); 857 858 /** 859 * Get the body of the response as an array of bytes. 860 * @return body bytes 861 */ 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 */ 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 */ 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 */ 898 KeyVal key(String key); 899 900 /** 901 * Get the key of a keyval 902 * @return the key 903 */ 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 */ 911 KeyVal value(String value); 912 913 /** 914 * Get the value of a keyval 915 * @return the value 916 */ 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 */ 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 */ 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 */ 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 */ 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 */ 951 @Nullable String contentType(); 952 } 953}