1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "rtsp_request.h"
17 #include <iomanip>
18 #include <iostream>
19 #include <sstream>
20
21 namespace OHOS {
22 namespace Sharing {
Stringify()23 std::string RtspRequest::Stringify()
24 {
25 std::stringstream ss;
26 ss << method_ << RTSP_SP << url_ << RTSP_SP << RTSP_VERSION << RTSP_CRLF;
27 ss << RTSP_TOKEN_CSEQ << ":" << RTSP_SP << cSeq_ << RTSP_CRLF;
28 if (!authorization_.empty()) {
29 ss << RTSP_TOKEN_AUTHORIZATION << ":" << RTSP_SP << authorization_ << RTSP_CRLF;
30 }
31 ss << RTSP_TOKEN_UA << ":" << RTSP_SP << userAgent_ << RTSP_CRLF;
32 if (!session_.empty()) {
33 ss << RTSP_TOKEN_SESSION << ":" << RTSP_SP << session_;
34 if (timeout_ > 0) {
35 ss << ";timeout=" << timeout_;
36 }
37 ss << RTSP_CRLF;
38 }
39
40 if (!customHeaders_.empty()) {
41 ss << customHeaders_;
42 }
43 ss << RTSP_CRLF;
44 return ss.str();
45 }
46
Parse(const std::string &request)47 RtspError RtspRequest::Parse(const std::string &request)
48 {
49 std::vector<std::string> firstLine;
50 auto result = RtspCommon::ParseMessage(request, firstLine, tokens_, body_);
51 if (result.code != RtspErrorType::OK) {
52 return result;
53 }
54
55 if (firstLine.size() < 2 || tokens_.empty()) { // 2:rtsp line
56 tokens_.clear();
57 body_.clear();
58 return {RtspErrorType::INVALID_MESSAGE, "invalid message"};
59 }
60
61 // "METHOD URL VERSION"
62 if (firstLine.size() != 3 || firstLine[2] != RTSP_VERSION) { // 2:rtsp line, 3:rtsp line
63 tokens_.clear();
64 body_.clear();
65 return {RtspErrorType::INVALID_MESSAGE, "invalid message"};
66 }
67
68 if (!RtspCommon::VerifyMethod(firstLine[0])) {
69 tokens_.clear();
70 body_.clear();
71 return {RtspErrorType::INVALID_METHOD, "invalid method"};
72 }
73
74 method_ = firstLine[0];
75 url_ = firstLine[1];
76
77 if (tokens_.find(RTSP_TOKEN_CSEQ) != tokens_.end()) {
78 cSeq_ = atoi(tokens_.at(RTSP_TOKEN_CSEQ).c_str());
79 }
80
81 if (tokens_.find(RTSP_TOKEN_UA) != tokens_.end()) {
82 userAgent_ = tokens_.at(RTSP_TOKEN_UA);
83 }
84
85 if (tokens_.find(RTSP_TOKEN_SESSION) != tokens_.end()) {
86 session_ = tokens_.at(RTSP_TOKEN_SESSION);
87 }
88
89 return {};
90 }
91
GetToken(const std::string &token)92 std::string RtspRequest::GetToken(const std::string &token)
93 {
94 if (tokens_.find(token) != tokens_.end()) {
95 return tokens_.at(token);
96 }
97
98 return {};
99 }
100
Stringify()101 std::string RtspRequestOptions::Stringify()
102 {
103 if (!require_.empty()) {
104 std::stringstream ss;
105 ss << RTSP_TOKEN_REQUIRE << ":" << RTSP_SP << require_ << RTSP_CRLF;
106 ClearCustomHeader();
107 AddCustomHeader(ss.str());
108 }
109
110 return RtspRequest::Stringify();
111 }
112
Stringify()113 std::string RtspRequestDescribe::Stringify()
114 {
115 std::stringstream ss;
116 ss << RTSP_TOKEN_ACCEPT << ":" << RTSP_SP << acceptType_ << RTSP_CRLF;
117 ClearCustomHeader();
118 AddCustomHeader(ss.str());
119 return RtspRequest::Stringify();
120 }
121
Stringify()122 std::string RtspRequestSetup::Stringify()
123 {
124 std::stringstream ss;
125 ss << RTSP_TOKEN_TRANSPORT << ":" << RTSP_SP << "RTP/AVP;unicast;client_port=" << minPort_;
126 if (maxPort_ > 0) {
127 ss << "-" << maxPort_;
128 }
129 ss << RTSP_CRLF;
130 ClearCustomHeader();
131 AddCustomHeader(ss.str());
132 return RtspRequest::Stringify();
133 }
134
Stringify()135 std::string RtspRequestPlay::Stringify()
136 {
137 if (range_ >= 0) {
138 std::stringstream ss;
139 ss << RTSP_TOKEN_RANGE << ":" << RTSP_SP << "npt=";
140 ss << std::fixed << std::setprecision(3) << range_ << "-" << RTSP_CRLF; // 3:precision
141 ClearCustomHeader();
142 AddCustomHeader(ss.str());
143 }
144
145 return RtspRequest::Stringify();
146 }
147
Stringify()148 std::string RtspRequestParameter::Stringify()
149 {
150 std::stringstream body;
151 for (auto &item : body_) {
152 body << item << RTSP_CRLF;
153 }
154
155 if (body.str().empty()) {
156 return RtspRequest::Stringify();
157 } else {
158 std::stringstream ss;
159 ss << RTSP_TOKEN_CONTENT_TYPE << ":" << RTSP_SP << "text/parameters" << RTSP_CRLF;
160 ss << RTSP_TOKEN_CONTENT_LENGTH << ":" << RTSP_SP << body.str().length() << RTSP_CRLF;
161 ClearCustomHeader();
162 AddCustomHeader(ss.str());
163 return RtspRequest::Stringify() + body.str();
164 }
165 }
166 } // namespace Sharing
167 } // namespace OHOS