mirror of
https://github.com/curl/curl.git
synced 2025-01-30 14:22:33 +08:00
gopher: fix memory leak and busyloop
The fix for the busyloop really only is a temporary work-around. It causes a BLOCKING behavior which is a NO-NO. This function should rather be split up in a do and a doing piece where the pieces that aren't possible to send now will be sent in the doing function repeatedly until the entire request is sent.
This commit is contained in:
parent
67d1616018
commit
cb64c987a0
32
lib/gopher.c
32
lib/gopher.c
@ -76,6 +76,8 @@
|
|||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "gopher.h"
|
#include "gopher.h"
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
|
#include "select.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@ -122,6 +124,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
curl_off_t *bytecount = &data->req.bytecount;
|
curl_off_t *bytecount = &data->req.bytecount;
|
||||||
char *path = data->state.path;
|
char *path = data->state.path;
|
||||||
char *sel;
|
char *sel;
|
||||||
|
char *sel_org = NULL;
|
||||||
ssize_t amount, k;
|
ssize_t amount, k;
|
||||||
|
|
||||||
*done = TRUE; /* unconditionally */
|
*done = TRUE; /* unconditionally */
|
||||||
@ -139,19 +142,21 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
/* ... then turn ? into TAB for search servers, Veronica, etc. ... */
|
/* ... then turn ? into TAB for search servers, Veronica, etc. ... */
|
||||||
j = strlen(newp);
|
j = strlen(newp);
|
||||||
if (j)
|
for(i=0; i<j; i++)
|
||||||
for(i=0; i<j; i++)
|
if(newp[i] == '?')
|
||||||
newp[i] = ((newp[i] == '?') ? '\x09' : newp[i]);
|
newp[i] = '\x09';
|
||||||
|
|
||||||
/* ... and finally unescape */
|
/* ... and finally unescape */
|
||||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||||
if (!sel)
|
if (!sel)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
sel_org = sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We use Curl_write instead of Curl_sendf to make sure the entire buffer
|
/* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
|
||||||
is sent, which could be sizeable with long selectors. */
|
sent, which could be sizeable with long selectors. */
|
||||||
k = strlen(sel);
|
k = strlen(sel);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||||
if (CURLE_OK == result) { /* Which may not have written it all! */
|
if (CURLE_OK == result) { /* Which may not have written it all! */
|
||||||
@ -159,11 +164,26 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
|||||||
sel += amount;
|
sel += amount;
|
||||||
if (k < 1)
|
if (k < 1)
|
||||||
break; /* but it did write it all */
|
break; /* but it did write it all */
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
failf(data, "Failed sending Gopher request");
|
failf(data, "Failed sending Gopher request");
|
||||||
|
Curl_safefree(sel_org);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/* Don't busyloop. The entire loop thing is a work-around as it causes a
|
||||||
|
BLOCKING behavior which is a NO-NO. This function should rather be
|
||||||
|
split up in a do and a doing piece where the pieces that aren't
|
||||||
|
possible to send now will be sent in the doing function repeatedly
|
||||||
|
until the entire request is sent.
|
||||||
|
|
||||||
|
Wait a while for the socket to be writable. Note that this doesn't
|
||||||
|
acknowledge the timeout.
|
||||||
|
*/
|
||||||
|
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(sel_org);
|
||||||
|
|
||||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||||
save allocing another string/doing another _write loop. */
|
save allocing another string/doing another _write loop. */
|
||||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user