1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 #include "test.h"
23 #include "memdebug.h"
24 
test(char * URL)25 int test(char *URL)
26 {
27    CURLcode res;
28    CURL *curl = NULL;
29    char *newURL = NULL;
30    struct curl_slist *slist = NULL;
31 
32    if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
33      fprintf(stderr, "curl_global_init() failed\n");
34      return TEST_ERR_MAJOR_BAD;
35    }
36 
37    curl = curl_easy_init();
38    if(!curl) {
39      fprintf(stderr, "curl_easy_init() failed\n");
40      res = TEST_ERR_MAJOR_BAD;
41      goto test_cleanup;
42    }
43 
44    /* test: CURLFTPMETHOD_SINGLECWD with absolute path should
45             skip CWD to entry path */
46    newURL = aprintf("%s/folderA/661", URL);
47    test_setopt(curl, CURLOPT_URL, newURL);
48    test_setopt(curl, CURLOPT_VERBOSE, 1L);
49    test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L);
50    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD);
51    res = curl_easy_perform(curl);
52 
53    free(newURL);
54    newURL = aprintf("%s/folderB/661", URL);
55    test_setopt(curl, CURLOPT_URL, newURL);
56    res = curl_easy_perform(curl);
57 
58    /* test: CURLFTPMETHOD_NOCWD with absolute path should
59       never emit CWD (for both new and reused easy handle) */
60    curl_easy_cleanup(curl);
61    curl = curl_easy_init();
62    if(!curl) {
63      fprintf(stderr, "curl_easy_init() failed\n");
64      res = TEST_ERR_MAJOR_BAD;
65      goto test_cleanup;
66    }
67 
68    free(newURL);
69    newURL = aprintf("%s/folderA/661", URL);
70    test_setopt(curl, CURLOPT_URL, newURL);
71    test_setopt(curl, CURLOPT_VERBOSE, 1L);
72    test_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L);
73    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
74    res = curl_easy_perform(curl);
75 
76    /* curve ball: CWD /folderB before reusing connection with _NOCWD */
77    free(newURL);
78    newURL = aprintf("%s/folderB/661", URL);
79    test_setopt(curl, CURLOPT_URL, newURL);
80    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD);
81    res = curl_easy_perform(curl);
82 
83    free(newURL);
84    newURL = aprintf("%s/folderA/661", URL);
85    test_setopt(curl, CURLOPT_URL, newURL);
86    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
87    res = curl_easy_perform(curl);
88 
89    /* test: CURLFTPMETHOD_NOCWD with home-relative path should
90       not emit CWD for first FTP access after login */
91    curl_easy_cleanup(curl);
92    curl = curl_easy_init();
93    if(!curl) {
94      fprintf(stderr, "curl_easy_init() failed\n");
95      res = TEST_ERR_MAJOR_BAD;
96      goto test_cleanup;
97    }
98 
99    slist = curl_slist_append(NULL, "SYST");
100    if(slist == NULL) {
101      fprintf(stderr, "curl_slist_append() failed\n");
102      res = TEST_ERR_MAJOR_BAD;
103      goto test_cleanup;
104    }
105 
106    test_setopt(curl, CURLOPT_URL, URL);
107    test_setopt(curl, CURLOPT_VERBOSE, 1L);
108    test_setopt(curl, CURLOPT_NOBODY, 1L);
109    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
110    test_setopt(curl, CURLOPT_QUOTE, slist);
111    res = curl_easy_perform(curl);
112 
113    /* test: CURLFTPMETHOD_SINGLECWD with home-relative path should
114       not emit CWD for first FTP access after login */
115    curl_easy_cleanup(curl);
116    curl = curl_easy_init();
117    if(!curl) {
118      fprintf(stderr, "curl_easy_init() failed\n");
119      res = TEST_ERR_MAJOR_BAD;
120      goto test_cleanup;
121    }
122 
123    test_setopt(curl, CURLOPT_URL, URL);
124    test_setopt(curl, CURLOPT_VERBOSE, 1L);
125    test_setopt(curl, CURLOPT_NOBODY, 1L);
126    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD);
127    test_setopt(curl, CURLOPT_QUOTE, slist);
128    res = curl_easy_perform(curl);
129 
130    /* test: CURLFTPMETHOD_NOCWD with home-relative path should
131       not emit CWD for second FTP access when not needed +
132       bonus: see if path buffering survives curl_easy_reset() */
133    curl_easy_reset(curl);
134    test_setopt(curl, CURLOPT_URL, URL);
135    test_setopt(curl, CURLOPT_VERBOSE, 1L);
136    test_setopt(curl, CURLOPT_NOBODY, 1L);
137    test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
138    test_setopt(curl, CURLOPT_QUOTE, slist);
139    res = curl_easy_perform(curl);
140 
141 
142 test_cleanup:
143 
144    curl_slist_free_all(slist);
145    free(newURL);
146    curl_easy_cleanup(curl);
147    curl_global_cleanup();
148 
149    return (int)res;
150 }
151