- Igor Novoseltsev filed bug #2351645
(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with the multi interface that occured if you removed an easy handle while in progress and the handle was used in a HTTP pipeline.
This commit is contained in:
Родитель
4ee27b4594
Коммит
479ddb1fee
7
CHANGES
7
CHANGES
|
@ -6,7 +6,12 @@
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
Daniel Fandrich (3 Dec 2008)
|
Daniel Stenberg (3 Dec 2008)
|
||||||
|
- Igor Novoseltsev filed bug #2351645
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with
|
||||||
|
the multi interface that occured if you removed an easy handle while in
|
||||||
|
progress and the handle was used in a HTTP pipeline.
|
||||||
|
|
||||||
- Pawel Kierski pointed out a mistake in the cookie code that could lead to a
|
- Pawel Kierski pointed out a mistake in the cookie code that could lead to a
|
||||||
bad fclose() after a fatal error had occured.
|
bad fclose() after a fatal error had occured.
|
||||||
(http://curl.haxx.se/bug/view.cgi?id=2382219)
|
(http://curl.haxx.se/bug/view.cgi?id=2382219)
|
||||||
|
|
|
@ -23,6 +23,7 @@ This release includes the following bugfixes:
|
||||||
o removed the default use of "Pragma: no-cache"
|
o removed the default use of "Pragma: no-cache"
|
||||||
o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
|
o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
|
||||||
o bad fclose() after a fatal error in cookie code
|
o bad fclose() after a fatal error in cookie code
|
||||||
|
o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
|
@ -32,6 +33,6 @@ This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
|
Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
|
||||||
Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski
|
Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski, Igor Novoseltsev
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
|
31
lib/multi.c
31
lib/multi.c
|
@ -620,22 +620,27 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||||
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
|
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we must call Curl_done() here (if we still "own it") so that we don't
|
if(easy->easy_conn) {
|
||||||
leave a half-baked one around */
|
|
||||||
if(easy->easy_conn &&
|
|
||||||
(easy->easy_conn->data == easy->easy_handle)) {
|
|
||||||
|
|
||||||
/* Curl_done() clears the conn->data field to lose the association
|
/* we must call Curl_done() here (if we still "own it") so that we don't
|
||||||
between the easy handle and the connection
|
leave a half-baked one around */
|
||||||
|
if (easy->easy_conn->data == easy->easy_handle) {
|
||||||
|
|
||||||
Note that this ignores the return code simply because there's nothing
|
/* Curl_done() clears the conn->data field to lose the association
|
||||||
really useful to do with it anyway! */
|
between the easy handle and the connection
|
||||||
(void)Curl_done(&easy->easy_conn, easy->result, premature);
|
|
||||||
|
|
||||||
if(easy->easy_conn)
|
Note that this ignores the return code simply because there's
|
||||||
/* the connection is still alive, set back the association to enable
|
nothing really useful to do with it anyway! */
|
||||||
the check below to trigger TRUE */
|
(void)Curl_done(&easy->easy_conn, easy->result, premature);
|
||||||
easy->easy_conn->data = easy->easy_handle;
|
|
||||||
|
if(easy->easy_conn)
|
||||||
|
/* the connection is still alive, set back the association to enable
|
||||||
|
the check below to trigger TRUE */
|
||||||
|
easy->easy_conn->data = easy->easy_handle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Clear connection pipelines, if Curl_done above was not called */
|
||||||
|
Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this easy_handle was the last one in charge for one or more
|
/* If this easy_handle was the last one in charge for one or more
|
||||||
|
|
22
lib/url.c
22
lib/url.c
|
@ -2359,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove the specified connection from all (possible) pipelines and related
|
||||||
|
queues */
|
||||||
|
void Curl_getoff_all_pipelines(struct SessionHandle *data,
|
||||||
|
struct connectdata *conn)
|
||||||
|
{
|
||||||
|
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
|
||||||
|
conn->readchannel_inuse)
|
||||||
|
conn->readchannel_inuse = FALSE;
|
||||||
|
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
|
||||||
|
conn->writechannel_inuse)
|
||||||
|
conn->writechannel_inuse = FALSE;
|
||||||
|
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* this code is saved here as it is useful for debugging purposes */
|
#if 0 /* this code is saved here as it is useful for debugging purposes */
|
||||||
static void Curl_printPipeline(struct curl_llist *pipeline)
|
static void Curl_printPipeline(struct curl_llist *pipeline)
|
||||||
{
|
{
|
||||||
|
@ -4548,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp,
|
||||||
|
|
||||||
Curl_expire(data, 0); /* stop timer */
|
Curl_expire(data, 0); /* stop timer */
|
||||||
|
|
||||||
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
|
Curl_getoff_all_pipelines(data, conn);
|
||||||
conn->readchannel_inuse)
|
|
||||||
conn->readchannel_inuse = FALSE;
|
|
||||||
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
|
|
||||||
conn->writechannel_inuse)
|
|
||||||
conn->writechannel_inuse = FALSE;
|
|
||||||
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
|
|
||||||
|
|
||||||
if(conn->bits.done ||
|
if(conn->bits.done ||
|
||||||
(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||||
|
|
|
@ -69,6 +69,10 @@ CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
|
||||||
struct curl_llist *pipeline);
|
struct curl_llist *pipeline);
|
||||||
int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
|
int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
|
||||||
struct curl_llist *pipeline);
|
struct curl_llist *pipeline);
|
||||||
|
/* remove the specified connection from all (possible) pipelines and related
|
||||||
|
queues */
|
||||||
|
void Curl_getoff_all_pipelines(struct SessionHandle *data,
|
||||||
|
struct connectdata *conn);
|
||||||
|
|
||||||
void Curl_close_connections(struct SessionHandle *data);
|
void Curl_close_connections(struct SessionHandle *data);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче