19bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. 99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com> 109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This software is licensed as described in the file COPYING, which 129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * you should have received as part of this distribution. The terms 138f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * You may opt to use, copy, modify, merge, publish, distribute and/or sell 169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * copies of the Software, and permit persons to whom the Software is 179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * furnished to do so, under the terms of the COPYING file. 189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * KIND, either express or implied. 219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ***************************************************************************/ 239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#ifdef USE_LIBRTMP 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes#include "curl_rtmp.h" 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "urldata.h" 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "nonblock.h" /* for curlx_nonblock */ 319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "progress.h" /* for Curl_pgrsSetUploadSize */ 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "transfer.h" 33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "warnless.h" 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h> 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <librtmp/rtmp.h> 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curl_memory.h" 379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* The last #include file should be: */ 389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "memdebug.h" 399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#ifdef _WIN32 419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) 429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define SET_RCVTIMEO(tv,s) int tv = s*1000 439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#else 449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0} 459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */ 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic CURLcode rtmp_setup_connection(struct connectdata *conn); 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_do(struct connectdata *conn, bool *done); 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature); 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_connect(struct connectdata *conn, bool *done); 53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic CURLcode rtmp_disconnect(struct connectdata *conn, bool dead); 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic Curl_recv rtmp_recv; 569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic Curl_send rtmp_send; 579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 598f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmp = { 639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMP", /* scheme */ 64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 7782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMP, /* defport */ 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMP, /* protocol */ 80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmpt = { 849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMPT", /* scheme */ 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 9882be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMPT, /* defport */ 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMPT, /* protocol */ 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmpe = { 1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMPE", /* scheme */ 106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 11982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMP, /* defport */ 121e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMPE, /* protocol */ 122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmpte = { 1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMPTE", /* scheme */ 127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 14082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 1419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMPT, /* defport */ 142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMPTE, /* protocol */ 143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 1449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 1459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmps = { 1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMPS", /* scheme */ 148e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 1499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 1509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 1519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 1529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 1539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 1549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 1559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 1569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 157e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 1599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 160e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 16182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 1629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMPS, /* defport */ 163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMPS, /* protocol */ 164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 1659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 1679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsconst struct Curl_handler Curl_handler_rtmpts = { 1689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "RTMPTS", /* scheme */ 169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rtmp_setup_connection, /* setup_connection */ 1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_do, /* do_it */ 1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_done, /* done */ 1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* do_more */ 1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_connect, /* connect_it */ 1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* connecting */ 1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing */ 1769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* proto_getsock */ 1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* doing_getsock */ 178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* domore_getsock */ 1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ZERO_NULL, /* perform_getsock */ 1809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rtmp_disconnect, /* disconnect */ 181e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ZERO_NULL, /* readwrite */ 18282be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes ZERO_NULL, /* connection_check */ 1839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels PORT_RTMPS, /* defport */ 184e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLPROTO_RTMPTS, /* protocol */ 185e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROTOPT_NONE /* flags*/ 1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 1879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic CURLcode rtmp_setup_connection(struct connectdata *conn) 1899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = RTMP_Alloc(); 191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!r) 1929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OUT_OF_MEMORY; 1939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP_Init(r); 1959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP_SetBufferMS(r, DEF_BUFTIME); 196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!RTMP_SetupURL(r, conn->data->change.url)) { 1979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP_Free(r); 1989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_URL_MALFORMAT; 1999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->proto.generic = r; 2019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OK; 2029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_connect(struct connectdata *conn, bool *done) 2059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = conn->proto.generic; 207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET SET_RCVTIMEO(tv, 10); 2089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 20982be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET]; 2109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* We have to know if it's a write before we send the 2129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * connect request packet 2139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 214e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(conn->data->set.upload) 2159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels r->Link.protocol |= RTMP_FEATURE_WRITE; 2169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* For plain streams, use the buffer toggle trick to keep data flowing */ 218e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!(r->Link.lFlags & RTMP_LF_LIVE) && 219e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET !(r->Link.protocol & RTMP_FEATURE_HTTP)) 2209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels r->Link.lFlags |= RTMP_LF_BUFX; 2219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 222e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)curlx_nonblock(r->m_sb.sb_socket, FALSE); 223e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, 224e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (char *)&tv, sizeof(tv)); 2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 226e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!RTMP_Connect1(r, NULL)) 2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_FAILED_INIT; 2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* Clients must send a periodic BytesReceived report to the server */ 2309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels r->m_bSendCounter = true; 2319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *done = TRUE; 2339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->recv[FIRSTSOCKET] = rtmp_recv; 2349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->send[FIRSTSOCKET] = rtmp_send; 2359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OK; 2369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_do(struct connectdata *conn, bool *done) 2399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = conn->proto.generic; 2419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 242e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!RTMP_ConnectStream(r, 0)) 2439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_FAILED_INIT; 2449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 245e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(conn->data->set.upload) { 246e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize); 2479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); 248e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 249e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 2509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); 2519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *done = TRUE; 2529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OK; 2539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic CURLcode rtmp_done(struct connectdata *conn, CURLcode status, 2569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels bool premature) 2579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)conn; /* unused */ 2599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)status; /* unused */ 2609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)premature; /* unused */ 2619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OK; 2639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 265e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic CURLcode rtmp_disconnect(struct connectdata *conn, 266e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool dead_connection) 2679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = conn->proto.generic; 269e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)dead_connection; 270e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(r) { 2719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->proto.generic = NULL; 2729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP_Close(r); 2739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP_Free(r); 2749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return CURLE_OK; 2769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf, 2799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t len, CURLcode *err) 2809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = conn->proto.generic; 2829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ssize_t nread; 2839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)sockindex; /* unused */ 2859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 286e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nread = RTMP_Read(r, buf, curlx_uztosi(len)); 287e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(nread < 0) { 288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(r->m_read.status == RTMP_READ_COMPLETE || 2899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels r->m_read.status == RTMP_READ_EOF) { 2909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->data->req.size = conn->data->req.bytecount; 2919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels nread = 0; 292e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 293e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 2949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *err = CURLE_RECV_ERROR; 2959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return nread; 2979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic ssize_t rtmp_send(struct connectdata *conn, int sockindex, 3009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels const void *buf, size_t len, CURLcode *err) 3019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 3029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels RTMP *r = conn->proto.generic; 3039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ssize_t num; 3049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)sockindex; /* unused */ 3069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 307e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET num = RTMP_Write(r, (char *)buf, curlx_uztosi(len)); 308e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(num < 0) 3099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *err = CURLE_SEND_ERROR; 310e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 3119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return num; 3129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 3139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif /* USE_LIBRTMP */ 314