Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 711 lines (619 sloc) 20.936 kb
ba4e69b @bagder updated source code boilerplate/header
authored
1 /***************************************************************************
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
ae1912c @bagder Initial revision
authored
6 * \___|\___/|_| \_\_____|
7 *
df5578a @bagder mprintf.h: remove #ifdef CURLDEBUG
authored
8 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
ae1912c @bagder Initial revision
authored
9 *
ba4e69b @bagder updated source code boilerplate/header
authored
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 http://curl.haxx.se/docs/copyright.html.
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
13 *
24dee48 @bagder dual-license fix
authored
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
ba4e69b @bagder updated source code boilerplate/header
authored
16 * furnished to do so, under the terms of the COPYING file.
ae1912c @bagder Initial revision
authored
17 *
24dee48 @bagder dual-license fix
authored
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
ae1912c @bagder Initial revision
authored
20 *
ba4e69b @bagder updated source code boilerplate/header
authored
21 ***************************************************************************/
ae1912c @bagder Initial revision
authored
22
5a053ff @yangtse build: fix circular header inclusion with other packages
yangtse authored
23 #include "curl_setup.h"
b6e18f2 @bagder #include "setup.h" moved first of all includes
authored
24
ae1912c @bagder Initial revision
authored
25 #include <curl/curl.h>
a0b2071 @yangtse setup_once.h: refactor inclusion of <unistd.h> and <sys/socket.h>
yangtse authored
26
4a5aa66 @yangtse Revert changes relative to lib/*.[ch] recent renaming
yangtse authored
27 #include "urldata.h"
28 #include "sendf.h"
29 #include "connect.h"
11e8066 @bagder vtls: renamed sslgen.[ch] to vtls.[ch]
authored
30 #include "vtls/vtls.h"
4a5aa66 @yangtse Revert changes relative to lib/*.[ch] recent renaming
yangtse authored
31 #include "ssh.h"
32 #include "multiif.h"
33 #include "non-ascii.h"
df5578a @bagder mprintf.h: remove #ifdef CURLDEBUG
authored
34 #include "curl_printf.h"
4a5aa66 @yangtse Revert changes relative to lib/*.[ch] recent renaming
yangtse authored
35 #include "strerror.h"
c828646 @bagder CURL_DOES_CONVERSIONS: cleanup
authored
36
35648f2 @dfandrich curl_memory: make curl_memory.h the second-last header file loaded
dfandrich authored
37 /* The last #include files should be: */
38 #include "curl_memory.h"
4a5aa66 @yangtse Revert changes relative to lib/*.[ch] recent renaming
yangtse authored
39 #include "memdebug.h"
a82eb0f @bagder adjusted to support krb4
authored
40
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
41 #ifdef CURL_DO_LINEEND_CONV
42 /*
43 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
44 * (\n), with special processing for CRLF sequences that are split between two
45 * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
46 * size of the data is returned.
47 */
48 static size_t convert_lineends(struct SessionHandle *data,
49 char *startPtr, size_t size)
50 {
51 char *inPtr, *outPtr;
52
53 /* sanity check */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
54 if((startPtr == NULL) || (size < 1)) {
a6b8fe2 @bagder checksrc: use space before paren in "return (expr);"
authored
55 return size;
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
56 }
57
a502107 @yangtse fix bool variables checking and assignment
yangtse authored
58 if(data->state.prev_block_had_trailing_cr) {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
59 /* The previous block of incoming data
60 had a trailing CR, which was turned into a LF. */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
61 if(*startPtr == '\n') {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
62 /* This block of incoming data starts with the
63 previous block's LF so get rid of it */
b0b40d9 @bagder Andrew Moise filed bug report #1847501
authored
64 memmove(startPtr, startPtr+1, size-1);
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
65 size--;
66 /* and it wasn't a bare CR but a CRLF conversion instead */
67 data->state.crlf_conversions++;
68 }
69 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
70 }
71
72 /* find 1st CR, if any */
73 inPtr = outPtr = memchr(startPtr, '\r', size);
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
74 if(inPtr) {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
75 /* at least one CR, now look for CRLF */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
76 while(inPtr < (startPtr+size-1)) {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
77 /* note that it's size-1, so we'll never look past the last byte */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
78 if(memcmp(inPtr, "\r\n", 2) == 0) {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
79 /* CRLF found, bump past the CR and copy the NL */
80 inPtr++;
81 *outPtr = *inPtr;
82 /* keep track of how many CRLFs we converted */
83 data->state.crlf_conversions++;
84 }
85 else {
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
86 if(*inPtr == '\r') {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
87 /* lone CR, move LF instead */
88 *outPtr = '\n';
89 }
90 else {
91 /* not a CRLF nor a CR, just copy whatever it is */
92 *outPtr = *inPtr;
93 }
94 }
95 outPtr++;
96 inPtr++;
97 } /* end of while loop */
98
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
99 if(inPtr < startPtr+size) {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
100 /* handle last byte */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
101 if(*inPtr == '\r') {
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
102 /* deal with a CR at the end of the buffer */
103 *outPtr = '\n'; /* copy a NL instead */
104 /* note that a CRLF might be split across two blocks */
105 data->state.prev_block_had_trailing_cr = TRUE;
106 }
107 else {
108 /* copy last byte */
109 *outPtr = *inPtr;
110 }
111 outPtr++;
112 }
3521770 @bagder - Fabian Keil ran clang on the (lib)curl code, found a bunch of warni…
authored
113 if(outPtr < startPtr+size)
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
114 /* tidy up by null terminating the now shorter data */
115 *outPtr = '\0';
3521770 @bagder - Fabian Keil ran clang on the (lib)curl code, found a bunch of warni…
authored
116
a6b8fe2 @bagder checksrc: use space before paren in "return (expr);"
authored
117 return (outPtr - startPtr);
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
118 }
a6b8fe2 @bagder checksrc: use space before paren in "return (expr);"
authored
119 return size;
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
120 }
121 #endif /* CURL_DO_LINEEND_CONV */
122
c622f2b @bagder failf() now respects the mute flag
authored
123 /* Curl_infof() is for info message along the way */
ae1912c @bagder Initial revision
authored
124
0ece1b5 @bagder Major rename and redesign of the internal "backbone" structs. Details…
authored
125 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
ae1912c @bagder Initial revision
authored
126 {
96e217b @bagder the new cookie functions that require 'data' passed in
authored
127 if(data && data->set.verbose) {
128 va_list ap;
ec956b0 @yangtse Explicit typecast for Curl_debug() size argument
yangtse authored
129 size_t len;
4c97685 @bagder - Introducing CURLOPT_CERTINFO and the corresponding CURLINFO_CERTINF…
authored
130 char print_buffer[2048 + 1];
ae1912c @bagder Initial revision
authored
131 va_start(ap, fmt);
4c97685 @bagder - Introducing CURLOPT_CERTINFO and the corresponding CURLINFO_CERTINF…
authored
132 vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
ae1912c @bagder Initial revision
authored
133 va_end(ap);
ec956b0 @yangtse Explicit typecast for Curl_debug() size argument
yangtse authored
134 len = strlen(print_buffer);
135 Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
ae1912c @bagder Initial revision
authored
136 }
137 }
138
e192261 @bagder failf() calls should not have newlines in the message string!
authored
139 /* Curl_failf() is for messages stating why we failed.
140 * The message SHALL NOT include any LF or CR.
141 */
ae1912c @bagder Initial revision
authored
142
0ece1b5 @bagder Major rename and redesign of the internal "backbone" structs. Details…
authored
143 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
ae1912c @bagder Initial revision
authored
144 {
145 va_list ap;
a173e07 @bagder Prevent failf() from using the va_list variable more than once.
authored
146 size_t len;
444f642 @bagder oops, variables first then code
authored
147 va_start(ap, fmt);
a173e07 @bagder Prevent failf() from using the va_list variable more than once.
authored
148
149 vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
150
4163b86 @bagder failf() now only overwrites the error buffer the first time it gets c…
authored
151 if(data->set.errorbuffer && !data->state.errorbuf) {
a173e07 @bagder Prevent failf() from using the va_list variable more than once.
authored
152 snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
4163b86 @bagder failf() now only overwrites the error buffer the first time it gets c…
authored
153 data->state.errorbuf = TRUE; /* wrote error string */
4435e3b @bagder Fixed so that the final error message is sent to the verbose info "st…
authored
154 }
155 if(data->set.verbose) {
a173e07 @bagder Prevent failf() from using the va_list variable more than once.
authored
156 len = strlen(data->state.buffer);
157 if(len < BUFSIZE - 1) {
158 data->state.buffer[len] = '\n';
159 data->state.buffer[++len] = '\0';
160 }
161 Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
4163b86 @bagder failf() now only overwrites the error buffer the first time it gets c…
authored
162 }
4435e3b @bagder Fixed so that the final error message is sent to the verbose info "st…
authored
163
ae1912c @bagder Initial revision
authored
164 va_end(ap);
165 }
166
1552bd9 @bagder sendf is now only Curl_sendf
authored
167 /* Curl_sendf() sends formated data to the server */
ce5805a @bagder Use curl_socket_t instead of int for holding sockets. The typedefs and
authored
168 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
eaf475b @bagder return type cleanup
authored
169 const char *fmt, ...)
ae1912c @bagder Initial revision
authored
170 {
0ece1b5 @bagder Major rename and redesign of the internal "backbone" structs. Details…
authored
171 struct SessionHandle *data = conn->data;
df01507 @bagder Curl_read() and Curl_write() are both now adjusted to return properly in
authored
172 ssize_t bytes_written;
d571064 @bagder Clear up int/long/size_t/ssize_t usage a bit
authored
173 size_t write_len;
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
174 CURLcode result = CURLE_OK;
ae1912c @bagder Initial revision
authored
175 char *s;
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
176 char *sptr;
ae1912c @bagder Initial revision
authored
177 va_list ap;
178 va_start(ap, fmt);
1552bd9 @bagder sendf is now only Curl_sendf
authored
179 s = vaprintf(fmt, ap); /* returns an allocated string */
ae1912c @bagder Initial revision
authored
180 va_end(ap);
181 if(!s)
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
182 return CURLE_OUT_OF_MEMORY; /* failure */
183
184 bytes_written=0;
185 write_len = strlen(s);
186 sptr = s;
187
d1717e7 @yangtse Fix compiler warning: conditional expression is constant
yangtse authored
188 for(;;) {
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
189 /* Write the buffer to the socket */
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
190 result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
191
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
192 if(result)
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
193 break;
194
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
195 if(data->set.verbose)
ec956b0 @yangtse Explicit typecast for Curl_debug() size argument
yangtse authored
196 Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
197
d571064 @bagder Clear up int/long/size_t/ssize_t usage a bit
authored
198 if((size_t)bytes_written != write_len) {
bc9705f @bagder sendf() now deals with Curl_write() returning -1 properly, which it m…
authored
199 /* if not all was written at once, we must advance the pointer, decrease
200 the size left and try again! */
201 write_len -= bytes_written;
202 sptr += bytes_written;
203 }
204 else
205 break;
4d17d68 @bagder Dan Fandrich's cleanup patch to make pedantic compiler options cause …
authored
206 }
1552bd9 @bagder sendf is now only Curl_sendf
authored
207
ae1912c @bagder Initial revision
authored
208 free(s); /* free the output string */
1552bd9 @bagder sendf is now only Curl_sendf
authored
209
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
210 return result;
ae1912c @bagder Initial revision
authored
211 }
212
1552bd9 @bagder sendf is now only Curl_sendf
authored
213 /*
be0d17e @bagder cleaned up Curl_write() and the sub functions it uses for various pro…
authored
214 * Curl_write() is an internal write function that sends data to the
215 * server. Works with plain sockets, SCP, SSL or kerberos.
ff87111 @kdudka refactorize interface of Curl_ssl_recv/Curl_ssl_send
kdudka authored
216 *
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
217 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
ff87111 @kdudka refactorize interface of Curl_ssl_recv/Curl_ssl_send
kdudka authored
218 * (*written == 0). Otherwise we return regular CURLcode value.
1552bd9 @bagder sendf is now only Curl_sendf
authored
219 */
1e98727 @bagder FTPS support added as RFC2228 and the murray-ftp-auth-ssl draft descr…
authored
220 CURLcode Curl_write(struct connectdata *conn,
ce5805a @bagder Use curl_socket_t instead of int for holding sockets. The typedefs and
authored
221 curl_socket_t sockfd,
e2b82b4 @michal42 - Make Curl_write and it's callees accept a const pointer, in prepara…
michal42 authored
222 const void *mem,
ce5805a @bagder Use curl_socket_t instead of int for holding sockets. The typedefs and
authored
223 size_t len,
df01507 @bagder Curl_read() and Curl_write() are both now adjusted to return properly in
authored
224 ssize_t *written)
1b1f143 @bagder hostname and large file support added
authored
225 {
df01507 @bagder Curl_read() and Curl_write() are both now adjusted to return properly in
authored
226 ssize_t bytes_written;
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
227 CURLcode result = CURLE_OK;
1e98727 @bagder FTPS support added as RFC2228 and the murray-ftp-auth-ssl draft descr…
authored
228 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
6e61939 @bagder GnuTLS support added. There's now a "generic" SSL layer that we use a…
authored
229
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
230 bytes_written = conn->send[num](conn, num, mem, len, &result);
bc7fe85 @bagder Just moved around some logic in Curl_write() to make it easier to debug.
authored
231
1552bd9 @bagder sendf is now only Curl_sendf
authored
232 *written = bytes_written;
1b15b31 @bagder sendrecv: treat all negative values from send/recv as errors
authored
233 if(bytes_written >= 0)
234 /* we completely ignore the curlcode value when subzero is not returned */
ff87111 @kdudka refactorize interface of Curl_ssl_recv/Curl_ssl_send
kdudka authored
235 return CURLE_OK;
bc7fe85 @bagder Just moved around some logic in Curl_write() to make it easier to debug.
authored
236
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
237 /* handle CURLE_AGAIN or a send failure */
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
238 switch(result) {
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
239 case CURLE_AGAIN:
240 *written = 0;
ff87111 @kdudka refactorize interface of Curl_ssl_recv/Curl_ssl_send
kdudka authored
241 return CURLE_OK;
242
243 case CURLE_OK:
244 /* general send failure */
245 return CURLE_SEND_ERROR;
246
247 default:
248 /* we got a specific curlcode, forward it */
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
249 return result;
ff87111 @kdudka refactorize interface of Curl_ssl_recv/Curl_ssl_send
kdudka authored
250 }
1b1f143 @bagder hostname and large file support added
authored
251 }
252
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
253 ssize_t Curl_send_plain(struct connectdata *conn, int num,
254 const void *mem, size_t len, CURLcode *code)
255 {
256 curl_socket_t sockfd = conn->sock[num];
257 ssize_t bytes_written = swrite(sockfd, mem, len);
258
259 *code = CURLE_OK;
260 if(-1 == bytes_written) {
261 int err = SOCKERRNO;
262
263 if(
264 #ifdef WSAEWOULDBLOCK
265 /* This is how Windows does it */
266 (WSAEWOULDBLOCK == err)
267 #else
268 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
269 due to its inability to send off data without blocking. We therefor
270 treat both error codes the same here */
271 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
272 #endif
273 ) {
274 /* this is just a case of EWOULDBLOCK */
275 bytes_written=0;
276 *code = CURLE_AGAIN;
b903186 @bagder source cleanup: unify look, style and indent levels
authored
277 }
278 else {
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
279 failf(conn->data, "Send failure: %s",
280 Curl_strerror(conn, err));
c2bfe60 @bagder Curl_send/recv_plain: return errno on failure
authored
281 conn->data->state.os_errno = err;
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
282 *code = CURLE_SEND_ERROR;
283 }
284 }
285 return bytes_written;
286 }
287
422fd93 @bagder - Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
authored
288 /*
289 * Curl_write_plain() is an internal write function that sends data to the
290 * server using plain sockets only. Otherwise meant to have the exact same
291 * proto as Curl_write()
292 */
293 CURLcode Curl_write_plain(struct connectdata *conn,
294 curl_socket_t sockfd,
295 const void *mem,
296 size_t len,
297 ssize_t *written)
298 {
299 ssize_t bytes_written;
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
300 CURLcode result;
422fd93 @bagder - Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
authored
301 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
302
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
303 bytes_written = Curl_send_plain(conn, num, mem, len, &result);
422fd93 @bagder - Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
authored
304
305 *written = bytes_written;
306
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
307 return result;
422fd93 @bagder - Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
authored
308 }
309
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
310 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
311 size_t len, CURLcode *code)
312 {
313 curl_socket_t sockfd = conn->sock[num];
314 ssize_t nread = sread(sockfd, buf, len);
315
316 *code = CURLE_OK;
317 if(-1 == nread) {
318 int err = SOCKERRNO;
319
320 if(
321 #ifdef WSAEWOULDBLOCK
322 /* This is how Windows does it */
323 (WSAEWOULDBLOCK == err)
324 #else
325 /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
326 due to its inability to send off data without blocking. We therefor
327 treat both error codes the same here */
328 (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
329 #endif
330 ) {
331 /* this is just a case of EWOULDBLOCK */
332 *code = CURLE_AGAIN;
b903186 @bagder source cleanup: unify look, style and indent levels
authored
333 }
334 else {
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
335 failf(conn->data, "Recv failure: %s",
336 Curl_strerror(conn, err));
c2bfe60 @bagder Curl_send/recv_plain: return errno on failure
authored
337 conn->data->state.os_errno = err;
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
338 *code = CURLE_RECV_ERROR;
339 }
340 }
341 return nread;
342 }
343
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
344 static CURLcode pausewrite(struct SessionHandle *data,
345 int type, /* what type of data */
bb67388 @dfandrich Made some variables const
dfandrich authored
346 const char *ptr,
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
347 size_t len)
348 {
349 /* signalled to pause sending on this connection, but since we have data
350 we want to send we need to dup it to save a copy for when the sending
351 is again enabled */
352 struct SingleRequest *k = &data->req;
353 char *dupl = malloc(len);
354 if(!dupl)
355 return CURLE_OUT_OF_MEMORY;
356
357 memcpy(dupl, ptr, len);
358
359 /* store this information in the state struct for later use */
360 data->state.tempwrite = dupl;
361 data->state.tempwritesize = len;
362 data->state.tempwritetype = type;
363
364 /* mark the connection as RECV paused */
3aa3d7e @bagder Internal cleanup: KEEP_WRITE and KEEP_READ are now called KEEP_SEND and
authored
365 k->keepon |= KEEP_RECV_PAUSE;
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
366
7aef172 @yangtse fix printf-style format strings
yangtse authored
367 DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
368 len, type));
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
369
370 return CURLE_OK;
371 }
372
373
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
374 /* Curl_client_chop_write() writes chunks of data not larger than
375 * CURL_MAX_WRITE_SIZE via client write callback(s) and
376 * takes care of pause requests from the callbacks.
39abde5 @bagder Added the client_write() function
authored
377 */
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
378 CURLcode Curl_client_chop_write(struct connectdata *conn,
379 int type,
380 char * ptr,
381 size_t len)
39abde5 @bagder Added the client_write() function
authored
382 {
cfdcae4 @bagder Based on a patch by Armel Asselin, the FTP code no longer re-issues t…
authored
383 struct SessionHandle *data = conn->data;
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
384 curl_write_callback writeheader = NULL;
385 curl_write_callback writebody = NULL;
39abde5 @bagder Added the client_write() function
authored
386
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
387 if(!len)
388 return CURLE_OK;
c331c73 @michal42 - Fixed a potential data loss in Curl_client_write() when the transfe…
michal42 authored
389
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
390 /* If reading is actually paused, we're forced to append this chunk of data
391 to the already held data, but only if it is the same type as otherwise it
392 can't work and it'll return error instead. */
3aa3d7e @bagder Internal cleanup: KEEP_WRITE and KEEP_READ are now called KEEP_SEND and
authored
393 if(data->req.keepon & KEEP_RECV_PAUSE) {
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
394 size_t newlen;
395 char *newptr;
396 if(type != data->state.tempwritetype)
397 /* major internal confusion */
398 return CURLE_RECV_ERROR;
399
3acd114 @dfandrich Use realloc when paused in Curl_client_write
dfandrich authored
400 DEBUGASSERT(data->state.tempwrite);
401
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
402 /* figure out the new size of the data to save */
403 newlen = len + data->state.tempwritesize;
404 /* allocate the new memory area */
3acd114 @dfandrich Use realloc when paused in Curl_client_write
dfandrich authored
405 newptr = realloc(data->state.tempwrite, newlen);
de23b98 @bagder Introducing curl_easy_pause() and new magic return codes for both the…
authored
406 if(!newptr)
407 return CURLE_OUT_OF_MEMORY;
408 /* copy the new data to the end of the new area */
409 memcpy(newptr + data->state.tempwritesize, ptr, len);
410 /* update the pointer and the size */
411 data->state.tempwrite = newptr;
412 data->state.tempwritesize = newlen;
413 return CURLE_OK;
b7eeb6e @bagder Major overhaul introducing http pipelining support and shared connection
authored
414 }
415
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
416 /* Determine the callback(s) to use. */
417 if(type & CLIENTWRITE_BODY)
418 writebody = data->set.fwrite_func;
419 if((type & CLIENTWRITE_HEADER) &&
420 (data->set.fwrite_header || data->set.writeheader)) {
421 /*
422 * Write headers to the same callback or to the especially setup
423 * header callback function (added after version 7.7.1).
424 */
425 writeheader =
426 data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
427 }
428
429 /* Chop data, write chunks. */
430 while(len) {
431 size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
432
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
433 if(writebody) {
434 size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
95152ae @bagder David McCreedy brought line end conversions when doing FTP ASCII
authored
435
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
436 if(CURL_WRITEFUNC_PAUSE == wrote) {
437 if(conn->handler->flags & PROTOPT_NONETWORK) {
438 /* Protocols that work without network cannot be paused. This is
439 actually only FILE:// just now, and it can't pause since the
440 transfer isn't done using the "normal" procedure. */
441 failf(data, "Write callback asked for PAUSE when not supported!");
442 return CURLE_WRITE_ERROR;
443 }
444 else
445 return pausewrite(data, type, ptr, len);
446 }
447 else if(wrote != chunklen) {
448 failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
f2d234a @captain-caveman2k FILE: Fixed sending of data would always return CURLE_WRITE_ERROR
captain-caveman2k authored
449 return CURLE_WRITE_ERROR;
450 }
39abde5 @bagder Added the client_write() function
authored
451 }
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
452
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
453 if(writeheader) {
454 size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
455
456 if(CURL_WRITEFUNC_PAUSE == wrote)
457 /* here we pass in the HEADER bit only since if this was body as well
458 then it was passed already and clearly that didn't trigger the
459 pause, so this is saved for later with the HEADER bit only */
460 return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
461
462 if(wrote != chunklen) {
463 failf (data, "Failed writing header");
464 return CURLE_WRITE_ERROR;
465 }
39abde5 @bagder Added the client_write() function
authored
466 }
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
467
468 ptr += chunklen;
469 len -= chunklen;
39abde5 @bagder Added the client_write() function
authored
470 }
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
471
39abde5 @bagder Added the client_write() function
authored
472 return CURLE_OK;
473 }
474
6ea4ee9 @monnerat Curl_client_write() & al.: chop long data, convert data only once.
monnerat authored
475
476 /* Curl_client_write() sends data to the write callback(s)
477
478 The bit pattern defines to what "streams" to write to. Body and/or header.
479 The defines are in sendf.h of course.
480
481 If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
482 local character encoding. This is a problem and should be changed in
483 the future to leave the original data alone.
484 */
485 CURLcode Curl_client_write(struct connectdata *conn,
486 int type,
487 char *ptr,
488 size_t len)
489 {
490 struct SessionHandle *data = conn->data;
491
492 if(0 == len)
493 len = strlen(ptr);
494
495 /* FTP data may need conversion. */
496 if((type & CLIENTWRITE_BODY) &&
497 (conn->handler->protocol & PROTO_FAMILY_FTP) &&
498 conn->proto.ftpc.transfertype == 'A') {
499 /* convert from the network encoding */
500 CURLcode result = Curl_convert_from_network(data, ptr, len);
501 /* Curl_convert_from_network calls failf if unsuccessful */
502 if(result)
503 return result;
504
505 #ifdef CURL_DO_LINEEND_CONV
506 /* convert end-of-line markers */
507 len = convert_lineends(data, ptr, len);
508 #endif /* CURL_DO_LINEEND_CONV */
509 }
510
511 return Curl_client_chop_write(conn, type, ptr, len);
512 }
513
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
514 CURLcode Curl_read_plain(curl_socket_t sockfd,
391e8af @bagder - Made the SOCKS code use the new Curl_read_plain() function to fix t…
authored
515 char *buf,
516 size_t bytesfromsocket,
517 ssize_t *n)
518 {
519 ssize_t nread = sread(sockfd, buf, bytesfromsocket);
520
521 if(-1 == nread) {
522 int err = SOCKERRNO;
523 #ifdef USE_WINSOCK
524 if(WSAEWOULDBLOCK == err)
525 #else
526 if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
527 #endif
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
528 return CURLE_AGAIN;
391e8af @bagder - Made the SOCKS code use the new Curl_read_plain() function to fix t…
authored
529 else
530 return CURLE_RECV_ERROR;
531 }
532
533 /* we only return number of bytes read when we return OK */
534 *n = nread;
535 return CURLE_OK;
536 }
537
1552bd9 @bagder sendf is now only Curl_sendf
authored
538 /*
539 * Internal read-from-socket function. This is meant to deal with plain
540 * sockets, SSL sockets and kerberos sockets.
4931fbc @bagder Curl_read() now returns a negative return code if EWOULDBLOCK or similar
authored
541 *
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
542 * Returns a regular CURLcode value.
1552bd9 @bagder sendf is now only Curl_sendf
authored
543 */
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
544 CURLcode Curl_read(struct connectdata *conn, /* connection data */
0fd2bf3 @bagder Curl_read_plain: indent code
authored
545 curl_socket_t sockfd, /* read from this socket */
546 char *buf, /* store read data here */
547 size_t sizerequested, /* max amount to read */
548 ssize_t *n) /* amount bytes read */
1552bd9 @bagder sendf is now only Curl_sendf
authored
549 {
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
550 CURLcode result = CURLE_RECV_ERROR;
6a175b4 Suppress warning "'nread' might be used uninitialized in this function".
Gisle Vanem authored
551 ssize_t nread = 0;
e1edd41 @bagder Ravi Pratap provided a major update with pipelining fixes. We also no…
authored
552 size_t bytesfromsocket = 0;
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
553 char *buffertofill = NULL;
02ec1ce @bagder CURLMOPT_PIPELINE: bit 1 is for multiplexing
authored
554 bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1);
6e61939 @bagder GnuTLS support added. There's now a "generic" SSL layer that we use a…
authored
555
1e98727 @bagder FTPS support added as RFC2228 and the murray-ftp-auth-ssl draft descr…
authored
556 /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
557 If it is the second socket, we set num to 1. Otherwise to 0. This lets
558 us use the correct ssl handle. */
559 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
560
39dc14c @bagder Fixed the usage of SSL_read() to properly return -1 if the EWOULDBLOCK
authored
561 *n=0; /* reset amount to zero */
1552bd9 @bagder sendf is now only Curl_sendf
authored
562
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
563 /* If session can pipeline, check connection buffer */
564 if(pipelining) {
33ce0ec @bagder wrap long lines and do some indent policing
authored
565 size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
566 sizerequested);
b7eeb6e @bagder Major overhaul introducing http pipelining support and shared connection
authored
567
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
568 /* Copy from our master buffer first if we have some unread data there*/
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
569 if(bytestocopy > 0) {
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
570 memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
571 conn->read_pos += bytestocopy;
572 conn->bits.stream_was_rewound = FALSE;
b7eeb6e @bagder Major overhaul introducing http pipelining support and shared connection
authored
573
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
574 *n = (ssize_t)bytestocopy;
575 return CURLE_OK;
576 }
577 /* If we come here, it means that there is no data to read from the buffer,
578 * so we read from the socket */
80ffd35 @dfandrich Created a CURLMIN macro to match CURLMAX
dfandrich authored
579 bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
580 buffertofill = conn->master_buffer;
581 }
582 else {
33ce0ec @bagder wrap long lines and do some indent policing
authored
583 bytesfromsocket = CURLMIN((long)sizerequested,
584 conn->data->set.buffer_size ?
585 conn->data->set.buffer_size : BUFSIZE);
d8ff033 @bagder - Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
authored
586 buffertofill = buf;
587 }
e1edd41 @bagder Ravi Pratap provided a major update with pipelining fixes. We also no…
authored
588
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
589 nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
1b15b31 @bagder sendrecv: treat all negative values from send/recv as errors
authored
590 if(nread < 0)
0eb3d15 @bagder code cleanup: we prefer 'CURLcode result'
authored
591 return result;
6e61939 @bagder GnuTLS support added. There's now a "generic" SSL layer that we use a…
authored
592
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
593 if(pipelining) {
594 memcpy(buf, conn->master_buffer, nread);
595 conn->buf_len = nread;
596 conn->read_pos = nread;
1552bd9 @bagder sendf is now only Curl_sendf
authored
597 }
b7eeb6e @bagder Major overhaul introducing http pipelining support and shared connection
authored
598
d64bd82 sendrecv: split the I/O handling into private handler
Howard Chu authored
599 *n += nread;
b7eeb6e @bagder Major overhaul introducing http pipelining support and shared connection
authored
600
1552bd9 @bagder sendf is now only Curl_sendf
authored
601 return CURLE_OK;
602 }
603
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
604 /* return 0 on success */
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
605 static int showit(struct SessionHandle *data, curl_infotype type,
0f77fe5 @dfandrich Reverted the const change--what was I thinking?
dfandrich authored
606 char *ptr, size_t size)
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
607 {
7fc4e8a @dfandrich Changed some arrays of char* to arrays of char[] to reduce data size and
dfandrich authored
608 static const char s_infotype[CURLINFO_END][3] = {
bd3d5a1 @bagder Gisle's "SSL patch" from June 16th 2004, modified by me as discussed …
authored
609 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
610
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
611 #ifdef CURL_DOES_CONVERSIONS
612 char buf[BUFSIZE+1];
7b704e1 Supress "comparison between signed and unsigned" warning.
Gisle Vanem authored
613 size_t conv_size = 0;
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
614
615 switch(type) {
616 case CURLINFO_HEADER_OUT:
617 /* assume output headers are ASCII */
618 /* copy the data into my buffer so the original is unchanged */
ad6e280 @bagder removed space after if and while before the parenthesis for better so…
authored
619 if(size > BUFSIZE) {
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
620 size = BUFSIZE; /* truncate if necessary */
621 buf[BUFSIZE] = '\0';
622 }
0fb5a65 @bagder - David McCreedy provided libcurl changes for doing HTTP communicatio…
authored
623 conv_size = size;
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
624 memcpy(buf, ptr, size);
0fb5a65 @bagder - David McCreedy provided libcurl changes for doing HTTP communicatio…
authored
625 /* Special processing is needed for this block if it
626 * contains both headers and data (separated by CRLFCRLF).
627 * We want to convert just the headers, leaving the data as-is.
628 */
629 if(size > 4) {
7b704e1 Supress "comparison between signed and unsigned" warning.
Gisle Vanem authored
630 size_t i;
0fb5a65 @bagder - David McCreedy provided libcurl changes for doing HTTP communicatio…
authored
631 for(i = 0; i < size-4; i++) {
632 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
1702a2c Fix a couple of spelling errors in lib/
Fabian Keil authored
633 /* convert everything through this CRLFCRLF but no further */
0fb5a65 @bagder - David McCreedy provided libcurl changes for doing HTTP communicatio…
authored
634 conv_size = i + 4;
635 break;
636 }
637 }
638 }
639
640 Curl_convert_from_network(data, buf, conv_size);
5a4b438 @bagder First commit of David McCreedy's EBCDIC and TPF changes.
authored
641 /* Curl_convert_from_network calls failf if unsuccessful */
642 /* we might as well continue even if it fails... */
643 ptr = buf; /* switch pointer to use my buffer instead */
644 break;
645 default:
646 /* leave everything else as-is */
647 break;
648 }
649 #endif /* CURL_DOES_CONVERSIONS */
650
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
651 if(data->set.fdebug)
652 return (*data->set.fdebug)(data, type, ptr, size,
653 data->set.debugdata);
654
d321056 @bagder made VERBOSE output more like it used to be, HEADER_IN is thus also i…
authored
655 switch(type) {
656 case CURLINFO_TEXT:
657 case CURLINFO_HEADER_OUT:
3c3ad13 @bagder the default debugfunction shows incoming headers as well
authored
658 case CURLINFO_HEADER_IN:
d321056 @bagder made VERBOSE output more like it used to be, HEADER_IN is thus also i…
authored
659 fwrite(s_infotype[type], 2, 1, data->set.err);
660 fwrite(ptr, size, 1, data->set.err);
0fb5a65 @bagder - David McCreedy provided libcurl changes for doing HTTP communicatio…
authored
661 #ifdef CURL_DOES_CONVERSIONS
662 if(size != conv_size) {
663 /* we had untranslated data so we need an explicit newline */
664 fwrite("\n", 1, 1, data->set.err);
665 }
666 #endif
d321056 @bagder made VERBOSE output more like it used to be, HEADER_IN is thus also i…
authored
667 break;
668 default: /* nada */
669 break;
670 }
3f6133b @bagder Jean-Philippe Barrette-LaPierre provided his patch that introduces
authored
671 return 0;
672 }
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
673
674 int Curl_debug(struct SessionHandle *data, curl_infotype type,
0f77fe5 @dfandrich Reverted the const change--what was I thinking?
dfandrich authored
675 char *ptr, size_t size,
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
676 struct connectdata *conn)
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
677 {
678 int rc;
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
679 if(data->set.printhost && conn && conn->host.dispname) {
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
680 char buffer[160];
f0969c9 @bagder prevent compiler warning with picky compilers
authored
681 const char *t=NULL;
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
682 const char *w="Data";
4c58797 @bagder When sending info about which host that sends what, include proper di…
authored
683 switch (type) {
684 case CURLINFO_HEADER_IN:
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
685 w = "Header";
3aa8999 @bagder Curl_debug: document switch fallthroughs
authored
686 /* FALLTHROUGH */
4c58797 @bagder When sending info about which host that sends what, include proper di…
authored
687 case CURLINFO_DATA_IN:
688 t = "from";
689 break;
690 case CURLINFO_HEADER_OUT:
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
691 w = "Header";
3aa8999 @bagder Curl_debug: document switch fallthroughs
authored
692 /* FALLTHROUGH */
4c58797 @bagder When sending info about which host that sends what, include proper di…
authored
693 case CURLINFO_DATA_OUT:
694 t = "to";
695 break;
696 default:
697 break;
698 }
699
700 if(t) {
5e0d9ae @bagder Support for FTP third party transfers is now dropped
authored
701 snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
7e42cb6 @bagder FTP third transfer support overhaul. See CHANGES for details.
authored
702 conn->host.dispname);
4c58797 @bagder When sending info about which host that sends what, include proper di…
authored
703 rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
704 if(rc)
705 return rc;
706 }
ea81dd9 @bagder Alexander Krasnostavsky's FTP third party transfer (proxy) support
authored
707 }
708 rc = showit(data, type, ptr, size);
709 return rc;
710 }
Something went wrong with that request. Please try again.