sendf.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 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 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. #ifdef HAVE_NETINET_IN_H
  26. #include <netinet/in.h>
  27. #endif
  28. #ifdef HAVE_LINUX_TCP_H
  29. #include <linux/tcp.h>
  30. #elif defined(HAVE_NETINET_TCP_H)
  31. #include <netinet/tcp.h>
  32. #endif
  33. #include "urldata.h"
  34. #include "sendf.h"
  35. #include "curl_trc.h"
  36. #include "transfer.h"
  37. #include "cfilters.h"
  38. #include "connect.h"
  39. #include "cw-out.h"
  40. #include "cw-pause.h"
  41. #include "multiif.h"
  42. #include "strerror.h"
  43. #include "progress.h"
  44. static CURLcode do_init_writer_stack(struct Curl_easy *data);
  45. /* Curl_client_write() sends data to the write callback(s)
  46. The bit pattern defines to what "streams" to write to. Body and/or header.
  47. The defines are in sendf.h of course.
  48. */
  49. CURLcode Curl_client_write(struct Curl_easy *data,
  50. int type, const char *buf, size_t blen)
  51. {
  52. CURLcode result;
  53. /* it is one of those, at least */
  54. DEBUGASSERT(type &
  55. (CLIENTWRITE_BODY | CLIENTWRITE_HEADER | CLIENTWRITE_INFO));
  56. /* BODY is only BODY (with optional EOS) */
  57. DEBUGASSERT(!(type & CLIENTWRITE_BODY) ||
  58. ((type & ~(CLIENTWRITE_BODY | CLIENTWRITE_EOS)) == 0));
  59. /* INFO is only INFO (with optional EOS) */
  60. DEBUGASSERT(!(type & CLIENTWRITE_INFO) ||
  61. ((type & ~(CLIENTWRITE_INFO | CLIENTWRITE_EOS)) == 0));
  62. if(!data->req.writer_stack) {
  63. result = do_init_writer_stack(data);
  64. if(result)
  65. return result;
  66. DEBUGASSERT(data->req.writer_stack);
  67. }
  68. result = Curl_cwriter_write(data, data->req.writer_stack, type, buf, blen);
  69. CURL_TRC_WRITE(data, "client_write(type=%x, len=%zu) -> %d",
  70. type, blen, result);
  71. return result;
  72. }
  73. static void cl_reset_writer(struct Curl_easy *data)
  74. {
  75. struct Curl_cwriter *writer = data->req.writer_stack;
  76. while(writer) {
  77. data->req.writer_stack = writer->next;
  78. writer->cwt->do_close(data, writer);
  79. curlx_free(writer);
  80. writer = data->req.writer_stack;
  81. }
  82. }
  83. static void cl_reset_reader(struct Curl_easy *data)
  84. {
  85. struct Curl_creader *reader = data->req.reader_stack;
  86. data->req.reader_started = FALSE;
  87. while(reader) {
  88. data->req.reader_stack = reader->next;
  89. reader->crt->do_close(data, reader);
  90. curlx_free(reader);
  91. reader = data->req.reader_stack;
  92. }
  93. }
  94. void Curl_client_cleanup(struct Curl_easy *data)
  95. {
  96. cl_reset_reader(data);
  97. cl_reset_writer(data);
  98. data->req.bytecount = 0;
  99. data->req.headerline = 0;
  100. }
  101. void Curl_client_reset(struct Curl_easy *data)
  102. {
  103. if(data->req.rewind_read) {
  104. /* already requested */
  105. CURL_TRC_READ(data, "client_reset, will rewind reader");
  106. }
  107. else {
  108. CURL_TRC_READ(data, "client_reset, clear readers");
  109. cl_reset_reader(data);
  110. }
  111. cl_reset_writer(data);
  112. data->req.bytecount = 0;
  113. data->req.headerline = 0;
  114. }
  115. CURLcode Curl_client_start(struct Curl_easy *data)
  116. {
  117. if(data->req.rewind_read) {
  118. struct Curl_creader *r = data->req.reader_stack;
  119. CURLcode result = CURLE_OK;
  120. CURL_TRC_READ(data, "client start, rewind readers");
  121. while(r) {
  122. result = r->crt->cntrl(data, r, CURL_CRCNTRL_REWIND);
  123. if(result) {
  124. failf(data, "rewind of client reader '%s' failed: %d",
  125. r->crt->name, result);
  126. return result;
  127. }
  128. r = r->next;
  129. }
  130. data->req.rewind_read = FALSE;
  131. cl_reset_reader(data);
  132. }
  133. return CURLE_OK;
  134. }
  135. bool Curl_creader_will_rewind(struct Curl_easy *data)
  136. {
  137. return data->req.rewind_read;
  138. }
  139. void Curl_creader_set_rewind(struct Curl_easy *data, bool enable)
  140. {
  141. data->req.rewind_read = !!enable;
  142. }
  143. /* Write data using an unencoding writer stack. */
  144. CURLcode Curl_cwriter_write(struct Curl_easy *data,
  145. struct Curl_cwriter *writer, int type,
  146. const char *buf, size_t nbytes)
  147. {
  148. if(!writer)
  149. return CURLE_WRITE_ERROR;
  150. return writer->cwt->do_write(data, writer, type, buf, nbytes);
  151. }
  152. CURLcode Curl_cwriter_def_init(struct Curl_easy *data,
  153. struct Curl_cwriter *writer)
  154. {
  155. (void)data;
  156. (void)writer;
  157. return CURLE_OK;
  158. }
  159. CURLcode Curl_cwriter_def_write(struct Curl_easy *data,
  160. struct Curl_cwriter *writer, int type,
  161. const char *buf, size_t nbytes)
  162. {
  163. return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
  164. }
  165. void Curl_cwriter_def_close(struct Curl_easy *data,
  166. struct Curl_cwriter *writer)
  167. {
  168. (void)data;
  169. (void)writer;
  170. }
  171. static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit)
  172. {
  173. if(limit != -1) {
  174. /* How much more are we allowed to write? */
  175. return curlx_sotouz_range(limit - data->req.bytecount, 0, SIZE_MAX);
  176. }
  177. return SIZE_MAX;
  178. }
  179. struct cw_download_ctx {
  180. struct Curl_cwriter super;
  181. BIT(started_response);
  182. };
  183. /* Download client writer in phase CURL_CW_PROTOCOL that
  184. * sees the "real" download body data. */
  185. static CURLcode cw_download_write(struct Curl_easy *data,
  186. struct Curl_cwriter *writer, int type,
  187. const char *buf, size_t nbytes)
  188. {
  189. struct cw_download_ctx *ctx = writer->ctx;
  190. CURLcode result;
  191. size_t nwrite, excess_len = 0;
  192. bool is_connect = !!(type & CLIENTWRITE_CONNECT);
  193. if(!ctx->started_response &&
  194. !(type & (CLIENTWRITE_INFO | CLIENTWRITE_CONNECT))) {
  195. Curl_pgrsTime(data, TIMER_STARTTRANSFER);
  196. Curl_rlimit_start(&data->progress.dl.rlimit, Curl_pgrs_now(data));
  197. ctx->started_response = TRUE;
  198. }
  199. if(!(type & CLIENTWRITE_BODY)) {
  200. if(is_connect && data->set.suppress_connect_headers)
  201. return CURLE_OK;
  202. result = Curl_cwriter_write(data, writer->next, type, buf, nbytes);
  203. CURL_TRC_WRITE(data, "download_write header(type=%x, blen=%zu) -> %d",
  204. type, nbytes, result);
  205. return result;
  206. }
  207. /* Here, we deal with REAL BODY bytes. All filtering and transfer
  208. * encodings have been applied and only the true content, e.g. BODY,
  209. * bytes are passed here.
  210. * This allows us to check sizes, update stats, etc. independent
  211. * from the protocol in play. */
  212. if(data->req.no_body && nbytes > 0) {
  213. /* BODY arrives although we want none, bail out */
  214. streamclose(data->conn, "ignoring body");
  215. CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu), "
  216. "did not want a BODY", type, nbytes);
  217. data->req.download_done = TRUE;
  218. if(data->info.header_size)
  219. /* if headers have been received, this is fine */
  220. return CURLE_OK;
  221. return CURLE_WEIRD_SERVER_REPLY;
  222. }
  223. /* Determine if we see any bytes in excess to what is allowed.
  224. * We write the allowed bytes and handle excess further below.
  225. * This gives deterministic BODY writes on varying buffer receive
  226. * lengths. */
  227. nwrite = nbytes;
  228. if(data->req.maxdownload != -1) {
  229. size_t wmax = get_max_body_write_len(data, data->req.maxdownload);
  230. if(nwrite > wmax) {
  231. excess_len = nbytes - wmax;
  232. nwrite = wmax;
  233. }
  234. if(nwrite == wmax) {
  235. data->req.download_done = TRUE;
  236. }
  237. if((type & CLIENTWRITE_EOS) && !data->req.no_body &&
  238. (data->req.size > data->req.bytecount)) {
  239. failf(data, "end of response with %" FMT_OFF_T " bytes missing",
  240. data->req.size - data->req.bytecount);
  241. return CURLE_PARTIAL_FILE;
  242. }
  243. }
  244. /* Error on too large filesize is handled below, after writing
  245. * the permitted bytes */
  246. if(data->set.max_filesize && !data->req.ignorebody) {
  247. size_t wmax = get_max_body_write_len(data, data->set.max_filesize);
  248. if(nwrite > wmax) {
  249. nwrite = wmax;
  250. }
  251. }
  252. if(!data->req.ignorebody && (nwrite || (type & CLIENTWRITE_EOS))) {
  253. result = Curl_cwriter_write(data, writer->next, type, buf, nwrite);
  254. CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu) -> %d",
  255. type, nbytes, result);
  256. if(result)
  257. return result;
  258. }
  259. /* Update stats, write and report progress */
  260. if(nwrite) {
  261. data->req.bytecount += nwrite;
  262. Curl_pgrs_download_inc(data, nwrite);
  263. }
  264. if(excess_len) {
  265. if(!data->req.ignorebody) {
  266. infof(data,
  267. "Excess found writing body:"
  268. " excess = %zu"
  269. ", size = %" FMT_OFF_T
  270. ", maxdownload = %" FMT_OFF_T
  271. ", bytecount = %" FMT_OFF_T,
  272. excess_len, data->req.size, data->req.maxdownload,
  273. data->req.bytecount);
  274. connclose(data->conn, "excess found in a read");
  275. }
  276. }
  277. else if((nwrite < nbytes) && !data->req.ignorebody) {
  278. failf(data, "Exceeded the maximum allowed file size "
  279. "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes",
  280. data->set.max_filesize, data->req.bytecount);
  281. return CURLE_FILESIZE_EXCEEDED;
  282. }
  283. return CURLE_OK;
  284. }
  285. static const struct Curl_cwtype cw_download = {
  286. "protocol",
  287. NULL,
  288. Curl_cwriter_def_init,
  289. cw_download_write,
  290. Curl_cwriter_def_close,
  291. sizeof(struct cw_download_ctx)
  292. };
  293. /* RAW client writer in phase CURL_CW_RAW that
  294. * enabled tracing of raw data. */
  295. static CURLcode cw_raw_write(struct Curl_easy *data,
  296. struct Curl_cwriter *writer, int type,
  297. const char *buf, size_t nbytes)
  298. {
  299. if(type & CLIENTWRITE_BODY && data->set.verbose && !data->req.ignorebody) {
  300. Curl_debug(data, CURLINFO_DATA_IN, buf, nbytes);
  301. }
  302. return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
  303. }
  304. static const struct Curl_cwtype cw_raw = {
  305. "raw",
  306. NULL,
  307. Curl_cwriter_def_init,
  308. cw_raw_write,
  309. Curl_cwriter_def_close,
  310. sizeof(struct Curl_cwriter)
  311. };
  312. /* Create an unencoding writer stage using the given handler. */
  313. CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter,
  314. struct Curl_easy *data,
  315. const struct Curl_cwtype *cwt,
  316. Curl_cwriter_phase phase)
  317. {
  318. struct Curl_cwriter *writer = NULL;
  319. CURLcode result = CURLE_OUT_OF_MEMORY;
  320. void *p;
  321. DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter));
  322. p = curlx_calloc(1, cwt->cwriter_size);
  323. if(!p)
  324. goto out;
  325. writer = (struct Curl_cwriter *)p;
  326. writer->cwt = cwt;
  327. writer->ctx = p;
  328. writer->phase = phase;
  329. result = cwt->do_init(data, writer);
  330. out:
  331. *pwriter = result ? NULL : writer;
  332. if(result)
  333. curlx_free(writer);
  334. return result;
  335. }
  336. void Curl_cwriter_free(struct Curl_easy *data,
  337. struct Curl_cwriter *writer)
  338. {
  339. if(writer) {
  340. writer->cwt->do_close(data, writer);
  341. curlx_free(writer);
  342. }
  343. }
  344. size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase)
  345. {
  346. struct Curl_cwriter *w;
  347. size_t n = 0;
  348. for(w = data->req.writer_stack; w; w = w->next) {
  349. if(w->phase == phase)
  350. ++n;
  351. }
  352. return n;
  353. }
  354. static CURLcode do_init_writer_stack(struct Curl_easy *data)
  355. {
  356. struct Curl_cwriter *writer;
  357. CURLcode result;
  358. DEBUGASSERT(!data->req.writer_stack);
  359. result = Curl_cwriter_create(&data->req.writer_stack,
  360. data, &Curl_cwt_out, CURL_CW_CLIENT);
  361. if(result)
  362. return result;
  363. /* This places the "pause" writer behind the "download" writer that
  364. * is added below. Meaning the "download" can do checks on content length
  365. * and other things *before* write outs are buffered for paused transfers. */
  366. result = Curl_cwriter_create(&writer, data, &Curl_cwt_pause,
  367. CURL_CW_PROTOCOL);
  368. if(!result) {
  369. result = Curl_cwriter_add(data, writer);
  370. if(result)
  371. Curl_cwriter_free(data, writer);
  372. }
  373. if(result)
  374. return result;
  375. result = Curl_cwriter_create(&writer, data, &cw_download, CURL_CW_PROTOCOL);
  376. if(!result) {
  377. result = Curl_cwriter_add(data, writer);
  378. if(result)
  379. Curl_cwriter_free(data, writer);
  380. }
  381. if(result)
  382. return result;
  383. result = Curl_cwriter_create(&writer, data, &cw_raw, CURL_CW_RAW);
  384. if(!result) {
  385. result = Curl_cwriter_add(data, writer);
  386. if(result)
  387. Curl_cwriter_free(data, writer);
  388. }
  389. if(result)
  390. return result;
  391. return result;
  392. }
  393. CURLcode Curl_cwriter_add(struct Curl_easy *data,
  394. struct Curl_cwriter *writer)
  395. {
  396. CURLcode result;
  397. struct Curl_cwriter **anchor = &data->req.writer_stack;
  398. if(!*anchor) {
  399. result = do_init_writer_stack(data);
  400. if(result)
  401. return result;
  402. }
  403. /* Insert the writer as first in its phase.
  404. * Skip existing writers of lower phases. */
  405. while(*anchor && (*anchor)->phase < writer->phase)
  406. anchor = &((*anchor)->next);
  407. writer->next = *anchor;
  408. *anchor = writer;
  409. return CURLE_OK;
  410. }
  411. struct Curl_cwriter *Curl_cwriter_get_by_name(struct Curl_easy *data,
  412. const char *name)
  413. {
  414. struct Curl_cwriter *writer;
  415. for(writer = data->req.writer_stack; writer; writer = writer->next) {
  416. if(!strcmp(name, writer->cwt->name))
  417. return writer;
  418. }
  419. return NULL;
  420. }
  421. struct Curl_cwriter *Curl_cwriter_get_by_type(struct Curl_easy *data,
  422. const struct Curl_cwtype *cwt)
  423. {
  424. struct Curl_cwriter *writer;
  425. for(writer = data->req.writer_stack; writer; writer = writer->next) {
  426. if(writer->cwt == cwt)
  427. return writer;
  428. }
  429. return NULL;
  430. }
  431. bool Curl_cwriter_is_content_decoding(struct Curl_easy *data)
  432. {
  433. struct Curl_cwriter *writer;
  434. for(writer = data->req.writer_stack; writer; writer = writer->next) {
  435. if(writer->phase == CURL_CW_CONTENT_DECODE)
  436. return TRUE;
  437. }
  438. return FALSE;
  439. }
  440. bool Curl_cwriter_is_paused(struct Curl_easy *data)
  441. {
  442. return Curl_cw_out_is_paused(data);
  443. }
  444. CURLcode Curl_cwriter_unpause(struct Curl_easy *data)
  445. {
  446. return Curl_cw_out_unpause(data);
  447. }
  448. CURLcode Curl_creader_read(struct Curl_easy *data,
  449. struct Curl_creader *reader,
  450. char *buf, size_t blen, size_t *nread, bool *eos)
  451. {
  452. *nread = 0;
  453. *eos = FALSE;
  454. if(!reader)
  455. return CURLE_READ_ERROR;
  456. return reader->crt->do_read(data, reader, buf, blen, nread, eos);
  457. }
  458. void Curl_creader_clear_eos(struct Curl_easy *data,
  459. struct Curl_creader *reader)
  460. {
  461. while(reader) {
  462. (void)reader->crt->cntrl(data, reader, CURL_CRCNTRL_CLEAR_EOS);
  463. reader = reader->next;
  464. }
  465. }
  466. CURLcode Curl_creader_def_init(struct Curl_easy *data,
  467. struct Curl_creader *reader)
  468. {
  469. (void)data;
  470. (void)reader;
  471. return CURLE_OK;
  472. }
  473. void Curl_creader_def_close(struct Curl_easy *data,
  474. struct Curl_creader *reader)
  475. {
  476. (void)data;
  477. (void)reader;
  478. }
  479. CURLcode Curl_creader_def_read(struct Curl_easy *data,
  480. struct Curl_creader *reader,
  481. char *buf, size_t blen,
  482. size_t *nread, bool *eos)
  483. {
  484. if(reader->next)
  485. return reader->next->crt->do_read(data, reader->next, buf, blen,
  486. nread, eos);
  487. else {
  488. *nread = 0;
  489. *eos = FALSE;
  490. return CURLE_READ_ERROR;
  491. }
  492. }
  493. bool Curl_creader_def_needs_rewind(struct Curl_easy *data,
  494. struct Curl_creader *reader)
  495. {
  496. (void)data;
  497. (void)reader;
  498. return FALSE;
  499. }
  500. curl_off_t Curl_creader_def_total_length(struct Curl_easy *data,
  501. struct Curl_creader *reader)
  502. {
  503. return reader->next ?
  504. reader->next->crt->total_length(data, reader->next) : -1;
  505. }
  506. CURLcode Curl_creader_def_resume_from(struct Curl_easy *data,
  507. struct Curl_creader *reader,
  508. curl_off_t offset)
  509. {
  510. (void)data;
  511. (void)reader;
  512. (void)offset;
  513. return CURLE_READ_ERROR;
  514. }
  515. CURLcode Curl_creader_def_cntrl(struct Curl_easy *data,
  516. struct Curl_creader *reader,
  517. Curl_creader_cntrl opcode)
  518. {
  519. (void)data;
  520. (void)reader;
  521. (void)opcode;
  522. return CURLE_OK;
  523. }
  524. bool Curl_creader_def_is_paused(struct Curl_easy *data,
  525. struct Curl_creader *reader)
  526. {
  527. (void)data;
  528. (void)reader;
  529. return FALSE;
  530. }
  531. void Curl_creader_def_done(struct Curl_easy *data,
  532. struct Curl_creader *reader, int premature)
  533. {
  534. (void)data;
  535. (void)reader;
  536. (void)premature;
  537. }
  538. struct cr_in_ctx {
  539. struct Curl_creader super;
  540. curl_read_callback read_cb;
  541. void *cb_user_data;
  542. curl_off_t total_len;
  543. curl_off_t read_len;
  544. CURLcode error_result;
  545. BIT(seen_eos);
  546. BIT(errored);
  547. BIT(has_used_cb);
  548. BIT(is_paused);
  549. };
  550. static CURLcode cr_in_init(struct Curl_easy *data, struct Curl_creader *reader)
  551. {
  552. struct cr_in_ctx *ctx = reader->ctx;
  553. (void)data;
  554. ctx->read_cb = data->state.fread_func;
  555. ctx->cb_user_data = data->state.in;
  556. ctx->total_len = -1;
  557. ctx->read_len = 0;
  558. return CURLE_OK;
  559. }
  560. /* Real client reader to installed client callbacks. */
  561. static CURLcode cr_in_read(struct Curl_easy *data,
  562. struct Curl_creader *reader,
  563. char *buf, size_t blen,
  564. size_t *pnread, bool *peos)
  565. {
  566. struct cr_in_ctx *ctx = reader->ctx;
  567. CURLcode result = CURLE_OK;
  568. size_t nread;
  569. ctx->is_paused = FALSE;
  570. /* Once we have errored, we will return the same error forever */
  571. if(ctx->errored) {
  572. *pnread = 0;
  573. *peos = FALSE;
  574. return ctx->error_result;
  575. }
  576. if(ctx->seen_eos) {
  577. *pnread = 0;
  578. *peos = TRUE;
  579. return CURLE_OK;
  580. }
  581. /* respect length limitations */
  582. if(ctx->total_len >= 0) {
  583. blen = curlx_sotouz_range(ctx->total_len - ctx->read_len, 0, blen);
  584. }
  585. nread = 0;
  586. if(ctx->read_cb && blen) {
  587. Curl_set_in_callback(data, TRUE);
  588. nread = ctx->read_cb(buf, 1, blen, ctx->cb_user_data);
  589. Curl_set_in_callback(data, FALSE);
  590. ctx->has_used_cb = TRUE;
  591. }
  592. switch(nread) {
  593. case 0:
  594. if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) {
  595. failf(data, "client read function EOF fail, "
  596. "only %"FMT_OFF_T"/%"FMT_OFF_T " of needed bytes read",
  597. ctx->read_len, ctx->total_len);
  598. result = CURLE_READ_ERROR;
  599. break;
  600. }
  601. *pnread = 0;
  602. *peos = TRUE;
  603. ctx->seen_eos = TRUE;
  604. break;
  605. case CURL_READFUNC_ABORT:
  606. failf(data, "operation aborted by callback");
  607. *pnread = 0;
  608. *peos = FALSE;
  609. ctx->errored = TRUE;
  610. ctx->error_result = CURLE_ABORTED_BY_CALLBACK;
  611. result = CURLE_ABORTED_BY_CALLBACK;
  612. break;
  613. case CURL_READFUNC_PAUSE:
  614. if(data->conn->handler->flags & PROTOPT_NONETWORK) {
  615. /* protocols that work without network cannot be paused. This is
  616. actually only FILE:// just now, and it cannot pause since the transfer
  617. is not done using the "normal" procedure. */
  618. failf(data, "Read callback asked for PAUSE when not supported");
  619. result = CURLE_READ_ERROR;
  620. break;
  621. }
  622. /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
  623. CURL_TRC_READ(data, "cr_in_read, callback returned CURL_READFUNC_PAUSE");
  624. ctx->is_paused = TRUE;
  625. *pnread = 0;
  626. *peos = FALSE;
  627. result = Curl_xfer_pause_send(data, TRUE);
  628. break; /* nothing was read */
  629. default:
  630. if(nread > blen) {
  631. /* the read function returned a too large value */
  632. failf(data, "read function returned funny value");
  633. *pnread = 0;
  634. *peos = FALSE;
  635. ctx->errored = TRUE;
  636. ctx->error_result = CURLE_READ_ERROR;
  637. result = CURLE_READ_ERROR;
  638. break;
  639. }
  640. ctx->read_len += nread;
  641. if(ctx->total_len >= 0)
  642. ctx->seen_eos = (ctx->read_len >= ctx->total_len);
  643. *pnread = nread;
  644. *peos = ctx->seen_eos;
  645. break;
  646. }
  647. CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%"FMT_OFF_T
  648. ", read=%"FMT_OFF_T") -> %d, nread=%zu, eos=%d",
  649. blen, ctx->total_len, ctx->read_len, result,
  650. *pnread, *peos);
  651. return result;
  652. }
  653. static bool cr_in_needs_rewind(struct Curl_easy *data,
  654. struct Curl_creader *reader)
  655. {
  656. struct cr_in_ctx *ctx = reader->ctx;
  657. (void)data;
  658. return ctx->has_used_cb;
  659. }
  660. static curl_off_t cr_in_total_length(struct Curl_easy *data,
  661. struct Curl_creader *reader)
  662. {
  663. struct cr_in_ctx *ctx = reader->ctx;
  664. (void)data;
  665. return ctx->total_len;
  666. }
  667. static CURLcode cr_in_resume_from(struct Curl_easy *data,
  668. struct Curl_creader *reader,
  669. curl_off_t offset)
  670. {
  671. struct cr_in_ctx *ctx = reader->ctx;
  672. int seekerr = CURL_SEEKFUNC_CANTSEEK;
  673. DEBUGASSERT(data->conn);
  674. /* already started reading? */
  675. if(ctx->read_len)
  676. return CURLE_READ_ERROR;
  677. if(data->set.seek_func) {
  678. Curl_set_in_callback(data, TRUE);
  679. seekerr = data->set.seek_func(data->set.seek_client, offset, SEEK_SET);
  680. Curl_set_in_callback(data, FALSE);
  681. }
  682. if(seekerr != CURL_SEEKFUNC_OK) {
  683. curl_off_t passed = 0;
  684. if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
  685. failf(data, "Could not seek stream");
  686. return CURLE_READ_ERROR;
  687. }
  688. /* when seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
  689. do {
  690. char scratch[4 * 1024];
  691. size_t readthisamountnow =
  692. (offset - passed > (curl_off_t)sizeof(scratch)) ?
  693. sizeof(scratch) :
  694. curlx_sotouz(offset - passed);
  695. size_t actuallyread;
  696. Curl_set_in_callback(data, TRUE);
  697. actuallyread = ctx->read_cb(scratch, 1, readthisamountnow,
  698. ctx->cb_user_data);
  699. Curl_set_in_callback(data, FALSE);
  700. passed += actuallyread;
  701. if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
  702. /* this checks for greater-than only to make sure that the
  703. CURL_READFUNC_ABORT return code still aborts */
  704. failf(data, "Could only read %" FMT_OFF_T " bytes from the input",
  705. passed);
  706. return CURLE_READ_ERROR;
  707. }
  708. } while(passed < offset);
  709. }
  710. /* now, decrease the size of the read */
  711. if(ctx->total_len > 0) {
  712. ctx->total_len -= offset;
  713. if(ctx->total_len <= 0) {
  714. failf(data, "File already completely uploaded");
  715. return CURLE_PARTIAL_FILE;
  716. }
  717. }
  718. /* we have passed, proceed as normal */
  719. return CURLE_OK;
  720. }
  721. static CURLcode cr_in_rewind(struct Curl_easy *data,
  722. struct Curl_creader *reader)
  723. {
  724. struct cr_in_ctx *ctx = reader->ctx;
  725. /* If we never invoked the callback, there is noting to rewind */
  726. if(!ctx->has_used_cb)
  727. return CURLE_OK;
  728. if(data->set.seek_func) {
  729. int err;
  730. Curl_set_in_callback(data, TRUE);
  731. err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
  732. Curl_set_in_callback(data, FALSE);
  733. CURL_TRC_READ(data, "cr_in, rewind via set.seek_func -> %d", err);
  734. if(err) {
  735. failf(data, "seek callback returned error %d", err);
  736. return CURLE_SEND_FAIL_REWIND;
  737. }
  738. }
  739. else if(data->set.ioctl_func) {
  740. curlioerr err;
  741. Curl_set_in_callback(data, TRUE);
  742. err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
  743. data->set.ioctl_client);
  744. Curl_set_in_callback(data, FALSE);
  745. CURL_TRC_READ(data, "cr_in, rewind via set.ioctl_func -> %d", (int)err);
  746. if(err) {
  747. failf(data, "ioctl callback returned error %d", (int)err);
  748. return CURLE_SEND_FAIL_REWIND;
  749. }
  750. }
  751. else {
  752. /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
  753. given FILE * stream and we can actually attempt to rewind that
  754. ourselves with fseek() */
  755. #if defined(__clang__) && __clang_major__ >= 16
  756. #pragma clang diagnostic push
  757. #pragma clang diagnostic ignored "-Wcast-function-type-strict"
  758. #endif
  759. if(data->state.fread_func == (curl_read_callback)fread) {
  760. #if defined(__clang__) && __clang_major__ >= 16
  761. #pragma clang diagnostic pop
  762. #endif
  763. int err = fseek(data->state.in, 0, SEEK_SET);
  764. CURL_TRC_READ(data, "cr_in, rewind via fseek -> %d(%d)",
  765. (int)err, (int)errno);
  766. if(err != -1)
  767. /* successful rewind */
  768. return CURLE_OK;
  769. }
  770. /* no callback set or failure above, makes us fail at once */
  771. failf(data, "necessary data rewind was not possible");
  772. return CURLE_SEND_FAIL_REWIND;
  773. }
  774. return CURLE_OK;
  775. }
  776. static CURLcode cr_in_cntrl(struct Curl_easy *data,
  777. struct Curl_creader *reader,
  778. Curl_creader_cntrl opcode)
  779. {
  780. struct cr_in_ctx *ctx = reader->ctx;
  781. switch(opcode) {
  782. case CURL_CRCNTRL_REWIND:
  783. return cr_in_rewind(data, reader);
  784. case CURL_CRCNTRL_UNPAUSE:
  785. ctx->is_paused = FALSE;
  786. break;
  787. case CURL_CRCNTRL_CLEAR_EOS:
  788. ctx->seen_eos = FALSE;
  789. break;
  790. default:
  791. break;
  792. }
  793. return CURLE_OK;
  794. }
  795. static bool cr_in_is_paused(struct Curl_easy *data,
  796. struct Curl_creader *reader)
  797. {
  798. struct cr_in_ctx *ctx = reader->ctx;
  799. (void)data;
  800. return ctx->is_paused;
  801. }
  802. static const struct Curl_crtype cr_in = {
  803. "cr-in",
  804. cr_in_init,
  805. cr_in_read,
  806. Curl_creader_def_close,
  807. cr_in_needs_rewind,
  808. cr_in_total_length,
  809. cr_in_resume_from,
  810. cr_in_cntrl,
  811. cr_in_is_paused,
  812. Curl_creader_def_done,
  813. sizeof(struct cr_in_ctx)
  814. };
  815. CURLcode Curl_creader_create(struct Curl_creader **preader,
  816. struct Curl_easy *data,
  817. const struct Curl_crtype *crt,
  818. Curl_creader_phase phase)
  819. {
  820. struct Curl_creader *reader = NULL;
  821. CURLcode result = CURLE_OUT_OF_MEMORY;
  822. void *p;
  823. DEBUGASSERT(crt->creader_size >= sizeof(struct Curl_creader));
  824. p = curlx_calloc(1, crt->creader_size);
  825. if(!p)
  826. goto out;
  827. reader = (struct Curl_creader *)p;
  828. reader->crt = crt;
  829. reader->ctx = p;
  830. reader->phase = phase;
  831. result = crt->do_init(data, reader);
  832. out:
  833. *preader = result ? NULL : reader;
  834. if(result)
  835. curlx_free(reader);
  836. return result;
  837. }
  838. void Curl_creader_free(struct Curl_easy *data, struct Curl_creader *reader)
  839. {
  840. if(reader) {
  841. reader->crt->do_close(data, reader);
  842. curlx_free(reader);
  843. }
  844. }
  845. struct cr_lc_ctx {
  846. struct Curl_creader super;
  847. struct bufq buf;
  848. BIT(read_eos); /* we read an EOS from the next reader */
  849. BIT(eos); /* we have returned an EOS */
  850. BIT(prev_cr); /* the last byte was a CR */
  851. };
  852. static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader)
  853. {
  854. struct cr_lc_ctx *ctx = reader->ctx;
  855. (void)data;
  856. Curl_bufq_init2(&ctx->buf, (16 * 1024), 1, BUFQ_OPT_SOFT_LIMIT);
  857. return CURLE_OK;
  858. }
  859. static void cr_lc_close(struct Curl_easy *data, struct Curl_creader *reader)
  860. {
  861. struct cr_lc_ctx *ctx = reader->ctx;
  862. (void)data;
  863. Curl_bufq_free(&ctx->buf);
  864. }
  865. /* client reader doing line end conversions. */
  866. static CURLcode cr_lc_read(struct Curl_easy *data,
  867. struct Curl_creader *reader,
  868. char *buf, size_t blen,
  869. size_t *pnread, bool *peos)
  870. {
  871. struct cr_lc_ctx *ctx = reader->ctx;
  872. CURLcode result;
  873. size_t nread, i, start, n;
  874. bool eos;
  875. if(ctx->eos) {
  876. *pnread = 0;
  877. *peos = TRUE;
  878. return CURLE_OK;
  879. }
  880. if(Curl_bufq_is_empty(&ctx->buf)) {
  881. if(ctx->read_eos) {
  882. ctx->eos = TRUE;
  883. *pnread = 0;
  884. *peos = TRUE;
  885. return CURLE_OK;
  886. }
  887. /* Still getting data form the next reader, ctx->buf is empty */
  888. result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos);
  889. if(result)
  890. return result;
  891. ctx->read_eos = eos;
  892. if(!nread || !memchr(buf, '\n', nread)) {
  893. /* nothing to convert, return this right away */
  894. if(ctx->read_eos)
  895. ctx->eos = TRUE;
  896. *pnread = nread;
  897. *peos = ctx->eos;
  898. goto out;
  899. }
  900. /* at least one \n might need conversion to '\r\n', place into ctx->buf */
  901. for(i = start = 0; i < nread; ++i) {
  902. /* if this byte is not an LF character, or if the preceding character is
  903. a CR (meaning this already is a CRLF pair), go to next */
  904. if((buf[i] != '\n') || ctx->prev_cr) {
  905. ctx->prev_cr = (buf[i] == '\r');
  906. continue;
  907. }
  908. ctx->prev_cr = FALSE;
  909. /* on a soft limit bufq, we do not need to check length */
  910. result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n);
  911. if(!result)
  912. result = Curl_bufq_cwrite(&ctx->buf, STRCONST("\r\n"), &n);
  913. if(result)
  914. return result;
  915. start = i + 1;
  916. }
  917. if(start < i) { /* leftover */
  918. result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n);
  919. if(result)
  920. return result;
  921. }
  922. }
  923. DEBUGASSERT(!Curl_bufq_is_empty(&ctx->buf));
  924. *peos = FALSE;
  925. result = Curl_bufq_cread(&ctx->buf, buf, blen, pnread);
  926. if(!result && ctx->read_eos && Curl_bufq_is_empty(&ctx->buf)) {
  927. /* no more data, read all, done. */
  928. ctx->eos = TRUE;
  929. *peos = TRUE;
  930. }
  931. out:
  932. CURL_TRC_READ(data, "cr_lc_read(len=%zu) -> %d, nread=%zu, eos=%d",
  933. blen, result, *pnread, *peos);
  934. return result;
  935. }
  936. static curl_off_t cr_lc_total_length(struct Curl_easy *data,
  937. struct Curl_creader *reader)
  938. {
  939. /* this reader changes length depending on input */
  940. (void)data;
  941. (void)reader;
  942. return -1;
  943. }
  944. static const struct Curl_crtype cr_lc = {
  945. "cr-lineconv",
  946. cr_lc_init,
  947. cr_lc_read,
  948. cr_lc_close,
  949. Curl_creader_def_needs_rewind,
  950. cr_lc_total_length,
  951. Curl_creader_def_resume_from,
  952. Curl_creader_def_cntrl,
  953. Curl_creader_def_is_paused,
  954. Curl_creader_def_done,
  955. sizeof(struct cr_lc_ctx)
  956. };
  957. static CURLcode cr_lc_add(struct Curl_easy *data)
  958. {
  959. struct Curl_creader *reader = NULL;
  960. CURLcode result;
  961. result = Curl_creader_create(&reader, data, &cr_lc, CURL_CR_CONTENT_ENCODE);
  962. if(!result)
  963. result = Curl_creader_add(data, reader);
  964. if(result && reader)
  965. Curl_creader_free(data, reader);
  966. return result;
  967. }
  968. static CURLcode do_init_reader_stack(struct Curl_easy *data,
  969. struct Curl_creader *r)
  970. {
  971. CURLcode result = CURLE_OK;
  972. curl_off_t clen;
  973. DEBUGASSERT(r);
  974. DEBUGASSERT(r->crt);
  975. DEBUGASSERT(r->phase == CURL_CR_CLIENT);
  976. DEBUGASSERT(!data->req.reader_stack);
  977. data->req.reader_stack = r;
  978. clen = r->crt->total_length(data, r);
  979. /* if we do not have 0 length init, and crlf conversion is wanted,
  980. * add the reader for it */
  981. if(clen && (data->set.crlf
  982. #ifdef CURL_PREFER_LF_LINEENDS
  983. || data->state.prefer_ascii
  984. #endif
  985. )) {
  986. result = cr_lc_add(data);
  987. if(result)
  988. return result;
  989. }
  990. return result;
  991. }
  992. CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len)
  993. {
  994. CURLcode result;
  995. struct Curl_creader *r;
  996. struct cr_in_ctx *ctx;
  997. result = Curl_creader_create(&r, data, &cr_in, CURL_CR_CLIENT);
  998. if(result)
  999. goto out;
  1000. ctx = r->ctx;
  1001. ctx->total_len = len;
  1002. cl_reset_reader(data);
  1003. result = do_init_reader_stack(data, r);
  1004. out:
  1005. CURL_TRC_READ(data, "add fread reader, len=%"FMT_OFF_T " -> %d",
  1006. len, result);
  1007. return result;
  1008. }
  1009. CURLcode Curl_creader_add(struct Curl_easy *data,
  1010. struct Curl_creader *reader)
  1011. {
  1012. CURLcode result;
  1013. struct Curl_creader **anchor = &data->req.reader_stack;
  1014. if(!*anchor) {
  1015. result = Curl_creader_set_fread(data, data->state.infilesize);
  1016. if(result)
  1017. return result;
  1018. }
  1019. /* Insert the writer as first in its phase.
  1020. * Skip existing readers of lower phases. */
  1021. while(*anchor && (*anchor)->phase < reader->phase)
  1022. anchor = &((*anchor)->next);
  1023. reader->next = *anchor;
  1024. *anchor = reader;
  1025. return CURLE_OK;
  1026. }
  1027. CURLcode Curl_creader_set(struct Curl_easy *data, struct Curl_creader *r)
  1028. {
  1029. CURLcode result;
  1030. DEBUGASSERT(r);
  1031. DEBUGASSERT(r->crt);
  1032. DEBUGASSERT(r->phase == CURL_CR_CLIENT);
  1033. cl_reset_reader(data);
  1034. result = do_init_reader_stack(data, r);
  1035. if(result)
  1036. Curl_creader_free(data, r);
  1037. return result;
  1038. }
  1039. CURLcode Curl_client_read(struct Curl_easy *data, char *buf, size_t blen,
  1040. size_t *nread, bool *eos)
  1041. {
  1042. CURLcode result;
  1043. DEBUGASSERT(buf);
  1044. DEBUGASSERT(blen);
  1045. DEBUGASSERT(nread);
  1046. DEBUGASSERT(eos);
  1047. *nread = 0;
  1048. if(!data->req.reader_stack) {
  1049. result = Curl_creader_set_fread(data, data->state.infilesize);
  1050. if(result)
  1051. return result;
  1052. DEBUGASSERT(data->req.reader_stack);
  1053. }
  1054. if(!data->req.reader_started) {
  1055. Curl_rlimit_start(&data->progress.ul.rlimit, Curl_pgrs_now(data));
  1056. data->req.reader_started = TRUE;
  1057. }
  1058. if(Curl_rlimit_active(&data->progress.ul.rlimit)) {
  1059. curl_off_t ul_avail = Curl_rlimit_avail(&data->progress.ul.rlimit,
  1060. Curl_pgrs_now(data));
  1061. if(ul_avail <= 0) {
  1062. result = CURLE_OK;
  1063. *eos = FALSE;
  1064. goto out;
  1065. }
  1066. if(ul_avail < (curl_off_t)blen)
  1067. blen = (size_t)ul_avail;
  1068. }
  1069. result = Curl_creader_read(data, data->req.reader_stack, buf, blen,
  1070. nread, eos);
  1071. out:
  1072. CURL_TRC_READ(data, "client_read(len=%zu) -> %d, nread=%zu, eos=%d",
  1073. blen, result, *nread, *eos);
  1074. return result;
  1075. }
  1076. bool Curl_creader_needs_rewind(struct Curl_easy *data)
  1077. {
  1078. struct Curl_creader *reader = data->req.reader_stack;
  1079. while(reader) {
  1080. if(reader->crt->needs_rewind(data, reader)) {
  1081. CURL_TRC_READ(data, "client reader needs rewind before next request");
  1082. return TRUE;
  1083. }
  1084. reader = reader->next;
  1085. }
  1086. return FALSE;
  1087. }
  1088. static CURLcode cr_null_read(struct Curl_easy *data,
  1089. struct Curl_creader *reader,
  1090. char *buf, size_t blen,
  1091. size_t *pnread, bool *peos)
  1092. {
  1093. (void)data;
  1094. (void)reader;
  1095. (void)buf;
  1096. (void)blen;
  1097. *pnread = 0;
  1098. *peos = TRUE;
  1099. return CURLE_OK;
  1100. }
  1101. static curl_off_t cr_null_total_length(struct Curl_easy *data,
  1102. struct Curl_creader *reader)
  1103. {
  1104. /* this reader changes length depending on input */
  1105. (void)data;
  1106. (void)reader;
  1107. return 0;
  1108. }
  1109. static const struct Curl_crtype cr_null = {
  1110. "cr-null",
  1111. Curl_creader_def_init,
  1112. cr_null_read,
  1113. Curl_creader_def_close,
  1114. Curl_creader_def_needs_rewind,
  1115. cr_null_total_length,
  1116. Curl_creader_def_resume_from,
  1117. Curl_creader_def_cntrl,
  1118. Curl_creader_def_is_paused,
  1119. Curl_creader_def_done,
  1120. sizeof(struct Curl_creader)
  1121. };
  1122. CURLcode Curl_creader_set_null(struct Curl_easy *data)
  1123. {
  1124. struct Curl_creader *r;
  1125. CURLcode result;
  1126. result = Curl_creader_create(&r, data, &cr_null, CURL_CR_CLIENT);
  1127. if(result)
  1128. return result;
  1129. cl_reset_reader(data);
  1130. return do_init_reader_stack(data, r);
  1131. }
  1132. struct cr_buf_ctx {
  1133. struct Curl_creader super;
  1134. const char *buf;
  1135. size_t blen;
  1136. size_t index;
  1137. };
  1138. static CURLcode cr_buf_read(struct Curl_easy *data,
  1139. struct Curl_creader *reader,
  1140. char *buf, size_t blen,
  1141. size_t *pnread, bool *peos)
  1142. {
  1143. struct cr_buf_ctx *ctx = reader->ctx;
  1144. size_t nread = ctx->blen - ctx->index;
  1145. (void)data;
  1146. if(!nread || !ctx->buf) {
  1147. *pnread = 0;
  1148. *peos = TRUE;
  1149. }
  1150. else {
  1151. if(nread > blen)
  1152. nread = blen;
  1153. memcpy(buf, ctx->buf + ctx->index, nread);
  1154. *pnread = nread;
  1155. ctx->index += nread;
  1156. *peos = (ctx->index == ctx->blen);
  1157. }
  1158. CURL_TRC_READ(data, "cr_buf_read(len=%zu) -> 0, nread=%zu, eos=%d",
  1159. blen, *pnread, *peos);
  1160. return CURLE_OK;
  1161. }
  1162. static bool cr_buf_needs_rewind(struct Curl_easy *data,
  1163. struct Curl_creader *reader)
  1164. {
  1165. struct cr_buf_ctx *ctx = reader->ctx;
  1166. (void)data;
  1167. return ctx->index > 0;
  1168. }
  1169. static CURLcode cr_buf_cntrl(struct Curl_easy *data,
  1170. struct Curl_creader *reader,
  1171. Curl_creader_cntrl opcode)
  1172. {
  1173. struct cr_buf_ctx *ctx = reader->ctx;
  1174. (void)data;
  1175. switch(opcode) {
  1176. case CURL_CRCNTRL_REWIND:
  1177. ctx->index = 0;
  1178. break;
  1179. default:
  1180. break;
  1181. }
  1182. return CURLE_OK;
  1183. }
  1184. static curl_off_t cr_buf_total_length(struct Curl_easy *data,
  1185. struct Curl_creader *reader)
  1186. {
  1187. struct cr_buf_ctx *ctx = reader->ctx;
  1188. (void)data;
  1189. return (curl_off_t)ctx->blen;
  1190. }
  1191. static CURLcode cr_buf_resume_from(struct Curl_easy *data,
  1192. struct Curl_creader *reader,
  1193. curl_off_t offset)
  1194. {
  1195. struct cr_buf_ctx *ctx = reader->ctx;
  1196. size_t boffset;
  1197. (void)data;
  1198. DEBUGASSERT(data->conn);
  1199. /* already started reading? */
  1200. if(ctx->index)
  1201. return CURLE_READ_ERROR;
  1202. boffset = curlx_sotouz_range(offset, 0, SIZE_MAX);
  1203. if(!boffset)
  1204. return CURLE_OK;
  1205. if(boffset > ctx->blen)
  1206. return CURLE_READ_ERROR;
  1207. ctx->buf += boffset;
  1208. ctx->blen -= boffset;
  1209. return CURLE_OK;
  1210. }
  1211. static const struct Curl_crtype cr_buf = {
  1212. "cr-buf",
  1213. Curl_creader_def_init,
  1214. cr_buf_read,
  1215. Curl_creader_def_close,
  1216. cr_buf_needs_rewind,
  1217. cr_buf_total_length,
  1218. cr_buf_resume_from,
  1219. cr_buf_cntrl,
  1220. Curl_creader_def_is_paused,
  1221. Curl_creader_def_done,
  1222. sizeof(struct cr_buf_ctx)
  1223. };
  1224. CURLcode Curl_creader_set_buf(struct Curl_easy *data,
  1225. const char *buf, size_t blen)
  1226. {
  1227. CURLcode result;
  1228. struct Curl_creader *r;
  1229. struct cr_buf_ctx *ctx;
  1230. result = Curl_creader_create(&r, data, &cr_buf, CURL_CR_CLIENT);
  1231. if(result)
  1232. goto out;
  1233. ctx = r->ctx;
  1234. ctx->buf = buf;
  1235. ctx->blen = blen;
  1236. ctx->index = 0;
  1237. cl_reset_reader(data);
  1238. result = do_init_reader_stack(data, r);
  1239. out:
  1240. CURL_TRC_READ(data, "add buf reader, len=%zu -> %d", blen, result);
  1241. return result;
  1242. }
  1243. curl_off_t Curl_creader_total_length(struct Curl_easy *data)
  1244. {
  1245. struct Curl_creader *r = data->req.reader_stack;
  1246. return r ? r->crt->total_length(data, r) : -1;
  1247. }
  1248. curl_off_t Curl_creader_client_length(struct Curl_easy *data)
  1249. {
  1250. struct Curl_creader *r = data->req.reader_stack;
  1251. while(r && r->phase != CURL_CR_CLIENT)
  1252. r = r->next;
  1253. return r ? r->crt->total_length(data, r) : -1;
  1254. }
  1255. CURLcode Curl_creader_resume_from(struct Curl_easy *data, curl_off_t offset)
  1256. {
  1257. struct Curl_creader *r = data->req.reader_stack;
  1258. while(r && r->phase != CURL_CR_CLIENT)
  1259. r = r->next;
  1260. return r ? r->crt->resume_from(data, r, offset) : CURLE_READ_ERROR;
  1261. }
  1262. CURLcode Curl_creader_unpause(struct Curl_easy *data)
  1263. {
  1264. struct Curl_creader *reader = data->req.reader_stack;
  1265. CURLcode result = CURLE_OK;
  1266. while(reader) {
  1267. result = reader->crt->cntrl(data, reader, CURL_CRCNTRL_UNPAUSE);
  1268. CURL_TRC_READ(data, "unpausing %s -> %d", reader->crt->name, result);
  1269. if(result)
  1270. break;
  1271. reader = reader->next;
  1272. }
  1273. return result;
  1274. }
  1275. bool Curl_creader_is_paused(struct Curl_easy *data)
  1276. {
  1277. struct Curl_creader *reader = data->req.reader_stack;
  1278. while(reader) {
  1279. if(reader->crt->is_paused(data, reader))
  1280. return TRUE;
  1281. reader = reader->next;
  1282. }
  1283. return FALSE;
  1284. }
  1285. void Curl_creader_done(struct Curl_easy *data, int premature)
  1286. {
  1287. struct Curl_creader *reader = data->req.reader_stack;
  1288. while(reader) {
  1289. reader->crt->done(data, reader, premature);
  1290. reader = reader->next;
  1291. }
  1292. }
  1293. struct Curl_creader *Curl_creader_get_by_type(struct Curl_easy *data,
  1294. const struct Curl_crtype *crt)
  1295. {
  1296. struct Curl_creader *r;
  1297. for(r = data->req.reader_stack; r; r = r->next) {
  1298. if(r->crt == crt)
  1299. return r;
  1300. }
  1301. return NULL;
  1302. }