1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

pop3: Added support for additional pop3 commands

This feature allows the user to specify and use additional POP3
commands such as UIDL and DELE via libcurl's CURLOPT_CUSTOMREQUEST or
curl's -X command line option.
This commit is contained in:
Steve Holme 2012-03-31 18:46:22 +01:00
parent 66c0e26e28
commit 761c3c5446
2 changed files with 37 additions and 5 deletions

View File

@ -89,6 +89,7 @@
/* Local API functions */ /* Local API functions */
static CURLcode pop3_parse_url_path(struct connectdata *conn); static CURLcode pop3_parse_url_path(struct connectdata *conn);
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done); static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
static CURLcode pop3_do(struct connectdata *conn, bool *done); static CURLcode pop3_do(struct connectdata *conn, bool *done);
static CURLcode pop3_done(struct connectdata *conn, static CURLcode pop3_done(struct connectdata *conn,
@ -502,10 +503,14 @@ static CURLcode pop3_list(struct connectdata *conn)
struct FTP *pop3 = conn->data->state.proto.pop3; struct FTP *pop3 = conn->data->state.proto.pop3;
pop3->transfer = FTPTRANSFER_INFO; pop3->transfer = FTPTRANSFER_INFO;
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "LIST %s", pop3c->mailbox); result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
(pop3c->custom && pop3c->custom[0] != '\0' ?
pop3c->custom : "LIST"), pop3c->mailbox);
} }
else else
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "LIST"); result = Curl_pp_sendf(&conn->proto.pop3c.pp,
(pop3c->custom && pop3c->custom[0] != '\0' ?
pop3c->custom : "LIST"));
if(result) if(result)
return result; return result;
@ -521,7 +526,9 @@ static CURLcode pop3_retr(struct connectdata *conn)
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c; struct pop3_conn *pop3c = &conn->proto.pop3c;
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "RETR %s", pop3c->mailbox); result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
(pop3c->custom && pop3c->custom[0] != '\0' ?
pop3c->custom : "RETR"), pop3c->mailbox);
if(result) if(result)
return result; return result;
@ -730,7 +737,9 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
result = status; /* use the already set error code */ result = status; /* use the already set error code */
} }
/* Clear our variables for the next connection */
Curl_safefree(pop3c->mailbox); Curl_safefree(pop3c->mailbox);
Curl_safefree(pop3c->custom);
/* Clear the transfer mode for the next connection */ /* Clear the transfer mode for the next connection */
pop3->transfer = FTPTRANSFER_BODY; pop3->transfer = FTPTRANSFER_BODY;
@ -817,10 +826,16 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
if(retcode) if(retcode)
return retcode; return retcode;
/* Parse the URL path */
retcode = pop3_parse_url_path(conn); retcode = pop3_parse_url_path(conn);
if(retcode) if(retcode)
return retcode; return retcode;
/* Parse the custom request */
retcode = pop3_parse_custom_request(conn);
if(retcode)
return retcode;
retcode = pop3_regular_transfer(conn, done); retcode = pop3_regular_transfer(conn, done);
return retcode; return retcode;
@ -890,15 +905,30 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
const char *path = data->state.path; const char *path = data->state.path;
/* url decode the path and use this mailbox */ /* URL decode the path and use this mailbox */
return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE); return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE);
} }
static CURLcode pop3_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
struct SessionHandle *data = conn->data;
const char *custom = conn->data->set.str[STRING_CUSTOMREQUEST];
/* URL decode the custom request */
if(custom)
result = Curl_urldecode(data, custom, 0, &pop3c->custom, NULL, TRUE);
return result;
}
/* call this when the DO phase has completed */ /* call this when the DO phase has completed */
static CURLcode pop3_dophase_done(struct connectdata *conn, static CURLcode pop3_dophase_done(struct connectdata *conn,
bool connected) bool connected)
{ {
struct FTP *pop3 = conn->data->state.proto.pop3; struct FTP *pop3 = conn->data->state.proto.pop3;
(void)connected; (void)connected;
if(pop3->transfer != FTPTRANSFER_BODY) if(pop3->transfer != FTPTRANSFER_BODY)
@ -983,6 +1013,7 @@ static CURLcode pop3_setup_connection(struct connectdata * conn)
return CURLE_UNSUPPORTED_PROTOCOL; return CURLE_UNSUPPORTED_PROTOCOL;
#endif #endif
} }
/* /*
* We explicitly mark this connection as persistent here as we're doing * We explicitly mark this connection as persistent here as we're doing
* POP3 over HTTP and thus we accidentally avoid setting this value * POP3 over HTTP and thus we accidentally avoid setting this value

View File

@ -42,7 +42,8 @@ typedef enum {
struct */ struct */
struct pop3_conn { struct pop3_conn {
struct pingpong pp; struct pingpong pp;
char *mailbox; /* what to RETR */ char *mailbox; /* message id */
char *custom; /* custom request */
size_t eob; /* number of bytes of the EOB (End Of Body) that has been size_t eob; /* number of bytes of the EOB (End Of Body) that has been
received thus far */ received thus far */
size_t strip; /* number of bytes from the start to ignore as non-body */ size_t strip; /* number of bytes from the start to ignore as non-body */