1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-24 09:08:49 -05:00

http: make 'authneg' also work for Hyper

When doing a request with a request body expecting a 401/407 back, that
initial request is sent with a zero content-length. Test 177 and more.

Closes #6424
This commit is contained in:
Daniel Stenberg 2021-01-08 16:17:12 +01:00
parent 83f1ca6929
commit 8b2dec6ab7
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 25 additions and 21 deletions

View File

@ -670,7 +670,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(!pq) if(!pq)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
result = Curl_http_output_auth(conn, method, result = Curl_http_output_auth(conn, method, httpreq,
(pq ? pq : data->state.up.path), FALSE); (pq ? pq : data->state.up.path), FALSE);
free(pq); free(pq);
if(result) if(result)

View File

@ -784,6 +784,7 @@ output_auth_headers(struct connectdata *conn,
CURLcode CURLcode
Curl_http_output_auth(struct connectdata *conn, Curl_http_output_auth(struct connectdata *conn,
const char *request, const char *request,
Curl_HttpReq httpreq,
const char *path, const char *path,
bool proxytunnel) /* TRUE if this is the request setting bool proxytunnel) /* TRUE if this is the request setting
up the proxy tunnel */ up the proxy tunnel */
@ -850,6 +851,17 @@ Curl_http_output_auth(struct connectdata *conn,
else else
authhost->done = TRUE; authhost->done = TRUE;
if(((authhost->multipass && !authhost->done) ||
(authproxy->multipass && !authproxy->done)) &&
(httpreq != HTTPREQ_GET) &&
(httpreq != HTTPREQ_HEAD)) {
/* Auth is required and we are not authenticated yet. Make a PUT or POST
with content-length zero as a "probe". */
conn->bits.authneg = TRUE;
}
else
conn->bits.authneg = FALSE;
return result; return result;
} }
@ -1962,7 +1974,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
if(data->set.opt_no_body) if(data->set.opt_no_body)
request = "HEAD"; request = "HEAD";
else { else {
DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); DEBUGASSERT((httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD));
switch(httpreq) { switch(httpreq) {
case HTTPREQ_POST: case HTTPREQ_POST:
case HTTPREQ_POST_FORM: case HTTPREQ_POST_FORM:
@ -2972,24 +2984,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(!pq) if(!pq)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
result = Curl_http_output_auth(conn, request, result = Curl_http_output_auth(conn, request, httpreq,
(pq ? pq : data->state.up.path), FALSE); (pq ? pq : data->state.up.path), FALSE);
free(pq); free(pq);
if(result) if(result)
return result; return result;
} }
if(((data->state.authhost.multipass && !data->state.authhost.done)
|| (data->state.authproxy.multipass && !data->state.authproxy.done)) &&
(httpreq != HTTPREQ_GET) &&
(httpreq != HTTPREQ_HEAD)) {
/* Auth is required and we are not authenticated yet. Make a PUT or POST
with content-length zero as a "probe". */
conn->bits.authneg = TRUE;
}
else
conn->bits.authneg = FALSE;
Curl_safefree(data->state.aptr.ref); Curl_safefree(data->state.aptr.ref);
if(data->change.referer && !Curl_checkheaders(conn, "Referer")) { if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer); data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);

View File

@ -24,14 +24,12 @@
#include "curl_setup.h" #include "curl_setup.h"
typedef enum { typedef enum {
HTTPREQ_NONE, /* first in list */
HTTPREQ_GET, HTTPREQ_GET,
HTTPREQ_POST, HTTPREQ_POST,
HTTPREQ_POST_FORM, /* we make a difference internally */ HTTPREQ_POST_FORM, /* we make a difference internally */
HTTPREQ_POST_MIME, /* we make a difference internally */ HTTPREQ_POST_MIME, /* we make a difference internally */
HTTPREQ_PUT, HTTPREQ_PUT,
HTTPREQ_HEAD, HTTPREQ_HEAD
HTTPREQ_LAST /* last in list */
} Curl_HttpReq; } Curl_HttpReq;
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
@ -295,6 +293,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* *
* @param conn all information about the current connection * @param conn all information about the current connection
* @param request pointer to the request keyword * @param request pointer to the request keyword
* @param httpreq is the request type
* @param path pointer to the requested path * @param path pointer to the requested path
* @param proxytunnel boolean if this is the request setting up a "proxy * @param proxytunnel boolean if this is the request setting up a "proxy
* tunnel" * tunnel"
@ -304,6 +303,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
CURLcode CURLcode
Curl_http_output_auth(struct connectdata *conn, Curl_http_output_auth(struct connectdata *conn,
const char *request, const char *request,
Curl_HttpReq httpreq,
const char *path, const char *path,
bool proxytunnel); /* TRUE if this is the request setting bool proxytunnel); /* TRUE if this is the request setting
up the proxy tunnel */ up the proxy tunnel */

View File

@ -263,7 +263,8 @@ static CURLcode CONNECT(struct connectdata *conn,
return result; return result;
/* Setup the proxy-authorization header, if any */ /* Setup the proxy-authorization header, if any */
result = Curl_http_output_auth(conn, "CONNECT", hostheader, TRUE); result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
hostheader, TRUE);
if(!result) { if(!result) {
const char *proxyconn = ""; const char *proxyconn = "";
@ -739,7 +740,8 @@ static CURLcode CONNECT(struct connectdata *conn,
result = CURLE_OUT_OF_MEMORY; result = CURLE_OUT_OF_MEMORY;
} }
/* Setup the proxy-authorization header, if any */ /* Setup the proxy-authorization header, if any */
result = Curl_http_output_auth(conn, "CONNECT", hostheader, TRUE); result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
hostheader, TRUE);
if(result) if(result)
goto error; goto error;
Curl_safefree(hostheader); Curl_safefree(hostheader);

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -385,7 +385,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
} }
/* setup the authentication headers */ /* setup the authentication headers */
result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE); result = Curl_http_output_auth(conn, p_request, HTTPREQ_GET,
p_stream_uri, FALSE);
if(result) if(result)
return result; return result;