2
0

sendf.c 38 KB

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