Compare commits
3 Commits
master
...
bagder/CUR
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cddf7e20b | ||
|
|
8d3f947df6 | ||
|
|
a968b2ecdc |
@ -602,7 +602,7 @@ problems may have been fixed or changed somewhat since this was written.
|
|||||||
|
|
||||||
16.3 aws-sigv4 has problems with particular URLs
|
16.3 aws-sigv4 has problems with particular URLs
|
||||||
|
|
||||||
https://github.com/curl/curl/issues/13058
|
https://github.com/curl/curl/issues/13085
|
||||||
|
|
||||||
16.6 aws-sigv4 does not behave well with AWS VPC Lattice
|
16.6 aws-sigv4 does not behave well with AWS VPC Lattice
|
||||||
|
|
||||||
|
|||||||
@ -247,11 +247,11 @@ local system or network, the bar is raised. If a local user wrongfully has
|
|||||||
elevated rights on your system enough to attack curl, they can probably
|
elevated rights on your system enough to attack curl, they can probably
|
||||||
already do much worse harm and the problem is not really in curl.
|
already do much worse harm and the problem is not really in curl.
|
||||||
|
|
||||||
## Debug & Experiments
|
## Experiments
|
||||||
|
|
||||||
Vulnerabilities in features which are off by default (in the build) and
|
Vulnerabilities in features which are off by default (in the build) and
|
||||||
documented as experimental, or exist only in debug mode, are not eligible for a
|
documented as experimental, are not eligible for a reward and we do not
|
||||||
reward and we do not consider them security problems.
|
consider them security problems.
|
||||||
|
|
||||||
## URL inconsistencies
|
## URL inconsistencies
|
||||||
|
|
||||||
|
|||||||
@ -418,22 +418,22 @@ static int init_fifo(GlobalInfo *g)
|
|||||||
struct epoll_event epev;
|
struct epoll_event epev;
|
||||||
|
|
||||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||||
if(lstat(fifo, &st) == 0) {
|
if(lstat (fifo, &st) == 0) {
|
||||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
perror("lstat");
|
perror("lstat");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlink(fifo);
|
unlink(fifo);
|
||||||
if(mkfifo(fifo, 0600) == -1) {
|
if(mkfifo (fifo, 0600) == -1) {
|
||||||
perror("mkfifo");
|
perror("mkfifo");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||||
if(sockfd == -1) {
|
if(sockfd == -1) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g->fifofd = sockfd;
|
g->fifofd = sockfd;
|
||||||
@ -478,13 +478,13 @@ int main(int argc, char **argv)
|
|||||||
g.epfd = epoll_create1(EPOLL_CLOEXEC);
|
g.epfd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if(g.epfd == -1) {
|
if(g.epfd == -1) {
|
||||||
perror("epoll_create1 failed");
|
perror("epoll_create1 failed");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g.tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
g.tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
if(g.tfd == -1) {
|
if(g.tfd == -1) {
|
||||||
perror("timerfd_create failed");
|
perror("timerfd_create failed");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&its, 0, sizeof(struct itimerspec));
|
memset(&its, 0, sizeof(struct itimerspec));
|
||||||
@ -496,8 +496,7 @@ int main(int argc, char **argv)
|
|||||||
ev.data.fd = g.tfd;
|
ev.data.fd = g.tfd;
|
||||||
epoll_ctl(g.epfd, EPOLL_CTL_ADD, g.tfd, &ev);
|
epoll_ctl(g.epfd, EPOLL_CTL_ADD, g.tfd, &ev);
|
||||||
|
|
||||||
if(init_fifo(&g))
|
init_fifo(&g);
|
||||||
return 1;
|
|
||||||
g.multi = curl_multi_init();
|
g.multi = curl_multi_init();
|
||||||
|
|
||||||
/* setup the generic multi interface options we want */
|
/* setup the generic multi interface options we want */
|
||||||
@ -522,7 +521,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
perror("epoll_wait");
|
perror("epoll_wait");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -402,22 +402,22 @@ static int init_fifo(GlobalInfo *g)
|
|||||||
curl_socket_t sockfd;
|
curl_socket_t sockfd;
|
||||||
|
|
||||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||||
if(lstat(fifo, &st) == 0) {
|
if(lstat (fifo, &st) == 0) {
|
||||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
perror("lstat");
|
perror("lstat");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlink(fifo);
|
unlink(fifo);
|
||||||
if(mkfifo(fifo, 0600) == -1) {
|
if(mkfifo (fifo, 0600) == -1) {
|
||||||
perror("mkfifo");
|
perror("mkfifo");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||||
if(sockfd == -1) {
|
if(sockfd == -1) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
g->input = fdopen(sockfd, "r");
|
g->input = fdopen(sockfd, "r");
|
||||||
|
|
||||||
@ -436,8 +436,7 @@ int main(int argc, char **argv)
|
|||||||
memset(&g, 0, sizeof(GlobalInfo));
|
memset(&g, 0, sizeof(GlobalInfo));
|
||||||
g.loop = ev_default_loop(0);
|
g.loop = ev_default_loop(0);
|
||||||
|
|
||||||
if(init_fifo(&g))
|
init_fifo(&g);
|
||||||
return 1;
|
|
||||||
g.multi = curl_multi_init();
|
g.multi = curl_multi_init();
|
||||||
|
|
||||||
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
|
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
|
||||||
|
|||||||
@ -392,21 +392,21 @@ int init_fifo(void)
|
|||||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
perror("lstat");
|
perror("lstat");
|
||||||
return CURL_SOCKET_BAD;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink(fifo);
|
unlink(fifo);
|
||||||
if(mkfifo(fifo, 0600) == -1) {
|
if(mkfifo (fifo, 0600) == -1) {
|
||||||
perror("mkfifo");
|
perror("mkfifo");
|
||||||
return CURL_SOCKET_BAD;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||||
|
|
||||||
if(socket == CURL_SOCKET_BAD) {
|
if(socket == -1) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return socket;
|
exit(1);
|
||||||
}
|
}
|
||||||
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
||||||
|
|
||||||
@ -421,8 +421,6 @@ int main(void)
|
|||||||
GIOChannel* ch;
|
GIOChannel* ch;
|
||||||
|
|
||||||
fd = init_fifo();
|
fd = init_fifo();
|
||||||
if(fd == CURL_SOCKET_BAD)
|
|
||||||
return 1;
|
|
||||||
ch = g_io_channel_unix_new(fd);
|
ch = g_io_channel_unix_new(fd);
|
||||||
g_io_add_watch(ch, G_IO_IN, fifo_cb, g);
|
g_io_add_watch(ch, G_IO_IN, fifo_cb, g);
|
||||||
gmain = g_main_loop_new(NULL, FALSE);
|
gmain = g_main_loop_new(NULL, FALSE);
|
||||||
|
|||||||
@ -399,22 +399,22 @@ static int init_fifo(GlobalInfo *g)
|
|||||||
curl_socket_t sockfd;
|
curl_socket_t sockfd;
|
||||||
|
|
||||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||||
if(lstat(fifo, &st) == 0) {
|
if(lstat (fifo, &st) == 0) {
|
||||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
perror("lstat");
|
perror("lstat");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlink(fifo);
|
unlink(fifo);
|
||||||
if(mkfifo (fifo, 0600) == -1) {
|
if(mkfifo (fifo, 0600) == -1) {
|
||||||
perror("mkfifo");
|
perror("mkfifo");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||||
if(sockfd == -1) {
|
if(sockfd == -1) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
g->input = fdopen(sockfd, "r");
|
g->input = fdopen(sockfd, "r");
|
||||||
|
|
||||||
@ -440,8 +440,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
memset(&g, 0, sizeof(GlobalInfo));
|
memset(&g, 0, sizeof(GlobalInfo));
|
||||||
g.evbase = event_base_new();
|
g.evbase = event_base_new();
|
||||||
if(init_fifo(&g))
|
init_fifo(&g);
|
||||||
return 1;
|
|
||||||
g.multi = curl_multi_init();
|
g.multi = curl_multi_init();
|
||||||
evtimer_assign(&g.timer_event, g.evbase, timer_cb, &g);
|
evtimer_assign(&g.timer_event, g.evbase, timer_cb, &g);
|
||||||
|
|
||||||
|
|||||||
@ -66,9 +66,15 @@ Many people have wrongly used this option to replace the entire request with
|
|||||||
their own, including multiple headers and POST contents. While that might work
|
their own, including multiple headers and POST contents. While that might work
|
||||||
in many cases, it might cause libcurl to send invalid requests and it could
|
in many cases, it might cause libcurl to send invalid requests and it could
|
||||||
possibly confuse the remote server badly. Use CURLOPT_POST(3) and
|
possibly confuse the remote server badly. Use CURLOPT_POST(3) and
|
||||||
CURLOPT_POSTFIELDS(3) to set POST data. Use CURLOPT_HTTPHEADER(3)
|
CURLOPT_POSTFIELDS(3) to set POST data. Use CURLOPT_HTTPHEADER(3) to replace
|
||||||
to replace or extend the set of headers sent by libcurl. Use
|
or extend the set of headers sent by libcurl. Use CURLOPT_HTTP_VERSION(3) to
|
||||||
CURLOPT_HTTP_VERSION(3) to change HTTP version.
|
change the HTTP version.
|
||||||
|
|
||||||
|
When this option is used together with CURLOPT_FOLLOWLOCATION(3), the custom
|
||||||
|
set method overrides the method libcurl could otherwise change to for the
|
||||||
|
subsequent requests. You can fine-tune that decision by using the
|
||||||
|
CURLFOLLOW_OBEYCODE bit to CURLOPT_FOLLOWLOCATION(3) to make redirects adhere
|
||||||
|
to the redirect response code as the protocol instructs.
|
||||||
|
|
||||||
## FTP
|
## FTP
|
||||||
|
|
||||||
|
|||||||
@ -25,19 +25,23 @@ CURLOPT_FOLLOWLOCATION - follow HTTP 3xx redirects
|
|||||||
~~~c
|
~~~c
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_FOLLOWLOCATION, long enable);
|
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_FOLLOWLOCATION, long mode);
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
A long parameter set to 1 tells the library to follow any Location: header
|
This option tells the library to follow `Location:` header redirects that an
|
||||||
redirects that an HTTP server sends in a 30x response. The Location: header
|
HTTP server sends in a 30x response. The `Location:` header can specify a
|
||||||
can specify a relative or an absolute URL to follow.
|
relative or an absolute URL to follow. The long parameter *mode* instructs how
|
||||||
|
libcurl should act on subsequent requests.
|
||||||
|
|
||||||
libcurl issues another request for the new URL and follows subsequent new
|
*mode* only had a single value (1L) for a long time that enables redirect
|
||||||
`Location:` redirects all the way until no more such headers are returned or
|
following. Since 8.13.0, two additional modes are also supported. See below.
|
||||||
the maximum limit is reached. CURLOPT_MAXREDIRS(3) is used to limit the number
|
|
||||||
of redirects libcurl follows.
|
When following redirects, libcurl issues another request for the new URL and
|
||||||
|
follows subsequent new `Location:` redirects all the way until no more such
|
||||||
|
headers are returned or the maximum limit is reached. CURLOPT_MAXREDIRS(3) is
|
||||||
|
used to limit the number of redirects libcurl follows.
|
||||||
|
|
||||||
libcurl restricts what protocols it automatically follow redirects to. The
|
libcurl restricts what protocols it automatically follow redirects to. The
|
||||||
accepted target protocols are set with CURLOPT_REDIR_PROTOCOLS_STR(3). By
|
accepted target protocols are set with CURLOPT_REDIR_PROTOCOLS_STR(3). By
|
||||||
@ -64,6 +68,45 @@ client may not want to pass on to other servers than the initially intended
|
|||||||
host and for all other headers than the two mentioned above, there is no
|
host and for all other headers than the two mentioned above, there is no
|
||||||
protection from this happening when libcurl is told to follow redirects.
|
protection from this happening when libcurl is told to follow redirects.
|
||||||
|
|
||||||
|
Pick one of the following modes:
|
||||||
|
|
||||||
|
## CURLFOLLOW_ALL (1)
|
||||||
|
|
||||||
|
Before 8.13.0 this bit had no name and 1L was just the value to enable this
|
||||||
|
option. This makes a set custom method be used in all HTTP requests, even
|
||||||
|
after redirects.
|
||||||
|
|
||||||
|
## CURLFOLLOW_OBEYCODE (2)
|
||||||
|
|
||||||
|
When there is a custom request method set with CURLOPT_CUSTOMREQUEST(3), that
|
||||||
|
set method replaces what libcurl would otherwise use. If a 301/302/303
|
||||||
|
response code is returned to signal a redirect, the method is changed from
|
||||||
|
POST to `GET`. For 307/308, the custom method remains set and used.
|
||||||
|
|
||||||
|
Note that only POST (or a custom post) is changed to GET on 301/302, its not
|
||||||
|
change PUT etc - and therefore also not when libcurl issues a custom PUT. A
|
||||||
|
303 response makes it switch to GET independently of the original method
|
||||||
|
(except for HEAD).
|
||||||
|
|
||||||
|
To control for which of the 301/302/303 status codes libcurl should *not*
|
||||||
|
switch back to GET for when doing a custom POST, and instead keep the custom
|
||||||
|
method, use CURLOPT_POSTREDIR(3).
|
||||||
|
|
||||||
|
If you prefer a custom POST method to be reset to exactly the method `POST`,
|
||||||
|
use CURLFOLLOW_FIRSTONLY instead.
|
||||||
|
|
||||||
|
## CURLFOLLOW_FIRSTONLY (3)
|
||||||
|
|
||||||
|
When there is a custom request method set with CURLOPT_CUSTOMREQUEST(3), that
|
||||||
|
set method replaces what libcurl would otherwise use in the first outgoing
|
||||||
|
request only. The second request is then done according to the redirect
|
||||||
|
response code.
|
||||||
|
|
||||||
|
If you prefer your custom method to remain in use after a 307/308 redirect,
|
||||||
|
use CURLFOLLOW_OBEYCODE instead.
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
# NOTE
|
# NOTE
|
||||||
|
|
||||||
Since libcurl changes method or not based on the specific HTTP response code,
|
Since libcurl changes method or not based on the specific HTTP response code,
|
||||||
@ -72,6 +115,10 @@ libcurl would otherwise do and if not that carefully may even make it
|
|||||||
misbehave since CURLOPT_CUSTOMREQUEST(3) overrides the method libcurl would
|
misbehave since CURLOPT_CUSTOMREQUEST(3) overrides the method libcurl would
|
||||||
otherwise select internally.
|
otherwise select internally.
|
||||||
|
|
||||||
|
Setting the CURLFOLLOW_OBEYCODE bit makes libcurl *not* use the custom set
|
||||||
|
method after redirects for 301, 302 and 303 responses. Unless the
|
||||||
|
CURLOPT_POSTREDIR(3) bits are set for those status codes.
|
||||||
|
|
||||||
# DEFAULT
|
# DEFAULT
|
||||||
|
|
||||||
0, disabled
|
0, disabled
|
||||||
|
|||||||
@ -337,11 +337,11 @@ CURLE_UNRECOVERABLE_POLL 7.84.0
|
|||||||
CURLE_UNSUPPORTED_PROTOCOL 7.1
|
CURLE_UNSUPPORTED_PROTOCOL 7.1
|
||||||
CURLE_UPLOAD_FAILED 7.16.3
|
CURLE_UPLOAD_FAILED 7.16.3
|
||||||
CURLE_URL_MALFORMAT 7.1
|
CURLE_URL_MALFORMAT 7.1
|
||||||
|
CURLE_ECH_REQUIRED 8.8.0
|
||||||
CURLE_URL_MALFORMAT_USER 7.1 7.17.0
|
CURLE_URL_MALFORMAT_USER 7.1 7.17.0
|
||||||
CURLE_USE_SSL_FAILED 7.17.0
|
CURLE_USE_SSL_FAILED 7.17.0
|
||||||
CURLE_WEIRD_SERVER_REPLY 7.51.0
|
CURLE_WEIRD_SERVER_REPLY 7.51.0
|
||||||
CURLE_WRITE_ERROR 7.1
|
CURLE_WRITE_ERROR 7.1
|
||||||
CURLE_ECH_REQUIRED 8.8.0
|
|
||||||
CURLFILETYPE_DEVICE_BLOCK 7.21.0
|
CURLFILETYPE_DEVICE_BLOCK 7.21.0
|
||||||
CURLFILETYPE_DEVICE_CHAR 7.21.0
|
CURLFILETYPE_DEVICE_CHAR 7.21.0
|
||||||
CURLFILETYPE_DIRECTORY 7.21.0
|
CURLFILETYPE_DIRECTORY 7.21.0
|
||||||
@ -359,6 +359,9 @@ CURLFINFOFLAG_KNOWN_PERM 7.21.0
|
|||||||
CURLFINFOFLAG_KNOWN_SIZE 7.21.0
|
CURLFINFOFLAG_KNOWN_SIZE 7.21.0
|
||||||
CURLFINFOFLAG_KNOWN_TIME 7.21.0
|
CURLFINFOFLAG_KNOWN_TIME 7.21.0
|
||||||
CURLFINFOFLAG_KNOWN_UID 7.21.0
|
CURLFINFOFLAG_KNOWN_UID 7.21.0
|
||||||
|
CURLFOLLOW_ALL 8.13.0
|
||||||
|
CURLFOLLOW_OBEYCODE 8.13.0
|
||||||
|
CURLFOLLOW_FIRSTONLY 8.13.0
|
||||||
CURLFORM_ARRAY 7.9.1 7.56.0
|
CURLFORM_ARRAY 7.9.1 7.56.0
|
||||||
CURLFORM_ARRAY_END 7.9.1 7.9.5 7.9.6
|
CURLFORM_ARRAY_END 7.9.1 7.9.5 7.9.6
|
||||||
CURLFORM_ARRAY_START 7.9.1 7.9.5 7.9.6
|
CURLFORM_ARRAY_START 7.9.1 7.9.5 7.9.6
|
||||||
|
|||||||
@ -175,6 +175,16 @@ typedef enum {
|
|||||||
#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
|
#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
|
||||||
#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
|
#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
|
||||||
|
|
||||||
|
/* bits for the CURLOPT_FOLLOWLOCATION option */
|
||||||
|
#define CURLFOLLOW_ALL 1L /* generic follow redirects */
|
||||||
|
|
||||||
|
/* Do not use the custom method in the follow-up request if the HTTP code
|
||||||
|
instructs so (301, 302, 303). */
|
||||||
|
#define CURLFOLLOW_OBEYCODE 2L
|
||||||
|
|
||||||
|
/* Only use the custom method in the first request, always reset in the next */
|
||||||
|
#define CURLFOLLOW_FIRSTONLY 3L
|
||||||
|
|
||||||
struct curl_httppost {
|
struct curl_httppost {
|
||||||
struct curl_httppost *next; /* next entry in the list */
|
struct curl_httppost *next; /* next entry in the list */
|
||||||
char *name; /* pointer to allocated name */
|
char *name; /* pointer to allocated name */
|
||||||
|
|||||||
48
lib/http.c
48
lib/http.c
@ -1155,6 +1155,21 @@ static bool http_should_fail(struct Curl_easy *data, int httpcode)
|
|||||||
return data->state.authproblem;
|
return data->state.authproblem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void http_switch_to_get(struct Curl_easy *data, int code)
|
||||||
|
{
|
||||||
|
const char *req = data->set.str[STRING_CUSTOMREQUEST];
|
||||||
|
if((req || data->state.httpreq != HTTPREQ_GET) &&
|
||||||
|
(data->set.http_follow_mode == CURLFOLLOW_OBEYCODE)) {
|
||||||
|
infof(data, "Switch to GET because of %d response", code);
|
||||||
|
data->state.http_ignorecustom = TRUE;
|
||||||
|
}
|
||||||
|
else if(req && (data->set.http_follow_mode != CURLFOLLOW_FIRSTONLY))
|
||||||
|
infof(data, "Stick to %s instead of GET", req);
|
||||||
|
|
||||||
|
data->state.httpreq = HTTPREQ_GET;
|
||||||
|
Curl_creader_set_rewind(data, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
||||||
followtype type)
|
followtype type)
|
||||||
{
|
{
|
||||||
@ -1321,6 +1336,12 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||||||
data->state.url_alloc = TRUE;
|
data->state.url_alloc = TRUE;
|
||||||
Curl_req_soft_reset(&data->req, data);
|
Curl_req_soft_reset(&data->req, data);
|
||||||
infof(data, "Issue another request to this URL: '%s'", data->state.url);
|
infof(data, "Issue another request to this URL: '%s'", data->state.url);
|
||||||
|
if((data->set.http_follow_mode == CURLFOLLOW_FIRSTONLY) &&
|
||||||
|
data->set.str[STRING_CUSTOMREQUEST] &&
|
||||||
|
!data->state.http_ignorecustom) {
|
||||||
|
data->state.http_ignorecustom = TRUE;
|
||||||
|
infof(data, "Drop custom request method for next request");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
||||||
@ -1362,11 +1383,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||||||
if((data->state.httpreq == HTTPREQ_POST
|
if((data->state.httpreq == HTTPREQ_POST
|
||||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||||
&& !(data->set.keep_post & CURL_REDIR_POST_301)) {
|
&& !(data->set.keep_post & CURL_REDIR_POST_301))
|
||||||
infof(data, "Switch from POST to GET");
|
http_switch_to_get(data, 301);
|
||||||
data->state.httpreq = HTTPREQ_GET;
|
|
||||||
Curl_creader_set_rewind(data, FALSE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 302: /* Found */
|
case 302: /* Found */
|
||||||
/* (quote from RFC7231, section 6.4.3)
|
/* (quote from RFC7231, section 6.4.3)
|
||||||
@ -1388,11 +1406,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||||||
if((data->state.httpreq == HTTPREQ_POST
|
if((data->state.httpreq == HTTPREQ_POST
|
||||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||||
&& !(data->set.keep_post & CURL_REDIR_POST_302)) {
|
&& !(data->set.keep_post & CURL_REDIR_POST_302))
|
||||||
infof(data, "Switch from POST to GET");
|
http_switch_to_get(data, 302);
|
||||||
data->state.httpreq = HTTPREQ_GET;
|
|
||||||
Curl_creader_set_rewind(data, FALSE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 303: /* See Other */
|
case 303: /* See Other */
|
||||||
@ -1405,11 +1420,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||||||
((data->state.httpreq != HTTPREQ_POST &&
|
((data->state.httpreq != HTTPREQ_POST &&
|
||||||
data->state.httpreq != HTTPREQ_POST_FORM &&
|
data->state.httpreq != HTTPREQ_POST_FORM &&
|
||||||
data->state.httpreq != HTTPREQ_POST_MIME) ||
|
data->state.httpreq != HTTPREQ_POST_MIME) ||
|
||||||
!(data->set.keep_post & CURL_REDIR_POST_303))) {
|
!(data->set.keep_post & CURL_REDIR_POST_303)))
|
||||||
data->state.httpreq = HTTPREQ_GET;
|
http_switch_to_get(data, 303);
|
||||||
infof(data, "Switch to %s",
|
|
||||||
data->req.no_body ? "HEAD" : "GET");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 304: /* Not Modified */
|
case 304: /* Not Modified */
|
||||||
/* 304 means we did a conditional request and it was "Not modified".
|
/* 304 means we did a conditional request and it was "Not modified".
|
||||||
@ -1803,8 +1815,10 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
|
|||||||
httpreq = HTTPREQ_PUT;
|
httpreq = HTTPREQ_PUT;
|
||||||
|
|
||||||
/* Now set the 'request' pointer to the proper request string */
|
/* Now set the 'request' pointer to the proper request string */
|
||||||
if(data->set.str[STRING_CUSTOMREQUEST])
|
if(data->set.str[STRING_CUSTOMREQUEST] &&
|
||||||
|
!data->state.http_ignorecustom) {
|
||||||
request = data->set.str[STRING_CUSTOMREQUEST];
|
request = data->set.str[STRING_CUSTOMREQUEST];
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if(data->req.no_body)
|
if(data->req.no_body)
|
||||||
request = "HEAD";
|
request = "HEAD";
|
||||||
@ -3138,7 +3152,7 @@ static CURLcode http_header(struct Curl_easy *data,
|
|||||||
else {
|
else {
|
||||||
data->req.location = location;
|
data->req.location = location;
|
||||||
|
|
||||||
if(data->set.http_follow_location) {
|
if(data->set.http_follow_mode) {
|
||||||
DEBUGASSERT(!data->req.newurl);
|
DEBUGASSERT(!data->req.newurl);
|
||||||
data->req.newurl = strdup(data->req.location); /* clone */
|
data->req.newurl = strdup(data->req.location); /* clone */
|
||||||
if(!data->req.newurl)
|
if(!data->req.newurl)
|
||||||
|
|||||||
@ -525,7 +525,9 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
|
|||||||
/*
|
/*
|
||||||
* Follow Location: header hints on an HTTP-server.
|
* Follow Location: header hints on an HTTP-server.
|
||||||
*/
|
*/
|
||||||
data->set.http_follow_location = enabled;
|
if(uarg > 3)
|
||||||
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
|
data->set.http_follow_mode = (unsigned char)uarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_UNRESTRICTED_AUTH:
|
case CURLOPT_UNRESTRICTED_AUTH:
|
||||||
|
|||||||
@ -1354,6 +1354,7 @@ struct UrlState {
|
|||||||
BIT(internal); /* internal: true if this easy handle was created for
|
BIT(internal); /* internal: true if this easy handle was created for
|
||||||
internal use and the user does not have ownership of the
|
internal use and the user does not have ownership of the
|
||||||
handle. */
|
handle. */
|
||||||
|
BIT(http_ignorecustom); /* ignore custom method from now */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1723,6 +1724,7 @@ struct UserDefined {
|
|||||||
CURLOPT_GSSAPI_DELEGATION */
|
CURLOPT_GSSAPI_DELEGATION */
|
||||||
unsigned char gssapi_delegation;
|
unsigned char gssapi_delegation;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned char http_follow_mode; /* follow HTTP redirects */
|
||||||
BIT(connect_only); /* make connection/request, then let application use the
|
BIT(connect_only); /* make connection/request, then let application use the
|
||||||
socket */
|
socket */
|
||||||
BIT(connect_only_ws); /* special websocket connect-only level */
|
BIT(connect_only_ws); /* special websocket connect-only level */
|
||||||
@ -1774,7 +1776,6 @@ struct UserDefined {
|
|||||||
BIT(hide_progress); /* do not use the progress meter */
|
BIT(hide_progress); /* do not use the progress meter */
|
||||||
BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */
|
BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */
|
||||||
BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */
|
BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */
|
||||||
BIT(http_follow_location); /* follow HTTP redirects */
|
|
||||||
BIT(http_transfer_encoding); /* request compressed HTTP transfer-encoding */
|
BIT(http_transfer_encoding); /* request compressed HTTP transfer-encoding */
|
||||||
BIT(allow_auth_to_other_hosts);
|
BIT(allow_auth_to_other_hosts);
|
||||||
BIT(include_header); /* include received protocol headers in data output */
|
BIT(include_header); /* include received protocol headers in data output */
|
||||||
|
|||||||
@ -207,7 +207,8 @@ test1540 test1541 test1542 test1543 test1544 test1545 test1546 \
|
|||||||
\
|
\
|
||||||
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
|
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
|
||||||
test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
|
test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
|
||||||
test1566 test1567 test1568 test1569 test1570 \
|
test1566 test1567 test1568 test1569 test1570 test1571 test1572 test1573 \
|
||||||
|
test1574 test1575 test1576 test1577 test1578 test1579 test1580 test1581 \
|
||||||
\
|
\
|
||||||
test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \
|
test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \
|
||||||
test1598 \
|
test1598 \
|
||||||
|
|||||||
95
tests/data/test1571
Normal file
95
tests/data/test1571
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib%TESTNUMBER
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom POST method, 302 => GET
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1571
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
mooGET /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
97
tests/data/test1572
Normal file
97
tests/data/test1572
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1571
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom POST method, 308 => custom
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1571
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
mooIGLOO /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
moo
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
92
tests/data/test1573
Normal file
92
tests/data/test1573
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1571
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom GET method, 301 => custom
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1573
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
IGLOO /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
92
tests/data/test1574
Normal file
92
tests/data/test1574
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_FIRSTONLY
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1571
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_FIRSTONLY with custom GET method, 301 => GET
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1574
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
97
tests/data/test1575
Normal file
97
tests/data/test1575
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_FIRSTONLY
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1571
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_FIRSTONLY with custom POST method, 308 => POST
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1575
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
mooPOST /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
moo
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
95
tests/data/test1576
Normal file
95
tests/data/test1576
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib%TESTNUMBER
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom PUT method, 302 => custom
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1576
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
CURL /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which madeCURL /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which made
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
95
tests/data/test1577
Normal file
95
tests/data/test1577
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1576
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom PUT method, 308 => custom
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER %TESTNUMBER
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
CURL /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which madeCURL /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which made
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
95
tests/data/test1578
Normal file
95
tests/data/test1578
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_FIRSTONLY
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 302 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1576
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_FIRSTONLY with custom PUT method, 302 => PUT
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER %TESTNUMBER
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
CURL /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which madePUT /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which made
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
93
tests/data/test1579
Normal file
93
tests/data/test1579
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 303 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 303 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1576
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom PUT method, 303 => GET
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER %TESTNUMBER
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol crlf="yes">
|
||||||
|
CURL /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which madeGET /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
95
tests/data/test1580
Normal file
95
tests/data/test1580
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_FIRSTONLY
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 308 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1576
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_FIRSTONLY with custom PUT method, 308 => PUT
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1578
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
CURL /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which madePUT /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 45
|
||||||
|
|
||||||
|
request indicates that the client, which made
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
97
tests/data/test1581
Normal file
97
tests/data/test1581
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
CURLFOLLOW_OBEYCODE
|
||||||
|
CURLOPT_FOLLOWLOCATION
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data crlf="yes">
|
||||||
|
HTTP/1.1 301 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
<data1 crlf="yes">
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</data>
|
||||||
|
<datacheck crlf="yes">
|
||||||
|
HTTP/1.1 301 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Location: %TESTNUMBER0001
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
-bar-
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<features>
|
||||||
|
http
|
||||||
|
</features>
|
||||||
|
<tool>
|
||||||
|
lib1571
|
||||||
|
</tool>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
CURLFOLLOW_OBEYCODE with custom POST301 method, 301 => custom
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/%TESTNUMBER 1581
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol nonewline="yes" crlf="yes">
|
||||||
|
IGLOO /%TESTNUMBER HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
mooIGLOO /%TESTNUMBER0001 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 3
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
moo
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
@ -60,7 +60,8 @@ LIBTESTPROGS = libauthretry libntlmconnect libprereq \
|
|||||||
lib1534 lib1535 lib1536 lib1537 lib1538 lib1539 \
|
lib1534 lib1535 lib1536 lib1537 lib1538 lib1539 \
|
||||||
lib1540 lib1541 lib1542 lib1543 lib1545 \
|
lib1540 lib1541 lib1542 lib1543 lib1545 \
|
||||||
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
|
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
|
||||||
lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 lib1568 lib1569 \
|
lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 lib1568 lib1569 lib1571 \
|
||||||
|
lib1576 lib1578 \
|
||||||
lib1591 lib1592 lib1593 lib1594 lib1596 lib1597 lib1598 \
|
lib1591 lib1592 lib1593 lib1594 lib1596 lib1597 lib1598 \
|
||||||
\
|
\
|
||||||
lib1662 \
|
lib1662 \
|
||||||
@ -523,6 +524,14 @@ lib1568_SOURCES = lib1568.c $(SUPPORTFILES)
|
|||||||
|
|
||||||
lib1569_SOURCES = lib1569.c $(SUPPORTFILES)
|
lib1569_SOURCES = lib1569.c $(SUPPORTFILES)
|
||||||
|
|
||||||
|
lib1571_SOURCES = lib1571.c $(SUPPORTFILES)
|
||||||
|
lib1571_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1571
|
||||||
|
|
||||||
|
lib1576_SOURCES = lib1576.c $(SUPPORTFILES)
|
||||||
|
|
||||||
|
lib1578_SOURCES = lib1576.c $(SUPPORTFILES)
|
||||||
|
lib1578_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1578
|
||||||
|
|
||||||
lib1591_SOURCES = lib1591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
lib1591_SOURCES = lib1591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
lib1591_LDADD = $(TESTUTIL_LIBS)
|
lib1591_LDADD = $(TESTUTIL_LIBS)
|
||||||
|
|
||||||
|
|||||||
72
tests/libtest/lib1571.c
Normal file
72
tests/libtest/lib1571.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at https://curl.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: curl
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
CURLcode test(char *URL)
|
||||||
|
{
|
||||||
|
CURLcode res;
|
||||||
|
CURL *curl;
|
||||||
|
int testno = atoi(libtest_arg2);
|
||||||
|
|
||||||
|
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||||
|
fprintf(stderr, "curl_global_init() failed\n");
|
||||||
|
return TEST_ERR_MAJOR_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(!curl) {
|
||||||
|
fprintf(stderr, "curl_easy_init() failed\n");
|
||||||
|
curl_global_cleanup();
|
||||||
|
return TEST_ERR_MAJOR_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_setopt(curl, CURLOPT_HEADER, 1L);
|
||||||
|
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
test_setopt(curl, CURLOPT_URL, URL);
|
||||||
|
if((testno == 1571) || (testno == 1575) || (testno == 1581)) {
|
||||||
|
test_setopt(curl, CURLOPT_POSTFIELDS, "moo");
|
||||||
|
}
|
||||||
|
if(testno == 1581) {
|
||||||
|
test_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_301);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_setopt(curl, CURLOPT_CUSTOMREQUEST, "IGLOO");
|
||||||
|
if((testno == 1574) || (testno == 1575)) {
|
||||||
|
test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_FIRSTONLY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_OBEYCODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
test_cleanup:
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
86
tests/libtest/lib1576.c
Normal file
86
tests/libtest/lib1576.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at https://curl.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: curl
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
static char testdata[] = "request indicates that the client, which made";
|
||||||
|
|
||||||
|
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
size_t amount = nmemb * size; /* Total bytes curl wants */
|
||||||
|
if(amount < strlen(testdata)) {
|
||||||
|
return strlen(testdata);
|
||||||
|
}
|
||||||
|
(void)stream;
|
||||||
|
memcpy(ptr, testdata, strlen(testdata));
|
||||||
|
return strlen(testdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode test(char *URL)
|
||||||
|
{
|
||||||
|
CURLcode res;
|
||||||
|
CURL *curl;
|
||||||
|
struct curl_slist *pHeaderList = NULL;
|
||||||
|
int testno = atoi(libtest_arg2);
|
||||||
|
|
||||||
|
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||||
|
fprintf(stderr, "curl_global_init() failed\n");
|
||||||
|
return TEST_ERR_MAJOR_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(!curl) {
|
||||||
|
fprintf(stderr, "curl_easy_init() failed\n");
|
||||||
|
curl_global_cleanup();
|
||||||
|
return TEST_ERR_MAJOR_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_setopt(curl, CURLOPT_HEADER, 1L);
|
||||||
|
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
test_setopt(curl, CURLOPT_URL, URL);
|
||||||
|
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
|
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||||
|
test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata));
|
||||||
|
|
||||||
|
test_setopt(curl, CURLOPT_CUSTOMREQUEST, "CURL");
|
||||||
|
if(testno == 1578) {
|
||||||
|
test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_FIRSTONLY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
test_setopt(curl, CURLOPT_FOLLOWLOCATION, CURLFOLLOW_OBEYCODE);
|
||||||
|
}
|
||||||
|
/* Remove "Expect: 100-continue" */
|
||||||
|
pHeaderList = curl_slist_append(pHeaderList, "Expect:");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaderList);
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
test_cleanup:
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_global_cleanup();
|
||||||
|
curl_slist_free_all(pHeaderList);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@ -58,11 +58,9 @@ CFGSET=true
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!INCLUDE "../lib/Makefile.inc"
|
!INCLUDE "../lib/Makefile.inc"
|
||||||
CSOURCES=$(CSOURCES: = )
|
|
||||||
LIBCURL_OBJS=$(CSOURCES:.c=.obj)
|
LIBCURL_OBJS=$(CSOURCES:.c=.obj)
|
||||||
|
|
||||||
!INCLUDE "../src/Makefile.inc"
|
!INCLUDE "../src/Makefile.inc"
|
||||||
CURL_CFILES=$(CURL_CFILES: = )
|
|
||||||
CURL_OBJS=$(CURL_CFILES:.c=.obj)
|
CURL_OBJS=$(CURL_CFILES:.c=.obj)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user