different connections. (Added in 7.20.0)
.IP CURL_RTSPREQ_GET_PARAMETER
Retrieve a parameter from the server. By default, libcurl will automatically
-include an \fIAccept: text/parameters\fP header unless a custom one is set.
+include a \fIContent-Type: text/parameters\fP header on all non-empty requests
+unless a custom one is set. GET_PARAMETER acts just like an HTTP PUT or POST
+(see \fICURL_RTSPREQ_SET_PARAMETER\fP).
Applications wishing to send a heartbeat message (e.g. in the presence of a
server-specified timeout) should send use an empty GET_PARAMETER request.
(Added in 7.20.0)
p_request = "TEARDOWN";
break;
case RTSPREQ_GET_PARAMETER:
+ /* GET_PARAMETER's no_body status is determined later */
p_request = "GET_PARAMETER";
- data->set.opt_no_body = FALSE;
break;
case RTSPREQ_SET_PARAMETER:
p_request = "SET_PARAMETER";
}
}
- /* Default to text/parameters for GET_PARAMETER */
- if(rtspreq == RTSPREQ_GET_PARAMETER) {
- p_accept = Curl_checkheaders(data, "Accept:")?
- NULL:"Accept: text/parameters\r\n";
- }
-
/* The User-Agent string might have been allocated in url.c already, because
it might have been used in the proxy connect, but if we have got a header
with the user-agent string specified, we erase the previously made string
if(result)
return result;
- if(rtspreq == RTSPREQ_ANNOUNCE || rtspreq == RTSPREQ_SET_PARAMETER) {
+ if(rtspreq == RTSPREQ_ANNOUNCE ||
+ rtspreq == RTSPREQ_SET_PARAMETER ||
+ rtspreq == RTSPREQ_GET_PARAMETER) {
+
if(data->set.upload) {
putsize = data->set.infilesize;
data->set.httpreq = HTTPREQ_PUT;
data->set.httpreq = HTTPREQ_POST;
}
- /* As stated in the http comments, it is probably not wise to
- * actually set a custom Content-Length in the headers */
- if(!Curl_checkheaders(data, "Content-Length:")) {
- result = Curl_add_bufferf(req_buffer,
- "Content-Length: %" FORMAT_OFF_T"\r\n",
- (data->set.upload ? putsize : postsize));
- if(result)
- return result;
- }
-
- if(rtspreq == RTSPREQ_SET_PARAMETER) {
- if(!Curl_checkheaders(data, "Content-Type:")) {
+ if(putsize > 0 || postsize > 0) {
+ /* As stated in the http comments, it is probably not wise to
+ * actually set a custom Content-Length in the headers */
+ if(!Curl_checkheaders(data, "Content-Length:")) {
result = Curl_add_bufferf(req_buffer,
- "Content-Type: text/parameters\r\n");
+ "Content-Length: %" FORMAT_OFF_T"\r\n",
+ (data->set.upload ? putsize : postsize));
if(result)
return result;
}
- }
- if(rtspreq == RTSPREQ_ANNOUNCE) {
- if(!Curl_checkheaders(data, "Content-Type:")) {
- result = Curl_add_bufferf(req_buffer,
- "Content-Type: application/sdp\r\n");
- if(result)
- return result;
+ if(rtspreq == RTSPREQ_SET_PARAMETER ||
+ rtspreq == RTSPREQ_GET_PARAMETER) {
+ if(!Curl_checkheaders(data, "Content-Type:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Type: text/parameters\r\n");
+ if(result)
+ return result;
+ }
+ }
+
+ if(rtspreq == RTSPREQ_ANNOUNCE) {
+ if(!Curl_checkheaders(data, "Content-Type:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Type: application/sdp\r\n");
+ if(result)
+ return result;
+ }
}
- }
data->state.expect100header = FALSE; /* RTSP posts are simple/small */
+ } else if(rtspreq == RTSPREQ_GET_PARAMETER) {
+ /* Check for an empty GET_PARAMETER (heartbeat) request */
+ data->set.httpreq = HTTPREQ_HEAD;
+ data->set.opt_no_body = TRUE;
+ }
}
-
/* RTSP never allows chunked transfer */
data->req.forbidchunk = TRUE;
/* Finish the request buffer */
test564 test1101 test1102 test1103 test1104 test299 test310 test311 \
test312 test1105 test565 test800 test1106 test801 test566 test802 test803 \
test1107 test1108 test1109 test1110 test1111 test1112 test129 test567 \
- test568 test569 test570 test571 test804
+ test568 test569 test570 test571 test804 test572
filecheck:
@mkdir test-place; \
--- /dev/null
+<testcase>
+
+#Informational
+<info>
+<keywords>
+RTSP
+GET_PARAMETER
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data1>
+RTSP/1.0 200 OK
+Server: RTSPD/libcurl-test
+Session: getparams-test
+CSeq: 1
+
+</data1>
+
+<data2>
+RTSP/1.0 200 OK
+Server: RTSPD/libcurl-test
+Session: getparams-test
+Content-Type: text/parameters
+Content-Length: 32
+Cseq: 2
+
+scale=enormous
+speed=ludicrous
+</data2>
+
+<data3>
+RTSP/1.0 200 OK
+Server: RTSPD/libcurl-test
+Session: getparams-test
+Cseq: 3
+
+</data3>
+
+<data4>
+RTSP/1.0 200 Okie Dokie
+Server: RTSPD/libcurl-test
+Session: getparams-test
+Cseq: 4
+Content-Length: 37
+
+packets_received: 1000
+jitter: 0.314
+</data4>
+<data5>
+RTSP/1.0 200 OK
+Server: RTSPD/libcurl-test
+Session: getparams-test
+CSeq: 5
+Curl-private: swsclose
+Informational: Empty Options Response
+
+</data5>
+</reply>
+
+# Client-Side
+<client>
+<server>
+rtsp
+</server>
+<tool>
+lib572
+</tool>
+
+<name>
+RTSP GET_PARAMETER (Put/Heartbeat/Post)
+</name>
+<command>
+rtsp://%HOSTIP:%RTSPPORT/572
+</command>
+# file written before test command runs
+<file name="log/file572.txt">
+scale
+speed
+</file>
+</client>
+
+<verify>
+<strip>
+^If-Modified-Since:.*
+</strip>
+<protocol>
+SETUP rtsp://%HOSTIP:%RTSPPORT/5720001 RTSP/1.0\r
+CSeq: 1\r
+Transport: Planes/Trains/Automobiles\r
+\r
+GET_PARAMETER rtsp://%HOSTIP:%RTSPPORT/5720002 RTSP/1.0\r
+CSeq: 2\r
+Session: getparams-test\r
+Content-Length: 12\r
+Content-Type: text/parameters\r
+\r
+scale
+speed
+GET_PARAMETER rtsp://%HOSTIP:%RTSPPORT/5720003 RTSP/1.0\r
+CSeq: 3\r
+Session: getparams-test\r
+\r
+GET_PARAMETER rtsp://%HOSTIP:%RTSPPORT/5720004 RTSP/1.0\r
+CSeq: 4\r
+Session: getparams-test\r
+Content-Length: 24\r
+Content-Type: text/parameters\r
+\r
+packets_received
+jitter
+OPTIONS rtsp://%HOSTIP:%RTSPPORT/5720005 RTSP/1.0\r
+CSeq: 5\r
+Session: getparams-test\r
+\r
+</protocol>
+</verify>
+
+</testcase>
+
lib529 lib530 lib532 lib533 lib536 lib537 lib540 lib541 lib542 lib543 \
lib544 lib545 lib547 lib548 lib549 lib552 lib553 lib554 lib555 lib556 \
lib539 lib557 lib558 lib559 lib560 lib562 lib564 lib565 lib566 lib567 \
- lib568 lib569 lib570 lib571
+ lib568 lib569 lib570 lib571 lib572
lib500_SOURCES = lib500.c $(SUPPORTFILES)
lib571_SOURCES = lib571.c $(SUPPORTFILES)
+lib572_SOURCES = lib572.c $(SUPPORTFILES)
+
--- /dev/null
+
+/*****************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * $Id$
+ */
+
+#include "test.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <curl/mprintf.h>
+
+#include "memdebug.h"
+
+/* build request url */
+static char *suburl(const char *base, int i)
+{
+ return curl_maprintf("%s%.4d", base, i);
+}
+
+/*
+ * Test GET_PARAMETER: PUT, HEARTBEAT, and POST
+ */
+int test(char *URL)
+{
+ int res;
+ CURL *curl;
+ int params;
+ FILE *paramsf = NULL;
+ struct_stat file_info;
+ char *stream_uri = NULL;
+ int request=1;
+ struct curl_slist *custom_headers=NULL;
+
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if ((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+
+ test_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ test_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* SETUP */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "Planes/Trains/Automobiles");
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+ res = curl_easy_perform(curl);
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+ if(res)
+ goto test_cleanup;
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+
+ /* PUT style GET_PARAMETERS */
+ params = open("log/file572.txt", O_RDONLY);
+ fstat(params, &file_info);
+ close(params);
+
+ paramsf = fopen("log/file572.txt", "rb");
+ if(paramsf == NULL) {
+ fprintf(stderr, "can't open log/file572.txt\n");
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER);
+
+ test_setopt(curl, CURLOPT_READDATA, paramsf);
+ test_setopt(curl, CURLOPT_UPLOAD, 1L);
+ test_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) file_info.st_size);
+
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_UPLOAD, 0L);
+ fclose(paramsf);
+ paramsf = NULL;
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+
+ /* Heartbeat GET_PARAMETERS */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ fprintf(stderr, "CPC: %s:%d\n", __FILE__, __LINE__);
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ /* POST GET_PARAMETERS */
+
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER);
+ test_setopt(curl, CURLOPT_POSTFIELDS, "packets_received\njitter\n");
+
+ res = curl_easy_perform(curl);
+ if(res)
+ goto test_cleanup;
+
+ test_setopt(curl, CURLOPT_POSTFIELDS, NULL);
+
+ /* Make sure we can do a normal request now */
+ if((stream_uri = suburl(URL, request++)) == NULL) {
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri);
+ free(stream_uri);
+ stream_uri = NULL;
+
+ test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ if(paramsf)
+ fclose(paramsf);
+
+ if(stream_uri)
+ free(stream_uri);
+
+ if(custom_headers)
+ curl_slist_free_all(custom_headers);
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return res;
+}
+