request.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 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.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. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "curl_setup.h"
  25. #include "urldata.h"
  26. #include "cfilters.h"
  27. #include "dynbuf.h"
  28. #include "doh.h"
  29. #include "multiif.h"
  30. #include "progress.h"
  31. #include "request.h"
  32. #include "sendf.h"
  33. #include "transfer.h"
  34. #include "url.h"
  35. /* The last 3 #include files should be in this order */
  36. #include "curl_printf.h"
  37. #include "curl_memory.h"
  38. #include "memdebug.h"
  39. CURLcode Curl_req_init(struct SingleRequest *req)
  40. {
  41. memset(req, 0, sizeof(*req));
  42. return CURLE_OK;
  43. }
  44. CURLcode Curl_req_start(struct SingleRequest *req,
  45. struct Curl_easy *data)
  46. {
  47. CURLcode result;
  48. req->start = Curl_now();
  49. result = Curl_client_start(data);
  50. if(result)
  51. return result;
  52. if(!req->sendbuf_init) {
  53. Curl_bufq_init2(&req->sendbuf, data->set.upload_buffer_size, 1,
  54. BUFQ_OPT_SOFT_LIMIT);
  55. req->sendbuf_init = TRUE;
  56. }
  57. else {
  58. Curl_bufq_reset(&req->sendbuf);
  59. if(data->set.upload_buffer_size != req->sendbuf.chunk_size) {
  60. Curl_bufq_free(&req->sendbuf);
  61. Curl_bufq_init2(&req->sendbuf, data->set.upload_buffer_size, 1,
  62. BUFQ_OPT_SOFT_LIMIT);
  63. }
  64. }
  65. return CURLE_OK;
  66. }
  67. static CURLcode req_flush(struct Curl_easy *data);
  68. CURLcode Curl_req_done(struct SingleRequest *req,
  69. struct Curl_easy *data, bool aborted)
  70. {
  71. (void)req;
  72. if(!aborted)
  73. (void)req_flush(data);
  74. Curl_client_reset(data);
  75. return CURLE_OK;
  76. }
  77. void Curl_req_reset(struct SingleRequest *req, struct Curl_easy *data)
  78. {
  79. struct curltime t0 = {0, 0};
  80. /* This is a bit ugly. `req->p` is a union and we assume we can
  81. * free this safely without leaks. */
  82. Curl_safefree(req->p.http);
  83. Curl_safefree(req->newurl);
  84. Curl_client_reset(data);
  85. if(req->sendbuf_init)
  86. Curl_bufq_reset(&req->sendbuf);
  87. #ifndef CURL_DISABLE_DOH
  88. if(req->doh) {
  89. Curl_close(&req->doh->probe[0].easy);
  90. Curl_close(&req->doh->probe[1].easy);
  91. }
  92. #endif
  93. /* Can no longer memset() this struct as we need to keep some state */
  94. req->size = -1;
  95. req->maxdownload = -1;
  96. req->bytecount = 0;
  97. req->writebytecount = 0;
  98. req->start = t0;
  99. req->headerbytecount = 0;
  100. req->allheadercount = 0;
  101. req->deductheadercount = 0;
  102. req->headerline = 0;
  103. req->offset = 0;
  104. req->httpcode = 0;
  105. req->keepon = 0;
  106. req->start100 = t0;
  107. req->exp100 = EXP100_SEND_DATA;
  108. req->upgr101 = UPGR101_INIT;
  109. req->timeofdoc = 0;
  110. req->bodywrites = 0;
  111. req->location = NULL;
  112. req->newurl = NULL;
  113. #ifndef CURL_DISABLE_COOKIES
  114. req->setcookies = 0;
  115. #endif
  116. req->header = FALSE;
  117. req->content_range = FALSE;
  118. req->download_done = FALSE;
  119. req->eos_written = FALSE;
  120. req->eos_read = FALSE;
  121. req->upload_done = FALSE;
  122. req->upload_aborted = FALSE;
  123. req->ignorebody = FALSE;
  124. req->http_bodyless = FALSE;
  125. req->chunk = FALSE;
  126. req->ignore_cl = FALSE;
  127. req->upload_chunky = FALSE;
  128. req->getheader = FALSE;
  129. req->forbidchunk = FALSE;
  130. req->no_body = data->set.opt_no_body;
  131. req->authneg = FALSE;
  132. }
  133. void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data)
  134. {
  135. /* This is a bit ugly. `req->p` is a union and we assume we can
  136. * free this safely without leaks. */
  137. Curl_safefree(req->p.http);
  138. Curl_safefree(req->newurl);
  139. if(req->sendbuf_init)
  140. Curl_bufq_free(&req->sendbuf);
  141. Curl_client_cleanup(data);
  142. #ifndef CURL_DISABLE_DOH
  143. if(req->doh) {
  144. Curl_close(&req->doh->probe[0].easy);
  145. Curl_close(&req->doh->probe[1].easy);
  146. Curl_dyn_free(&req->doh->probe[0].serverdoh);
  147. Curl_dyn_free(&req->doh->probe[1].serverdoh);
  148. curl_slist_free_all(req->doh->headers);
  149. Curl_safefree(req->doh);
  150. }
  151. #endif
  152. }
  153. static CURLcode xfer_send(struct Curl_easy *data,
  154. const char *buf, size_t blen,
  155. size_t hds_len, size_t *pnwritten)
  156. {
  157. CURLcode result = CURLE_OK;
  158. *pnwritten = 0;
  159. #ifdef CURLDEBUG
  160. {
  161. /* Allow debug builds to override this logic to force short initial
  162. sends
  163. */
  164. char *p = getenv("CURL_SMALLREQSEND");
  165. if(p) {
  166. size_t altsize = (size_t)strtoul(p, NULL, 10);
  167. if(altsize && altsize < blen)
  168. blen = altsize;
  169. }
  170. }
  171. #endif
  172. /* Make sure this doesn't send more body bytes than what the max send
  173. speed says. The headers do not count to the max speed. */
  174. if(data->set.max_send_speed) {
  175. size_t body_bytes = blen - hds_len;
  176. if((curl_off_t)body_bytes > data->set.max_send_speed)
  177. blen = hds_len + (size_t)data->set.max_send_speed;
  178. }
  179. result = Curl_xfer_send(data, buf, blen, pnwritten);
  180. if(!result && *pnwritten) {
  181. if(hds_len)
  182. Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf,
  183. CURLMIN(hds_len, *pnwritten));
  184. if(*pnwritten > hds_len) {
  185. size_t body_len = *pnwritten - hds_len;
  186. Curl_debug(data, CURLINFO_DATA_OUT, (char *)buf + hds_len, body_len);
  187. data->req.writebytecount += body_len;
  188. Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
  189. }
  190. }
  191. return result;
  192. }
  193. static CURLcode req_send_buffer_flush(struct Curl_easy *data)
  194. {
  195. CURLcode result = CURLE_OK;
  196. const unsigned char *buf;
  197. size_t blen;
  198. while(Curl_bufq_peek(&data->req.sendbuf, &buf, &blen)) {
  199. size_t nwritten, hds_len = CURLMIN(data->req.sendbuf_hds_len, blen);
  200. result = xfer_send(data, (const char *)buf, blen, hds_len, &nwritten);
  201. if(result)
  202. break;
  203. Curl_bufq_skip(&data->req.sendbuf, nwritten);
  204. if(hds_len) {
  205. data->req.sendbuf_hds_len -= CURLMIN(hds_len, nwritten);
  206. if(!data->req.sendbuf_hds_len) {
  207. /* all request headers sent */
  208. if(data->req.exp100 == EXP100_SENDING_REQUEST) {
  209. /* We are now waiting for a reply from the server or
  210. * a timeout on our side */
  211. data->req.exp100 = EXP100_AWAITING_CONTINUE;
  212. data->req.start100 = Curl_now();
  213. Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
  214. }
  215. }
  216. }
  217. /* leave if we could not send all. Maybe network blocking or
  218. * speed limits on transfer */
  219. if(nwritten < blen)
  220. break;
  221. }
  222. return result;
  223. }
  224. static CURLcode req_set_upload_done(struct Curl_easy *data)
  225. {
  226. DEBUGASSERT(!data->req.upload_done);
  227. data->req.upload_done = TRUE;
  228. data->req.keepon &= ~KEEP_SEND; /* we're done sending */
  229. /* FIXME: http specific stuff, need to go somewhere else */
  230. data->req.exp100 = EXP100_SEND_DATA;
  231. Curl_expire_done(data, EXPIRE_100_TIMEOUT);
  232. if(data->req.upload_aborted) {
  233. if(data->req.writebytecount)
  234. infof(data, "abort upload after having sent %" CURL_FORMAT_CURL_OFF_T
  235. " bytes", data->req.writebytecount);
  236. else
  237. infof(data, "abort upload");
  238. }
  239. else if(data->req.writebytecount)
  240. infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
  241. " bytes", data->req.writebytecount);
  242. else
  243. infof(data, "We are completely uploaded and fine");
  244. return Curl_xfer_send_close(data);
  245. }
  246. static CURLcode req_flush(struct Curl_easy *data)
  247. {
  248. CURLcode result;
  249. if(!data || !data->conn)
  250. return CURLE_FAILED_INIT;
  251. if(!Curl_bufq_is_empty(&data->req.sendbuf)) {
  252. result = req_send_buffer_flush(data);
  253. if(result)
  254. return result;
  255. if(!Curl_bufq_is_empty(&data->req.sendbuf)) {
  256. return CURLE_AGAIN;
  257. }
  258. }
  259. if(!data->req.upload_done && data->req.eos_read &&
  260. Curl_bufq_is_empty(&data->req.sendbuf)) {
  261. return req_set_upload_done(data);
  262. }
  263. return CURLE_OK;
  264. }
  265. static ssize_t add_from_client(void *reader_ctx,
  266. unsigned char *buf, size_t buflen,
  267. CURLcode *err)
  268. {
  269. struct Curl_easy *data = reader_ctx;
  270. size_t nread;
  271. bool eos;
  272. *err = Curl_client_read(data, (char *)buf, buflen, &nread, &eos);
  273. if(*err)
  274. return -1;
  275. if(eos)
  276. data->req.eos_read = TRUE;
  277. return (ssize_t)nread;
  278. }
  279. #ifndef USE_HYPER
  280. static CURLcode req_send_buffer_add(struct Curl_easy *data,
  281. const char *buf, size_t blen,
  282. size_t hds_len)
  283. {
  284. CURLcode result = CURLE_OK;
  285. ssize_t n;
  286. n = Curl_bufq_write(&data->req.sendbuf,
  287. (const unsigned char *)buf, blen, &result);
  288. if(n < 0)
  289. return result;
  290. /* We rely on a SOFTLIMIT on sendbuf, so it can take all data in */
  291. DEBUGASSERT((size_t)n == blen);
  292. data->req.sendbuf_hds_len += hds_len;
  293. return CURLE_OK;
  294. }
  295. CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *buf)
  296. {
  297. CURLcode result;
  298. if(!data || !data->conn)
  299. return CURLE_FAILED_INIT;
  300. /* We always buffer and send from there. The reason is that on
  301. * blocking, we can retry using the same memory address. This is
  302. * important for TLS libraries that expect this.
  303. * We *could* optimized for non-TLS transfers, but that would mean
  304. * separate code paths and seems not worth it. */
  305. result = req_send_buffer_add(data, Curl_dyn_ptr(buf), Curl_dyn_len(buf),
  306. Curl_dyn_len(buf));
  307. if(result)
  308. return result;
  309. return Curl_req_send_more(data);
  310. }
  311. #endif /* !USE_HYPER */
  312. bool Curl_req_want_send(struct Curl_easy *data)
  313. {
  314. return data->req.sendbuf_init && !Curl_bufq_is_empty(&data->req.sendbuf);
  315. }
  316. bool Curl_req_done_sending(struct Curl_easy *data)
  317. {
  318. if(data->req.upload_done) {
  319. DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf));
  320. return TRUE;
  321. }
  322. return FALSE;
  323. }
  324. CURLcode Curl_req_send_more(struct Curl_easy *data)
  325. {
  326. CURLcode result;
  327. /* Fill our send buffer if more from client can be read and
  328. * we are not in a "expect-100" situation. */
  329. if(!data->req.eos_read && !Curl_bufq_is_full(&data->req.sendbuf) &&
  330. (data->req.exp100 == EXP100_SEND_DATA)) {
  331. ssize_t nread = Curl_bufq_sipn(&data->req.sendbuf, 0,
  332. add_from_client, data, &result);
  333. if(nread < 0 && result != CURLE_AGAIN)
  334. return result;
  335. }
  336. result = req_flush(data);
  337. if(result == CURLE_AGAIN)
  338. result = CURLE_OK;
  339. return result;
  340. }
  341. CURLcode Curl_req_abort_sending(struct Curl_easy *data)
  342. {
  343. if(!data->req.upload_done) {
  344. Curl_bufq_reset(&data->req.sendbuf);
  345. data->req.upload_aborted = TRUE;
  346. return req_set_upload_done(data);
  347. }
  348. return CURLE_OK;
  349. }