Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:12

0001 /*
0002  * This File is part of Davix, The IO library for HTTP based protocols
0003  * Copyright (C) CERN 2013
0004  * Author: Adrien Devresse <adrien.devresse@cern.ch>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Lesser General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2.1 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Lesser General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Lesser General Public
0017  * License along with this library; if not, write to the Free Software
0018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0019  *
0020 */
0021 
0022 #ifndef DAVIX_HTTPREQUEST_H
0023 #define DAVIX_HTTPREQUEST_H
0024 
0025 #include <vector>
0026 #include <unistd.h>
0027 #include <utils/davix_types.hpp>
0028 #include <utils/davix_uri.hpp>
0029 #include <status/davixstatusrequest.hpp>
0030 #include <params/davixrequestparams.hpp>
0031 
0032 #ifndef __DAVIX_INSIDE__
0033 #error "Only davix.h or davix.hpp should be included."
0034 #endif
0035 
0036 /**
0037   @file httprequest.hpp
0038   @author Devresse Adrien
0039 
0040   @brief Http low level request interface
0041  */
0042 
0043 
0044 
0045 
0046 namespace Davix {
0047 
0048 /// Callback for body providers
0049 /// Before each time the body is provided, the callback will be called
0050 /// once with buflen == 0.  The body may have to be provided >1 time
0051 /// per request (for authentication retries etc.).
0052 /// For a call with buflen > 0, the callback must return:
0053 ///    <0           : error, abort request; session error string must be set.
0054 ///     0           : ignore 'buffer' contents, end of body.
0055 ///     0 < x <= buflen : buffer contains x bytes of body data.  */
0056 typedef dav_ssize_t (*HttpBodyProvider)(void *userdata,
0057                                     char *buffer, dav_size_t buflen);
0058 
0059 
0060 ///////////////////////////////////////////////////////////////////////////
0061 ///////////////////////////////////////////////////////////////////////////
0062 
0063 class NEONRequest;
0064 class HttpCacheToken;
0065 class ContentProvider;
0066 
0067 namespace RequestFlag{
0068     ///
0069     /// \brief Request flag
0070     ///
0071     ///
0072     enum RequestFlag{
0073         SupportContinue100 = 0x01, /**< Enable support for 100 Continue code (default: OFF) */
0074         IdempotentRequest  = 0x02  /**< Specifie the request as Idempotent ( default : ON) */
0075     };
0076 
0077 }
0078 
0079 /// @class HttpRequest
0080 /// @brief Http low level request interface.
0081 ///
0082 /// HTTPRequest is the main davix class for low level HTTP queries.
0083 ///
0084 /// HTTPRequest objects are provided by Davix::Context
0085 ///
0086 class DAVIX_EXPORT HttpRequest : private NonCopyable
0087 {
0088 public:
0089     ///
0090     /// \brief HttpRequest constructor with a defined URL
0091     /// \param context davix context
0092     /// \param url URL of the resource
0093     /// \param err Davix error report system
0094     ///
0095     /// @snippet example_code_snippets.cpp HttpRequest uri
0096     HttpRequest(Context & context, const Uri & url, DavixError** err);
0097 
0098     ///
0099     /// \brief HttpRequest constructor with a defined URL from a string
0100     /// \param context davix context
0101     /// \param url URL of the resource
0102     /// \param err Davix error report system
0103     ///
0104     /// @snippet example_code_snippets.cpp HttpRequest
0105     HttpRequest(Context & context, const std::string & url, DavixError** err);
0106 
0107     ///
0108     /// \brief HttpRequest internal usage
0109     /// \param req
0110     ///
0111     HttpRequest(NEONRequest* req);
0112     virtual ~HttpRequest();
0113 
0114     ///  add a optional HTTP header request
0115     ///  replace an existing one if already exist
0116     ///  if the content of value of the header field is empty : remove an existing one
0117     ///  @param field  header field name
0118     ///  @param value header field value
0119     ///
0120     /// @snippet example_code_snippets.cpp HttpRequest::addHeaderField
0121     void addHeaderField(const std::string & field, const std::string & value);
0122 
0123     ///
0124     /// \brief set the request method ( "GET", "PUT", ... )
0125     /// \param method request method
0126     ///
0127     /// @snippet example_code_snippets.cpp HttpRequest::setRequestMethod
0128     void setRequestMethod(const std::string & method);
0129 
0130 
0131     ///
0132     /// \brief set the request parameter
0133     /// \param parameters Davix Request parameters
0134     ///
0135     ///  define the request parameters, can be used to define parameters
0136     ///  such as authentication scheme, timeout or user agent.
0137     ///
0138     /// @snippet example_code_snippets.cpp HttpRequest::setParameters
0139     void setParameters(const RequestParams &parameters);
0140 
0141     ///   @brief execute this request completely
0142     ///
0143     ///   the answer is accessible with \ref Davix::HttpRequest::getAnswerContent
0144     ///   @param err davix error report
0145     ///   @return 0 on success
0146     ///
0147     /// @snippet example_code_snippets.cpp HttpRequest::executeRequest
0148     int executeRequest(DavixError** err);
0149 
0150     ///
0151     ///  set the content of the request from a string
0152     ///  an empty string set no request content
0153     ///  @warning this string is not duplicated internally for performance reasons
0154     ///
0155     ///  @snippet example_code_snippets.cpp HttpRequest::setRequestBody
0156     void setRequestBody(const std::string & body);
0157 
0158     ///
0159     /// set the content of the request from a buffer
0160     ///  NULL pointer means a empty content
0161     ///
0162     ///  @snippet example_code_snippets.cpp HttpRequest::setRequestBody
0163     void setRequestBody(const void * buffer, dav_size_t len_buff);
0164 
0165     ///
0166     /// set the content of the request from a file descriptor
0167     /// start at offset and read a maximum of len bytes
0168     ///
0169     ///  @snippet example_code_snippets.cpp HttpRequest::setRequestBody
0170     void setRequestBody(int fd, dav_off_t offset, dav_size_t len);
0171 
0172     ///
0173     /// set a callback to provide the body of the requests
0174     ///
0175     void setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata);
0176 
0177     ///
0178     /// set a content provider object to provide the body of the requests
0179     ///
0180     void setRequestBody(ContentProvider &provider);
0181 
0182     ///
0183     /// @brief start a multi-part HTTP Request
0184     ///
0185     ///  the multi-part HTTP Request of davix
0186     ///  should be used for request with a large answer
0187     ///
0188     ///
0189     /// @param err : DavixError error report system
0190     /// @return return 0 if success, or a negative value if an error occures
0191     ///
0192     ///  @snippet example_code_snippets.cpp HttpRequest::beginRequest
0193     int beginRequest(DavixError** err);
0194 
0195     ///
0196     /// read a block of a maximum size bytes in the answer
0197     /// can return < max_size bytes depending of the data available
0198     ///
0199     /// @param buffer : buffer to fill
0200     /// @param max_size : maximum number of byte to read
0201     /// @param err : DavixError error report system
0202     /// @return number of bytes readed
0203     ///
0204     ///  @snippet example_code_snippets.cpp HttpRequest::readBlock
0205     dav_ssize_t readBlock(char* buffer, dav_size_t max_size, DavixError** err);
0206 
0207 
0208     ///
0209     /// read a block of a maximum size bytes in the answer into buffer
0210     /// can return < max_size bytes depending of the data available
0211     ///
0212     /// @param buffer : vector to fill
0213     /// @param max_size : maximum number of byte to read
0214     /// @param err : DavixError error report system
0215     /// @return number of bytes readed
0216     ///
0217     ///  @snippet example_code_snippets.cpp HttpRequest::readBlock
0218     dav_ssize_t readBlock(std::vector<char> & buffer, dav_size_t max_size, DavixError** err);
0219 
0220     ///
0221     /// read a segment of size bytes, return always max_size excepted if the end of the content is reached
0222     ///
0223     /// @param buffer : vector to fill
0224     /// @param max_size : maximum number of byte to read
0225     /// @param err : DavixError error report system
0226     /// @return number of bytes readed
0227     ///
0228     ///  @snippet example_code_snippets.cpp HttpRequest::readSegment
0229     dav_ssize_t readSegment(char* buffer, dav_size_t max_size, DavixError** err);
0230 
0231 
0232 
0233     ///
0234     /// write the full answer content to the given file descriptor
0235     /// @param fd : buffer to fill
0236     /// @param err : DavixError error report system
0237     /// @return number of bytes read
0238     ///
0239     ///  @snippet example_code_snippets.cpp HttpRequest::readToFd
0240     dav_ssize_t readToFd(int fd, DavixError** err);
0241 
0242     ///
0243     /// write the first 'read_size' first bytes to the given file descriptor
0244     /// @param fd : buffer to fill
0245     /// @param read_size : number of bytes to read
0246     /// @param err : DavixError error report system
0247     /// @return number of bytes read
0248     ///
0249     ///  @snippet example_code_snippets.cpp HttpRequest::readToFd
0250     dav_ssize_t readToFd(int fd, dav_size_t read_size, DavixError** err);
0251 
0252     ///
0253     /// read a line of text of a maximum size bytes in the answer
0254     /// @param buffer : buffer to fill
0255     /// @param max_size : maximum number of bytes to read
0256     /// @param err : DavixError error report system
0257     /// @return number of bytes readed, if return == max_size -> the line too big
0258     ///
0259     ///  @snippet example_code_snippets.cpp HttpRequest::readLine
0260     dav_ssize_t readLine(char* buffer, dav_size_t max_size, DavixError** err);
0261 
0262     ///
0263     /// discard the response body
0264     /// @param err: DavixError error report system
0265     ///
0266     /// @snippet example_code_snippets.cpp HttpRequest::discardBody
0267     void discardBody(DavixError** err);
0268 
0269     ///
0270     /// finish a request stated with beginRequest
0271     ///
0272     /// @snippet example_code_snippets.cpp HttpRequest::endRequest
0273     int endRequest(DavixError** err);
0274 
0275     /// return the body of the answer
0276     ///
0277     /// @snippet example_code_snippets.cpp HttpRequest::getAnswerContent
0278     const char* getAnswerContent();
0279 
0280     /// return the body of the answer in a vector
0281     ///
0282     /// @snippet example_code_snippets.cpp HttpRequest::getAnswerContentVec
0283     std::vector<char>  & getAnswerContentVec();
0284 
0285     /// get content length
0286     /// @return content size, return -1 if chunked
0287     ///
0288     /// @snippet example_code_snippets.cpp HttpRequest::getAnswerSize
0289     dav_ssize_t getAnswerSize() const;
0290 
0291     /// get last modified time
0292     ///
0293     /// @snippet example_code_snippets.cpp HttpRequest::getLastModified
0294     time_t getLastModified() const;
0295 
0296     ///
0297     ///  clear the current result
0298     ///
0299     /// @snippet example_code_snippets.cpp HttpRequest::clearAnswerContent
0300     void clearAnswerContent();
0301 
0302     ///
0303     /// @return current request code error
0304     /// undefined if executeRequest or beginRequest has not be called before
0305     ///
0306     /// @snippet example_code_snippets.cpp HttpRequest::getRequestCode
0307     int getRequestCode();
0308 
0309     ///
0310     /// get the value associated to a header key in the request answer
0311     /// @param header_name : key of the header field
0312     /// @param value : reference of the string to set
0313     /// @return true if this header exist or false if it does not
0314     ///
0315     /// @snippet example_code_snippets.cpp HttpRequest::getAnswerHeader
0316     bool getAnswerHeader(const std::string & header_name, std::string & value) const;
0317 
0318 
0319     ///
0320     /// get all the headers associated with this answer
0321     /// @param vec_headers : vector of headers
0322     /// @return true if this header exist or false if it does not
0323     ///
0324     /// @snippet example_code_snippets.cpp HttpRequest::getAnswerHeaders
0325     size_t getAnswerHeaders( HeaderVec & vec_headers) const;
0326 
0327 
0328     /// @deprecated not in use anymore
0329     DEPRECATED(HttpCacheToken* extractCacheToken() const);
0330 
0331     /// @deprecated not in use anymore
0332     DEPRECATED(void useCacheToken(const HttpCacheToken* token));
0333 
0334     /// set a HttpRequest flag
0335     void setFlag(const RequestFlag::RequestFlag flag, bool value);
0336 
0337     /// get a HttpRequest flag value
0338     bool getFlag(const RequestFlag::RequestFlag flag);
0339 
0340 private:
0341     NEONRequest* d_ptr;
0342 
0343     void runPreRunHook();
0344     void runRegisterHooks();
0345 };
0346 
0347 
0348 /// @class GetRequest
0349 /// @brief Http low level request configured for GET operation
0350 class GetRequest : public HttpRequest{
0351 public:
0352     ///
0353     /// \brief Construct a HttpRequest for GET a operation
0354     /// \param context
0355     /// \param uri
0356     /// \param err
0357     ///
0358     /// @snippet example_code_snippets.cpp HttpRequest::GetRequest
0359     GetRequest(Context & context, const Uri & uri, DavixError** err);
0360 };
0361 
0362 /// @class PutRequest
0363 /// @brief Http low level request configured for PUT operation
0364 class PutRequest : public HttpRequest{
0365 public:
0366     ///
0367     /// \brief Construct a HttpRequest for PUT a operation
0368     /// \param context
0369     /// \param uri
0370     /// \param err
0371     ///
0372     /// @snippet example_code_snippets.cpp HttpRequest::PutRequest
0373     PutRequest(Context & context, const Uri & uri, DavixError** err);
0374 };
0375 
0376 /// @class PostRequest
0377 /// @brief Http low level request configured for POST operation
0378 class PostRequest : public HttpRequest{
0379 public:
0380     ///
0381     /// \brief Construct a HttpRequest for POST a operation
0382     /// \param context
0383     /// \param uri
0384     /// \param err
0385     ///
0386     /// @snippet example_code_snippets.cpp HttpRequest::PutRequest
0387     PostRequest(Context & context, const Uri & uri, DavixError** err);
0388 };
0389 
0390 
0391 /// @class HeadRequest
0392 /// @brief Http low level request configured for HEAD operation
0393 class HeadRequest : public HttpRequest{
0394 public:
0395     ///
0396     /// \brief Construct a HttpRequest for a HEAD operation
0397     /// \param context
0398     /// \param uri
0399     /// \param err
0400     ///
0401     /// @snippet example_code_snippets.cpp HttpRequest::HeadRequest
0402     HeadRequest(Context & context, const Uri & uri, DavixError** err);
0403 };
0404 
0405 
0406 /// @class DeleteRequest
0407 /// @brief Http low level request configured for DELETE operation
0408 class DeleteRequest : public HttpRequest{
0409 public:
0410     ///
0411     /// \brief  Construct a HttpRequest forfor a DELETE operation
0412     /// \param context
0413     /// \param uri
0414     /// \param err
0415     ///
0416     /// @snippet example_code_snippets.cpp HttpRequest::DeleteRequest
0417     DeleteRequest(Context & context, const Uri & uri, DavixError** err);
0418 };
0419 
0420 
0421 /// @class PropfindRequest
0422 /// @brief Webdav low level request configured for PROPFIND operation
0423 class PropfindRequest : public HttpRequest{
0424 public:
0425     ///
0426     /// \brief  Construct a HttpRequest for a PROPFIND operation
0427     /// \param context
0428     /// \param uri
0429     /// \param err
0430     ///
0431     /// @snippet example_code_snippets.cpp HttpRequest::PropfindRequest
0432     PropfindRequest(Context & context, const Uri & uri, DavixError** err);
0433 };
0434 
0435 }
0436 
0437 #endif // DAVIX_HTTPREQUEST_H