File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / transfer.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 1998 - 2020, 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.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  ***************************************************************************/
   22: 
   23: #include "curl_setup.h"
   24: #include "strtoofft.h"
   25: 
   26: #ifdef HAVE_NETINET_IN_H
   27: #include <netinet/in.h>
   28: #endif
   29: #ifdef HAVE_NETDB_H
   30: #include <netdb.h>
   31: #endif
   32: #ifdef HAVE_ARPA_INET_H
   33: #include <arpa/inet.h>
   34: #endif
   35: #ifdef HAVE_NET_IF_H
   36: #include <net/if.h>
   37: #endif
   38: #ifdef HAVE_SYS_IOCTL_H
   39: #include <sys/ioctl.h>
   40: #endif
   41: #ifdef HAVE_SIGNAL_H
   42: #include <signal.h>
   43: #endif
   44: 
   45: #ifdef HAVE_SYS_PARAM_H
   46: #include <sys/param.h>
   47: #endif
   48: 
   49: #ifdef HAVE_SYS_SELECT_H
   50: #include <sys/select.h>
   51: #elif defined(HAVE_UNISTD_H)
   52: #include <unistd.h>
   53: #endif
   54: 
   55: #ifndef HAVE_SOCKET
   56: #error "We can't compile without socket() support!"
   57: #endif
   58: 
   59: #include "urldata.h"
   60: #include <curl/curl.h>
   61: #include "netrc.h"
   62: 
   63: #include "content_encoding.h"
   64: #include "hostip.h"
   65: #include "transfer.h"
   66: #include "sendf.h"
   67: #include "speedcheck.h"
   68: #include "progress.h"
   69: #include "http.h"
   70: #include "url.h"
   71: #include "getinfo.h"
   72: #include "vtls/vtls.h"
   73: #include "select.h"
   74: #include "multiif.h"
   75: #include "connect.h"
   76: #include "non-ascii.h"
   77: #include "http2.h"
   78: #include "mime.h"
   79: #include "strcase.h"
   80: #include "urlapi-int.h"
   81: 
   82: /* The last 3 #include files should be in this order */
   83: #include "curl_printf.h"
   84: #include "curl_memory.h"
   85: #include "memdebug.h"
   86: 
   87: #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
   88:     !defined(CURL_DISABLE_IMAP)
   89: /*
   90:  * checkheaders() checks the linked list of custom headers for a
   91:  * particular header (prefix). Provide the prefix without colon!
   92:  *
   93:  * Returns a pointer to the first matching header or NULL if none matched.
   94:  */
   95: char *Curl_checkheaders(const struct connectdata *conn,
   96:                         const char *thisheader)
   97: {
   98:   struct curl_slist *head;
   99:   size_t thislen = strlen(thisheader);
  100:   struct Curl_easy *data = conn->data;
  101: 
  102:   for(head = data->set.headers; head; head = head->next) {
  103:     if(strncasecompare(head->data, thisheader, thislen) &&
  104:        Curl_headersep(head->data[thislen]) )
  105:       return head->data;
  106:   }
  107: 
  108:   return NULL;
  109: }
  110: #endif
  111: 
  112: CURLcode Curl_get_upload_buffer(struct Curl_easy *data)
  113: {
  114:   if(!data->state.ulbuf) {
  115:     data->state.ulbuf = malloc(data->set.upload_buffer_size);
  116:     if(!data->state.ulbuf)
  117:       return CURLE_OUT_OF_MEMORY;
  118:   }
  119:   return CURLE_OK;
  120: }
  121: 
  122: #ifndef CURL_DISABLE_HTTP
  123: /*
  124:  * This function will be called to loop through the trailers buffer
  125:  * until no more data is available for sending.
  126:  */
  127: static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems,
  128:                                  void *raw)
  129: {
  130:   struct Curl_easy *data = (struct Curl_easy *)raw;
  131:   Curl_send_buffer *trailers_buf = data->state.trailers_buf;
  132:   size_t bytes_left = trailers_buf->size_used-data->state.trailers_bytes_sent;
  133:   size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left;
  134:   if(to_copy) {
  135:     memcpy(buffer,
  136:            &trailers_buf->buffer[data->state.trailers_bytes_sent],
  137:            to_copy);
  138:     data->state.trailers_bytes_sent += to_copy;
  139:   }
  140:   return to_copy;
  141: }
  142: 
  143: static size_t Curl_trailers_left(void *raw)
  144: {
  145:   struct Curl_easy *data = (struct Curl_easy *)raw;
  146:   Curl_send_buffer *trailers_buf = data->state.trailers_buf;
  147:   return trailers_buf->size_used - data->state.trailers_bytes_sent;
  148: }
  149: #endif
  150: 
  151: /*
  152:  * This function will call the read callback to fill our buffer with data
  153:  * to upload.
  154:  */
  155: CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
  156:                              size_t *nreadp)
  157: {
  158:   struct Curl_easy *data = conn->data;
  159:   size_t buffersize = bytes;
  160:   size_t nread;
  161: 
  162:   curl_read_callback readfunc = NULL;
  163:   void *extra_data = NULL;
  164: 
  165: #ifdef CURL_DOES_CONVERSIONS
  166:   bool sending_http_headers = FALSE;
  167: 
  168:   if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
  169:     const struct HTTP *http = data->req.protop;
  170: 
  171:     if(http->sending == HTTPSEND_REQUEST)
  172:       /* We're sending the HTTP request headers, not the data.
  173:          Remember that so we don't re-translate them into garbage. */
  174:       sending_http_headers = TRUE;
  175:   }
  176: #endif
  177: 
  178: #ifndef CURL_DISABLE_HTTP
  179:   if(data->state.trailers_state == TRAILERS_INITIALIZED) {
  180:     struct curl_slist *trailers = NULL;
  181:     CURLcode result;
  182:     int trailers_ret_code;
  183: 
  184:     /* at this point we already verified that the callback exists
  185:        so we compile and store the trailers buffer, then proceed */
  186:     infof(data,
  187:           "Moving trailers state machine from initialized to sending.\n");
  188:     data->state.trailers_state = TRAILERS_SENDING;
  189:     data->state.trailers_buf = Curl_add_buffer_init();
  190:     if(!data->state.trailers_buf) {
  191:       failf(data, "Unable to allocate trailing headers buffer !");
  192:       return CURLE_OUT_OF_MEMORY;
  193:     }
  194:     data->state.trailers_bytes_sent = 0;
  195:     Curl_set_in_callback(data, true);
  196:     trailers_ret_code = data->set.trailer_callback(&trailers,
  197:                                                    data->set.trailer_data);
  198:     Curl_set_in_callback(data, false);
  199:     if(trailers_ret_code == CURL_TRAILERFUNC_OK) {
  200:       result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf,
  201:                                           data);
  202:     }
  203:     else {
  204:       failf(data, "operation aborted by trailing headers callback");
  205:       *nreadp = 0;
  206:       result = CURLE_ABORTED_BY_CALLBACK;
  207:     }
  208:     if(result) {
  209:       Curl_add_buffer_free(&data->state.trailers_buf);
  210:       curl_slist_free_all(trailers);
  211:       return result;
  212:     }
  213:     infof(data, "Successfully compiled trailers.\r\n");
  214:     curl_slist_free_all(trailers);
  215:   }
  216: #endif
  217: 
  218:   /* if we are transmitting trailing data, we don't need to write
  219:      a chunk size so we skip this */
  220:   if(data->req.upload_chunky &&
  221:      data->state.trailers_state == TRAILERS_NONE) {
  222:     /* if chunked Transfer-Encoding */
  223:     buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
  224:     data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
  225:   }
  226: 
  227: #ifndef CURL_DISABLE_HTTP
  228:   if(data->state.trailers_state == TRAILERS_SENDING) {
  229:     /* if we're here then that means that we already sent the last empty chunk
  230:        but we didn't send a final CR LF, so we sent 0 CR LF. We then start
  231:        pulling trailing data until we have no more at which point we
  232:        simply return to the previous point in the state machine as if
  233:        nothing happened.
  234:        */
  235:     readfunc = Curl_trailers_read;
  236:     extra_data = (void *)data;
  237:   }
  238:   else
  239: #endif
  240:   {
  241:     readfunc = data->state.fread_func;
  242:     extra_data = data->state.in;
  243:   }
  244: 
  245:   Curl_set_in_callback(data, true);
  246:   nread = readfunc(data->req.upload_fromhere, 1,
  247:                    buffersize, extra_data);
  248:   Curl_set_in_callback(data, false);
  249: 
  250:   if(nread == CURL_READFUNC_ABORT) {
  251:     failf(data, "operation aborted by callback");
  252:     *nreadp = 0;
  253:     return CURLE_ABORTED_BY_CALLBACK;
  254:   }
  255:   if(nread == CURL_READFUNC_PAUSE) {
  256:     struct SingleRequest *k = &data->req;
  257: 
  258:     if(conn->handler->flags & PROTOPT_NONETWORK) {
  259:       /* protocols that work without network cannot be paused. This is
  260:          actually only FILE:// just now, and it can't pause since the transfer
  261:          isn't done using the "normal" procedure. */
  262:       failf(data, "Read callback asked for PAUSE when not supported!");
  263:       return CURLE_READ_ERROR;
  264:     }
  265: 
  266:     /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
  267:     k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
  268:     if(data->req.upload_chunky) {
  269:         /* Back out the preallocation done above */
  270:       data->req.upload_fromhere -= (8 + 2);
  271:     }
  272:     *nreadp = 0;
  273: 
  274:     return CURLE_OK; /* nothing was read */
  275:   }
  276:   else if(nread > buffersize) {
  277:     /* the read function returned a too large value */
  278:     *nreadp = 0;
  279:     failf(data, "read function returned funny value");
  280:     return CURLE_READ_ERROR;
  281:   }
  282: 
  283:   if(!data->req.forbidchunk && data->req.upload_chunky) {
  284:     /* if chunked Transfer-Encoding
  285:      *    build chunk:
  286:      *
  287:      *        <HEX SIZE> CRLF
  288:      *        <DATA> CRLF
  289:      */
  290:     /* On non-ASCII platforms the <DATA> may or may not be
  291:        translated based on set.prefer_ascii while the protocol
  292:        portion must always be translated to the network encoding.
  293:        To further complicate matters, line end conversion might be
  294:        done later on, so we need to prevent CRLFs from becoming
  295:        CRCRLFs if that's the case.  To do this we use bare LFs
  296:        here, knowing they'll become CRLFs later on.
  297:      */
  298: 
  299:     bool added_crlf = FALSE;
  300:     int hexlen = 0;
  301:     const char *endofline_native;
  302:     const char *endofline_network;
  303: 
  304:     if(
  305: #ifdef CURL_DO_LINEEND_CONV
  306:        (data->set.prefer_ascii) ||
  307: #endif
  308:        (data->set.crlf)) {
  309:       /* \n will become \r\n later on */
  310:       endofline_native  = "\n";
  311:       endofline_network = "\x0a";
  312:     }
  313:     else {
  314:       endofline_native  = "\r\n";
  315:       endofline_network = "\x0d\x0a";
  316:     }
  317: 
  318:     /* if we're not handling trailing data, proceed as usual */
  319:     if(data->state.trailers_state != TRAILERS_SENDING) {
  320:       char hexbuffer[11] = "";
  321:       hexlen = msnprintf(hexbuffer, sizeof(hexbuffer),
  322:                          "%zx%s", nread, endofline_native);
  323: 
  324:       /* move buffer pointer */
  325:       data->req.upload_fromhere -= hexlen;
  326:       nread += hexlen;
  327: 
  328:       /* copy the prefix to the buffer, leaving out the NUL */
  329:       memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
  330: 
  331:       /* always append ASCII CRLF to the data unless
  332:          we have a valid trailer callback */
  333: #ifndef CURL_DISABLE_HTTP
  334:       if((nread-hexlen) == 0 &&
  335:           data->set.trailer_callback != NULL &&
  336:           data->state.trailers_state == TRAILERS_NONE) {
  337:         data->state.trailers_state = TRAILERS_INITIALIZED;
  338:       }
  339:       else
  340: #endif
  341:       {
  342:         memcpy(data->req.upload_fromhere + nread,
  343:                endofline_network,
  344:                strlen(endofline_network));
  345:         added_crlf = TRUE;
  346:       }
  347:     }
  348: 
  349: #ifdef CURL_DOES_CONVERSIONS
  350:     {
  351:       CURLcode result;
  352:       size_t length;
  353:       if(data->set.prefer_ascii)
  354:         /* translate the protocol and data */
  355:         length = nread;
  356:       else
  357:         /* just translate the protocol portion */
  358:         length = hexlen;
  359:       if(length) {
  360:         result = Curl_convert_to_network(data, data->req.upload_fromhere,
  361:                                          length);
  362:         /* Curl_convert_to_network calls failf if unsuccessful */
  363:         if(result)
  364:           return result;
  365:       }
  366:     }
  367: #endif /* CURL_DOES_CONVERSIONS */
  368: 
  369: #ifndef CURL_DISABLE_HTTP
  370:     if(data->state.trailers_state == TRAILERS_SENDING &&
  371:        !Curl_trailers_left(data)) {
  372:       Curl_add_buffer_free(&data->state.trailers_buf);
  373:       data->state.trailers_state = TRAILERS_DONE;
  374:       data->set.trailer_data = NULL;
  375:       data->set.trailer_callback = NULL;
  376:       /* mark the transfer as done */
  377:       data->req.upload_done = TRUE;
  378:       infof(data, "Signaling end of chunked upload after trailers.\n");
  379:     }
  380:     else
  381: #endif
  382:       if((nread - hexlen) == 0 &&
  383:          data->state.trailers_state != TRAILERS_INITIALIZED) {
  384:         /* mark this as done once this chunk is transferred */
  385:         data->req.upload_done = TRUE;
  386:         infof(data,
  387:               "Signaling end of chunked upload via terminating chunk.\n");
  388:       }
  389: 
  390:     if(added_crlf)
  391:       nread += strlen(endofline_network); /* for the added end of line */
  392:   }
  393: #ifdef CURL_DOES_CONVERSIONS
  394:   else if((data->set.prefer_ascii) && (!sending_http_headers)) {
  395:     CURLcode result;
  396:     result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
  397:     /* Curl_convert_to_network calls failf if unsuccessful */
  398:     if(result)
  399:       return result;
  400:   }
  401: #endif /* CURL_DOES_CONVERSIONS */
  402: 
  403:   *nreadp = nread;
  404: 
  405:   return CURLE_OK;
  406: }
  407: 
  408: 
  409: /*
  410:  * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
  411:  * POST/PUT with multi-pass authentication when a sending was denied and a
  412:  * resend is necessary.
  413:  */
  414: CURLcode Curl_readrewind(struct connectdata *conn)
  415: {
  416:   struct Curl_easy *data = conn->data;
  417:   curl_mimepart *mimepart = &data->set.mimepost;
  418: 
  419:   conn->bits.rewindaftersend = FALSE; /* we rewind now */
  420: 
  421:   /* explicitly switch off sending data on this connection now since we are
  422:      about to restart a new transfer and thus we want to avoid inadvertently
  423:      sending more data on the existing connection until the next transfer
  424:      starts */
  425:   data->req.keepon &= ~KEEP_SEND;
  426: 
  427:   /* We have sent away data. If not using CURLOPT_POSTFIELDS or
  428:      CURLOPT_HTTPPOST, call app to rewind
  429:   */
  430:   if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
  431:     struct HTTP *http = data->req.protop;
  432: 
  433:     if(http->sendit)
  434:       mimepart = http->sendit;
  435:   }
  436:   if(data->set.postfields)
  437:     ; /* do nothing */
  438:   else if(data->set.httpreq == HTTPREQ_POST_MIME ||
  439:           data->set.httpreq == HTTPREQ_POST_FORM) {
  440:     if(Curl_mime_rewind(mimepart)) {
  441:       failf(data, "Cannot rewind mime/post data");
  442:       return CURLE_SEND_FAIL_REWIND;
  443:     }
  444:   }
  445:   else {
  446:     if(data->set.seek_func) {
  447:       int err;
  448: 
  449:       Curl_set_in_callback(data, true);
  450:       err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
  451:       Curl_set_in_callback(data, false);
  452:       if(err) {
  453:         failf(data, "seek callback returned error %d", (int)err);
  454:         return CURLE_SEND_FAIL_REWIND;
  455:       }
  456:     }
  457:     else if(data->set.ioctl_func) {
  458:       curlioerr err;
  459: 
  460:       Curl_set_in_callback(data, true);
  461:       err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
  462:                                    data->set.ioctl_client);
  463:       Curl_set_in_callback(data, false);
  464:       infof(data, "the ioctl callback returned %d\n", (int)err);
  465: 
  466:       if(err) {
  467:         failf(data, "ioctl callback returned error %d", (int)err);
  468:         return CURLE_SEND_FAIL_REWIND;
  469:       }
  470:     }
  471:     else {
  472:       /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
  473:          given FILE * stream and we can actually attempt to rewind that
  474:          ourselves with fseek() */
  475:       if(data->state.fread_func == (curl_read_callback)fread) {
  476:         if(-1 != fseek(data->state.in, 0, SEEK_SET))
  477:           /* successful rewind */
  478:           return CURLE_OK;
  479:       }
  480: 
  481:       /* no callback set or failure above, makes us fail at once */
  482:       failf(data, "necessary data rewind wasn't possible");
  483:       return CURLE_SEND_FAIL_REWIND;
  484:     }
  485:   }
  486:   return CURLE_OK;
  487: }
  488: 
  489: static int data_pending(const struct Curl_easy *data)
  490: {
  491:   struct connectdata *conn = data->conn;
  492:   /* in the case of libssh2, we can never be really sure that we have emptied
  493:      its internal buffers so we MUST always try until we get EAGAIN back */
  494:   return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
  495: #if defined(USE_NGHTTP2)
  496:     Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
  497:     /* For HTTP/2, we may read up everything including response body
  498:        with header fields in Curl_http_readwrite_headers. If no
  499:        content-length is provided, curl waits for the connection
  500:        close, which we emulate it using conn->proto.httpc.closed =
  501:        TRUE. The thing is if we read everything, then http2_recv won't
  502:        be called and we cannot signal the HTTP/2 stream has closed. As
  503:        a workaround, we return nonzero here to call http2_recv. */
  504:     ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
  505: #elif defined(ENABLE_QUIC)
  506:     Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data);
  507: #else
  508:     Curl_ssl_data_pending(conn, FIRSTSOCKET);
  509: #endif
  510: }
  511: 
  512: /*
  513:  * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
  514:  * remote document with the time provided by CURLOPT_TIMEVAL
  515:  */
  516: bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
  517: {
  518:   if((timeofdoc == 0) || (data->set.timevalue == 0))
  519:     return TRUE;
  520: 
  521:   switch(data->set.timecondition) {
  522:   case CURL_TIMECOND_IFMODSINCE:
  523:   default:
  524:     if(timeofdoc <= data->set.timevalue) {
  525:       infof(data,
  526:             "The requested document is not new enough\n");
  527:       data->info.timecond = TRUE;
  528:       return FALSE;
  529:     }
  530:     break;
  531:   case CURL_TIMECOND_IFUNMODSINCE:
  532:     if(timeofdoc >= data->set.timevalue) {
  533:       infof(data,
  534:             "The requested document is not old enough\n");
  535:       data->info.timecond = TRUE;
  536:       return FALSE;
  537:     }
  538:     break;
  539:   }
  540: 
  541:   return TRUE;
  542: }
  543: 
  544: /*
  545:  * Go ahead and do a read if we have a readable socket or if
  546:  * the stream was rewound (in which case we have data in a
  547:  * buffer)
  548:  *
  549:  * return '*comeback' TRUE if we didn't properly drain the socket so this
  550:  * function should get called again without select() or similar in between!
  551:  */
  552: static CURLcode readwrite_data(struct Curl_easy *data,
  553:                                struct connectdata *conn,
  554:                                struct SingleRequest *k,
  555:                                int *didwhat, bool *done,
  556:                                bool *comeback)
  557: {
  558:   CURLcode result = CURLE_OK;
  559:   ssize_t nread; /* number of bytes read */
  560:   size_t excess = 0; /* excess bytes read */
  561:   bool readmore = FALSE; /* used by RTP to signal for more data */
  562:   int maxloops = 100;
  563: 
  564:   *done = FALSE;
  565:   *comeback = FALSE;
  566: 
  567:   /* This is where we loop until we have read everything there is to
  568:      read or we get a CURLE_AGAIN */
  569:   do {
  570:     bool is_empty_data = FALSE;
  571:     size_t buffersize = data->set.buffer_size;
  572:     size_t bytestoread = buffersize;
  573: #ifdef USE_NGHTTP2
  574:     bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
  575:                      (conn->httpversion == 20));
  576: #endif
  577: 
  578:     if(
  579: #ifdef USE_NGHTTP2
  580:        /* For HTTP/2, read data without caring about the content
  581:           length. This is safe because body in HTTP/2 is always
  582:           segmented thanks to its framing layer. Meanwhile, we have to
  583:           call Curl_read to ensure that http2_handle_stream_close is
  584:           called when we read all incoming bytes for a particular
  585:           stream. */
  586:        !is_http2 &&
  587: #endif
  588:        k->size != -1 && !k->header) {
  589:       /* make sure we don't read too much */
  590:       curl_off_t totalleft = k->size - k->bytecount;
  591:       if(totalleft < (curl_off_t)bytestoread)
  592:         bytestoread = (size_t)totalleft;
  593:     }
  594: 
  595:     if(bytestoread) {
  596:       /* receive data from the network! */
  597:       result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
  598: 
  599:       /* read would've blocked */
  600:       if(CURLE_AGAIN == result)
  601:         break; /* get out of loop */
  602: 
  603:       if(result>0)
  604:         return result;
  605:     }
  606:     else {
  607:       /* read nothing but since we wanted nothing we consider this an OK
  608:          situation to proceed from */
  609:       DEBUGF(infof(data, "readwrite_data: we're done!\n"));
  610:       nread = 0;
  611:     }
  612: 
  613:     if(!k->bytecount) {
  614:       Curl_pgrsTime(data, TIMER_STARTTRANSFER);
  615:       if(k->exp100 > EXP100_SEND_DATA)
  616:         /* set time stamp to compare with when waiting for the 100 */
  617:         k->start100 = Curl_now();
  618:     }
  619: 
  620:     *didwhat |= KEEP_RECV;
  621:     /* indicates data of zero size, i.e. empty file */
  622:     is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
  623: 
  624:     /* NUL terminate, allowing string ops to be used */
  625:     if(0 < nread || is_empty_data) {
  626:       k->buf[nread] = 0;
  627:     }
  628:     else {
  629:       /* if we receive 0 or less here, either the http2 stream is closed or the
  630:          server closed the connection and we bail out from this! */
  631: #ifdef USE_NGHTTP2
  632:       if(is_http2 && !nread)
  633:         DEBUGF(infof(data, "nread == 0, stream closed, bailing\n"));
  634:       else
  635: #endif
  636:         DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
  637:       k->keepon &= ~KEEP_RECV;
  638:       break;
  639:     }
  640: 
  641:     /* Default buffer to use when we write the buffer, it may be changed
  642:        in the flow below before the actual storing is done. */
  643:     k->str = k->buf;
  644: 
  645:     if(conn->handler->readwrite) {
  646:       result = conn->handler->readwrite(data, conn, &nread, &readmore);
  647:       if(result)
  648:         return result;
  649:       if(readmore)
  650:         break;
  651:     }
  652: 
  653: #ifndef CURL_DISABLE_HTTP
  654:     /* Since this is a two-state thing, we check if we are parsing
  655:        headers at the moment or not. */
  656:     if(k->header) {
  657:       /* we are in parse-the-header-mode */
  658:       bool stop_reading = FALSE;
  659:       result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading);
  660:       if(result)
  661:         return result;
  662: 
  663:       if(conn->handler->readwrite &&
  664:          (k->maxdownload <= 0 && nread > 0)) {
  665:         result = conn->handler->readwrite(data, conn, &nread, &readmore);
  666:         if(result)
  667:           return result;
  668:         if(readmore)
  669:           break;
  670:       }
  671: 
  672:       if(stop_reading) {
  673:         /* We've stopped dealing with input, get out of the do-while loop */
  674: 
  675:         if(nread > 0) {
  676:           infof(data,
  677:                 "Excess found:"
  678:                 " excess = %zd"
  679:                 " url = %s (zero-length body)\n",
  680:                 nread, data->state.up.path);
  681:         }
  682: 
  683:         break;
  684:       }
  685:     }
  686: #endif /* CURL_DISABLE_HTTP */
  687: 
  688: 
  689:     /* This is not an 'else if' since it may be a rest from the header
  690:        parsing, where the beginning of the buffer is headers and the end
  691:        is non-headers. */
  692:     if(k->str && !k->header && (nread > 0 || is_empty_data)) {
  693: 
  694:       if(data->set.opt_no_body) {
  695:         /* data arrives although we want none, bail out */
  696:         streamclose(conn, "ignoring body");
  697:         *done = TRUE;
  698:         return CURLE_WEIRD_SERVER_REPLY;
  699:       }
  700: 
  701: #ifndef CURL_DISABLE_HTTP
  702:       if(0 == k->bodywrites && !is_empty_data) {
  703:         /* These checks are only made the first time we are about to
  704:            write a piece of the body */
  705:         if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
  706:           /* HTTP-only checks */
  707: 
  708:           if(data->req.newurl) {
  709:             if(conn->bits.close) {
  710:               /* Abort after the headers if "follow Location" is set
  711:                  and we're set to close anyway. */
  712:               k->keepon &= ~KEEP_RECV;
  713:               *done = TRUE;
  714:               return CURLE_OK;
  715:             }
  716:             /* We have a new url to load, but since we want to be able
  717:                to re-use this connection properly, we read the full
  718:                response in "ignore more" */
  719:             k->ignorebody = TRUE;
  720:             infof(data, "Ignoring the response-body\n");
  721:           }
  722:           if(data->state.resume_from && !k->content_range &&
  723:              (data->set.httpreq == HTTPREQ_GET) &&
  724:              !k->ignorebody) {
  725: 
  726:             if(k->size == data->state.resume_from) {
  727:               /* The resume point is at the end of file, consider this fine
  728:                  even if it doesn't allow resume from here. */
  729:               infof(data, "The entire document is already downloaded");
  730:               connclose(conn, "already downloaded");
  731:               /* Abort download */
  732:               k->keepon &= ~KEEP_RECV;
  733:               *done = TRUE;
  734:               return CURLE_OK;
  735:             }
  736: 
  737:             /* we wanted to resume a download, although the server doesn't
  738:              * seem to support this and we did this with a GET (if it
  739:              * wasn't a GET we did a POST or PUT resume) */
  740:             failf(data, "HTTP server doesn't seem to support "
  741:                   "byte ranges. Cannot resume.");
  742:             return CURLE_RANGE_ERROR;
  743:           }
  744: 
  745:           if(data->set.timecondition && !data->state.range) {
  746:             /* A time condition has been set AND no ranges have been
  747:                requested. This seems to be what chapter 13.3.4 of
  748:                RFC 2616 defines to be the correct action for a
  749:                HTTP/1.1 client */
  750: 
  751:             if(!Curl_meets_timecondition(data, k->timeofdoc)) {
  752:               *done = TRUE;
  753:               /* We're simulating a http 304 from server so we return
  754:                  what should have been returned from the server */
  755:               data->info.httpcode = 304;
  756:               infof(data, "Simulate a HTTP 304 response!\n");
  757:               /* we abort the transfer before it is completed == we ruin the
  758:                  re-use ability. Close the connection */
  759:               connclose(conn, "Simulated 304 handling");
  760:               return CURLE_OK;
  761:             }
  762:           } /* we have a time condition */
  763: 
  764:         } /* this is HTTP or RTSP */
  765:       } /* this is the first time we write a body part */
  766: #endif /* CURL_DISABLE_HTTP */
  767: 
  768:       k->bodywrites++;
  769: 
  770:       /* pass data to the debug function before it gets "dechunked" */
  771:       if(data->set.verbose) {
  772:         if(k->badheader) {
  773:           Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
  774:                      (size_t)k->hbuflen);
  775:           if(k->badheader == HEADER_PARTHEADER)
  776:             Curl_debug(data, CURLINFO_DATA_IN,
  777:                        k->str, (size_t)nread);
  778:         }
  779:         else
  780:           Curl_debug(data, CURLINFO_DATA_IN,
  781:                      k->str, (size_t)nread);
  782:       }
  783: 
  784: #ifndef CURL_DISABLE_HTTP
  785:       if(k->chunk) {
  786:         /*
  787:          * Here comes a chunked transfer flying and we need to decode this
  788:          * properly.  While the name says read, this function both reads
  789:          * and writes away the data. The returned 'nread' holds the number
  790:          * of actual data it wrote to the client.
  791:          */
  792:         CURLcode extra;
  793:         CHUNKcode res =
  794:           Curl_httpchunk_read(conn, k->str, nread, &nread, &extra);
  795: 
  796:         if(CHUNKE_OK < res) {
  797:           if(CHUNKE_PASSTHRU_ERROR == res) {
  798:             failf(data, "Failed reading the chunked-encoded stream");
  799:             return extra;
  800:           }
  801:           failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
  802:           return CURLE_RECV_ERROR;
  803:         }
  804:         if(CHUNKE_STOP == res) {
  805:           size_t dataleft;
  806:           /* we're done reading chunks! */
  807:           k->keepon &= ~KEEP_RECV; /* read no more */
  808: 
  809:           /* There are now possibly N number of bytes at the end of the
  810:              str buffer that weren't written to the client.
  811:              Push it back to be read on the next pass. */
  812: 
  813:           dataleft = conn->chunk.dataleft;
  814:           if(dataleft != 0) {
  815:             infof(conn->data, "Leftovers after chunking: %zu bytes\n",
  816:                   dataleft);
  817:           }
  818:         }
  819:         /* If it returned OK, we just keep going */
  820:       }
  821: #endif   /* CURL_DISABLE_HTTP */
  822: 
  823:       /* Account for body content stored in the header buffer */
  824:       if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) {
  825:         DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
  826:                      k->hbuflen));
  827:         k->bytecount += k->hbuflen;
  828:       }
  829: 
  830:       if((-1 != k->maxdownload) &&
  831:          (k->bytecount + nread >= k->maxdownload)) {
  832: 
  833:         excess = (size_t)(k->bytecount + nread - k->maxdownload);
  834:         if(excess > 0 && !k->ignorebody) {
  835:           infof(data,
  836:                 "Excess found in a read:"
  837:                 " excess = %zu"
  838:                 ", size = %" CURL_FORMAT_CURL_OFF_T
  839:                 ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
  840:                 ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
  841:                 excess, k->size, k->maxdownload, k->bytecount);
  842:         }
  843: 
  844:         nread = (ssize_t) (k->maxdownload - k->bytecount);
  845:         if(nread < 0) /* this should be unusual */
  846:           nread = 0;
  847: 
  848:         k->keepon &= ~KEEP_RECV; /* we're done reading */
  849:       }
  850: 
  851:       k->bytecount += nread;
  852: 
  853:       Curl_pgrsSetDownloadCounter(data, k->bytecount);
  854: 
  855:       if(!k->chunk && (nread || k->badheader || is_empty_data)) {
  856:         /* If this is chunky transfer, it was already written */
  857: 
  858:         if(k->badheader && !k->ignorebody) {
  859:           /* we parsed a piece of data wrongly assuming it was a header
  860:              and now we output it as body instead */
  861: 
  862:           /* Don't let excess data pollute body writes */
  863:           if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
  864:             result = Curl_client_write(conn, CLIENTWRITE_BODY,
  865:                                        data->state.headerbuff,
  866:                                        k->hbuflen);
  867:           else
  868:             result = Curl_client_write(conn, CLIENTWRITE_BODY,
  869:                                        data->state.headerbuff,
  870:                                        (size_t)k->maxdownload);
  871: 
  872:           if(result)
  873:             return result;
  874:         }
  875:         if(k->badheader < HEADER_ALLBAD) {
  876:           /* This switch handles various content encodings. If there's an
  877:              error here, be sure to check over the almost identical code
  878:              in http_chunks.c.
  879:              Make sure that ALL_CONTENT_ENCODINGS contains all the
  880:              encodings handled here. */
  881:           if(conn->data->set.http_ce_skip || !k->writer_stack) {
  882:             if(!k->ignorebody) {
  883: #ifndef CURL_DISABLE_POP3
  884:               if(conn->handler->protocol & PROTO_FAMILY_POP3)
  885:                 result = Curl_pop3_write(conn, k->str, nread);
  886:               else
  887: #endif /* CURL_DISABLE_POP3 */
  888:                 result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
  889:                                            nread);
  890:             }
  891:           }
  892:           else if(!k->ignorebody)
  893:             result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
  894:         }
  895:         k->badheader = HEADER_NORMAL; /* taken care of now */
  896: 
  897:         if(result)
  898:           return result;
  899:       }
  900: 
  901:     } /* if(!header and data to read) */
  902: 
  903:     if(conn->handler->readwrite && excess) {
  904:       /* Parse the excess data */
  905:       k->str += nread;
  906: 
  907:       if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
  908:         /* the excess amount was too excessive(!), make sure
  909:            it doesn't read out of buffer */
  910:         excess = &k->buf[data->set.buffer_size] - k->str;
  911:       }
  912:       nread = (ssize_t)excess;
  913: 
  914:       result = conn->handler->readwrite(data, conn, &nread, &readmore);
  915:       if(result)
  916:         return result;
  917: 
  918:       if(readmore)
  919:         k->keepon |= KEEP_RECV; /* we're not done reading */
  920:       break;
  921:     }
  922: 
  923:     if(is_empty_data) {
  924:       /* if we received nothing, the server closed the connection and we
  925:          are done */
  926:       k->keepon &= ~KEEP_RECV;
  927:     }
  928: 
  929:     if(k->keepon & KEEP_RECV_PAUSE) {
  930:       /* this is a paused transfer */
  931:       break;
  932:     }
  933: 
  934:   } while(data_pending(data) && maxloops--);
  935: 
  936:   if(maxloops <= 0) {
  937:     /* we mark it as read-again-please */
  938:     conn->cselect_bits = CURL_CSELECT_IN;
  939:     *comeback = TRUE;
  940:   }
  941: 
  942:   if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
  943:      conn->bits.close) {
  944:     /* When we've read the entire thing and the close bit is set, the server
  945:        may now close the connection. If there's now any kind of sending going
  946:        on from our side, we need to stop that immediately. */
  947:     infof(data, "we are done reading and this is set to close, stop send\n");
  948:     k->keepon &= ~KEEP_SEND; /* no writing anymore either */
  949:   }
  950: 
  951:   return CURLE_OK;
  952: }
  953: 
  954: CURLcode Curl_done_sending(struct connectdata *conn,
  955:                            struct SingleRequest *k)
  956: {
  957:   k->keepon &= ~KEEP_SEND; /* we're done writing */
  958: 
  959:   /* These functions should be moved into the handler struct! */
  960:   Curl_http2_done_sending(conn);
  961:   Curl_quic_done_sending(conn);
  962: 
  963:   if(conn->bits.rewindaftersend) {
  964:     CURLcode result = Curl_readrewind(conn);
  965:     if(result)
  966:       return result;
  967:   }
  968:   return CURLE_OK;
  969: }
  970: 
  971: #if defined(WIN32) && !defined(USE_LWIPSOCK)
  972: #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
  973: #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
  974: #endif
  975: 
  976: static void win_update_buffer_size(curl_socket_t sockfd)
  977: {
  978:   int result;
  979:   ULONG ideal;
  980:   DWORD ideallen;
  981:   result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
  982:                     &ideal, sizeof(ideal), &ideallen, 0, 0);
  983:   if(result == 0) {
  984:     setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
  985:                (const char *)&ideal, sizeof(ideal));
  986:   }
  987: }
  988: #else
  989: #define win_update_buffer_size(x)
  990: #endif
  991: 
  992: /*
  993:  * Send data to upload to the server, when the socket is writable.
  994:  */
  995: static CURLcode readwrite_upload(struct Curl_easy *data,
  996:                                  struct connectdata *conn,
  997:                                  int *didwhat)
  998: {
  999:   ssize_t i, si;
 1000:   ssize_t bytes_written;
 1001:   CURLcode result;
 1002:   ssize_t nread; /* number of bytes read */
 1003:   bool sending_http_headers = FALSE;
 1004:   struct SingleRequest *k = &data->req;
 1005: 
 1006:   if((k->bytecount == 0) && (k->writebytecount == 0))
 1007:     Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 1008: 
 1009:   *didwhat |= KEEP_SEND;
 1010: 
 1011:   do {
 1012:     /* only read more data if there's no upload data already
 1013:        present in the upload buffer */
 1014:     if(0 == k->upload_present) {
 1015:       result = Curl_get_upload_buffer(data);
 1016:       if(result)
 1017:         return result;
 1018:       /* init the "upload from here" pointer */
 1019:       k->upload_fromhere = data->state.ulbuf;
 1020: 
 1021:       if(!k->upload_done) {
 1022:         /* HTTP pollution, this should be written nicer to become more
 1023:            protocol agnostic. */
 1024:         size_t fillcount;
 1025:         struct HTTP *http = k->protop;
 1026: 
 1027:         if((k->exp100 == EXP100_SENDING_REQUEST) &&
 1028:            (http->sending == HTTPSEND_BODY)) {
 1029:           /* If this call is to send body data, we must take some action:
 1030:              We have sent off the full HTTP 1.1 request, and we shall now
 1031:              go into the Expect: 100 state and await such a header */
 1032:           k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
 1033:           k->keepon &= ~KEEP_SEND;         /* disable writing */
 1034:           k->start100 = Curl_now();       /* timeout count starts now */
 1035:           *didwhat &= ~KEEP_SEND;  /* we didn't write anything actually */
 1036:           /* set a timeout for the multi interface */
 1037:           Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
 1038:           break;
 1039:         }
 1040: 
 1041:         if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
 1042:           if(http->sending == HTTPSEND_REQUEST)
 1043:             /* We're sending the HTTP request headers, not the data.
 1044:                Remember that so we don't change the line endings. */
 1045:             sending_http_headers = TRUE;
 1046:           else
 1047:             sending_http_headers = FALSE;
 1048:         }
 1049: 
 1050:         result = Curl_fillreadbuffer(conn, data->set.upload_buffer_size,
 1051:                                      &fillcount);
 1052:         if(result)
 1053:           return result;
 1054: 
 1055:         nread = fillcount;
 1056:       }
 1057:       else
 1058:         nread = 0; /* we're done uploading/reading */
 1059: 
 1060:       if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
 1061:         /* this is a paused transfer */
 1062:         break;
 1063:       }
 1064:       if(nread <= 0) {
 1065:         result = Curl_done_sending(conn, k);
 1066:         if(result)
 1067:           return result;
 1068:         break;
 1069:       }
 1070: 
 1071:       /* store number of bytes available for upload */
 1072:       k->upload_present = nread;
 1073: 
 1074:       /* convert LF to CRLF if so asked */
 1075:       if((!sending_http_headers) && (
 1076: #ifdef CURL_DO_LINEEND_CONV
 1077:          /* always convert if we're FTPing in ASCII mode */
 1078:          (data->set.prefer_ascii) ||
 1079: #endif
 1080:          (data->set.crlf))) {
 1081:         /* Do we need to allocate a scratch buffer? */
 1082:         if(!data->state.scratch) {
 1083:           data->state.scratch = malloc(2 * data->set.upload_buffer_size);
 1084:           if(!data->state.scratch) {
 1085:             failf(data, "Failed to alloc scratch buffer!");
 1086: 
 1087:             return CURLE_OUT_OF_MEMORY;
 1088:           }
 1089:         }
 1090: 
 1091:         /*
 1092:          * ASCII/EBCDIC Note: This is presumably a text (not binary)
 1093:          * transfer so the data should already be in ASCII.
 1094:          * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
 1095:          * must be used instead of the escape sequences \r & \n.
 1096:          */
 1097:         for(i = 0, si = 0; i < nread; i++, si++) {
 1098:           if(k->upload_fromhere[i] == 0x0a) {
 1099:             data->state.scratch[si++] = 0x0d;
 1100:             data->state.scratch[si] = 0x0a;
 1101:             if(!data->set.crlf) {
 1102:               /* we're here only because FTP is in ASCII mode...
 1103:                  bump infilesize for the LF we just added */
 1104:               if(data->state.infilesize != -1)
 1105:                 data->state.infilesize++;
 1106:             }
 1107:           }
 1108:           else
 1109:             data->state.scratch[si] = k->upload_fromhere[i];
 1110:         }
 1111: 
 1112:         if(si != nread) {
 1113:           /* only perform the special operation if we really did replace
 1114:              anything */
 1115:           nread = si;
 1116: 
 1117:           /* upload from the new (replaced) buffer instead */
 1118:           k->upload_fromhere = data->state.scratch;
 1119: 
 1120:           /* set the new amount too */
 1121:           k->upload_present = nread;
 1122:         }
 1123:       }
 1124: 
 1125: #ifndef CURL_DISABLE_SMTP
 1126:       if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
 1127:         result = Curl_smtp_escape_eob(conn, nread);
 1128:         if(result)
 1129:           return result;
 1130:       }
 1131: #endif /* CURL_DISABLE_SMTP */
 1132:     } /* if 0 == k->upload_present */
 1133:     else {
 1134:       /* We have a partial buffer left from a previous "round". Use
 1135:          that instead of reading more data */
 1136:     }
 1137: 
 1138:     /* write to socket (send away data) */
 1139:     result = Curl_write(conn,
 1140:                         conn->writesockfd,  /* socket to send to */
 1141:                         k->upload_fromhere, /* buffer pointer */
 1142:                         k->upload_present,  /* buffer size */
 1143:                         &bytes_written);    /* actually sent */
 1144:     if(result)
 1145:       return result;
 1146: 
 1147:     win_update_buffer_size(conn->writesockfd);
 1148: 
 1149:     if(data->set.verbose)
 1150:       /* show the data before we change the pointer upload_fromhere */
 1151:       Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
 1152:                  (size_t)bytes_written);
 1153: 
 1154:     k->writebytecount += bytes_written;
 1155:     Curl_pgrsSetUploadCounter(data, k->writebytecount);
 1156: 
 1157:     if((!k->upload_chunky || k->forbidchunk) &&
 1158:        (k->writebytecount == data->state.infilesize)) {
 1159:       /* we have sent all data we were supposed to */
 1160:       k->upload_done = TRUE;
 1161:       infof(data, "We are completely uploaded and fine\n");
 1162:     }
 1163: 
 1164:     if(k->upload_present != bytes_written) {
 1165:       /* we only wrote a part of the buffer (if anything), deal with it! */
 1166: 
 1167:       /* store the amount of bytes left in the buffer to write */
 1168:       k->upload_present -= bytes_written;
 1169: 
 1170:       /* advance the pointer where to find the buffer when the next send
 1171:          is to happen */
 1172:       k->upload_fromhere += bytes_written;
 1173:     }
 1174:     else {
 1175:       /* we've uploaded that buffer now */
 1176:       result = Curl_get_upload_buffer(data);
 1177:       if(result)
 1178:         return result;
 1179:       k->upload_fromhere = data->state.ulbuf;
 1180:       k->upload_present = 0; /* no more bytes left */
 1181: 
 1182:       if(k->upload_done) {
 1183:         result = Curl_done_sending(conn, k);
 1184:         if(result)
 1185:           return result;
 1186:       }
 1187:     }
 1188: 
 1189: 
 1190:   } while(0); /* just to break out from! */
 1191: 
 1192:   return CURLE_OK;
 1193: }
 1194: 
 1195: /*
 1196:  * Curl_readwrite() is the low-level function to be called when data is to
 1197:  * be read and written to/from the connection.
 1198:  *
 1199:  * return '*comeback' TRUE if we didn't properly drain the socket so this
 1200:  * function should get called again without select() or similar in between!
 1201:  */
 1202: CURLcode Curl_readwrite(struct connectdata *conn,
 1203:                         struct Curl_easy *data,
 1204:                         bool *done,
 1205:                         bool *comeback)
 1206: {
 1207:   struct SingleRequest *k = &data->req;
 1208:   CURLcode result;
 1209:   int didwhat = 0;
 1210: 
 1211:   curl_socket_t fd_read;
 1212:   curl_socket_t fd_write;
 1213:   int select_res = conn->cselect_bits;
 1214: 
 1215:   conn->cselect_bits = 0;
 1216: 
 1217:   /* only use the proper socket if the *_HOLD bit is not set simultaneously as
 1218:      then we are in rate limiting state in that transfer direction */
 1219: 
 1220:   if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
 1221:     fd_read = conn->sockfd;
 1222:   else
 1223:     fd_read = CURL_SOCKET_BAD;
 1224: 
 1225:   if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
 1226:     fd_write = conn->writesockfd;
 1227:   else
 1228:     fd_write = CURL_SOCKET_BAD;
 1229: 
 1230:   if(conn->data->state.drain) {
 1231:     select_res |= CURL_CSELECT_IN;
 1232:     DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
 1233:   }
 1234: 
 1235:   if(!select_res) /* Call for select()/poll() only, if read/write/error
 1236:                      status is not known. */
 1237:     select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0);
 1238: 
 1239:   if(select_res == CURL_CSELECT_ERR) {
 1240:     failf(data, "select/poll returned error");
 1241:     return CURLE_SEND_ERROR;
 1242:   }
 1243: 
 1244:   /* We go ahead and do a read if we have a readable socket or if
 1245:      the stream was rewound (in which case we have data in a
 1246:      buffer) */
 1247:   if((k->keepon & KEEP_RECV) && (select_res & CURL_CSELECT_IN)) {
 1248:     result = readwrite_data(data, conn, k, &didwhat, done, comeback);
 1249:     if(result || *done)
 1250:       return result;
 1251:   }
 1252: 
 1253:   /* If we still have writing to do, we check if we have a writable socket. */
 1254:   if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
 1255:     /* write */
 1256: 
 1257:     result = readwrite_upload(data, conn, &didwhat);
 1258:     if(result)
 1259:       return result;
 1260:   }
 1261: 
 1262:   k->now = Curl_now();
 1263:   if(didwhat) {
 1264:     ;
 1265:   }
 1266:   else {
 1267:     /* no read no write, this is a timeout? */
 1268:     if(k->exp100 == EXP100_AWAITING_CONTINUE) {
 1269:       /* This should allow some time for the header to arrive, but only a
 1270:          very short time as otherwise it'll be too much wasted time too
 1271:          often. */
 1272: 
 1273:       /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
 1274: 
 1275:          Therefore, when a client sends this header field to an origin server
 1276:          (possibly via a proxy) from which it has never seen a 100 (Continue)
 1277:          status, the client SHOULD NOT wait for an indefinite period before
 1278:          sending the request body.
 1279: 
 1280:       */
 1281: 
 1282:       timediff_t ms = Curl_timediff(k->now, k->start100);
 1283:       if(ms >= data->set.expect_100_timeout) {
 1284:         /* we've waited long enough, continue anyway */
 1285:         k->exp100 = EXP100_SEND_DATA;
 1286:         k->keepon |= KEEP_SEND;
 1287:         Curl_expire_done(data, EXPIRE_100_TIMEOUT);
 1288:         infof(data, "Done waiting for 100-continue\n");
 1289:       }
 1290:     }
 1291:   }
 1292: 
 1293:   if(Curl_pgrsUpdate(conn))
 1294:     result = CURLE_ABORTED_BY_CALLBACK;
 1295:   else
 1296:     result = Curl_speedcheck(data, k->now);
 1297:   if(result)
 1298:     return result;
 1299: 
 1300:   if(k->keepon) {
 1301:     if(0 > Curl_timeleft(data, &k->now, FALSE)) {
 1302:       if(k->size != -1) {
 1303:         failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
 1304:               " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
 1305:               CURL_FORMAT_CURL_OFF_T " bytes received",
 1306:               Curl_timediff(k->now, data->progress.t_startsingle),
 1307:               k->bytecount, k->size);
 1308:       }
 1309:       else {
 1310:         failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
 1311:               " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received",
 1312:               Curl_timediff(k->now, data->progress.t_startsingle),
 1313:               k->bytecount);
 1314:       }
 1315:       return CURLE_OPERATION_TIMEDOUT;
 1316:     }
 1317:   }
 1318:   else {
 1319:     /*
 1320:      * The transfer has been performed. Just make some general checks before
 1321:      * returning.
 1322:      */
 1323: 
 1324:     if(!(data->set.opt_no_body) && (k->size != -1) &&
 1325:        (k->bytecount != k->size) &&
 1326: #ifdef CURL_DO_LINEEND_CONV
 1327:        /* Most FTP servers don't adjust their file SIZE response for CRLFs,
 1328:           so we'll check to see if the discrepancy can be explained
 1329:           by the number of CRLFs we've changed to LFs.
 1330:        */
 1331:        (k->bytecount != (k->size + data->state.crlf_conversions)) &&
 1332: #endif /* CURL_DO_LINEEND_CONV */
 1333:        !k->newurl) {
 1334:       failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
 1335:             " bytes remaining to read", k->size - k->bytecount);
 1336:       return CURLE_PARTIAL_FILE;
 1337:     }
 1338:     if(!(data->set.opt_no_body) && k->chunk &&
 1339:        (conn->chunk.state != CHUNK_STOP)) {
 1340:       /*
 1341:        * In chunked mode, return an error if the connection is closed prior to
 1342:        * the empty (terminating) chunk is read.
 1343:        *
 1344:        * The condition above used to check for
 1345:        * conn->proto.http->chunk.datasize != 0 which is true after reading
 1346:        * *any* chunk, not just the empty chunk.
 1347:        *
 1348:        */
 1349:       failf(data, "transfer closed with outstanding read data remaining");
 1350:       return CURLE_PARTIAL_FILE;
 1351:     }
 1352:     if(Curl_pgrsUpdate(conn))
 1353:       return CURLE_ABORTED_BY_CALLBACK;
 1354:   }
 1355: 
 1356:   /* Now update the "done" boolean we return */
 1357:   *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
 1358:                             KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
 1359: 
 1360:   return CURLE_OK;
 1361: }
 1362: 
 1363: /*
 1364:  * Curl_single_getsock() gets called by the multi interface code when the app
 1365:  * has requested to get the sockets for the current connection. This function
 1366:  * will then be called once for every connection that the multi interface
 1367:  * keeps track of. This function will only be called for connections that are
 1368:  * in the proper state to have this information available.
 1369:  */
 1370: int Curl_single_getsock(const struct connectdata *conn,
 1371:                         curl_socket_t *sock)
 1372: {
 1373:   const struct Curl_easy *data = conn->data;
 1374:   int bitmap = GETSOCK_BLANK;
 1375:   unsigned sockindex = 0;
 1376: 
 1377:   if(conn->handler->perform_getsock)
 1378:     return conn->handler->perform_getsock(conn, sock);
 1379: 
 1380:   /* don't include HOLD and PAUSE connections */
 1381:   if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
 1382: 
 1383:     DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
 1384: 
 1385:     bitmap |= GETSOCK_READSOCK(sockindex);
 1386:     sock[sockindex] = conn->sockfd;
 1387:   }
 1388: 
 1389:   /* don't include HOLD and PAUSE connections */
 1390:   if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
 1391: 
 1392:     if((conn->sockfd != conn->writesockfd) ||
 1393:        bitmap == GETSOCK_BLANK) {
 1394:       /* only if they are not the same socket and we have a readable
 1395:          one, we increase index */
 1396:       if(bitmap != GETSOCK_BLANK)
 1397:         sockindex++; /* increase index if we need two entries */
 1398: 
 1399:       DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
 1400: 
 1401:       sock[sockindex] = conn->writesockfd;
 1402:     }
 1403: 
 1404:     bitmap |= GETSOCK_WRITESOCK(sockindex);
 1405:   }
 1406: 
 1407:   return bitmap;
 1408: }
 1409: 
 1410: /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
 1411:    which means this gets called once for each subsequent redirect etc */
 1412: void Curl_init_CONNECT(struct Curl_easy *data)
 1413: {
 1414:   data->state.fread_func = data->set.fread_func_set;
 1415:   data->state.in = data->set.in_set;
 1416: }
 1417: 
 1418: /*
 1419:  * Curl_pretransfer() is called immediately before a transfer starts, and only
 1420:  * once for one transfer no matter if it has redirects or do multi-pass
 1421:  * authentication etc.
 1422:  */
 1423: CURLcode Curl_pretransfer(struct Curl_easy *data)
 1424: {
 1425:   CURLcode result;
 1426: 
 1427:   if(!data->change.url && !data->set.uh) {
 1428:     /* we can't do anything without URL */
 1429:     failf(data, "No URL set!");
 1430:     return CURLE_URL_MALFORMAT;
 1431:   }
 1432: 
 1433:   /* since the URL may have been redirected in a previous use of this handle */
 1434:   if(data->change.url_alloc) {
 1435:     /* the already set URL is allocated, free it first! */
 1436:     Curl_safefree(data->change.url);
 1437:     data->change.url_alloc = FALSE;
 1438:   }
 1439: 
 1440:   if(!data->change.url && data->set.uh) {
 1441:     CURLUcode uc;
 1442:     uc = curl_url_get(data->set.uh,
 1443:                         CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
 1444:     if(uc) {
 1445:       failf(data, "No URL set!");
 1446:       return CURLE_URL_MALFORMAT;
 1447:     }
 1448:   }
 1449: 
 1450:   data->change.url = data->set.str[STRING_SET_URL];
 1451: 
 1452:   /* Init the SSL session ID cache here. We do it here since we want to do it
 1453:      after the *_setopt() calls (that could specify the size of the cache) but
 1454:      before any transfer takes place. */
 1455:   result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions);
 1456:   if(result)
 1457:     return result;
 1458: 
 1459:   data->state.wildcardmatch = data->set.wildcard_enabled;
 1460:   data->set.followlocation = 0; /* reset the location-follow counter */
 1461:   data->state.this_is_a_follow = FALSE; /* reset this */
 1462:   data->state.errorbuf = FALSE; /* no error has occurred */
 1463:   data->state.httpversion = 0; /* don't assume any particular server version */
 1464: 
 1465:   data->state.authproblem = FALSE;
 1466:   data->state.authhost.want = data->set.httpauth;
 1467:   data->state.authproxy.want = data->set.proxyauth;
 1468:   Curl_safefree(data->info.wouldredirect);
 1469:   data->info.wouldredirect = NULL;
 1470: 
 1471:   if(data->set.httpreq == HTTPREQ_PUT)
 1472:     data->state.infilesize = data->set.filesize;
 1473:   else if((data->set.httpreq != HTTPREQ_GET) &&
 1474:           (data->set.httpreq != HTTPREQ_HEAD)) {
 1475:     data->state.infilesize = data->set.postfieldsize;
 1476:     if(data->set.postfields && (data->state.infilesize == -1))
 1477:       data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
 1478:   }
 1479:   else
 1480:     data->state.infilesize = 0;
 1481: 
 1482:   /* If there is a list of cookie files to read, do it now! */
 1483:   if(data->change.cookielist)
 1484:     Curl_cookie_loadfiles(data);
 1485: 
 1486:   /* If there is a list of host pairs to deal with */
 1487:   if(data->change.resolve)
 1488:     result = Curl_loadhostpairs(data);
 1489: 
 1490:   if(!result) {
 1491:     /* Allow data->set.use_port to set which port to use. This needs to be
 1492:      * disabled for example when we follow Location: headers to URLs using
 1493:      * different ports! */
 1494:     data->state.allow_port = TRUE;
 1495: 
 1496: #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
 1497:     /*************************************************************
 1498:      * Tell signal handler to ignore SIGPIPE
 1499:      *************************************************************/
 1500:     if(!data->set.no_signal)
 1501:       data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
 1502: #endif
 1503: 
 1504:     Curl_initinfo(data); /* reset session-specific information "variables" */
 1505:     Curl_pgrsResetTransferSizes(data);
 1506:     Curl_pgrsStartNow(data);
 1507: 
 1508:     /* In case the handle is re-used and an authentication method was picked
 1509:        in the session we need to make sure we only use the one(s) we now
 1510:        consider to be fine */
 1511:     data->state.authhost.picked &= data->state.authhost.want;
 1512:     data->state.authproxy.picked &= data->state.authproxy.want;
 1513: 
 1514: #ifndef CURL_DISABLE_FTP
 1515:     if(data->state.wildcardmatch) {
 1516:       struct WildcardData *wc = &data->wildcard;
 1517:       if(wc->state < CURLWC_INIT) {
 1518:         result = Curl_wildcard_init(wc); /* init wildcard structures */
 1519:         if(result)
 1520:           return CURLE_OUT_OF_MEMORY;
 1521:       }
 1522:     }
 1523: #endif
 1524:     Curl_http2_init_state(&data->state);
 1525:   }
 1526: 
 1527:   return result;
 1528: }
 1529: 
 1530: /*
 1531:  * Curl_posttransfer() is called immediately after a transfer ends
 1532:  */
 1533: CURLcode Curl_posttransfer(struct Curl_easy *data)
 1534: {
 1535: #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
 1536:   /* restore the signal handler for SIGPIPE before we get back */
 1537:   if(!data->set.no_signal)
 1538:     signal(SIGPIPE, data->state.prev_signal);
 1539: #else
 1540:   (void)data; /* unused parameter */
 1541: #endif
 1542: 
 1543:   return CURLE_OK;
 1544: }
 1545: 
 1546: /*
 1547:  * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
 1548:  * as given by the remote server and set up the new URL to request.
 1549:  *
 1550:  * This function DOES NOT FREE the given url.
 1551:  */
 1552: CURLcode Curl_follow(struct Curl_easy *data,
 1553:                      char *newurl,    /* the Location: string */
 1554:                      followtype type) /* see transfer.h */
 1555: {
 1556: #ifdef CURL_DISABLE_HTTP
 1557:   (void)data;
 1558:   (void)newurl;
 1559:   (void)type;
 1560:   /* Location: following will not happen when HTTP is disabled */
 1561:   return CURLE_TOO_MANY_REDIRECTS;
 1562: #else
 1563: 
 1564:   /* Location: redirect */
 1565:   bool disallowport = FALSE;
 1566:   bool reachedmax = FALSE;
 1567:   CURLUcode uc;
 1568: 
 1569:   if(type == FOLLOW_REDIR) {
 1570:     if((data->set.maxredirs != -1) &&
 1571:        (data->set.followlocation >= data->set.maxredirs)) {
 1572:       reachedmax = TRUE;
 1573:       type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
 1574:                              to URL */
 1575:     }
 1576:     else {
 1577:       /* mark the next request as a followed location: */
 1578:       data->state.this_is_a_follow = TRUE;
 1579: 
 1580:       data->set.followlocation++; /* count location-followers */
 1581: 
 1582:       if(data->set.http_auto_referer) {
 1583:         /* We are asked to automatically set the previous URL as the referer
 1584:            when we get the next URL. We pick the ->url field, which may or may
 1585:            not be 100% correct */
 1586: 
 1587:         if(data->change.referer_alloc) {
 1588:           Curl_safefree(data->change.referer);
 1589:           data->change.referer_alloc = FALSE;
 1590:         }
 1591: 
 1592:         data->change.referer = strdup(data->change.url);
 1593:         if(!data->change.referer)
 1594:           return CURLE_OUT_OF_MEMORY;
 1595:         data->change.referer_alloc = TRUE; /* yes, free this later */
 1596:       }
 1597:     }
 1598:   }
 1599: 
 1600:   if(Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN))
 1601:     /* This is an absolute URL, don't allow the custom port number */
 1602:     disallowport = TRUE;
 1603: 
 1604:   DEBUGASSERT(data->state.uh);
 1605:   uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
 1606:                     (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
 1607:                     ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) );
 1608:   if(uc) {
 1609:     if(type != FOLLOW_FAKE)
 1610:       return Curl_uc_to_curlcode(uc);
 1611: 
 1612:     /* the URL could not be parsed for some reason, but since this is FAKE
 1613:        mode, just duplicate the field as-is */
 1614:     newurl = strdup(newurl);
 1615:     if(!newurl)
 1616:       return CURLE_OUT_OF_MEMORY;
 1617:   }
 1618:   else {
 1619: 
 1620:     uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
 1621:     if(uc)
 1622:       return Curl_uc_to_curlcode(uc);
 1623:   }
 1624: 
 1625:   if(type == FOLLOW_FAKE) {
 1626:     /* we're only figuring out the new url if we would've followed locations
 1627:        but now we're done so we can get out! */
 1628:     data->info.wouldredirect = newurl;
 1629: 
 1630:     if(reachedmax) {
 1631:       failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
 1632:       return CURLE_TOO_MANY_REDIRECTS;
 1633:     }
 1634:     return CURLE_OK;
 1635:   }
 1636: 
 1637:   if(disallowport)
 1638:     data->state.allow_port = FALSE;
 1639: 
 1640:   if(data->change.url_alloc)
 1641:     Curl_safefree(data->change.url);
 1642: 
 1643:   data->change.url = newurl;
 1644:   data->change.url_alloc = TRUE;
 1645: 
 1646:   infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
 1647: 
 1648:   /*
 1649:    * We get here when the HTTP code is 300-399 (and 401). We need to perform
 1650:    * differently based on exactly what return code there was.
 1651:    *
 1652:    * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
 1653:    * a HTTP (proxy-) authentication scheme other than Basic.
 1654:    */
 1655:   switch(data->info.httpcode) {
 1656:     /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
 1657:        Authorization: XXXX header in the HTTP request code snippet */
 1658:     /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
 1659:        Proxy-Authorization: XXXX header in the HTTP request code snippet */
 1660:     /* 300 - Multiple Choices */
 1661:     /* 306 - Not used */
 1662:     /* 307 - Temporary Redirect */
 1663:   default:  /* for all above (and the unknown ones) */
 1664:     /* Some codes are explicitly mentioned since I've checked RFC2616 and they
 1665:      * seem to be OK to POST to.
 1666:      */
 1667:     break;
 1668:   case 301: /* Moved Permanently */
 1669:     /* (quote from RFC7231, section 6.4.2)
 1670:      *
 1671:      * Note: For historical reasons, a user agent MAY change the request
 1672:      * method from POST to GET for the subsequent request.  If this
 1673:      * behavior is undesired, the 307 (Temporary Redirect) status code
 1674:      * can be used instead.
 1675:      *
 1676:      * ----
 1677:      *
 1678:      * Many webservers expect this, so these servers often answers to a POST
 1679:      * request with an error page. To be sure that libcurl gets the page that
 1680:      * most user agents would get, libcurl has to force GET.
 1681:      *
 1682:      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
 1683:      * can be overridden with CURLOPT_POSTREDIR.
 1684:      */
 1685:     if((data->set.httpreq == HTTPREQ_POST
 1686:         || data->set.httpreq == HTTPREQ_POST_FORM
 1687:         || data->set.httpreq == HTTPREQ_POST_MIME)
 1688:        && !(data->set.keep_post & CURL_REDIR_POST_301)) {
 1689:       infof(data, "Switch from POST to GET\n");
 1690:       data->set.httpreq = HTTPREQ_GET;
 1691:     }
 1692:     break;
 1693:   case 302: /* Found */
 1694:     /* (quote from RFC7231, section 6.4.3)
 1695:      *
 1696:      * Note: For historical reasons, a user agent MAY change the request
 1697:      * method from POST to GET for the subsequent request.  If this
 1698:      * behavior is undesired, the 307 (Temporary Redirect) status code
 1699:      * can be used instead.
 1700:      *
 1701:      * ----
 1702:      *
 1703:      * Many webservers expect this, so these servers often answers to a POST
 1704:      * request with an error page. To be sure that libcurl gets the page that
 1705:      * most user agents would get, libcurl has to force GET.
 1706:      *
 1707:      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
 1708:      * can be overridden with CURLOPT_POSTREDIR.
 1709:      */
 1710:     if((data->set.httpreq == HTTPREQ_POST
 1711:         || data->set.httpreq == HTTPREQ_POST_FORM
 1712:         || data->set.httpreq == HTTPREQ_POST_MIME)
 1713:        && !(data->set.keep_post & CURL_REDIR_POST_302)) {
 1714:       infof(data, "Switch from POST to GET\n");
 1715:       data->set.httpreq = HTTPREQ_GET;
 1716:     }
 1717:     break;
 1718: 
 1719:   case 303: /* See Other */
 1720:     /* 'See Other' location is not the resource but a substitute for the
 1721:      * resource. In this case we switch the method to GET/HEAD, unless the
 1722:      * method is POST and the user specified to keep it as POST.
 1723:      * https://github.com/curl/curl/issues/5237#issuecomment-614641049
 1724:      */
 1725:     if(data->set.httpreq != HTTPREQ_GET &&
 1726:        ((data->set.httpreq != HTTPREQ_POST &&
 1727:          data->set.httpreq != HTTPREQ_POST_FORM &&
 1728:          data->set.httpreq != HTTPREQ_POST_MIME) ||
 1729:         !(data->set.keep_post & CURL_REDIR_POST_303))) {
 1730:       data->set.httpreq = HTTPREQ_GET;
 1731:       data->set.upload = false;
 1732:       infof(data, "Switch to %s\n",
 1733:             data->set.opt_no_body?"HEAD":"GET");
 1734:     }
 1735:     break;
 1736:   case 304: /* Not Modified */
 1737:     /* 304 means we did a conditional request and it was "Not modified".
 1738:      * We shouldn't get any Location: header in this response!
 1739:      */
 1740:     break;
 1741:   case 305: /* Use Proxy */
 1742:     /* (quote from RFC2616, section 10.3.6):
 1743:      * "The requested resource MUST be accessed through the proxy given
 1744:      * by the Location field. The Location field gives the URI of the
 1745:      * proxy.  The recipient is expected to repeat this single request
 1746:      * via the proxy. 305 responses MUST only be generated by origin
 1747:      * servers."
 1748:      */
 1749:     break;
 1750:   }
 1751:   Curl_pgrsTime(data, TIMER_REDIRECT);
 1752:   Curl_pgrsResetTransferSizes(data);
 1753: 
 1754:   return CURLE_OK;
 1755: #endif /* CURL_DISABLE_HTTP */
 1756: }
 1757: 
 1758: /* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
 1759: 
 1760:    NOTE: that the *url is malloc()ed. */
 1761: CURLcode Curl_retry_request(struct connectdata *conn,
 1762:                             char **url)
 1763: {
 1764:   struct Curl_easy *data = conn->data;
 1765:   bool retry = FALSE;
 1766:   *url = NULL;
 1767: 
 1768:   /* if we're talking upload, we can't do the checks below, unless the protocol
 1769:      is HTTP as when uploading over HTTP we will still get a response */
 1770:   if(data->set.upload &&
 1771:      !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
 1772:     return CURLE_OK;
 1773: 
 1774:   if((data->req.bytecount + data->req.headerbytecount == 0) &&
 1775:       conn->bits.reuse &&
 1776:       (!data->set.opt_no_body
 1777:         || (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
 1778:       (data->set.rtspreq != RTSPREQ_RECEIVE))
 1779:     /* We got no data, we attempted to re-use a connection. For HTTP this
 1780:        can be a retry so we try again regardless if we expected a body.
 1781:        For other protocols we only try again only if we expected a body.
 1782: 
 1783:        This might happen if the connection was left alive when we were
 1784:        done using it before, but that was closed when we wanted to read from
 1785:        it again. Bad luck. Retry the same request on a fresh connect! */
 1786:     retry = TRUE;
 1787:   else if(data->state.refused_stream &&
 1788:           (data->req.bytecount + data->req.headerbytecount == 0) ) {
 1789:     /* This was sent on a refused stream, safe to rerun. A refused stream
 1790:        error can typically only happen on HTTP/2 level if the stream is safe
 1791:        to issue again, but the nghttp2 API can deliver the message to other
 1792:        streams as well, which is why this adds the check the data counters
 1793:        too. */
 1794:     infof(conn->data, "REFUSED_STREAM, retrying a fresh connect\n");
 1795:     data->state.refused_stream = FALSE; /* clear again */
 1796:     retry = TRUE;
 1797:   }
 1798:   if(retry) {
 1799: #define CONN_MAX_RETRIES 5
 1800:     if(conn->retrycount++ >= CONN_MAX_RETRIES) {
 1801:       failf(data, "Connection died, tried %d times before giving up",
 1802:             CONN_MAX_RETRIES);
 1803:       return CURLE_SEND_ERROR;
 1804:     }
 1805:     infof(conn->data, "Connection died, retrying a fresh connect\n");
 1806:     *url = strdup(conn->data->change.url);
 1807:     if(!*url)
 1808:       return CURLE_OUT_OF_MEMORY;
 1809: 
 1810:     connclose(conn, "retry"); /* close this connection */
 1811:     conn->bits.retry = TRUE; /* mark this as a connection we're about
 1812:                                 to retry. Marking it this way should
 1813:                                 prevent i.e HTTP transfers to return
 1814:                                 error just because nothing has been
 1815:                                 transferred! */
 1816: 
 1817: 
 1818:     if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
 1819:       if(data->req.writebytecount) {
 1820:         CURLcode result = Curl_readrewind(conn);
 1821:         if(result) {
 1822:           Curl_safefree(*url);
 1823:           return result;
 1824:         }
 1825:       }
 1826:     }
 1827:   }
 1828:   return CURLE_OK;
 1829: }
 1830: 
 1831: /*
 1832:  * Curl_setup_transfer() is called to setup some basic properties for the
 1833:  * upcoming transfer.
 1834:  */
 1835: void
 1836: Curl_setup_transfer(
 1837:   struct Curl_easy *data,   /* transfer */
 1838:   int sockindex,            /* socket index to read from or -1 */
 1839:   curl_off_t size,          /* -1 if unknown at this point */
 1840:   bool getheader,           /* TRUE if header parsing is wanted */
 1841:   int writesockindex        /* socket index to write to, it may very well be
 1842:                                the same we read from. -1 disables */
 1843:   )
 1844: {
 1845:   struct SingleRequest *k = &data->req;
 1846:   struct connectdata *conn = data->conn;
 1847:   struct HTTP *http = data->req.protop;
 1848:   bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
 1849:                       (http->sending == HTTPSEND_REQUEST));
 1850:   DEBUGASSERT(conn != NULL);
 1851:   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
 1852: 
 1853:   if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) {
 1854:     /* when multiplexing, the read/write sockets need to be the same! */
 1855:     conn->sockfd = sockindex == -1 ?
 1856:       ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) :
 1857:       conn->sock[sockindex];
 1858:     conn->writesockfd = conn->sockfd;
 1859:     if(httpsending)
 1860:       /* special and very HTTP-specific */
 1861:       writesockindex = FIRSTSOCKET;
 1862:   }
 1863:   else {
 1864:     conn->sockfd = sockindex == -1 ?
 1865:       CURL_SOCKET_BAD : conn->sock[sockindex];
 1866:     conn->writesockfd = writesockindex == -1 ?
 1867:       CURL_SOCKET_BAD:conn->sock[writesockindex];
 1868:   }
 1869:   k->getheader = getheader;
 1870: 
 1871:   k->size = size;
 1872: 
 1873:   /* The code sequence below is placed in this function just because all
 1874:      necessary input is not always known in do_complete() as this function may
 1875:      be called after that */
 1876: 
 1877:   if(!k->getheader) {
 1878:     k->header = FALSE;
 1879:     if(size > 0)
 1880:       Curl_pgrsSetDownloadSize(data, size);
 1881:   }
 1882:   /* we want header and/or body, if neither then don't do this! */
 1883:   if(k->getheader || !data->set.opt_no_body) {
 1884: 
 1885:     if(sockindex != -1)
 1886:       k->keepon |= KEEP_RECV;
 1887: 
 1888:     if(writesockindex != -1) {
 1889:       /* HTTP 1.1 magic:
 1890: 
 1891:          Even if we require a 100-return code before uploading data, we might
 1892:          need to write data before that since the REQUEST may not have been
 1893:          finished sent off just yet.
 1894: 
 1895:          Thus, we must check if the request has been sent before we set the
 1896:          state info where we wait for the 100-return code
 1897:       */
 1898:       if((data->state.expect100header) &&
 1899:          (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
 1900:          (http->sending == HTTPSEND_BODY)) {
 1901:         /* wait with write until we either got 100-continue or a timeout */
 1902:         k->exp100 = EXP100_AWAITING_CONTINUE;
 1903:         k->start100 = Curl_now();
 1904: 
 1905:         /* Set a timeout for the multi interface. Add the inaccuracy margin so
 1906:            that we don't fire slightly too early and get denied to run. */
 1907:         Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
 1908:       }
 1909:       else {
 1910:         if(data->state.expect100header)
 1911:           /* when we've sent off the rest of the headers, we must await a
 1912:              100-continue but first finish sending the request */
 1913:           k->exp100 = EXP100_SENDING_REQUEST;
 1914: 
 1915:         /* enable the write bit when we're not waiting for continue */
 1916:         k->keepon |= KEEP_SEND;
 1917:       }
 1918:     } /* if(writesockindex != -1) */
 1919:   } /* if(k->getheader || !data->set.opt_no_body) */
 1920: 
 1921: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>