moved the SMTP payload escape function into Curl_smtp_escape_eob and put

it in smtp.c
This commit is contained in:
Daniel Stenberg 2009-12-30 22:09:43 +00:00
parent 5e6ffe353a
commit a1311e5a24
3 changed files with 68 additions and 56 deletions

View File

@ -901,4 +901,67 @@ static CURLcode smtp_setup_connection(struct connectdata * conn)
return CURLE_OK;
}
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, int nread)
{
/* When sending SMTP payload, we must detect CRLF.CRLF sequences in
* the data and make sure it is sent as CRLF..CRLF instead, as
* otherwise it will wrongly be detected as end of data by the server.
*/
int i;
int si;
struct smtp_conn *smtpc = &conn->proto.smtpc;
struct SessionHandle *data = conn->data;
if(data->state.scratch == NULL)
data->state.scratch = malloc(2*BUFSIZE);
if(data->state.scratch == NULL) {
failf (data, "Failed to alloc scratch buffer!");
return CURLE_OUT_OF_MEMORY;
}
/* This loop can be improved by some kind of Boyer-Moore style of
approach but that is saved for later... */
for(i = 0, si = 0; i < nread; i++, si++) {
int left = nread - i;
if(left>= (SMTP_EOB_LEN-smtpc->eob)) {
if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i],
SMTP_EOB_LEN-smtpc->eob)) {
/* It matched, copy the replacement data to the target buffer
instead. Note that the replacement does not contain the
trailing CRLF but we instead continue to match on that one
to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
*/
memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
SMTP_EOB_REPL_LEN);
si+=SMTP_EOB_REPL_LEN-1; /* minus one since the for() increments
it */
i+=SMTP_EOB_LEN-smtpc->eob-1-2;
smtpc->eob = 0; /* start over */
continue;
}
}
else if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i],
left)) {
/* the last piece of the data matches the EOB so we can't send that
until we know the rest of it */
smtpc->eob += left;
break;
}
data->state.scratch[si] = data->req.upload_fromhere[i];
} /* for() */
if(si != nread) {
/* only use the new buffer if we replaced something */
nread = si;
/* upload from the new (replaced) buffer instead */
data->req.upload_fromhere = data->state.scratch;
/* set the new amount too */
data->req.upload_present = nread;
}
return CURLE_OK;
}
#endif /* CURL_DISABLE_SMTP */

View File

@ -62,4 +62,6 @@ extern const struct Curl_handler Curl_handler_smtps;
#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
#define SMTP_EOB_REPL_LEN 4
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, int nread);
#endif /* __SMTP_H */

View File

@ -786,62 +786,9 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
#ifndef CURL_DISABLE_SMTP
if(conn->protocol & PROT_SMTP) {
/* When sending SMTP payload, we must detect CRLF.CRLF sequences in
* the data and make sure it is sent as CRLF..CRLF instead, as
* otherwise it will wrongly be detected as end of data by the server.
*/
struct smtp_conn *smtpc = &conn->proto.smtpc;
if(data->state.scratch == NULL)
data->state.scratch = malloc(2*BUFSIZE);
if(data->state.scratch == NULL) {
failf (data, "Failed to alloc scratch buffer!");
return CURLE_OUT_OF_MEMORY;
}
/* This loop can be improved by some kind of Boyer-Moore style of
approach but that is saved for later... */
for(i = 0, si = 0; i < nread; i++, si++) {
int left = nread - i;
if(left>= (SMTP_EOB_LEN-smtpc->eob)) {
if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i],
SMTP_EOB_LEN-smtpc->eob)) {
/* It matched, copy the replacement data to the target buffer
instead. Note that the replacement does not contain the
trailing CRLF but we instead continue to match on that one
to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
*/
memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
SMTP_EOB_REPL_LEN);
si+=SMTP_EOB_REPL_LEN-1; /* minus one since the for() increments
it */
i+=SMTP_EOB_LEN-smtpc->eob-1-2;
smtpc->eob = 0; /* start over */
continue;
}
}
else if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i],
left)) {
/* the last piece of the data matches the EOB so we can't send that
until we know the rest of it */
smtpc->eob += left;
break;
}
data->state.scratch[si] = data->req.upload_fromhere[i];
} /* for() */
if(si != nread) {
/* only use the new buffer if we replaced something */
nread = si;
/* upload from the new (replaced) buffer instead */
data->req.upload_fromhere = data->state.scratch;
/* set the new amount too */
data->req.upload_present = nread;
}
result = Curl_smtp_escape_eob(conn, nread);
if(result)
return result;
}
else
#endif /* CURL_DISABLE_SMTP */