(void)instate;
- if(imapcode == '*')
- result = Curl_client_write(data, CLIENTWRITE_BODY, line, len);
+ if(imapcode == '*') {
+ /* Check if this response contains a literal (e.g. FETCH responses with
+ body data). Literal syntax is {size}\r\n */
+ const char *cr = memchr(line, '\r', len);
+ size_t line_len = cr ? (size_t)(cr - line) : len;
+ const char *ptr = memchr(line, '{', line_len);
+ if(ptr) {
+ curl_off_t size = 0;
+ bool parsed = FALSE;
+ ptr++;
+ if(!curlx_str_number(&ptr, &size, CURL_OFF_T_MAX) &&
+ !curlx_str_single(&ptr, '}'))
+ parsed = TRUE;
+
+ if(parsed) {
+ struct pingpong *pp = &imapc->pp;
+ size_t buffer_len = curlx_dyn_len(&pp->recvbuf);
+ size_t after_header = buffer_len - pp->nfinal;
+
+ /* This is a literal response, setup to receive the body data */
+ infof(data, "Found %" FMT_OFF_T " bytes to download", size);
+ /* Progress size includes both header line and literal body */
+ Curl_pgrsSetDownloadSize(data, size + len);
+
+ /* First write the header line */
+ result = Curl_client_write(data, CLIENTWRITE_BODY, line, len);
+ if(result)
+ return result;
+
+ /* Handle data already in buffer after the header line */
+ if(after_header > 0) {
+ /* There is already data in the buffer that is part of the literal
+ body or subsequent responses */
+ size_t chunk = after_header;
+
+ /* Keep only the data after the header line */
+ curlx_dyn_tail(&pp->recvbuf, chunk);
+ pp->nfinal = 0; /* done */
+
+ /* Limit chunk to the literal size */
+ if(chunk > (size_t)size)
+ chunk = (size_t)size;
+
+ if(chunk) {
+ /* Write the literal body data */
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
+ curlx_dyn_ptr(&pp->recvbuf), chunk);
+ if(result)
+ return result;
+ }
+
+ /* Handle remaining data in buffer (either more literal data or
+ subsequent responses) */
+ if(after_header > chunk) {
+ /* Keep the data after the literal body */
+ pp->overflow = after_header - chunk;
+ curlx_dyn_tail(&pp->recvbuf, pp->overflow);
+ }
+ else {
+ pp->overflow = 0;
+ curlx_dyn_reset(&pp->recvbuf);
+ }
+ }
+ else {
+ /* No data in buffer yet, reset overflow */
+ pp->overflow = 0;
+ }
+
+ if(data->req.bytecount == size + (curl_off_t)len)
+ /* All data already transferred (header + literal body) */
+ Curl_xfer_setup_nop(data);
+ else {
+ /* Setup to receive the literal body data.
+ maxdownload and transfer size include both header line and
+ literal body */
+ data->req.maxdownload = size + len;
+ Curl_xfer_setup_recv(data, FIRSTSOCKET, size + len);
+ }
+ /* End of DO phase */
+ imap_state(data, imapc, IMAP_STOP);
+ }
+ else {
+ /* Failed to parse literal, just write the line */
+ result = Curl_client_write(data, CLIENTWRITE_BODY, line, len);
+ }
+ }
+ else {
+ /* No literal, just write the line as-is */
+ result = Curl_client_write(data, CLIENTWRITE_BODY, line, len);
+ }
+ }
else if(imapcode != IMAP_RESP_OK)
result = CURLE_QUOTE_ERROR;
else
connclose(conn, "IMAP done with bad status"); /* marked for closure */
result = status; /* use the already set error code */
}
- else if(!data->set.connect_only && !imap->custom &&
- (imap->uid || imap->mindex || data->state.upload ||
- IS_MIME_POST(data))) {
- /* Handle responses after FETCH or APPEND transfer has finished */
+ else if(!data->set.connect_only &&
+ ((!imap->custom && (imap->uid || imap->mindex)) ||
+ (imap->custom && data->req.maxdownload > 0) ||
+ data->state.upload || IS_MIME_POST(data))) {
+ /* Handle responses after FETCH or APPEND transfer has finished.
+ For custom commands, check if we set up a download which indicates
+ a FETCH-like command with literal data. */
if(!data->state.upload && !IS_MIME_POST(data))
imap_state(data, imapc, IMAP_FETCH_FINAL);
--- /dev/null
+<testcase>
+<info>
+<keywords>
+IMAP
+Clear Text
+FETCH
+CUSTOMREQUEST
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+Line 001: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 002: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 003: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 004: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 005: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 006: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 007: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 008: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 009: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 010: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 011: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 012: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 013: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 014: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 015: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 016: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 017: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 018: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 019: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 020: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 021: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 022: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 023: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 024: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 025: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 026: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 027: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 028: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 029: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 030: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 031: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 032: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 033: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 034: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 035: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 036: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 037: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 038: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 039: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 040: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 041: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 042: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 043: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 044: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 045: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 046: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 047: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 048: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 049: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 050: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 051: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 052: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 053: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 054: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 055: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 056: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 057: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 058: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 059: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 060: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 061: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 062: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 063: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 064: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 065: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 066: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 067: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 068: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 069: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 070: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 071: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 072: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 073: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 074: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 075: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 076: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 077: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 078: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 079: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 080: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 081: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 082: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 083: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 084: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 085: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 086: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 087: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 088: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 089: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 090: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 091: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 092: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 093: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 094: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 095: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 096: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 097: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 098: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 099: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 100: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+
+</data>
+<datacheck>
+* 456 FETCH (BODY[TEXT] {7101}\r
+Line 001: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 002: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 003: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 004: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 005: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 006: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 007: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 008: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 009: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 010: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 011: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 012: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 013: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 014: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 015: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 016: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 017: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 018: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 019: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 020: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 021: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 022: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 023: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 024: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 025: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 026: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 027: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 028: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 029: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 030: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 031: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 032: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 033: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 034: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 035: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 036: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 037: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 038: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 039: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 040: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 041: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 042: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 043: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 044: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 045: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 046: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 047: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 048: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 049: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 050: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 051: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 052: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 053: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 054: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 055: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 056: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 057: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 058: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 059: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 060: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 061: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 062: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 063: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 064: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 065: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 066: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 067: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 068: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 069: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 070: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 071: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 072: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 073: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 074: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 075: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 076: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 077: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 078: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 079: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 080: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 081: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 082: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 083: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 084: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 085: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 086: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 087: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 088: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 089: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 090: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 091: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 092: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 093: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 094: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 095: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 096: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 097: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 098: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 099: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+Line 100: Testing large IMAP literal with custom FETCH. XXXXXXXXXXXXX\r
+
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+imap
+</server>
+<name>
+IMAP custom FETCH with larger literal response (~7KB)
+</name>
+<command>
+ imap://%HOSTIP:%IMAPPORT/%TESTNUMBER/ -u user:secret -X 'FETCH 456 BODY[TEXT]'
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+A001 CAPABILITY\r
+A002 LOGIN user secret\r
+A003 SELECT %TESTNUMBER\r
+A004 FETCH 456 BODY[TEXT]\r
+A005 LOGOUT\r
+</protocol>
+</verify>
+</testcase>