mirror of
https://github.com/curl/curl.git
synced 2026-08-06 13:26:14 +03:00
ftp: do lineend conversions in client writer
- remove the ftp special handling from sendf.c - let ftp_do() add a client writer that does the linened conversions - change the lineend conversion to no longer modify the passed buffer, but write smaller chunks to the next cwriter instead. The inefficiency of this will be mitigated once we add output buffering for all client writes. Closes #12878
This commit is contained in:
parent
6984aa3a45
commit
e7fd32b9ac
3 changed files with 110 additions and 97 deletions
95
lib/sendf.c
95
lib/sendf.c
|
|
@ -61,88 +61,6 @@
|
|||
|
||||
static CURLcode do_init_stack(struct Curl_easy *data);
|
||||
|
||||
#if defined(CURL_DO_LINEEND_CONV) && !defined(CURL_DISABLE_FTP)
|
||||
/*
|
||||
* convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
|
||||
* (\n), with special processing for CRLF sequences that are split between two
|
||||
* blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
|
||||
* size of the data is returned.
|
||||
*/
|
||||
static size_t convert_lineends(struct Curl_easy *data,
|
||||
char *startPtr, size_t size)
|
||||
{
|
||||
char *inPtr, *outPtr;
|
||||
|
||||
/* sanity check */
|
||||
if(!startPtr || (size < 1)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if(data->state.prev_block_had_trailing_cr) {
|
||||
/* The previous block of incoming data
|
||||
had a trailing CR, which was turned into a LF. */
|
||||
if(*startPtr == '\n') {
|
||||
/* This block of incoming data starts with the
|
||||
previous block's LF so get rid of it */
|
||||
memmove(startPtr, startPtr + 1, size-1);
|
||||
size--;
|
||||
/* and it wasn't a bare CR but a CRLF conversion instead */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
|
||||
}
|
||||
|
||||
/* find 1st CR, if any */
|
||||
inPtr = outPtr = memchr(startPtr, '\r', size);
|
||||
if(inPtr) {
|
||||
/* at least one CR, now look for CRLF */
|
||||
while(inPtr < (startPtr + size-1)) {
|
||||
/* note that it's size-1, so we'll never look past the last byte */
|
||||
if(memcmp(inPtr, "\r\n", 2) == 0) {
|
||||
/* CRLF found, bump past the CR and copy the NL */
|
||||
inPtr++;
|
||||
*outPtr = *inPtr;
|
||||
/* keep track of how many CRLFs we converted */
|
||||
data->state.crlf_conversions++;
|
||||
}
|
||||
else {
|
||||
if(*inPtr == '\r') {
|
||||
/* lone CR, move LF instead */
|
||||
*outPtr = '\n';
|
||||
}
|
||||
else {
|
||||
/* not a CRLF nor a CR, just copy whatever it is */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
}
|
||||
outPtr++;
|
||||
inPtr++;
|
||||
} /* end of while loop */
|
||||
|
||||
if(inPtr < startPtr + size) {
|
||||
/* handle last byte */
|
||||
if(*inPtr == '\r') {
|
||||
/* deal with a CR at the end of the buffer */
|
||||
*outPtr = '\n'; /* copy a NL instead */
|
||||
/* note that a CRLF might be split across two blocks */
|
||||
data->state.prev_block_had_trailing_cr = TRUE;
|
||||
}
|
||||
else {
|
||||
/* copy last byte */
|
||||
*outPtr = *inPtr;
|
||||
}
|
||||
outPtr++;
|
||||
}
|
||||
if(outPtr < startPtr + size)
|
||||
/* tidy up by null terminating the now shorter data */
|
||||
*outPtr = '\0';
|
||||
|
||||
return (outPtr - startPtr);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
#endif /* CURL_DO_LINEEND_CONV && !CURL_DISABLE_FTP */
|
||||
|
||||
/*
|
||||
* Curl_nwrite() is an internal write function that sends data to the
|
||||
* server. Works with a socket index for the connection.
|
||||
|
|
@ -376,25 +294,12 @@ static CURLcode chop_write(struct Curl_easy *data,
|
|||
|
||||
The bit pattern defines to what "streams" to write to. Body and/or header.
|
||||
The defines are in sendf.h of course.
|
||||
|
||||
If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
|
||||
local character encoding. This is a problem and should be changed in
|
||||
the future to leave the original data alone.
|
||||
*/
|
||||
CURLcode Curl_client_write(struct Curl_easy *data,
|
||||
int type, char *buf, size_t blen)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
#if !defined(CURL_DISABLE_FTP) && defined(CURL_DO_LINEEND_CONV)
|
||||
/* FTP data may need conversion. */
|
||||
if((type & CLIENTWRITE_BODY) &&
|
||||
(data->conn->handler->protocol & PROTO_FAMILY_FTP) &&
|
||||
data->conn->proto.ftpc.transfertype == 'A') {
|
||||
/* convert end-of-line markers */
|
||||
blen = convert_lineends(data, buf, blen);
|
||||
}
|
||||
#endif
|
||||
/* it is one of those, at least */
|
||||
DEBUGASSERT(type & (CLIENTWRITE_BODY|CLIENTWRITE_HEADER|CLIENTWRITE_INFO));
|
||||
/* BODY is only BODY (with optional EOS) */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue