• 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  * Description: rtsp parse class
15  * Author: dingkang
16  * Create: 2022-01-28
17  */
18 
19 #include "rtsp_parse.h"
20 
21 #include "cast_engine_log.h"
22 #include "rtsp_basetype.h"
23 #include "utils.h"
24 
25 namespace OHOS {
26 namespace CastEngine {
27 namespace CastEngineService {
28 namespace CastSessionRtsp {
29 DEFINE_CAST_ENGINE_LABEL("Cast-Rtsp-Parse");
30 
GetSeq()31 int RtspParse::GetSeq()
32 {
33     std::unordered_map<std::string, std::string>::const_iterator got = headers_.find("cseq");
34     if (got == headers_.end()) {
35         sequence_ = 0;
36     } else {
37         sequence_ = ParseIntSafe(got->second);
38     }
39 
40     return sequence_;
41 }
42 
ParseMsg(const std::string & str,RtspParse & msg)43 void RtspParse::ParseMsg(const std::string &str, RtspParse &msg)
44 {
45     CLOGD("In %{public}s", str.c_str());
46     std::string unmatched;
47     std::vector<std::string> spiltStrings;
48     Utils::SplitString(str, spiltStrings, MSG_SEPARATOR);
49     if (spiltStrings.size() <= MIN_SPLIT_LENGTH) {
50         CLOGE("Invalid request msg %{public}s length %{public}zu", str.c_str(), spiltStrings.size());
51         return;
52     }
53 
54     msg.firstLine_ = spiltStrings[0];
55     msg.statusCode_ = (msg.firstLine_.find(STATUS_OK_STR) != std::string::npos) ? STATUS_OK : 0;
56 
57     // Parsing headers of the request
58     for (size_t index = 1; index < spiltStrings.size(); index++) {
59         if (spiltStrings[index].length() <= MIN_LINE_LENGTH) {
60             continue;
61         }
62 
63         std::string subStrL;
64         std::string subStrR;
65         auto dotPos = spiltStrings[index].find(":");
66         if (dotPos == std::string::npos) {
67             unmatched.append(Utils::Trim(spiltStrings[index]));
68             continue;
69         } else {
70             subStrL = spiltStrings[index].substr(0, dotPos);
71             subStrR = spiltStrings[index].substr(dotPos + 1);
72             CLOGD("Parse msg subStrL %{public}s subStrR %{public}s", subStrL.c_str(), subStrR.c_str());
73         }
74 
75         if ((subStrL.length() == 0) || (subStrR.length() == 0)) {
76             CLOGD("Parsed Length error %{public}zu", subStrL.length());
77             continue;
78         }
79         CLOGD("Parse msg headers_ %{public}s %{public}s", Utils::Trim(Utils::ToLower(subStrL)).c_str(),
80             Utils::Trim(subStrR).c_str());
81         msg.headers_.insert(std::make_pair(Utils::Trim(Utils::ToLower(subStrL)), Utils::Trim(subStrR)));
82     }
83     msg.unmatchedString_ = unmatched;
84     if (msg.unmatchedString_.length() > 0) {
85         CLOGD("parsed Header's unmatched str = %{public}s", msg.unmatchedString_.c_str());
86     }
87     CLOGD("FirstLine_ %{public}s", msg.firstLine_.c_str());
88 }
89 
90 /*
91     statement:
92     1. INVALID_VALUE(-1) is global error value
93     2. strtol suppport "+2abc" out vlue 2, here is exception
94  */
ParseIntSafe(const std::string & str)95 int RtspParse::ParseIntSafe(const std::string &str)
96 {
97     if (str.size() == 0) {
98         return INVALID_VALUE;
99     }
100 
101     char *nextPtr = nullptr;
102     long result = strtol(str.c_str(), &nextPtr, DECIMALISM);
103     if (errno == ERANGE) {
104         CLOGE("Parse int out of range");
105         return INVALID_VALUE;
106     } else if (*nextPtr != '\0') {
107         CLOGE("Parse int error, invalid parament");
108         return INVALID_VALUE;
109     }
110     return static_cast<int>(result);
111 }
112 
ParseUint32Safe(const std::string & str)113 uint32_t RtspParse::ParseUint32Safe(const std::string &str)
114 {
115     return static_cast<uint32_t>(ParseIntSafe(str));
116 }
117 
118 /*
119     statement:
120     1. INVALID_VALUE(-1) is global error value
121     2. strtod suppport "+2.0abc" out vlue 2.0, here is exception
122  */
ParseDoubleSafe(const std::string & str)123 double RtspParse::ParseDoubleSafe(const std::string &str)
124 {
125     if (str.size() == 0) {
126         return INVALID_VALUE;
127     }
128 
129     char *nextPtr = nullptr;
130     double result = strtod(str.c_str(), nullptr);
131     if (errno == ERANGE) {
132         CLOGE("Parse double out of range");
133         return INVALID_VALUE;
134     } else if (*nextPtr != '\0') {
135         CLOGE("Parse double error, invalid parament");
136         return INVALID_VALUE;
137     }
138 
139     return result;
140 }
141 
GetTargetStr(const std::string & srcStr,const std::string & specificStr,const std::string & endStr)142 std::string RtspParse::GetTargetStr(const std::string &srcStr, const std::string &specificStr,
143     const std::string &endStr)
144 {
145     auto strPos = srcStr.find(specificStr);
146     if (strPos == std::string::npos) {
147         CLOGD("GetTargetStr [%{public}s] not find ", specificStr.c_str());
148         return "";
149     }
150     std::string leftStr = srcStr.substr(strPos + specificStr.length());
151     if (leftStr.length() == 0) {
152         CLOGD("GetStr [%{public}s] Error, left string not enough.", specificStr.c_str());
153         return "";
154     }
155     if (endStr.empty()) {
156         return Utils::Trim(leftStr);
157     }
158 
159     strPos = leftStr.find(endStr);
160     if (strPos == std::string::npos) {
161         CLOGD("GetTarget [%{public}s] left string not have endStr %{public}s", specificStr.c_str(), endStr.c_str());
162     }
163 
164     std::string strResult = leftStr.substr(0, strPos);
165     if (strResult.length() == 0) {
166         CLOGD("GetTargetStr [%{public}s] Error, target string len is 0. ", specificStr.c_str());
167         return "";
168     }
169     return Utils::Trim(strResult);
170 }
171 } // namespace CastSessionRtsp
172 } // namespace CastEngineService
173 } // namespace CastEngine
174 } // namespace OHOS
175