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