Git init
[external/curl.git] / tests / libtest / lib552.c
1 /*****************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  *
9  * argv1 = URL
10  * argv2 = proxy with embedded user+password
11  */
12
13 #include "test.h"
14
15 #include "memdebug.h"
16
17 struct data {
18   char trace_ascii; /* 1 or 0 */
19 };
20
21 static
22 void dump(const char *text,
23           FILE *stream, unsigned char *ptr, size_t size,
24           char nohex)
25 {
26   size_t i;
27   size_t c;
28
29   unsigned int width=0x10;
30
31   if(nohex)
32     /* without the hex output, we can fit more on screen */
33     width = 0x40;
34
35   fprintf(stream, "%s, %d bytes (0x%x)\n", text, (int)size, (int)size);
36
37   for(i=0; i<size; i+= width) {
38
39     fprintf(stream, "%04x: ", (int)i);
40
41     if(!nohex) {
42       /* hex not disabled, show it */
43       for(c = 0; c < width; c++)
44         if(i+c < size)
45           fprintf(stream, "%02x ", ptr[i+c]);
46         else
47           fputs("   ", stream);
48     }
49
50     for(c = 0; (c < width) && (i+c < size); c++) {
51       /* check for 0D0A; if found, skip past and start a new line of output */
52       if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
53         i+=(c+2-width);
54         break;
55       }
56       fprintf(stream, "%c",
57               (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
58       /* check again for 0D0A, to avoid an extra \n if it's at width */
59       if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
60         i+=(c+3-width);
61         break;
62       }
63     }
64     fputc('\n', stream); /* newline */
65   }
66   fflush(stream);
67 }
68
69 static
70 int my_trace(CURL *handle, curl_infotype type,
71              char *data, size_t size,
72              void *userp)
73 {
74   struct data *config = (struct data *)userp;
75   const char *text;
76   (void)handle; /* prevent compiler warning */
77
78   switch (type) {
79   case CURLINFO_TEXT:
80     fprintf(stderr, "== Info: %s", (char *)data);
81   default: /* in case a new one is introduced to shock us */
82     return 0;
83
84   case CURLINFO_HEADER_OUT:
85     text = "=> Send header";
86     break;
87   case CURLINFO_DATA_OUT:
88     text = "=> Send data";
89     break;
90   case CURLINFO_SSL_DATA_OUT:
91     text = "=> Send SSL data";
92     break;
93   case CURLINFO_HEADER_IN:
94     text = "<= Recv header";
95     break;
96   case CURLINFO_DATA_IN:
97     text = "<= Recv data";
98     break;
99   case CURLINFO_SSL_DATA_IN:
100     text = "<= Recv SSL data";
101     break;
102   }
103
104   dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
105   return 0;
106 }
107
108
109 static size_t current_offset = 0;
110 static char databuf[70000]; /* MUST be more than 64k OR MAX_INITIAL_POST_SIZE */
111
112 static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
113 {
114   size_t  amount = nmemb * size; /* Total bytes curl wants */
115   size_t  available = sizeof(databuf) - current_offset; /* What we have to give */
116   size_t  given = amount < available ? amount : available; /* What is given */
117   (void)stream;
118   memcpy(ptr, databuf + current_offset, given);
119   current_offset += given;
120   return given;
121 }
122
123
124 static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
125 {
126   printf("%.*s", (int)(size * nmemb), (char *)ptr);
127   (void)stream;
128   return size * nmemb;
129 }
130
131
132 static curlioerr ioctl_callback(CURL * handle, int cmd, void *clientp)
133 {
134   (void)clientp;
135   if (cmd == CURLIOCMD_RESTARTREAD ) {
136     printf("APPLICATION: recieved a CURLIOCMD_RESTARTREAD request\n");
137     printf("APPLICATION: ** REWINDING! **\n");
138     current_offset = 0;
139     return CURLIOE_OK;
140   }
141   (void)handle;
142   return CURLIOE_UNKNOWNCMD;
143 }
144
145
146
147 int test(char *URL)
148 {
149   CURL *curl;
150   CURLcode res = CURLE_OUT_OF_MEMORY;
151   struct data config;
152   size_t i;
153   static const char fill[] = "test data";
154
155   config.trace_ascii = 1; /* enable ascii tracing */
156
157   if((curl = curl_easy_init()) == NULL) {
158     fprintf(stderr, "curl_easy_init() failed\n");
159     curl_global_cleanup();
160     return TEST_ERR_MAJOR_BAD;
161   }
162
163   test_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
164   test_setopt(curl, CURLOPT_DEBUGDATA, &config);
165   /* the DEBUGFUNCTION has no effect until we enable VERBOSE */
166   test_setopt(curl, CURLOPT_VERBOSE, 1L);
167
168   /* setup repeated data string */
169   for (i=0; i < sizeof(databuf); ++i)
170       databuf[i] = fill[i % sizeof fill];
171
172   /* Post */
173   test_setopt(curl, CURLOPT_POST, 1L);
174
175 #ifdef CURL_DOES_CONVERSIONS
176   /* Convert the POST data to ASCII */
177   test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
178 #endif
179
180   /* Setup read callback */
181   test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(databuf));
182   test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
183
184   /* Write callback */
185   test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
186
187   /* Ioctl function */
188   test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback);
189
190   test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
191
192   test_setopt(curl, CURLOPT_URL, URL);
193
194   /* Accept any auth. But for this bug configure proxy with DIGEST, basic might work too, not NTLM */
195   test_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
196
197   res = curl_easy_perform(curl);
198   fprintf(stderr, "curl_easy_perform = %d\n", (int)res);
199
200 test_cleanup:
201
202   curl_easy_cleanup(curl);
203   curl_global_cleanup();
204   return (int)res;
205 }