aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-02-16 14:31:23 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-02-16 14:31:23 +0000
commitac022b2e30f42f860f365348ee569f87d0fbe1cf (patch)
treeb7f616cd8189ef4af0d9abff8812efe0595baeb8 /lib
parentf169b750b8bf231df6df776343acbd3e3979ada5 (diff)
Christopher R. Palmer reported a problem with HTTP-POSTing using "anyauth"
that picks NTLM. Thanks to David Byron letting me test NTLM against his servers, I could quickly repeat and fix the problem. It turned out to be: When libcurl POSTs without knowing/using an authentication and it gets back a list of types from which it picks NTLM, it needs to either continue sending its data if it keeps the connection alive, or not send the data but close the connection. Then do the first step in the NTLM auth. libcurl didn't send the data nor close the connection but simply read the response-body and then sent the first negotiation step. Which then failed miserably of course. The fixed version forces a connection if there is more than 2000 bytes left to send.
Diffstat (limited to 'lib')
-rw-r--r--lib/http.c39
-rw-r--r--lib/transfer.c7
2 files changed, 32 insertions, 14 deletions
diff --git a/lib/http.c b/lib/http.c
index 706cf7e30..a5f29da3b 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -251,21 +251,31 @@ static CURLcode perhapsrewind(struct connectdata *conn)
if((expectsend == -1) || (expectsend > bytessent)) {
/* There is still data left to send */
- if((data->state.authproxy.picked == CURLAUTH_NTLM) ||/* using NTLM */
- (data->state.authhost.picked == CURLAUTH_NTLM) ) {
- conn->bits.close = FALSE; /* don't close, keep on sending */
+ if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+ (data->state.authhost.picked == CURLAUTH_NTLM)) {
+ if(((expectsend - bytessent) < 2000) ||
+ (conn->ntlm.state != NTLMSTATE_NONE)) {
+ /* The NTLM-negotiation has started *OR* there is just a little (<2K)
+ data left to send, keep on sending. */
+
+ /* rewind data when completely done sending! */
+ if(!conn->bits.authneg)
+ conn->bits.rewindaftersend = TRUE;
+
+ return CURLE_OK;
+ }
+ if(conn->bits.close)
+ /* this is already marked to get closed */
+ return CURLE_OK;
- /* rewind data when completely done sending! */
- conn->bits.rewindaftersend = TRUE;
- return CURLE_OK;
- }
- else {
- /* If there is more than just a little data left to send, close the
- * current connection by force.
- */
- conn->bits.close = TRUE;
- conn->size = 0; /* don't download any more than 0 bytes */
+ infof(data, "NTLM send, close instead of sending %ld bytes\n",
+ expectsend - bytessent);
}
+
+ /* This is not NTLM or NTLM with many bytes left to send: close
+ */
+ conn->bits.close = TRUE;
+ conn->size = 0; /* don't download any more than 0 bytes */
}
if(bytessent)
@@ -310,7 +320,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
conn->newurl = strdup(data->change.url); /* clone URL */
if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD)) {
+ (data->set.httpreq != HTTPREQ_HEAD) &&
+ !conn->bits.rewindaftersend) {
code = perhapsrewind(conn);
if(code)
return code;
diff --git a/lib/transfer.c b/lib/transfer.c
index 97a085d54..7142d517b 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -541,6 +541,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(result)
return result;
+
+ if(conn->bits.rewindaftersend) {
+ /* We rewind after a complete send, so thus we continue
+ sending now */
+ infof(data, "Keep sending data to get tossed away!\n");
+ k->keepon |= KEEP_WRITE;
+ }
}
#endif /* CURL_DISABLE_HTTP */