• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rawfile_request.h"
17 
18 #include "threads.h"
19 
20 #include "hilog/log.h"
21 #include "rawfile/raw_file.h"
22 #include "rawfile/raw_file_manager.h"
23 
24 #undef LOG_TAG
25 #define LOG_TAG "ss-handler"
26 
27 namespace {
28 
29     uint8_t buffer[1024];
30     cnd_t http_body_cnd;
31     mtx_t http_body_mtx;
32     const int BUFF_LEN = 1000;
33     const int DO_NOT_FOUND = 404;
34     const int DO_OK = 200;
35 
36     // HttpBodyStream的读回调。
ReadCallback(const ArkWeb_HttpBodyStream * httpBodyStream,uint8_t * buffer,int bytesRead)37     void ReadCallback(const ArkWeb_HttpBodyStream *httpBodyStream, uint8_t *buffer, int bytesRead) {
38         OH_LOG_INFO(LOG_APP, "read http body back.");
39         bool isEof = OH_ArkWebHttpBodyStream_IsEof(httpBodyStream);
40         if (!isEof && bytesRead != 0) {
41             memset(buffer, 0, BUFF_LEN);
42             OH_ArkWebHttpBodyStream_Read(httpBodyStream, buffer, BUFF_LEN);
43         } else {
44             RawfileRequest *rawfileRequest = (RawfileRequest *)OH_ArkWebHttpBodyStream_GetUserData(httpBodyStream);
45             if (rawfileRequest) {
46                 rawfileRequest->ReadRawfileDataOnWorkerThread();
47             }
48         }
49     }
50 
ReadHttpBodyOnWorkerThread(void * userData)51     int ReadHttpBodyOnWorkerThread(void *userData) {
52         memset(buffer, 0, BUFF_LEN);
53         ArkWeb_HttpBodyStream *httpBodyStream = (ArkWeb_HttpBodyStream *)userData;
54         OH_ArkWebHttpBodyStream_Read(httpBodyStream, buffer, BUFF_LEN);
55 
56         return 0;
57     }
58 
ReadRawfileOnWorkerThread(void * userData)59     int ReadRawfileOnWorkerThread(void *userData) {
60         RawfileRequest *rawfileRequest = (RawfileRequest *)userData;
61         if (rawfileRequest) {
62             rawfileRequest->ReadRawfileDataOnWorkerThread();
63         }
64         return 0;
65     }
66 
67     // ArkWeb_HttpBodyStream的初始化回调。
InitCallback(const ArkWeb_HttpBodyStream * httpBodyStream,ArkWeb_NetError result)68     void InitCallback(const ArkWeb_HttpBodyStream *httpBodyStream, ArkWeb_NetError result) {
69         OH_LOG_INFO(LOG_APP, "init http body stream done %{public}d.", result);
70         bool isChunked = OH_ArkWebHttpBodyStream_IsChunked(httpBodyStream);
71         OH_LOG_INFO(LOG_APP, "http body stream is chunked %{public}d.", isChunked);
72 
73         ReadHttpBodyOnWorkerThread((void *)httpBodyStream);
74     }
75     const int blockSize = 1024 * 8;
76 
77 } // namespace
78 
RawfileRequest(const ArkWeb_ResourceRequest * resourceRequest,const ArkWeb_ResourceHandler * resourceHandler,const NativeResourceManager * resourceManager)79 RawfileRequest::RawfileRequest(const ArkWeb_ResourceRequest *resourceRequest,
80                                const ArkWeb_ResourceHandler *resourceHandler,
81                                const NativeResourceManager *resourceManager)
82     : resourceRequest_(resourceRequest), resourceHandler_(resourceHandler), resourceManager_(resourceManager) {}
83 
~RawfileRequest()84 RawfileRequest::~RawfileRequest() {}
85 
Start()86 void RawfileRequest::Start() {
87     OH_LOG_INFO(LOG_APP, "start a rawfile request.");
88     char *url;
89     OH_ArkWebResourceRequest_GetUrl(resourceRequest_, &url);
90 
91     std::string urlStr(url);
92     reqUrl_ = urlStr;
93 
94     std::size_t position = urlStr.rfind('/');
95     if (position != std::string::npos) {
96         rawfilePath_ = urlStr.substr(position + 1);
97     }
98     OH_ArkWeb_ReleaseString(url);
99     OH_ArkWeb_CreateResponse(&response_);
100     // 接口覆盖
101     OH_ArkWebResourceRequest_GetHttpBodyStream(resourceRequest(), &stream_);
102 
103     if (rawfilePath_ == "Error") {
104         DidFailWithError(ARKWEB_ERR_FILE_NOT_FOUND);
105         return;
106     }
107 
108     if (stream_) {
109         haveBodyStream_ = 0;
110         OH_LOG_ERROR(LOG_APP, "have http body stream");
111         OH_ArkWebHttpBodyStream_SetUserData(stream_, this);
112         isRead_ = OH_ArkWebHttpBodyStream_SetReadCallback(stream_, (ArkWeb_HttpBodyStreamReadCallback)ReadCallback);
113         isInit_ = OH_ArkWebHttpBodyStream_Init(stream_, (ArkWeb_HttpBodyStreamInitCallback)InitCallback);
114 
115     } else {
116         ReadRawfileOnWorkerThread(reinterpret_cast<void *>(this));
117     }
118 }
119 
120 // 在worker线程中读取rawfile,并通过ResourceHandler返回给Web内核。
ReadRawfileDataOnWorkerThread()121 void RawfileRequest::ReadRawfileDataOnWorkerThread() {
122     OH_LOG_INFO(LOG_APP, "read rawfile in worker thread.");
123     const struct UrlInfo {
124         std::string resource;
125         std::string mimeType;
126     } urlInfos[] = {
127                     {"post_data.html", "text/html"},
128                     {"chunked_post_stream.html", "text/html"},
129                     {"xhr", "application/json"}
130     };
131 
132     if (!resourceManager()) {
133         OH_LOG_ERROR(LOG_APP, "read rawfile error, resource manager is nullptr.");
134         return;
135     }
136 
137     RawFile *rawfile = OH_ResourceManager_OpenRawFile(resourceManager(), rawfilePath().c_str());
138     OH_LOG_INFO(LOG_APP, "read OH_ResourceManager_OpenRawFile %{public}s", rawfilePath().c_str());
139 
140     if (!rawfile) {
141         OH_LOG_INFO(LOG_APP, "read OH_ArkWebResponse_SetStatus %{public}d", DO_NOT_FOUND);
142         OH_ArkWebResponse_SetStatus(response(), DO_NOT_FOUND);
143     } else {
144         OH_LOG_INFO(LOG_APP, "read OH_ArkWebResponse_SetStatus %{public}d", DO_OK);
145         OH_ArkWebResponse_SetStatus(response(), DO_OK);
146     }
147 
148     for (auto &urlInfo : urlInfos) {
149         if (urlInfo.resource == rawfilePath()) {
150             OH_ArkWebResponse_SetMimeType(response(), urlInfo.mimeType.c_str());
151             break;
152         }
153     }
154     OH_ArkWebResponse_SetCharset(response(), "UTF-8");
155 
156     long len = OH_ResourceManager_GetRawFileSize(rawfile);
157     haveResponse_ = OH_ArkWebResponse_SetHeaderByName(response(), "content-length", std::to_string(len).c_str(), false);
158     haveResponse_ = OH_ArkWebResponse_SetHeaderByName(response(), "Access-Control-Allow-Origin", "*", false);
159 
160     DidReceiveResponse();
161 
162     long consumed = 0;
163     uint8_t buffer[blockSize];
164     while (true) {
165         int ret = OH_ResourceManager_ReadRawFile(rawfile, buffer, blockSize);
166         OH_LOG_INFO(LOG_APP, "read rawfile %{public}d bytes.", ret);
167         if (ret == 0) {
168             break;
169         }
170         consumed += ret;
171         OH_ResourceManager_SeekRawFile(rawfile, consumed, 0);
172         DidReceiveData(buffer, ret);
173         memset(buffer, 0, blockSize);
174     }
175     OH_ResourceManager_CloseRawFile(rawfile);
176     DidFinish();
177 }
178 
Stop()179 void RawfileRequest::Stop() {
180     OH_LOG_INFO(LOG_APP, "stop the rawfile request.");
181     stopped_ = true;
182     if (response_) {
183         OH_ArkWeb_DestroyResponse(response_);
184     }
185     OH_ArkWebResourceRequest_Destroy(resourceRequest_);
186     haveResourceHandler_ = OH_ArkWebResourceHandler_Destroy(resourceHandler_);
187 }
188 
DidReceiveResponse()189 void RawfileRequest::DidReceiveResponse() {
190     OH_LOG_INFO(LOG_APP, "did receive response.");
191 
192     if (!stopped_) {
193         // 接口覆盖
194         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidReceiveResponse start.");
195         OH_ArkWebResourceHandler_DidReceiveResponse(resourceHandler_, response_);
196         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidReceiveResponse end.");
197     }
198 }
199 
DidReceiveData(const uint8_t * buffer,int64_t bufLen)200 void RawfileRequest::DidReceiveData(const uint8_t *buffer, int64_t bufLen) {
201     OH_LOG_INFO(LOG_APP, "did receive data.");
202 
203     if (!stopped_) {
204         // 接口覆盖
205         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidReceiveData start.");
206         OH_ArkWebResourceHandler_DidReceiveData(resourceHandler_, buffer, bufLen);
207         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidReceiveData end.");
208     }
209 }
210 
DidFinish()211 void RawfileRequest::DidFinish() {
212     OH_LOG_INFO(LOG_APP, "did finish.");
213 
214     if (!stopped_) {
215         // 接口覆盖
216         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidFinish start.");
217         OH_ArkWebResourceHandler_DidFinish(resourceHandler_);
218         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidFinish end.");
219     }
220 }
221 
DidFailWithError(ArkWeb_NetError errorCode)222 void RawfileRequest::DidFailWithError(ArkWeb_NetError errorCode) {
223     OH_LOG_INFO(LOG_APP, "did finish with error %{public}d.", errorCode);
224     if (!stopped_) {
225         // 接口覆盖
226         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidFailWithError start.");
227         OH_ArkWebResourceHandler_DidFailWithError(resourceHandler_, errorCode);
228         OH_LOG_INFO(LOG_APP, "OH_ArkWebResourceHandler_DidFailWithError end.");
229     }
230 }
231 
releaseString()232 int32_t RawfileRequest::releaseString() {
233     OH_LOG_INFO(LOG_APP, "OH_ArkWeb_ReleaseString .");
234     char* url = new char[10];
235     strcpy(url, "test");
236     OH_ArkWeb_ReleaseString(url);
237     return 0;
238 }
239 
releaseByteArray()240 int32_t RawfileRequest::releaseByteArray() {
241     OH_LOG_INFO(LOG_APP, "OH_ArkWeb_ReleaseByteArray .");
242     uint8_t* buffer = new uint8_t[1024];
243     OH_ArkWeb_ReleaseByteArray(buffer);
244     return 0;
245 }
246 
destroyHttpBodyStream()247 int32_t RawfileRequest::destroyHttpBodyStream() {
248     OH_ArkWebResourceRequest_DestroyHttpBodyStream(stream_);
249     return 0;
250 }
251 
setHeaderByName()252 int32_t RawfileRequest::setHeaderByName() {
253     ArkWeb_Response* testResponse;
254     OH_ArkWeb_CreateResponse(&testResponse);
255     OH_ArkWebResponse_SetHeaderByName(testResponse, "test-headers", "test", true);
256 
257     char* testHeader;
258     OH_ArkWebResponse_GetHeaderByName(testResponse, "test-headers", &testHeader);
259     std::string testHeader1(testHeader);
260     if( testHeader1 == "test") {
261         return 0;
262     } else {
263         return -1;
264     }
265 }
266 
getRequestHeaderList()267 int32_t RawfileRequest::getRequestHeaderList() {
268 	ArkWeb_RequestHeaderList* headerList;
269 	OH_ArkWebResourceRequest_GetRequestHeaders(resourceRequest_, &headerList);
270 	return OH_ArkWebRequestHeaderList_GetSize(headerList);
271 }