mirror of
https://github.com/curl/curl.git
synced 2026-08-26 02:43:31 +03:00
lib: Curl_read/Curl_write clarifications
- replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to
clarify when and at what level they operate
- send/recv of transfer related data is now done via
`Curl_xfer_send()/Curl_xfer_recv()` which no longer has
socket/socketindex as parameter. It decides on the transfer
setup of `conn->sockfd` and `conn->writesockfd` on which
connection filter chain to operate.
- send/recv on a specific connection filter chain is done via
`Curl_conn_send()/Curl_conn_recv()` which get the socket index
as parameter.
- rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for
naming consistency
- clarify that the special CURLE_AGAIN hangling to return
`CURLE_OK` with length 0 only applies to `Curl_xfer_send()`
and CURLE_AGAIN is returned by all other send() variants.
- fix a bug in websocket `curl_ws_recv()` that mixed up data
when it arrived in more than a single chunk (to be made
into a sperate PR, also)
Added as documented [in
CLIENT-READER.md](5b1f31dfba/docs/CLIENT-READERS.md).
- old `Curl_buffer_send()` completely replaced by new `Curl_req_send()`
- old `Curl_fillreadbuffer()` replaced with `Curl_client_read()`
- HTTP chunked uploads are now formatted in a client reader added when
needed.
- FTP line-end conversions are done in a client reader added when
needed.
- when sending requests headers, remaining buffer space is filled with
body data for sending in "one go". This is independent of the request
body size. Resolves #12938 as now small and large requests have the
same code path.
Changes done to test cases:
- test513: now fails before sending request headers as this initial
"client read" triggers the setup fault. Behaves now the same as in
hyper build
- test547, test555, test1620: fix the length check in the lib code to
only fail for reads *smaller* than expected. This was a bug in the
test code that never triggered in the old implementation.
Closes #12969
This commit is contained in:
parent
8d67c61c47
commit
9369c30cd8
26 changed files with 1191 additions and 1021 deletions
83
lib/rtsp.c
83
lib/rtsp.c
|
|
@ -241,6 +241,8 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
const char *p_userpwd = NULL;
|
||||
|
||||
*done = TRUE;
|
||||
/* Initialize a dynamic send buffer */
|
||||
Curl_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER);
|
||||
|
||||
rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
|
||||
rtsp->CSeq_recv = 0;
|
||||
|
|
@ -311,8 +313,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
|
||||
if(rtspreq == RTSPREQ_RECEIVE) {
|
||||
Curl_xfer_setup(data, FIRSTSOCKET, -1, TRUE, -1);
|
||||
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p_session_id = data->set.str[STRING_RTSP_SESSION_ID];
|
||||
|
|
@ -320,7 +321,8 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
(rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
|
||||
failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
|
||||
p_request);
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Stream URI. Default to server '*' if not specified */
|
||||
|
|
@ -347,7 +349,8 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
else {
|
||||
failf(data,
|
||||
"Refusing to issue an RTSP SETUP without a Transport: header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p_transport = data->state.aptr.rtsp_transport;
|
||||
|
|
@ -366,9 +369,10 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
data->state.aptr.accept_encoding =
|
||||
aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
|
||||
|
||||
if(!data->state.aptr.accept_encoding)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!data->state.aptr.accept_encoding) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
p_accept_encoding = data->state.aptr.accept_encoding;
|
||||
}
|
||||
}
|
||||
|
|
@ -390,7 +394,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
result = Curl_http_output_auth(data, conn, p_request, HTTPREQ_GET,
|
||||
p_stream_uri, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
|
||||
p_proxyuserpwd = data->state.aptr.proxyuserpwd;
|
||||
p_userpwd = data->state.aptr.userpwd;
|
||||
|
|
@ -424,23 +428,22 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
*/
|
||||
if(Curl_checkheaders(data, STRCONST("CSeq"))) {
|
||||
failf(data, "CSeq cannot be set as a custom header.");
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
result = CURLE_RTSP_CSEQ_ERROR;
|
||||
goto out;
|
||||
}
|
||||
if(Curl_checkheaders(data, STRCONST("Session"))) {
|
||||
failf(data, "Session ID cannot be set as a custom header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Initialize a dynamic send buffer */
|
||||
Curl_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER);
|
||||
|
||||
result =
|
||||
Curl_dyn_addf(&req_buffer,
|
||||
"%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
|
||||
"CSeq: %ld\r\n", /* CSeq */
|
||||
p_request, p_stream_uri, rtsp->CSeq_sent);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Rather than do a normal alloc line, keep the session_id unformatted
|
||||
|
|
@ -449,7 +452,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
if(p_session_id) {
|
||||
result = Curl_dyn_addf(&req_buffer, "Session: %s\r\n", p_session_id);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -481,17 +484,17 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
Curl_safefree(data->state.aptr.userpwd);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
|
||||
if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
|
||||
result = Curl_add_timecondition(data, &req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(data, FALSE, &req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE ||
|
||||
rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
|
|
@ -500,13 +503,24 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
if(data->state.upload) {
|
||||
putsize = data->state.infilesize;
|
||||
data->state.httpreq = HTTPREQ_PUT;
|
||||
|
||||
result = Client_reader_set_fread(data, putsize);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
postsize = (data->state.infilesize != -1)?
|
||||
data->state.infilesize:
|
||||
(data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
|
||||
data->state.httpreq = HTTPREQ_POST;
|
||||
if(postsize > 0 && data->set.postfields)
|
||||
result = Client_reader_set_buf(data, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
else if(!postsize)
|
||||
result = Client_reader_set_null(data);
|
||||
else
|
||||
result = Client_reader_set_fread(data, postsize);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(putsize > 0 || postsize > 0) {
|
||||
|
|
@ -518,7 +532,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||
(data->state.upload ? putsize : postsize));
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
|
|
@ -528,7 +542,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
STRCONST("Content-Type: "
|
||||
"text/parameters\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -538,7 +552,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
STRCONST("Content-Type: "
|
||||
"application/sdp\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,31 +564,27 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
data->req.no_body = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = Client_reader_set_null(data);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* RTSP never allows chunked transfer */
|
||||
data->req.forbidchunk = TRUE;
|
||||
/* Finish the request buffer */
|
||||
result = Curl_dyn_addn(&req_buffer, STRCONST("\r\n"));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(postsize > 0) {
|
||||
result = Curl_dyn_addn(&req_buffer, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
goto out;
|
||||
|
||||
/* issue the request */
|
||||
result = Curl_req_send_hds(data, Curl_dyn_ptr(&req_buffer),
|
||||
Curl_dyn_len(&req_buffer));
|
||||
Curl_dyn_free(&req_buffer);
|
||||
result = Curl_req_send(data, &req_buffer);
|
||||
if(result) {
|
||||
failf(data, "Failed sending RTSP request");
|
||||
return result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Curl_xfer_setup(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1);
|
||||
Curl_xfer_setup(data, FIRSTSOCKET, -1, TRUE, FIRSTSOCKET);
|
||||
|
||||
/* Increment the CSeq on success */
|
||||
data->state.rtsp_next_client_CSeq++;
|
||||
|
|
@ -586,7 +596,8 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
if(Curl_pgrsUpdate(data))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
out:
|
||||
Curl_dyn_free(&req_buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue