1/* 2 * Copyright 2022 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Niels Sascha Reedijk, niels.reedijk@gmail.com 7 * 8 * Corresponds to: 9 * headers/private/netservices2/HttpRequest.h hrev????? 10 * src/kits/network/libnetservices2/HttpRequest.cpp hrev????? 11 */ 12 13 14#if __cplusplus >= 201703L 15 16 17/*! 18 \file HttpRequest.h 19 \ingroup netservices 20 \brief Provides the classes and tools to build HTTP Requests. 21 22 \since Haiku R1 23*/ 24 25 26namespace BPrivate { 27 28namespace Network { 29 30 31/*! 32 \class BHttpMethod 33 \ingroup netservices 34 \brief Represent a HTTP method. 35 36 The <a href="https://datatracker.ietf.org/doc/html/rfc7231#section-4.1">HTTP standard</a> 37 specifies that HTTP requests have a method. Common methods are \c GET and \c HEAD methods. 38 Standardized and common methods are in the form of \em verbs and are in capitalized letters 39 from the ASCII token set, though any valid token can be used. 40 41 It is most likely that you will not use the methods of this class directly, instead you will 42 use the implicit constructors while interacting with the \ref BHttpRequest class. 43 44 \code 45 auto url = BUrl("https://www.haiku-os.org/"); 46 // implicitly construct a standard get request 47 auto standard = BHttpRequest(url, BHttpMethod::Get); 48 // implicitly construct a nonstandard patch request 49 auto custom = BHttpRequest(url, "PATCH"sv); 50 \endcode 51 52 \note When you are using the standard list of verbs, there will never be an exception when 53 creating objects of this type. When you create a custom method, exceptions may be raised 54 when the system runs out of memory, or when your custom method contains invalid characters. 55 In almost all cases, you can probably safely assume you will not run into these exceptions, 56 except for cases where you use user input to create methods or you are very defensive 57 about memory management. 58 59 \since Haiku R1 60*/ 61 62 63/*! 64 \class BHttpMethod::InvalidMethod 65 \ingroup netservices 66 \brief Error that represents when a custom method does not conform to the HTTP standard. 67 68 \since Haiku R1 69*/ 70 71 72/*! 73 \var BString BHttpMethod::InvalidMethod::input 74 \brief The input that contains the invalid contents. 75 76 \since Haiku R1 77*/ 78 79 80/*! 81 \fn BHttpMethod::InvalidMethod::InvalidMethod(const char *origin, BString input) 82 \brief Constructor that sets the \a origin and the invalid \a input. 83 84 \since Haiku R1 85*/ 86 87 88/*! 89 \enum BHttpMethod::Verb 90 \ingroup netservices 91 \brief A list of standard HTTP methods. 92 93 \since Haiku R1 94*/ 95 96 97/*! 98 \var BHttpMethod::Verb BHttpMethod::Get 99 \brief Represents the \c GET method. 100 101 \since Haiku R1 102*/ 103 104 105/*! 106 \var BHttpMethod::Verb BHttpMethod::Head 107 \brief Represents the \c HEAD method. 108 109 \since Haiku R1 110*/ 111 112 113/*! 114 \var BHttpMethod::Verb BHttpMethod::Post 115 \brief Represents the \c POST method. 116 117 \since Haiku R1 118*/ 119 120 121/*! 122 \var BHttpMethod::Verb BHttpMethod::Put 123 \brief Represents the \c PUT method. 124 125 \since Haiku R1 126*/ 127 128 129/*! 130 \var BHttpMethod::Verb BHttpMethod::Delete 131 \brief Represents the \c DELETE method. 132 133 \since Haiku R1 134*/ 135 136 137/*! 138 \var BHttpMethod::Verb BHttpMethod::Connect 139 \brief Represents the \c CONNECT method. 140 141 \since Haiku R1 142*/ 143 144 145/*! 146 \var BHttpMethod::Verb BHttpMethod::Options 147 \brief Represents the \c OPTIONS method. 148 149 \since Haiku R1 150*/ 151 152 153/*! 154 \var BHttpMethod::Verb BHttpMethod::Trace 155 \brief Represents the \c TRACE method. 156 157 \since Haiku R1 158*/ 159 160 161/*! 162 \fn BHttpMethod::BHttpMethod(BHttpMethod &&other) noexcept 163 \brief Move constructor. 164 165 Moves the data from the \a other to this object. The \a other object will be set to 166 \ref BHttpMethod::Get. 167 168 \since Haiku R1 169*/ 170 171 172/*! 173 \fn BHttpMethod::BHttpMethod(const BHttpMethod &other) 174 \brief Copy constructor. 175 176 Copy data from an \a other object. 177 178 \exception std::bad_alloc When the \a other object contains a custom verb, this exception 179 will be raised if it is impossible to allocate memory. 180 181 \since Haiku R1 182*/ 183 184 185/*! 186 \fn BHttpMethod::BHttpMethod(const std::string_view &method) 187 \brief Construct a custom method. 188 189 \param method The verb for the method. 190 191 \exception std::bad_alloc In case it is not possible to allocate memory for the custom string. 192 \exception BHttpMethod::InvalidMethod In case the \a method is empty or contains invalid 193 characters. 194 195 \since Haiku R1 196*/ 197 198 199/*! 200 \fn BHttpMethod::BHttpMethod(Verb verb) noexcept 201 \brief Construct a standard method. 202 203 \param verb The chosen method. 204 205 \since Haiku R1 206*/ 207 208 209/*! 210 \fn BHttpMethod::~BHttpMethod() 211 \brief Destructor. 212 213 \since Haiku R1 214*/ 215 216 217/*! 218 \fn bool BHttpMethod::operator==(const Verb &other) const noexcept 219 \brief Comparison operator. 220 221 \param other The verb to compare to. 222 223 \retval true This method is equal to \a other. 224 \retval false This method is different from \a other. 225 226 \since Haiku R1 227*/ 228 229 230/*! 231 \fn bool BHttpMethod::operator!=(const Verb &other) const noexcept 232 \brief Comparison operator. 233 234 \param other The verb to compare to. 235 236 \retval true This method is different from \a other. 237 \retval false This method is equal to \a other. 238 239 \since Haiku R1 240*/ 241 242 243/*! 244 \fn const std::string_view BHttpMethod::Method() const noexcept 245 \brief Get a string representation of the method. 246 247 \return A \c std::string_view that is a string representation of the standard or custom method 248 in this object. The lifetime of the string view is bound to the lifetime of this method. 249 250 \since Haiku R1 251*/ 252 253 254/*! 255 \fn BHttpMethod& BHttpMethod::operator=(BHttpMethod &&other) noexcept 256 \brief Move assignment. 257 Moves the data from the \a other to this object. The \a other object will be set to 258 \ref BHttpMethod::Get. 259 260 \since Haiku R1 261*/ 262 263 264/*! 265 \fn BHttpMethod& BHttpMethod::operator=(const BHttpMethod &other) 266 \brief Copy assignment. 267 268 Copy data from an \a other object. 269 270 \exception std::bad_alloc When the \a other object contains a custom verb, this exception 271 will be raised if it is impossible to allocate memory. 272 273 \since Haiku R1 274*/ 275 276 277/*! 278 \struct BHttpAuthentication 279 \ingroup netservices 280 \brief Describe username and password for basic authentication for the request. 281 282 \see These options are used by \ref BHttpRequest::Authentication() and 283 \ref BHttpRequest::SetAuthentication() 284 285 \since Haiku R1 286*/ 287 288 289/*! 290 \var BString BHttpAuthentication::username 291 \brief The username for the request. 292 293 \since Haiku R1 294*/ 295 296 297/*! 298 \var BString BHttpAuthentication::password 299 \brief The password for the request. 300 301 \since Haiku R1 302*/ 303 304 305/*! 306 \struct BHttpRequest::Body 307 \ingroup netservices 308 \brief Describe the body for a network request 309 310 \since Haiku R1 311*/ 312 313 314/*! 315 \var std::unique_ptr<BDataIO> BHttpRequest::Body::input 316 \brief The \ref BDataIO object that holds the contents of the body. 317 318 \since Haiku R1 319*/ 320 321 322/*! 323 \var BString BHttpRequest::Body::mimeType 324 \brief The mimetype of the body. 325 326 The \c Content-Type header field of the request is set to this value. 327 328 \since Haiku R1 329*/ 330 331 332/*! 333 \var std::optional<off_t> BHttpRequest::Body::size 334 \brief The size of the content, if known. 335 336 \since Haiku R1 337*/ 338 339 340/*! 341 \var std::optional<off_t> BHttpRequest::Body::startPosition 342 \brief If the input is a \ref BPositionIO, this is the current position when the body was set. 343 344 This value is used to rewind the input when it needs to be resubmitted, for example in the case 345 of a redirection. 346 347 \since Haiku R1 348*/ 349 350 351/*! 352 \class BHttpRequest 353 \ingroup netservices 354 \brief Represent a HTTP request. 355 356 This class can be used to construct HTTP requests that can be executed by the Network Services 357 Kit. A request has two states, either it is is a valid request, or it is an empty request. The 358 criterium is whether or not the request has a URL. 359 This class has all kinds of convenience methods set and retrieve particular options. Most 360 options are wrapped in specialized container classes that do some form of validation. 361 362 The default options are: 363 <table> 364 <tr><th>Getter</th><th>Setter</th><th>Description</th><th>Default</th></tr> 365 <tr> 366 <td> \ref Url() </td> 367 <td> \ref SetUrl() </td> 368 <td> The URL. This must start with http or https. </td> 369 <td> Defaults to an empty \ref BUrl </td> 370 </tr> 371 <tr> 372 <td> \ref Fields() </td> 373 <td> \ref SetFields() </td> 374 <td> Additional fields set in the request header. </td> 375 <td> Defaults with no additional fields </td> 376 </tr> 377 <tr> 378 <td> \ref Method() </td> 379 <td> \ref SetMethod() </td> 380 <td> The HTTP method for the request </td> 381 <td> Defaults to \ref BHttpMethod::Get </td> 382 </tr> 383 <tr> 384 <td> \ref MaxRedirections() </td> 385 <td> \ref SetMaxRedirections() </td> 386 <td> How many redirections should be followed. Set to 0 to disable. </td> 387 <td> Defaults to 8 redirections per request </td> 388 </tr> 389 <tr> 390 <td> \ref RequestBody() </td> 391 <td> \ref SetRequestBody() </td> 392 <td> Body contents that is sent with the request. </td> 393 <td> Defaults to an empty body </td> 394 </tr> 395 <tr> 396 <td> \ref StopOnError() </td> 397 <td> \ref SetStopOnError() </td> 398 <td> Stop parsing the server response when there is a client or server error. </td> 399 <td> Defaults to \a false </td> 400 </tr> 401 <tr> 402 <td> \ref Timeout() </td> 403 <td> \ref SetTimeout() </td> 404 <td> The timeout determines how long is waited for the server to respond </td> 405 <td> \c B_INFINITE_TIMEOUT </td> 406 </tr> 407 </table> 408 409 \since Haiku R1 410*/ 411 412 413/*! 414 \name Constructors and Destructor 415*/ 416 417 418//! @{ 419 420 421/*! 422 \fn BHttpRequest::BHttpRequest() 423 \brief Construct an empty HTTP request. 424 425 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 426 427 \since Haiku R1 428*/ 429 430 431/*! 432 \fn BHttpRequest::BHttpRequest(const BUrl &url) 433 \brief Construct a HTTP request for an \a url. 434 435 \param url A valid URL with the \c http or \c https protocol. 436 437 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 438 \exception BUnsupportedProtocol This exception is raised when the protocol of the URL cannot be 439 handled. 440 \exception BInvalidUrl This exception is raised when the \a url is invalid. 441 442 \since Haiku R1 443*/ 444 445 446/*! 447 \fn BHttpRequest::BHttpRequest(const BHttpRequest &other)=delete 448 \brief Copying is not allowed. 449 450 \since Haiku R1 451*/ 452 453 454/*! 455 \fn BHttpRequest::BHttpRequest(BHttpRequest &&other) noexcept 456 \brief Move constructor. 457 458 After a move, the \a other object is left in an empty state. 459 460 \param other The request to move data from. 461 462 \since Haiku R1 463*/ 464 465 466/*! 467 \fn BPrivate::Network::BHttpRequest::~BHttpRequest() 468 \brief Destructor 469 470 \since Haiku R1 471*/ 472 473 474//! @} 475 476 477/*! 478 \name Assignment operators 479*/ 480 481 482//! @{ 483 484 485/*! 486 \fn BHttpRequest& BHttpRequest::operator=(const BHttpRequest &other)=delete 487 \brief Copy assignment is not allowed. 488 489 \since Haiku R1 490*/ 491 492 493/*! 494 \fn BHttpRequest& BHttpRequest::operator=(BHttpRequest &&other) noexcept 495 \brief Move assignment 496 497 After a move, the \a other object is left in an empty state. 498 499 \param other The request to move data from. 500 501 \since Haiku R1 502*/ 503 504 505//! @} 506 507 508/*! 509 \name Valid or empty 510*/ 511 512 513//! @{ 514 515 516/*! 517 \fn bool BHttpRequest::IsEmpty() const noexcept 518 \brief Check if the request is valid or empty 519 520 \retval true The request is empty. 521 \retval false The request is valid. 522 523 \since Haiku R1 524*/ 525 526 527//! @} 528 529 530/*! 531 \name Current Options 532*/ 533 534 535//! @{ 536 537 538/*! 539 \fn const BHttpAuthentication* BHttpRequest::Authentication() const noexcept 540 \brief Get the credentials for the authentication for the request. 541 542 \return When no credentials are set for this request, the method returns a \c nullptr. 543 Otherwise, it will return a pointer to the current BHttpAuthentication data set for this 544 request. 545 546 \since Haiku R1 547*/ 548 549 550/*! 551 \fn const BHttpFields& BHttpRequest::Fields() const noexcept 552 \brief Get the additional header fields set for the request. 553 554 The returned header fields may be empty if no additional header fields were set. 555 556 \since Haiku R1 557*/ 558 559 560/*! 561 \fn const BHttpMethod& BHttpRequest::Method() const noexcept 562 \brief Get the current method for the request. 563 564 This will either return the custom value set for this request, or the default as is listed in 565 the overview documentation of this class. 566 567 \since Haiku R1 568*/ 569 570 571/*! 572 \fn uint8 BHttpRequest::MaxRedirections() const noexcept 573 \brief Get the current redirection options for this request. 574 575 \see \ref BHttpRequest::SetMaxRedirections() for details on the options. 576 577 \since Haiku R1 578*/ 579 580 581/*! 582 \fn const BHttpRequest::Body* BHttpRequest::RequestBody() const noexcept 583 \brief Get the details of the custom body set for the request. 584 585 \return When no body is set for this request, the method returns a \c nullptr. 586 Otherwise, it will return a pointer to a struct that describes the current body. 587 588 \since Haiku R1 589*/ 590 591 592/*! 593 \fn bool BHttpRequest::StopOnError() const noexcept 594 \brief Is the request set to parse the full response on error. 595 596 \retval true When encountering a HTTP status of the client error class (4xx) or server error 597 class (5xx), then the response will not be parsed. 598 \retval false The full response will be parsed, even with an error status code. 599 600 \since Haiku R1 601*/ 602 603 604/*! 605 \fn bigtime_t BHttpRequest::Timeout() const noexcept 606 \brief Get the current timeout for the server to respond. 607 608 \since Haiku R1 609*/ 610 611 612/*! 613 \fn const BUrl& BHttpRequest::Url() const noexcept 614 \brief Get the current Url for the request. 615 616 This will either return the custom value set for this request, or the default as is listed in 617 the overview documentation of this class. 618 619 \since Haiku R1 620*/ 621 622 623//! @} 624 625 626/*! 627 \name Setting Options 628*/ 629 630 631//! @{ 632 633 634/*! 635 \fn void BHttpRequest::SetAuthentication(const BHttpAuthentication &authentication) 636 \brief Set the credentials to enable basic authentication for the request. 637 638 The Basic authorization line is added to the request upon setting the request details. There is 639 no support for other authentication schemes, like digest authentication. 640 641 \param authentication The credentials to apply to the request. 642 643 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 644 645 \since Haiku R1 646*/ 647 648 649/*! 650 \fn void BHttpRequest::SetFields(const BHttpFields &fields) 651 \brief Set additional header \a fields for this request. 652 653 There are a few reserved fields, which cannot be set as optional fields. These currently are: 654 * \c Host 655 * \c Accept-Encoding 656 * \c Connection 657 * \c Content-Type 658 * \c Content-Length 659 660 \param fields Additional fields for the header of the request. 661 662 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 663 \exception BHttpFields::InvalidData This exception is raised when the \a fields contain 664 reserved fields. 665 666 \since Haiku R1 667*/ 668 669 670/*! 671 \fn void BHttpRequest::SetMethod(const BHttpMethod &method) 672 \brief Set the \a method for this request. 673 674 Note that there currently is no additional validation done on any semantical incompatibilities. 675 This means that it is currently allowed to do a \c GET or \c HEAD request with data, while that 676 is forbidden by the standard. 677 678 \param method The method to use for the request. 679 680 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 681 682 \since Haiku R1 683*/ 684 685 686/*! 687 \fn void BHttpRequest::SetMaxRedirections(uint8 maxRedirections) 688 \brief Set the redirection options for this request. 689 690 The HTTP protocol allows the server to redirect requests if the resources have moved to a new 691 location. For your convenience, you can instruct the network services kit to follow these 692 redirections. You can set how many redirects should be followed. The maximum value is that of 693 an unsigned 8 bit int, so maximum is 256 redirects. This prevents the request from staying 694 stuck in a redirection loop. 695 696 If redirects are set to 0, or the maximum number of redirects have been processed, then the 697 response will be set to the actual (last) received redirection response. 698 699 \param maxRedirections The number of redirections to follow. Set to 0 to disable. 700 701 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 702 703 \since Haiku R1 704*/ 705 706 707/*! 708 \fn void BHttpRequest::SetRequestBody(std::unique_ptr<BDataIO> input, BString mimeType, 709 std::optional<off_t> size) 710 \brief Set a body for this request. 711 712 When the requests needs a body, this method can be used to set the contents of that body. 713 714 \param input The input is an owned pointer to an input. The lifetime of the input is guaranteed 715 up to the point that the request is sent for execution. 716 \param mimeType A valid mimetype, with a class and a subtype. For example \c text/plain is a 717 valid mime type. 718 \param size When the content size is set, the request will have a \c Content-Length header 719 field. If the \a input has less data in the buffer, this will cause the request to 720 error out. However, if the input has more data, it is only read up to size. If the actual 721 size of the data is unknown, this can be made optional. The request body will 722 then be sent as a so-called chunked transfer, sending data until the input is at the end. 723 724 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 725 \exception std::invalid_argument This exception is raised when the \a mimeType is invalid or 726 when \a input is a \c nullptr. 727 728 \since Haiku R1 729*/ 730 731 732/*! 733 \fn void BHttpRequest::SetStopOnError(bool stopOnError) 734 \brief Set whether the entire response will be parsed on a client or server error. 735 736 When the server encounters an error processing a request, it may respond with an error code. 737 Error responses can be either an error with the request, like the 404 Not Found error, or 738 errors on the server side, like a 500 Internal Server Error. Error responses may still have 739 header fields and bodies. 740 741 If your application is not interested in the rest of the response in case a client error or 742 a server error occurs, you can set this option to stop parsing. This will allow you to use the 743 \ref BHttpResult object as normal, but the response fields will be empty, and there will be no 744 body data. 745 746 \param stopOnError Set to \c true to stop parsing the HTTP response when a client error or 747 server error occurs. 748 749 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 750 751 \since Haiku R1 752*/ 753 754 755/*! 756 \fn void BHttpRequest::SetTimeout(bigtime_t timeout) 757 \brief Set the maximum time waiting for the server to respond. 758 759 If the request times out, then the response will hold the \ref BNetworkRequestError of the 760 \c NetworkError type. By default, the request does not time out. 761 762 \param timeout The timeout in milliseconds. 763 764 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 765 766 \since Haiku R1 767*/ 768 769 770/*! 771 \fn void BHttpRequest::SetUrl(const BUrl &url) 772 \brief Set the \a url for this request. 773 774 \param url A valid URL with the \c http or \c https protocol. 775 776 \exception std::bad_alloc This exception may be raised if it is impossible to allocate memory. 777 \exception BUnsupportedProtocol This exception is raised when the protocol of the URL cannot be 778 handled. 779 \exception BInvalidUrl This exception is raised when the \a url is invalid. 780 781 \since Haiku R1 782*/ 783 784 785//! @} 786 787 788/*! 789 \name Clearing options 790*/ 791 792 793//! @{ 794 795 796/*! 797 \fn void BHttpRequest::ClearAuthentication() noexcept 798 \brief Clear any authentication details previously set with \ref SetAuthentication(). 799 800 If there is no authentication data set, this method does nothing. 801 802 \since Haiku R1 803*/ 804 805 806/*! 807 \fn std::unique_ptr<BDataIO> BHttpRequest::ClearRequestBody() noexcept 808 \brief Clear any request body previously set with \ref SetRequestBody(). 809 810 \return Returns the previously set input \ref BDataIO object. If there is no request body set, 811 this method returns \c nullptr. 812 813 \since Haiku R1 814*/ 815 816 817//! @} 818 819 820/*! 821 \name Serialization 822*/ 823 824 825//! @{ 826 827 828/*! 829 \fn BString BHttpRequest::HeaderToString() const 830 \brief Serialize the HTTP Header of this request to a string. 831 832 The HTTP header consists of the request line, and the fields, serialized as text according to 833 the HTTP specification. 834 835 This method can be used to debug requests. 836 837 \return A new string that represents the HTTP request. 838 839 \exception std::bad_alloc In case it is not possible to allocate memory for the output string. 840 841 \since Haiku R1 842*/ 843 844 845//! @} 846 847 848} // namespace Network 849 850} // namespace BPrivate 851 852#endif 853