sendf.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  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. int len = (int)strlen(data->set.errorbuffer);
  135. bool doneit=FALSE;
  136. if(len < CURL_ERROR_SIZE) {
  137. doneit = TRUE;
  138. data->set.errorbuffer[len] = '\n';
  139. data->set.errorbuffer[++len] = '\0';
  140. }
  141. Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer, len);
  142. if(doneit)
  143. /* cut off the newline again */
  144. data->set.errorbuffer[--len]=0;
  145. }
  146. }
  147. va_end(ap);
  148. }
  149. /* Curl_sendf() sends formated data to the server */
  150. CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
  151. const char *fmt, ...)
  152. {
  153. struct SessionHandle *data = conn->data;
  154. ssize_t bytes_written;
  155. ssize_t write_len;
  156. CURLcode res;
  157. char *s;
  158. char *sptr;
  159. va_list ap;
  160. va_start(ap, fmt);
  161. s = vaprintf(fmt, ap); /* returns an allocated string */
  162. va_end(ap);
  163. if(!s)
  164. return CURLE_OUT_OF_MEMORY; /* failure */
  165. bytes_written=0;
  166. write_len = (int)strlen(s);
  167. sptr = s;
  168. do {
  169. /* Write the buffer to the socket */
  170. res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
  171. if(CURLE_OK != res)
  172. break;
  173. if(data->set.verbose)
  174. Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written);
  175. if(bytes_written != write_len) {
  176. /* if not all was written at once, we must advance the pointer, decrease
  177. the size left and try again! */
  178. write_len -= bytes_written;
  179. sptr += bytes_written;
  180. }
  181. else
  182. break;
  183. } while(1);
  184. free(s); /* free the output string */
  185. return res;
  186. }
  187. /*
  188. * Curl_write() is an internal write function that sends plain (binary) data
  189. * to the server. Works with plain sockets, SSL or kerberos.
  190. *
  191. */
  192. CURLcode Curl_write(struct connectdata *conn, int sockfd,
  193. void *mem, size_t len,
  194. ssize_t *written)
  195. {
  196. ssize_t bytes_written;
  197. (void)conn;
  198. #ifdef USE_SSLEAY
  199. /* SSL_write() is said to return 'int' while write() and send() returns
  200. 'size_t' */
  201. if (conn->ssl.use) {
  202. int err;
  203. int rc = SSL_write(conn->ssl.handle, mem, len);
  204. if(rc < 0) {
  205. err = SSL_get_error(conn->ssl.handle, rc);
  206. switch(err) {
  207. case SSL_ERROR_WANT_READ:
  208. case SSL_ERROR_WANT_WRITE:
  209. /* this is basicly the EWOULDBLOCK equivalent */
  210. *written = 0;
  211. return CURLE_OK;
  212. case SSL_ERROR_SYSCALL:
  213. failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n", errno);
  214. return CURLE_SEND_ERROR;
  215. }
  216. /* a true error */
  217. failf(conn->data, "SSL_write() return error %d\n", err);
  218. return CURLE_SEND_ERROR;
  219. }
  220. bytes_written = rc;
  221. }
  222. else {
  223. #endif
  224. #ifdef KRB4
  225. if(conn->sec_complete) {
  226. bytes_written = Curl_sec_write(conn, sockfd, mem, len);
  227. }
  228. else
  229. #endif /* KRB4 */
  230. {
  231. bytes_written = (int)swrite(sockfd, mem, (int)len);
  232. }
  233. if(-1 == bytes_written) {
  234. #ifdef WIN32
  235. if(WSAEWOULDBLOCK == GetLastError())
  236. #else
  237. if(EWOULDBLOCK == errno)
  238. #endif
  239. {
  240. /* this is just a case of EWOULDBLOCK */
  241. *written=0;
  242. return CURLE_OK;
  243. }
  244. }
  245. #ifdef USE_SSLEAY
  246. }
  247. #endif
  248. *written = bytes_written;
  249. return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
  250. }
  251. /* client_write() sends data to the write callback(s)
  252. The bit pattern defines to what "streams" to write to. Body and/or header.
  253. The defines are in sendf.h of course.
  254. */
  255. CURLcode Curl_client_write(struct SessionHandle *data,
  256. int type,
  257. char *ptr,
  258. size_t len)
  259. {
  260. size_t wrote;
  261. if(0 == len)
  262. len = strlen(ptr);
  263. if(type & CLIENTWRITE_BODY) {
  264. wrote = data->set.fwrite(ptr, 1, len, data->set.out);
  265. if(wrote != len) {
  266. failf (data, "Failed writing body");
  267. return CURLE_WRITE_ERROR;
  268. }
  269. }
  270. if((type & CLIENTWRITE_HEADER) &&
  271. (data->set.fwrite_header || data->set.writeheader) ) {
  272. /*
  273. * Write headers to the same callback or to the especially setup
  274. * header callback function (added after version 7.7.1).
  275. */
  276. curl_write_callback writeit=
  277. data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
  278. wrote = writeit(ptr, 1, len, data->set.writeheader);
  279. if(wrote != len) {
  280. failf (data, "Failed writing header");
  281. return CURLE_WRITE_ERROR;
  282. }
  283. }
  284. return CURLE_OK;
  285. }
  286. /*
  287. * Internal read-from-socket function. This is meant to deal with plain
  288. * sockets, SSL sockets and kerberos sockets.
  289. *
  290. * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
  291. * a regular CURLcode value.
  292. */
  293. int Curl_read(struct connectdata *conn,
  294. int sockfd,
  295. char *buf,
  296. size_t buffersize,
  297. ssize_t *n)
  298. {
  299. ssize_t nread;
  300. *n=0; /* reset amount to zero */
  301. (void)conn;
  302. #ifdef USE_SSLEAY
  303. if (conn->ssl.use) {
  304. nread = SSL_read(conn->ssl.handle, buf, buffersize);
  305. if(nread < 0) {
  306. /* failed SSL_read */
  307. int err = SSL_get_error(conn->ssl.handle, nread);
  308. switch(err) {
  309. case SSL_ERROR_NONE: /* this is not an error */
  310. case SSL_ERROR_ZERO_RETURN: /* no more data */
  311. break;
  312. case SSL_ERROR_WANT_READ:
  313. case SSL_ERROR_WANT_WRITE:
  314. /* there's data pending, re-invoke SSL_read() */
  315. return -1; /* basicly EWOULDBLOCK */
  316. default:
  317. failf(conn->data, "SSL read error: %d", err);
  318. return CURLE_RECV_ERROR;
  319. }
  320. }
  321. }
  322. else {
  323. #endif
  324. #ifdef KRB4
  325. if(conn->sec_complete)
  326. nread = Curl_sec_read(conn, sockfd, buf, buffersize);
  327. else
  328. #endif
  329. nread = sread (sockfd, buf, (int)buffersize);
  330. if(-1 == nread) {
  331. #ifdef WIN32
  332. if(WSAEWOULDBLOCK == GetLastError())
  333. #else
  334. if(EWOULDBLOCK == errno)
  335. #endif
  336. return -1;
  337. }
  338. #ifdef USE_SSLEAY
  339. }
  340. #endif /* USE_SSLEAY */
  341. *n = nread;
  342. return CURLE_OK;
  343. }
  344. /* return 0 on success */
  345. int Curl_debug(struct SessionHandle *data, curl_infotype type,
  346. char *ptr, size_t size)
  347. {
  348. static const char * const s_infotype[CURLINFO_END] = {
  349. "* ", "< ", "> ", "{ ", "} " };
  350. if(data->set.fdebug)
  351. return (*data->set.fdebug)(data, type, ptr, size,
  352. data->set.debugdata);
  353. switch(type) {
  354. case CURLINFO_TEXT:
  355. case CURLINFO_HEADER_OUT:
  356. fwrite(s_infotype[type], 2, 1, data->set.err);
  357. fwrite(ptr, size, 1, data->set.err);
  358. break;
  359. default: /* nada */
  360. break;
  361. }
  362. return 0;
  363. }
  364. /*
  365. * local variables:
  366. * eval: (load-file "../curl-mode.el")
  367. * end:
  368. * vim600: fdm=marker
  369. * vim: et sw=2 ts=2 sts=2 tw=78
  370. */