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