Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_RESOURCES_NETWORK_XLNETWORKREQUEST_H_
24 : #define XENOLITH_RESOURCES_NETWORK_XLNETWORKREQUEST_H_
25 :
26 : #include "XLApplication.h"
27 : #include "SPNetworkHandle.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::network {
30 :
31 : template <typename Interface>
32 : struct Context;
33 :
34 : }
35 :
36 : namespace STAPPLER_VERSIONIZED stappler::xenolith::network {
37 :
38 : class Controller;
39 : class Request;
40 :
41 : using Method = stappler::network::Method;
42 :
43 : class Handle final : public NetworkHandle {
44 : public:
45 : using Context = stappler::network::Context<Interface>;
46 :
47 21 : virtual ~Handle() { }
48 :
49 : // just GET url, actions with data defined with setSend*/setReceive*
50 : bool init(StringView url);
51 :
52 : // download to file with GET
53 : bool init(StringView url, FilePath fileName);
54 :
55 : // perform query with specific method, actions with data defined with setSend*/setReceive*
56 : bool init(Method method, StringView url);
57 :
58 : bool isSuccess() const { return _success; }
59 : int64_t getMTime() const { return _mtime; }
60 : StringView getETag() const { return _etag; }
61 21 : StringView getSharegroup() const { return _sharegroup; }
62 :
63 21 : void setMTime(int64_t val) { _mtime = val; }
64 21 : void setETag(StringView val) { _etag = val.str<Interface>(); }
65 : void setSharegroup(StringView val) { _sharegroup = val.str<Interface>(); }
66 :
67 : void setSignRequest(bool value) { _signRequest = value; }
68 21 : bool shouldSignRequest() const { return _signRequest; }
69 :
70 42 : const Rc<Request> &getReqeust() const { return _request; }
71 :
72 : protected:
73 : friend class Controller;
74 : friend class Request;
75 :
76 : bool prepare(Context *ctx);
77 : bool finalize(Context *ctx, bool success);
78 :
79 : bool _success = false;
80 : bool _signRequest = false;
81 : std::array<char, 256> _errorBuffer = { 0 };
82 :
83 : uint64_t _mtime = 0;
84 : String _etag;
85 : String _sharegroup;
86 :
87 : const Controller *_controller = nullptr;
88 : Rc<Request> _request;
89 : };
90 :
91 : class Request : public Ref {
92 : public:
93 : using CompleteCallback = Function<void(const Request &, bool)>;
94 : using ProgressCallback = Function<void(const Request &, int64_t total, int64_t now)>;
95 :
96 : virtual ~Request();
97 :
98 : virtual bool init(const Callback<bool(Handle &)> &setupCallback, Rc<Ref> && = nullptr);
99 :
100 : virtual void perform(Application *, CompleteCallback &&cb);
101 : virtual void perform(Controller *, CompleteCallback &&cb);
102 :
103 : void setIgnoreResponseData(bool);
104 : bool isIgnoreResponseData() const { return _ignoreResponseData; }
105 :
106 : bool isRunning() const { return _running; }
107 :
108 21 : const Handle &getHandle() const { return _handle; }
109 :
110 : float getUploadProgress() const { return float(_uploadProgress.second) / float(_uploadProgress.first); }
111 : float getDownloadProgress() const { return float(_downloadProgress.second) / float(_downloadProgress.first); }
112 :
113 : Pair<int64_t, int64_t> getUploadProgressCounters() const { return _uploadProgress; }
114 : Pair<int64_t, int64_t> getDownloadProgressCounters() const { return _downloadProgress; }
115 :
116 : void setUploadProgress(ProgressCallback &&);
117 : void setDownloadProgress(ProgressCallback &&);
118 :
119 : BytesView getData() const { return _data; }
120 :
121 : protected:
122 : friend class Controller;
123 :
124 : void handleHeader(StringView, StringView);
125 : size_t handleReceive(char *, size_t);
126 :
127 : void notifyOnComplete(bool);
128 : void notifyOnUploadProgress(int64_t total, int64_t now);
129 : void notifyOnDownloadProgress(int64_t total, int64_t now);
130 :
131 : bool _running = false;
132 : bool _ignoreResponseData = false;
133 : bool _setupInput = false;
134 : Function<void(StringView, StringView)> _targetHeaderCallback;
135 : Pair<int64_t, int64_t> _uploadProgress = pair(0, 0); // total, now
136 : Pair<int64_t, int64_t> _downloadProgress = pair(0, 0); // total, now
137 : ProgressCallback _onDownloadProgress;
138 : ProgressCallback _onUploadProgress;
139 : CompleteCallback _onComplete;
140 : Handle _handle;
141 : Rc<Ref> _owner;
142 :
143 : size_t _nbytes = 0;
144 : Bytes _data;
145 : };
146 :
147 : }
148 :
149 : #endif /* XENOLITH_RESOURCES_NETWORK_XLNETWORKREQUEST_H_ */
|