1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Howard Chu, <[email protected]>
10*6236dae4SAndroid Build Coastguard Worker *
11*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
12*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
13*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
14*6236dae4SAndroid Build Coastguard Worker *
15*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
17*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
18*6236dae4SAndroid Build Coastguard Worker *
19*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
21*6236dae4SAndroid Build Coastguard Worker *
22*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
23*6236dae4SAndroid Build Coastguard Worker *
24*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard Worker #ifdef USE_LIBRTMP
29*6236dae4SAndroid Build Coastguard Worker
30*6236dae4SAndroid Build Coastguard Worker #include "curl_rtmp.h"
31*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
32*6236dae4SAndroid Build Coastguard Worker #include "nonblock.h" /* for curlx_nonblock */
33*6236dae4SAndroid Build Coastguard Worker #include "progress.h" /* for Curl_pgrsSetUploadSize */
34*6236dae4SAndroid Build Coastguard Worker #include "transfer.h"
35*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
36*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
37*6236dae4SAndroid Build Coastguard Worker #include <librtmp/rtmp.h>
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker /* The last 3 #include files should be in this order */
40*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
41*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
42*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
43*6236dae4SAndroid Build Coastguard Worker
44*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(USE_LWIPSOCK)
45*6236dae4SAndroid Build Coastguard Worker #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
46*6236dae4SAndroid Build Coastguard Worker #define SET_RCVTIMEO(tv,s) int tv = s*1000
47*6236dae4SAndroid Build Coastguard Worker #elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD)
48*6236dae4SAndroid Build Coastguard Worker #define SET_RCVTIMEO(tv,s) int tv = s*1000
49*6236dae4SAndroid Build Coastguard Worker #else
50*6236dae4SAndroid Build Coastguard Worker #define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0}
51*6236dae4SAndroid Build Coastguard Worker #endif
52*6236dae4SAndroid Build Coastguard Worker
53*6236dae4SAndroid Build Coastguard Worker #define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
54*6236dae4SAndroid Build Coastguard Worker
55*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_setup_connection(struct Curl_easy *data,
56*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn);
57*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_do(struct Curl_easy *data, bool *done);
58*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_done(struct Curl_easy *data, CURLcode, bool premature);
59*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_connect(struct Curl_easy *data, bool *done);
60*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_disconnect(struct Curl_easy *data,
61*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn, bool dead);
62*6236dae4SAndroid Build Coastguard Worker
63*6236dae4SAndroid Build Coastguard Worker static Curl_recv rtmp_recv;
64*6236dae4SAndroid Build Coastguard Worker static Curl_send rtmp_send;
65*6236dae4SAndroid Build Coastguard Worker
66*6236dae4SAndroid Build Coastguard Worker /*
67*6236dae4SAndroid Build Coastguard Worker * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
68*6236dae4SAndroid Build Coastguard Worker */
69*6236dae4SAndroid Build Coastguard Worker
70*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmp = {
71*6236dae4SAndroid Build Coastguard Worker "rtmp", /* scheme */
72*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
73*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
74*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
75*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
76*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
77*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
78*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
79*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
80*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
81*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
82*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
83*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
84*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
85*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
86*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
87*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
88*6236dae4SAndroid Build Coastguard Worker PORT_RTMP, /* defport */
89*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMP, /* protocol */
90*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMP, /* family */
91*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
92*6236dae4SAndroid Build Coastguard Worker };
93*6236dae4SAndroid Build Coastguard Worker
94*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmpt = {
95*6236dae4SAndroid Build Coastguard Worker "rtmpt", /* scheme */
96*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
97*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
98*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
99*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
100*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
101*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
102*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
103*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
104*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
105*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
106*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
107*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
108*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
109*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
110*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
111*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
112*6236dae4SAndroid Build Coastguard Worker PORT_RTMPT, /* defport */
113*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPT, /* protocol */
114*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPT, /* family */
115*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
116*6236dae4SAndroid Build Coastguard Worker };
117*6236dae4SAndroid Build Coastguard Worker
118*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmpe = {
119*6236dae4SAndroid Build Coastguard Worker "rtmpe", /* scheme */
120*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
121*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
122*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
123*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
124*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
125*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
126*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
127*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
128*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
129*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
130*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
131*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
132*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
133*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
134*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
135*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
136*6236dae4SAndroid Build Coastguard Worker PORT_RTMP, /* defport */
137*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPE, /* protocol */
138*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPE, /* family */
139*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
140*6236dae4SAndroid Build Coastguard Worker };
141*6236dae4SAndroid Build Coastguard Worker
142*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmpte = {
143*6236dae4SAndroid Build Coastguard Worker "rtmpte", /* scheme */
144*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
145*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
146*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
147*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
148*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
149*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
150*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
151*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
152*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
153*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
154*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
155*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
156*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
157*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
158*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
159*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
160*6236dae4SAndroid Build Coastguard Worker PORT_RTMPT, /* defport */
161*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPTE, /* protocol */
162*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPTE, /* family */
163*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
164*6236dae4SAndroid Build Coastguard Worker };
165*6236dae4SAndroid Build Coastguard Worker
166*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmps = {
167*6236dae4SAndroid Build Coastguard Worker "rtmps", /* scheme */
168*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
169*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
170*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
171*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
172*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
173*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
174*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
175*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
176*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
177*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
178*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
179*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
180*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
181*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
182*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
183*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
184*6236dae4SAndroid Build Coastguard Worker PORT_RTMPS, /* defport */
185*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPS, /* protocol */
186*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMP, /* family */
187*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
188*6236dae4SAndroid Build Coastguard Worker };
189*6236dae4SAndroid Build Coastguard Worker
190*6236dae4SAndroid Build Coastguard Worker const struct Curl_handler Curl_handler_rtmpts = {
191*6236dae4SAndroid Build Coastguard Worker "rtmpts", /* scheme */
192*6236dae4SAndroid Build Coastguard Worker rtmp_setup_connection, /* setup_connection */
193*6236dae4SAndroid Build Coastguard Worker rtmp_do, /* do_it */
194*6236dae4SAndroid Build Coastguard Worker rtmp_done, /* done */
195*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* do_more */
196*6236dae4SAndroid Build Coastguard Worker rtmp_connect, /* connect_it */
197*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connecting */
198*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing */
199*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* proto_getsock */
200*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* doing_getsock */
201*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* domore_getsock */
202*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* perform_getsock */
203*6236dae4SAndroid Build Coastguard Worker rtmp_disconnect, /* disconnect */
204*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp */
205*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* write_resp_hd */
206*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* connection_check */
207*6236dae4SAndroid Build Coastguard Worker ZERO_NULL, /* attach connection */
208*6236dae4SAndroid Build Coastguard Worker PORT_RTMPS, /* defport */
209*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPTS, /* protocol */
210*6236dae4SAndroid Build Coastguard Worker CURLPROTO_RTMPT, /* family */
211*6236dae4SAndroid Build Coastguard Worker PROTOPT_NONE /* flags */
212*6236dae4SAndroid Build Coastguard Worker };
213*6236dae4SAndroid Build Coastguard Worker
rtmp_setup_connection(struct Curl_easy * data,struct connectdata * conn)214*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_setup_connection(struct Curl_easy *data,
215*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn)
216*6236dae4SAndroid Build Coastguard Worker {
217*6236dae4SAndroid Build Coastguard Worker RTMP *r = RTMP_Alloc();
218*6236dae4SAndroid Build Coastguard Worker if(!r)
219*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
220*6236dae4SAndroid Build Coastguard Worker
221*6236dae4SAndroid Build Coastguard Worker RTMP_Init(r);
222*6236dae4SAndroid Build Coastguard Worker RTMP_SetBufferMS(r, DEF_BUFTIME);
223*6236dae4SAndroid Build Coastguard Worker if(!RTMP_SetupURL(r, data->state.url)) {
224*6236dae4SAndroid Build Coastguard Worker RTMP_Free(r);
225*6236dae4SAndroid Build Coastguard Worker return CURLE_URL_MALFORMAT;
226*6236dae4SAndroid Build Coastguard Worker }
227*6236dae4SAndroid Build Coastguard Worker conn->proto.rtmp = r;
228*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
229*6236dae4SAndroid Build Coastguard Worker }
230*6236dae4SAndroid Build Coastguard Worker
rtmp_connect(struct Curl_easy * data,bool * done)231*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
232*6236dae4SAndroid Build Coastguard Worker {
233*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn = data->conn;
234*6236dae4SAndroid Build Coastguard Worker RTMP *r = conn->proto.rtmp;
235*6236dae4SAndroid Build Coastguard Worker SET_RCVTIMEO(tv, 10);
236*6236dae4SAndroid Build Coastguard Worker
237*6236dae4SAndroid Build Coastguard Worker r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
238*6236dae4SAndroid Build Coastguard Worker
239*6236dae4SAndroid Build Coastguard Worker /* We have to know if it is a write before we send the
240*6236dae4SAndroid Build Coastguard Worker * connect request packet
241*6236dae4SAndroid Build Coastguard Worker */
242*6236dae4SAndroid Build Coastguard Worker if(data->state.upload)
243*6236dae4SAndroid Build Coastguard Worker r->Link.protocol |= RTMP_FEATURE_WRITE;
244*6236dae4SAndroid Build Coastguard Worker
245*6236dae4SAndroid Build Coastguard Worker /* For plain streams, use the buffer toggle trick to keep data flowing */
246*6236dae4SAndroid Build Coastguard Worker if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
247*6236dae4SAndroid Build Coastguard Worker !(r->Link.protocol & RTMP_FEATURE_HTTP))
248*6236dae4SAndroid Build Coastguard Worker r->Link.lFlags |= RTMP_LF_BUFX;
249*6236dae4SAndroid Build Coastguard Worker
250*6236dae4SAndroid Build Coastguard Worker (void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
251*6236dae4SAndroid Build Coastguard Worker setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
252*6236dae4SAndroid Build Coastguard Worker (char *)&tv, sizeof(tv));
253*6236dae4SAndroid Build Coastguard Worker
254*6236dae4SAndroid Build Coastguard Worker if(!RTMP_Connect1(r, NULL))
255*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
256*6236dae4SAndroid Build Coastguard Worker
257*6236dae4SAndroid Build Coastguard Worker /* Clients must send a periodic BytesReceived report to the server */
258*6236dae4SAndroid Build Coastguard Worker r->m_bSendCounter = TRUE;
259*6236dae4SAndroid Build Coastguard Worker
260*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
261*6236dae4SAndroid Build Coastguard Worker conn->recv[FIRSTSOCKET] = rtmp_recv;
262*6236dae4SAndroid Build Coastguard Worker conn->send[FIRSTSOCKET] = rtmp_send;
263*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
264*6236dae4SAndroid Build Coastguard Worker }
265*6236dae4SAndroid Build Coastguard Worker
rtmp_do(struct Curl_easy * data,bool * done)266*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
267*6236dae4SAndroid Build Coastguard Worker {
268*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn = data->conn;
269*6236dae4SAndroid Build Coastguard Worker RTMP *r = conn->proto.rtmp;
270*6236dae4SAndroid Build Coastguard Worker
271*6236dae4SAndroid Build Coastguard Worker if(!RTMP_ConnectStream(r, 0))
272*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
273*6236dae4SAndroid Build Coastguard Worker
274*6236dae4SAndroid Build Coastguard Worker if(data->state.upload) {
275*6236dae4SAndroid Build Coastguard Worker Curl_pgrsSetUploadSize(data, data->state.infilesize);
276*6236dae4SAndroid Build Coastguard Worker Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
277*6236dae4SAndroid Build Coastguard Worker }
278*6236dae4SAndroid Build Coastguard Worker else
279*6236dae4SAndroid Build Coastguard Worker Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
280*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
281*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
282*6236dae4SAndroid Build Coastguard Worker }
283*6236dae4SAndroid Build Coastguard Worker
rtmp_done(struct Curl_easy * data,CURLcode status,bool premature)284*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_done(struct Curl_easy *data, CURLcode status,
285*6236dae4SAndroid Build Coastguard Worker bool premature)
286*6236dae4SAndroid Build Coastguard Worker {
287*6236dae4SAndroid Build Coastguard Worker (void)data; /* unused */
288*6236dae4SAndroid Build Coastguard Worker (void)status; /* unused */
289*6236dae4SAndroid Build Coastguard Worker (void)premature; /* unused */
290*6236dae4SAndroid Build Coastguard Worker
291*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
292*6236dae4SAndroid Build Coastguard Worker }
293*6236dae4SAndroid Build Coastguard Worker
rtmp_disconnect(struct Curl_easy * data,struct connectdata * conn,bool dead_connection)294*6236dae4SAndroid Build Coastguard Worker static CURLcode rtmp_disconnect(struct Curl_easy *data,
295*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn,
296*6236dae4SAndroid Build Coastguard Worker bool dead_connection)
297*6236dae4SAndroid Build Coastguard Worker {
298*6236dae4SAndroid Build Coastguard Worker RTMP *r = conn->proto.rtmp;
299*6236dae4SAndroid Build Coastguard Worker (void)data;
300*6236dae4SAndroid Build Coastguard Worker (void)dead_connection;
301*6236dae4SAndroid Build Coastguard Worker if(r) {
302*6236dae4SAndroid Build Coastguard Worker conn->proto.rtmp = NULL;
303*6236dae4SAndroid Build Coastguard Worker RTMP_Close(r);
304*6236dae4SAndroid Build Coastguard Worker RTMP_Free(r);
305*6236dae4SAndroid Build Coastguard Worker }
306*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
307*6236dae4SAndroid Build Coastguard Worker }
308*6236dae4SAndroid Build Coastguard Worker
rtmp_recv(struct Curl_easy * data,int sockindex,char * buf,size_t len,CURLcode * err)309*6236dae4SAndroid Build Coastguard Worker static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
310*6236dae4SAndroid Build Coastguard Worker size_t len, CURLcode *err)
311*6236dae4SAndroid Build Coastguard Worker {
312*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn = data->conn;
313*6236dae4SAndroid Build Coastguard Worker RTMP *r = conn->proto.rtmp;
314*6236dae4SAndroid Build Coastguard Worker ssize_t nread;
315*6236dae4SAndroid Build Coastguard Worker
316*6236dae4SAndroid Build Coastguard Worker (void)sockindex; /* unused */
317*6236dae4SAndroid Build Coastguard Worker
318*6236dae4SAndroid Build Coastguard Worker nread = RTMP_Read(r, buf, curlx_uztosi(len));
319*6236dae4SAndroid Build Coastguard Worker if(nread < 0) {
320*6236dae4SAndroid Build Coastguard Worker if(r->m_read.status == RTMP_READ_COMPLETE ||
321*6236dae4SAndroid Build Coastguard Worker r->m_read.status == RTMP_READ_EOF) {
322*6236dae4SAndroid Build Coastguard Worker data->req.size = data->req.bytecount;
323*6236dae4SAndroid Build Coastguard Worker nread = 0;
324*6236dae4SAndroid Build Coastguard Worker }
325*6236dae4SAndroid Build Coastguard Worker else
326*6236dae4SAndroid Build Coastguard Worker *err = CURLE_RECV_ERROR;
327*6236dae4SAndroid Build Coastguard Worker }
328*6236dae4SAndroid Build Coastguard Worker return nread;
329*6236dae4SAndroid Build Coastguard Worker }
330*6236dae4SAndroid Build Coastguard Worker
rtmp_send(struct Curl_easy * data,int sockindex,const void * buf,size_t len,bool eos,CURLcode * err)331*6236dae4SAndroid Build Coastguard Worker static ssize_t rtmp_send(struct Curl_easy *data, int sockindex,
332*6236dae4SAndroid Build Coastguard Worker const void *buf, size_t len, bool eos, CURLcode *err)
333*6236dae4SAndroid Build Coastguard Worker {
334*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn = data->conn;
335*6236dae4SAndroid Build Coastguard Worker RTMP *r = conn->proto.rtmp;
336*6236dae4SAndroid Build Coastguard Worker ssize_t num;
337*6236dae4SAndroid Build Coastguard Worker
338*6236dae4SAndroid Build Coastguard Worker (void)sockindex; /* unused */
339*6236dae4SAndroid Build Coastguard Worker (void)eos; /* unused */
340*6236dae4SAndroid Build Coastguard Worker
341*6236dae4SAndroid Build Coastguard Worker num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
342*6236dae4SAndroid Build Coastguard Worker if(num < 0)
343*6236dae4SAndroid Build Coastguard Worker *err = CURLE_SEND_ERROR;
344*6236dae4SAndroid Build Coastguard Worker
345*6236dae4SAndroid Build Coastguard Worker return num;
346*6236dae4SAndroid Build Coastguard Worker }
347*6236dae4SAndroid Build Coastguard Worker
Curl_rtmp_version(char * version,size_t len)348*6236dae4SAndroid Build Coastguard Worker void Curl_rtmp_version(char *version, size_t len)
349*6236dae4SAndroid Build Coastguard Worker {
350*6236dae4SAndroid Build Coastguard Worker char suff[2];
351*6236dae4SAndroid Build Coastguard Worker if(RTMP_LIB_VERSION & 0xff) {
352*6236dae4SAndroid Build Coastguard Worker suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
353*6236dae4SAndroid Build Coastguard Worker suff[1] = '\0';
354*6236dae4SAndroid Build Coastguard Worker }
355*6236dae4SAndroid Build Coastguard Worker else
356*6236dae4SAndroid Build Coastguard Worker suff[0] = '\0';
357*6236dae4SAndroid Build Coastguard Worker
358*6236dae4SAndroid Build Coastguard Worker msnprintf(version, len, "librtmp/%d.%d%s",
359*6236dae4SAndroid Build Coastguard Worker RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
360*6236dae4SAndroid Build Coastguard Worker suff);
361*6236dae4SAndroid Build Coastguard Worker }
362*6236dae4SAndroid Build Coastguard Worker
363*6236dae4SAndroid Build Coastguard Worker #endif /* USE_LIBRTMP */
364