mirror of
https://github.com/moparisthebest/curl
synced 2024-12-24 00:58:48 -05:00
http: fix for tiny "HTTP/0.9" response
Deal with tiny "HTTP/0.9" (header-less) responses by checking the status-line early, even before a full "HTTP/" is received to allow detecting 0.9 properly. Test 1266 and 1267 added to verify. Fixes #2420 Closes #2872
This commit is contained in:
parent
233908a55a
commit
8440616f53
@ -801,6 +801,11 @@ endings either CRLF or LF so 't' is appropriate.
|
|||||||
#define CURL_SA_FAMILY_T unsigned short
|
#define CURL_SA_FAMILY_T unsigned short
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Some convenience macros to get the larger/smaller value out of two given.
|
||||||
|
We prefix with CURL to prevent name collisions. */
|
||||||
|
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
|
||||||
|
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
|
||||||
|
|
||||||
/* Some versions of the Android SDK is missing the declaration */
|
/* Some versions of the Android SDK is missing the declaration */
|
||||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
||||||
struct passwd;
|
struct passwd;
|
||||||
|
68
lib/http.c
68
lib/http.c
@ -2899,17 +2899,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STATUS_UNKNOWN, /* not enough data to tell yet */
|
||||||
|
STATUS_DONE, /* a status line was read */
|
||||||
|
STATUS_BAD /* not a status line */
|
||||||
|
} statusline;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check a string for a prefix. Check no more than 'len' bytes */
|
||||||
|
static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
size_t ch = CURLMIN(strlen(prefix), len);
|
||||||
|
return curl_strnequal(prefix, buffer, ch);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* checkhttpprefix()
|
* checkhttpprefix()
|
||||||
*
|
*
|
||||||
* Returns TRUE if member of the list matches prefix of string
|
* Returns TRUE if member of the list matches prefix of string
|
||||||
*/
|
*/
|
||||||
static bool
|
static statusline
|
||||||
checkhttpprefix(struct Curl_easy *data,
|
checkhttpprefix(struct Curl_easy *data,
|
||||||
const char *s)
|
const char *s, size_t len)
|
||||||
{
|
{
|
||||||
struct curl_slist *head = data->set.http200aliases;
|
struct curl_slist *head = data->set.http200aliases;
|
||||||
bool rc = FALSE;
|
statusline rc = STATUS_BAD;
|
||||||
|
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
|
||||||
#ifdef CURL_DOES_CONVERSIONS
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
/* convert from the network encoding using a scratch area */
|
/* convert from the network encoding using a scratch area */
|
||||||
char *scratch = strdup(s);
|
char *scratch = strdup(s);
|
||||||
@ -2926,15 +2941,15 @@ checkhttpprefix(struct Curl_easy *data,
|
|||||||
#endif /* CURL_DOES_CONVERSIONS */
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
while(head) {
|
while(head) {
|
||||||
if(checkprefix(head->data, s)) {
|
if(checkprefixmax(head->data, s, len)) {
|
||||||
rc = TRUE;
|
rc = onmatch;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
head = head->next;
|
head = head->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!rc && (checkprefix("HTTP/", s)))
|
if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
|
||||||
rc = TRUE;
|
rc = onmatch;
|
||||||
|
|
||||||
#ifdef CURL_DOES_CONVERSIONS
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
free(scratch);
|
free(scratch);
|
||||||
@ -2943,11 +2958,12 @@ checkhttpprefix(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_RTSP
|
#ifndef CURL_DISABLE_RTSP
|
||||||
static bool
|
static statusline
|
||||||
checkrtspprefix(struct Curl_easy *data,
|
checkrtspprefix(struct Curl_easy *data,
|
||||||
const char *s)
|
const char *s, size_t len)
|
||||||
{
|
{
|
||||||
bool result = FALSE;
|
statusline result = STATUS_BAD;
|
||||||
|
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
|
||||||
|
|
||||||
#ifdef CURL_DOES_CONVERSIONS
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
/* convert from the network encoding using a scratch area */
|
/* convert from the network encoding using a scratch area */
|
||||||
@ -2960,30 +2976,31 @@ checkrtspprefix(struct Curl_easy *data,
|
|||||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||||
result = FALSE; /* can't return CURLE_foobar so return FALSE */
|
result = FALSE; /* can't return CURLE_foobar so return FALSE */
|
||||||
}
|
}
|
||||||
else
|
else if(checkprefixmax("RTSP/", scratch, len))
|
||||||
result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
|
result = onmatch;
|
||||||
free(scratch);
|
free(scratch);
|
||||||
#else
|
#else
|
||||||
(void)data; /* unused */
|
(void)data; /* unused */
|
||||||
result = checkprefix("RTSP/", s)? TRUE: FALSE;
|
if(checkprefixmax("RTSP/", s, len))
|
||||||
|
result = onmatch;
|
||||||
#endif /* CURL_DOES_CONVERSIONS */
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* CURL_DISABLE_RTSP */
|
#endif /* CURL_DISABLE_RTSP */
|
||||||
|
|
||||||
static bool
|
static statusline
|
||||||
checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
|
checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
|
||||||
const char *s)
|
const char *s, size_t len)
|
||||||
{
|
{
|
||||||
#ifndef CURL_DISABLE_RTSP
|
#ifndef CURL_DISABLE_RTSP
|
||||||
if(conn->handler->protocol & CURLPROTO_RTSP)
|
if(conn->handler->protocol & CURLPROTO_RTSP)
|
||||||
return checkrtspprefix(data, s);
|
return checkrtspprefix(data, s, len);
|
||||||
#else
|
#else
|
||||||
(void)conn;
|
(void)conn;
|
||||||
#endif /* CURL_DISABLE_RTSP */
|
#endif /* CURL_DISABLE_RTSP */
|
||||||
|
|
||||||
return checkhttpprefix(data, s);
|
return checkhttpprefix(data, s, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3097,12 +3114,15 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if(!k->headerline && (k->hbuflen>5)) {
|
if(!k->headerline) {
|
||||||
/* make a first check that this looks like a protocol header */
|
/* check if this looks like a protocol header */
|
||||||
if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
|
statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
|
||||||
|
k->hbuflen);
|
||||||
|
if(st == STATUS_BAD) {
|
||||||
/* this is not the beginning of a protocol first header line */
|
/* this is not the beginning of a protocol first header line */
|
||||||
k->header = FALSE;
|
k->header = FALSE;
|
||||||
k->badheader = HEADER_ALLBAD;
|
k->badheader = HEADER_ALLBAD;
|
||||||
|
streamclose(conn, "bad HTTP: No end-of-message indicator");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3131,8 +3151,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
|
|
||||||
if(!k->headerline) {
|
if(!k->headerline) {
|
||||||
/* the first read header */
|
/* the first read header */
|
||||||
if((k->hbuflen>5) &&
|
statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
|
||||||
!checkprotoprefix(data, conn, data->state.headerbuff)) {
|
k->hbuflen);
|
||||||
|
if(st == STATUS_BAD) {
|
||||||
|
streamclose(conn, "bad HTTP: No end-of-message indicator");
|
||||||
/* this is not the beginning of a protocol first header line */
|
/* this is not the beginning of a protocol first header line */
|
||||||
k->header = FALSE;
|
k->header = FALSE;
|
||||||
if(*nread)
|
if(*nread)
|
||||||
@ -3501,7 +3523,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
|||||||
compare header line against list of aliases
|
compare header line against list of aliases
|
||||||
*/
|
*/
|
||||||
if(!nc) {
|
if(!nc) {
|
||||||
if(checkhttpprefix(data, k->p)) {
|
if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
|
||||||
nc = 1;
|
nc = 1;
|
||||||
k->httpcode = 200;
|
k->httpcode = 200;
|
||||||
conn->httpversion = 10;
|
conn->httpversion = 10;
|
||||||
|
11
lib/http2.c
11
lib/http2.c
@ -42,7 +42,6 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define H2_BUFSIZE 32768
|
#define H2_BUFSIZE 32768
|
||||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
|
||||||
|
|
||||||
#if (NGHTTP2_VERSION_NUM < 0x010000)
|
#if (NGHTTP2_VERSION_NUM < 0x010000)
|
||||||
#error too old nghttp2 version, upgrade!
|
#error too old nghttp2 version, upgrade!
|
||||||
@ -667,7 +666,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
||||||
|
|
||||||
left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
||||||
ncopy = MIN(stream->len, left);
|
ncopy = CURLMIN(stream->len, left);
|
||||||
|
|
||||||
memcpy(&stream->mem[stream->memlen],
|
memcpy(&stream->mem[stream->memlen],
|
||||||
stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
||||||
@ -753,7 +752,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||||||
if(!stream)
|
if(!stream)
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||||
|
|
||||||
nread = MIN(stream->len, len);
|
nread = CURLMIN(stream->len, len);
|
||||||
memcpy(&stream->mem[stream->memlen], data, nread);
|
memcpy(&stream->mem[stream->memlen], data, nread);
|
||||||
|
|
||||||
stream->len -= nread;
|
stream->len -= nread;
|
||||||
@ -1076,7 +1075,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
|||||||
else
|
else
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
nread = MIN(stream->upload_len, length);
|
nread = CURLMIN(stream->upload_len, length);
|
||||||
if(nread > 0) {
|
if(nread > 0) {
|
||||||
memcpy(buf, stream->upload_mem, nread);
|
memcpy(buf, stream->upload_mem, nread);
|
||||||
stream->upload_mem += nread;
|
stream->upload_mem += nread;
|
||||||
@ -1534,7 +1533,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
|||||||
/* If there is body data pending for this stream to return, do that */
|
/* If there is body data pending for this stream to return, do that */
|
||||||
size_t left =
|
size_t left =
|
||||||
stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
|
||||||
size_t ncopy = MIN(len, left);
|
size_t ncopy = CURLMIN(len, left);
|
||||||
memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
|
||||||
ncopy);
|
ncopy);
|
||||||
stream->nread_header_recvbuf += ncopy;
|
stream->nread_header_recvbuf += ncopy;
|
||||||
@ -1570,7 +1569,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
|||||||
}
|
}
|
||||||
else if(stream->pausedata) {
|
else if(stream->pausedata) {
|
||||||
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
|
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
|
||||||
nread = MIN(len, stream->pauselen);
|
nread = CURLMIN(len, stream->pauselen);
|
||||||
memcpy(mem, stream->pausedata, nread);
|
memcpy(mem, stream->pausedata, nread);
|
||||||
|
|
||||||
stream->pausedata += nread;
|
stream->pausedata += nread;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
|
* Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com>
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -123,9 +123,6 @@ static const unsigned long K[64] = {
|
|||||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
|
||||||
#endif
|
|
||||||
/* compress 512-bits */
|
/* compress 512-bits */
|
||||||
static int sha256_compress(struct sha256_state *md,
|
static int sha256_compress(struct sha256_state *md,
|
||||||
unsigned char *buf)
|
unsigned char *buf)
|
||||||
@ -200,7 +197,7 @@ static int SHA256_Update(struct sha256_state *md,
|
|||||||
inlen -= block_size;
|
inlen -= block_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
n = MIN(inlen, (block_size - md->curlen));
|
n = CURLMIN(inlen, (block_size - md->curlen));
|
||||||
memcpy(md->buf + md->curlen, in, n);
|
memcpy(md->buf + md->curlen, in, n);
|
||||||
md->curlen += n;
|
md->curlen += n;
|
||||||
in += n;
|
in += n;
|
||||||
|
@ -157,11 +157,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
|
|||||||
#define GOOD_EASY_HANDLE(x) \
|
#define GOOD_EASY_HANDLE(x) \
|
||||||
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
|
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
|
||||||
|
|
||||||
/* Some convenience macros to get the larger/smaller value out of two given.
|
|
||||||
We prefix with CURL to prevent name collisions. */
|
|
||||||
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
|
|
||||||
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
|
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
/* Types needed for krb5-ftp connections */
|
/* Types needed for krb5-ftp connections */
|
||||||
struct krb5buffer {
|
struct krb5buffer {
|
||||||
|
@ -169,6 +169,7 @@ connection-monitor When used, this will log [DISCONNECT] to the server.input
|
|||||||
log when the connection is disconnected.
|
log when the connection is disconnected.
|
||||||
upgrade when an HTTP upgrade header is found, the server will upgrade
|
upgrade when an HTTP upgrade header is found, the server will upgrade
|
||||||
to http2
|
to http2
|
||||||
|
swsclose instruct server to close connection after response
|
||||||
|
|
||||||
For TFTP:
|
For TFTP:
|
||||||
writedelay: [secs] delay this amount between reply packets (each packet being
|
writedelay: [secs] delay this amount between reply packets (each packet being
|
||||||
|
@ -139,7 +139,7 @@ test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
|
|||||||
test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
|
test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
|
||||||
test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
|
test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
|
||||||
test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
|
test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
|
||||||
test1260 test1261 test1262 test1263 test1264 test1265 \
|
test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 \
|
||||||
\
|
\
|
||||||
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
|
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
|
||||||
test1288 test1289 test1290 test1291 test1292 \
|
test1288 test1289 test1290 test1291 test1292 \
|
||||||
|
46
tests/data/test1266
Normal file
46
tests/data/test1266
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP/0.9
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
o
|
||||||
|
</data>
|
||||||
|
<servercmd>
|
||||||
|
swsclose
|
||||||
|
</servercmd>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP GET with a single-byte HTTP/0.9 response
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/1266
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /1266 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
46
tests/data/test1267
Normal file
46
tests/data/test1267
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP/0.9
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTPr
|
||||||
|
</data>
|
||||||
|
<servercmd>
|
||||||
|
swsclose
|
||||||
|
</servercmd>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP GET with a invalid HTTP/1 response line start
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/1267
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /1267 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
@ -152,7 +152,7 @@ my $NEGTELNETPORT; # TELNET server port with negotiation
|
|||||||
|
|
||||||
my $srcdir = $ENV{'srcdir'} || '.';
|
my $srcdir = $ENV{'srcdir'} || '.';
|
||||||
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
|
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
|
||||||
my $VCURL=$CURL; # what curl binary to use to verify the servers with
|
my $VCURL="curl"; # what curl binary to use to verify the servers with
|
||||||
# VCURL is handy to set to the system one when the one you
|
# VCURL is handy to set to the system one when the one you
|
||||||
# just built hangs or crashes and thus prevent verification
|
# just built hangs or crashes and thus prevent verification
|
||||||
my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
|
my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2018, 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
|
||||||
@ -124,6 +124,8 @@ struct httprequest {
|
|||||||
bool connmon; /* monitor the state of the connection, log disconnects */
|
bool connmon; /* monitor the state of the connection, log disconnects */
|
||||||
bool upgrade; /* test case allows upgrade to http2 */
|
bool upgrade; /* test case allows upgrade to http2 */
|
||||||
bool upgrade_request; /* upgrade request found and allowed */
|
bool upgrade_request; /* upgrade request found and allowed */
|
||||||
|
bool close; /* similar to swsclose in response: close connection after
|
||||||
|
response is sent */
|
||||||
int done_processing;
|
int done_processing;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -177,6 +179,9 @@ const char *serverlogfile = DEFAULT_LOGFILE;
|
|||||||
/* upgrade to http2 */
|
/* upgrade to http2 */
|
||||||
#define CMD_UPGRADE "upgrade"
|
#define CMD_UPGRADE "upgrade"
|
||||||
|
|
||||||
|
/* close connection */
|
||||||
|
#define CMD_SWSCLOSE "swsclose"
|
||||||
|
|
||||||
#define END_OF_HEADERS "\r\n\r\n"
|
#define END_OF_HEADERS "\r\n\r\n"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -361,7 +366,7 @@ static int parse_servercmd(struct httprequest *req)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
filename = test2file(req->testno);
|
filename = test2file(req->testno);
|
||||||
|
req->close = FALSE;
|
||||||
stream = fopen(filename, "rb");
|
stream = fopen(filename, "rb");
|
||||||
if(!stream) {
|
if(!stream) {
|
||||||
error = errno;
|
error = errno;
|
||||||
@ -414,6 +419,10 @@ static int parse_servercmd(struct httprequest *req)
|
|||||||
logmsg("enabled upgrade to http2");
|
logmsg("enabled upgrade to http2");
|
||||||
req->upgrade = TRUE;
|
req->upgrade = TRUE;
|
||||||
}
|
}
|
||||||
|
else if(!strncmp(CMD_SWSCLOSE, cmd, strlen(CMD_SWSCLOSE))) {
|
||||||
|
logmsg("swsclose: close this connection after response");
|
||||||
|
req->close = TRUE;
|
||||||
|
}
|
||||||
else if(1 == sscanf(cmd, "pipe: %d", &num)) {
|
else if(1 == sscanf(cmd, "pipe: %d", &num)) {
|
||||||
logmsg("instructed to allow a pipe size of %d", num);
|
logmsg("instructed to allow a pipe size of %d", num);
|
||||||
if(num < 0)
|
if(num < 0)
|
||||||
@ -1194,7 +1203,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
|||||||
/* If the word 'swsclose' is present anywhere in the reply chunk, the
|
/* If the word 'swsclose' is present anywhere in the reply chunk, the
|
||||||
connection will be closed after the data has been sent to the requesting
|
connection will be closed after the data has been sent to the requesting
|
||||||
client... */
|
client... */
|
||||||
if(strstr(buffer, "swsclose") || !count) {
|
if(strstr(buffer, "swsclose") || !count || req->close) {
|
||||||
persistent = FALSE;
|
persistent = FALSE;
|
||||||
logmsg("connection close instruction \"swsclose\" found in response");
|
logmsg("connection close instruction \"swsclose\" found in response");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user