sendf.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2002, Daniel Stenberg, <[email protected]>, 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 http://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. * $Id$
  22. ***************************************************************************/
  23. #include "setup.h"
  24. #include <stdio.h>
  25. #include <stdarg.h>
  26. #include <stdlib.h>
  27. #include <errno.h>
  28. #ifdef HAVE_SYS_TYPES_H
  29. #include <sys/types.h>
  30. #endif
  31. #ifdef HAVE_SYS_SOCKET_H
  32. #include <sys/socket.h> /* required for send() & recv() prototypes */
  33. #endif
  34. #ifdef HAVE_UNISTD_H
  35. #include <unistd.h>
  36. #endif
  37. #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
  38. #include <winsock.h>
  39. #endif
  40. #include <curl/curl.h>
  41. #include "urldata.h"
  42. #include "sendf.h"
  43. #define _MPRINTF_REPLACE /* use the internal *printf() functions */
  44. #include <curl/mprintf.h>
  45. #ifdef KRB4
  46. #include "security.h"
  47. #endif
  48. #include <string.h>
  49. /* The last #include file should be: */
  50. #ifdef MALLOCDEBUG
  51. #include "memdebug.h"
  52. #endif
  53. /* returns last node in linked list */
  54. static struct curl_slist *slist_get_last(struct curl_slist *list)
  55. {
  56. struct curl_slist *item;
  57. /* if caller passed us a NULL, return now */
  58. if (!list)
  59. return NULL;
  60. /* loop through to find the last item */
  61. item = list;
  62. while (item->next) {
  63. item = item->next;
  64. }
  65. return item;
  66. }
  67. /* append a struct to the linked list. It always retunrs the address of the
  68. * first record, so that you can sure this function as an initialization
  69. * function as well as an append function. If you find this bothersome,
  70. * then simply create a separate _init function and call it appropriately from
  71. * within the proram. */
  72. struct curl_slist *curl_slist_append(struct curl_slist *list,
  73. const char *data)
  74. {
  75. struct curl_slist *last;
  76. struct curl_slist *new_item;
  77. new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
  78. if (new_item) {
  79. new_item->next = NULL;
  80. new_item->data = strdup(data);
  81. }
  82. if (new_item == NULL || new_item->data == NULL) {
  83. fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
  84. return NULL;
  85. }
  86. if (list) {
  87. last = slist_get_last(list);
  88. last->next = new_item;
  89. return list;
  90. }
  91. /* if this is the first item, then new_item *is* the list */
  92. return new_item;
  93. }
  94. /* be nice and clean up resources */
  95. void curl_slist_free_all(struct curl_slist *list)
  96. {
  97. struct curl_slist *next;
  98. struct curl_slist *item;
  99. if (!list)
  100. return;
  101. item = list;
  102. do {
  103. next = item->next;
  104. if (item->data) {
  105. free(item->data);
  106. }
  107. free(item);
  108. item = next;
  109. } while (next);
  110. }
  111. /* Curl_infof() is for info message along the way */
  112. void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
  113. {
  114. va_list ap;
  115. if(data->set.verbose) {
  116. char print_buffer[1024 + 1];
  117. va_start(ap, fmt);
  118. vsnprintf(print_buffer, 1024, fmt, ap);
  119. va_end(ap);
  120. Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer));
  121. }
  122. }
  123. /* Curl_failf() is for messages stating why we failed.
  124. * The message SHALL NOT include any LF or CR.
  125. */
  126. void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
  127. {
  128. va_list ap;
  129. va_start(ap, fmt);
  130. if(data->set.errorbuffer && !data->state.errorbuf) {
  131. vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
  132. data->state.errorbuf = TRUE; /* wrote error string */
  133. if(data->set.verbose)
  134. Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer,
  135. strlen(data->set.errorbuffer));
  136. }
  137. va_end(ap);
  138. }
  139. /* Curl_sendf() sends formated data to the server */
  140. CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
  141. const char *fmt, ...)
  142. {
  143. struct SessionHandle *data = conn->data;
  144. ssize_t bytes_written;
  145. ssize_t write_len;
  146. CURLcode res;
  147. char *s;
  148. char *sptr;
  149. va_list ap;
  150. va_start(ap, fmt);
  151. s = vaprintf(fmt, ap); /* returns an allocated string */
  152. va_end(ap);
  153. if(!s)
  154. return CURLE_OUT_OF_MEMORY; /* failure */
  155. bytes_written=0;
  156. write_len = strlen(s);
  157. sptr = s;
  158. do {
  159. /* Write the buffer to the socket */
  160. res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
  161. if(CURLE_OK != res)
  162. break;
  163. if(data->set.verbose)
  164. Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written);
  165. if(bytes_written != write_len) {
  166. /* if not all was written at once, we must advance the pointer, decrease
  167. the size left and try again! */
  168. write_len -= bytes_written;
  169. sptr += bytes_written;
  170. }
  171. else
  172. break;
  173. } while(1);
  174. free(s); /* free the output string */
  175. return res;
  176. }
  177. /*
  178. * Curl_write() is an internal write function that sends plain (binary) data
  179. * to the server. Works with plain sockets, SSL or kerberos.
  180. *
  181. */
  182. CURLcode Curl_write(struct connectdata *conn, int sockfd,
  183. void *mem, size_t len,
  184. ssize_t *written)
  185. {
  186. ssize_t bytes_written;
  187. #ifdef USE_SSLEAY
  188. /* SSL_write() is said to return 'int' while write() and send() returns
  189. 'size_t' */
  190. if (conn->ssl.use) {
  191. int err;
  192. int rc = SSL_write(conn->ssl.handle, mem, len);
  193. if(rc < 0) {
  194. err = SSL_get_error(conn->ssl.handle, rc);
  195. switch(err) {
  196. case SSL_ERROR_WANT_READ:
  197. case SSL_ERROR_WANT_WRITE:
  198. /* this is basicly the EWOULDBLOCK equivalent */
  199. *written = 0;
  200. return CURLE_OK;
  201. }
  202. /* a true error */
  203. failf(conn->data, "SSL_write() return error %d\n", err);
  204. return CURLE_SEND_ERROR;
  205. }
  206. bytes_written = rc;
  207. }
  208. else {
  209. #endif
  210. #ifdef KRB4
  211. if(conn->sec_complete) {
  212. bytes_written = Curl_sec_write(conn, sockfd, mem, len);
  213. }
  214. else
  215. #endif /* KRB4 */
  216. {
  217. bytes_written = swrite(sockfd, mem, len);
  218. }
  219. if(-1 == bytes_written) {
  220. #ifdef WIN32
  221. if(WSAEWOULDBLOCK == GetLastError())
  222. #else
  223. if(EWOULDBLOCK == errno)
  224. #endif
  225. {
  226. /* this is just a case of EWOULDBLOCK */
  227. *written=0;
  228. return CURLE_OK;
  229. }
  230. }
  231. #ifdef USE_SSLEAY
  232. }
  233. #endif
  234. *written = bytes_written;
  235. return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
  236. }
  237. /* client_write() sends data to the write callback(s)
  238. The bit pattern defines to what "streams" to write to. Body and/or header.
  239. The defines are in sendf.h of course.
  240. */
  241. CURLcode Curl_client_write(struct SessionHandle *data,
  242. int type,
  243. char *ptr,
  244. size_t len)
  245. {
  246. size_t wrote;
  247. if(0 == len)
  248. len = strlen(ptr);
  249. if(type & CLIENTWRITE_BODY) {
  250. wrote = data->set.fwrite(ptr, 1, len, data->set.out);
  251. if(wrote != len) {
  252. failf (data, "Failed writing body");
  253. return CURLE_WRITE_ERROR;
  254. }
  255. }
  256. if((type & CLIENTWRITE_HEADER) &&
  257. (data->set.fwrite_header || data->set.writeheader) ) {
  258. /*
  259. * Write headers to the same callback or to the especially setup
  260. * header callback function (added after version 7.7.1).
  261. */
  262. curl_write_callback writeit=
  263. data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
  264. wrote = writeit(ptr, 1, len, data->set.writeheader);
  265. if(wrote != len) {
  266. failf (data, "Failed writing header");
  267. return CURLE_WRITE_ERROR;
  268. }
  269. }
  270. return CURLE_OK;
  271. }
  272. /*
  273. * Internal read-from-socket function. This is meant to deal with plain
  274. * sockets, SSL sockets and kerberos sockets.
  275. *
  276. * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
  277. * a regular CURLcode value.
  278. */
  279. int Curl_read(struct connectdata *conn,
  280. int sockfd,
  281. char *buf,
  282. size_t buffersize,
  283. ssize_t *n)
  284. {
  285. ssize_t nread;
  286. #ifdef USE_SSLEAY
  287. if (conn->ssl.use) {
  288. bool loop=TRUE;
  289. int err;
  290. do {
  291. nread = SSL_read(conn->ssl.handle, buf, buffersize);
  292. if(nread >= 0)
  293. /* successful read */
  294. break;
  295. err = SSL_get_error(conn->ssl.handle, nread);
  296. switch(err) {
  297. case SSL_ERROR_NONE: /* this is not an error */
  298. case SSL_ERROR_ZERO_RETURN: /* no more data */
  299. loop=0; /* get out of loop */
  300. break;
  301. case SSL_ERROR_WANT_READ:
  302. case SSL_ERROR_WANT_WRITE:
  303. /* if there's data pending, then we re-invoke SSL_read() */
  304. break;
  305. default:
  306. failf(conn->data, "SSL read error: %d", err);
  307. return CURLE_RECV_ERROR;
  308. }
  309. } while(loop);
  310. if(loop && SSL_pending(conn->ssl.handle))
  311. return -1; /* basicly EWOULDBLOCK */
  312. }
  313. else {
  314. #endif
  315. #ifdef KRB4
  316. if(conn->sec_complete)
  317. nread = Curl_sec_read(conn, sockfd, buf, buffersize);
  318. else
  319. #endif
  320. nread = sread (sockfd, buf, buffersize);
  321. if(-1 == nread) {
  322. #ifdef WIN32
  323. if(WSAEWOULDBLOCK == GetLastError())
  324. #else
  325. if(EWOULDBLOCK == errno)
  326. #endif
  327. return -1;
  328. }
  329. #ifdef USE_SSLEAY
  330. }
  331. #endif /* USE_SSLEAY */
  332. *n = nread;
  333. return CURLE_OK;
  334. }
  335. /* return 0 on success */
  336. int Curl_debug(struct SessionHandle *data, curl_infotype type,
  337. char *ptr, size_t size)
  338. {
  339. static const char * const s_infotype[CURLINFO_END] = {
  340. "* ", "< ", "> ", "{ ", "} " };
  341. if(data->set.fdebug)
  342. return (*data->set.fdebug)(data, type, ptr, size,
  343. data->set.debugdata);
  344. switch(type) {
  345. case CURLINFO_TEXT:
  346. case CURLINFO_HEADER_OUT:
  347. fwrite(s_infotype[type], 2, 1, data->set.err);
  348. fwrite(ptr, size, 1, data->set.err);
  349. break;
  350. default: /* nada */
  351. break;
  352. }
  353. return 0;
  354. }
  355. /*
  356. * local variables:
  357. * eval: (load-file "../curl-mode.el")
  358. * end:
  359. * vim600: fdm=marker
  360. * vim: et sw=2 ts=2 sts=2 tw=78
  361. */