Skip to content
http.c 37 KiB
Newer Older
    Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
    switch(data->set.httpreq) {

    case HTTPREQ_POST_FORM:
      if(Curl_FormInit(&http->form, http->sendit)) {
        failf(data, "Internal HTTP POST error!");
        return CURLE_HTTP_POST_ERROR;
      /* set the read function to read from the generated form data */
      conn->fread = (curl_read_callback)Curl_FormReader;
      conn->fread_in = &http->form;
Daniel Stenberg's avatar
Daniel Stenberg committed

      if(!conn->bits.upload_chunky)
        /* only add Content-Length if not uploading chunked */
        add_bufferf(req_buffer,
                    "Content-Length: %d\r\n", http->postsize);
      if(!checkheaders(data, "Expect:")) {
        /* if not disabled explicitly we add a Expect: 100-continue
           to the headers which actually speeds up post operations (as
           there is one packet coming back from the web server) */
        add_bufferf(req_buffer,
                    "Expect: 100-continue\r\n");
      if(!checkheaders(data, "Content-Type:")) {
        /* Get Content-Type: line from Curl_FormReadOneLine, which happens
           to always be the first line. We can know this for sure since
           we always build the formpost linked list the same way!

           The Content-Type header line also contains the MIME boundary
           string etc why disabling this header is likely to not make things
           work, but we support it anyway.
        */
        char contentType[256];
        int linelength=0;
        linelength = Curl_FormReadOneLine (contentType,
                                           sizeof(contentType),
                                           1,
                                           (FILE *)&http->form);
        if(linelength == -1) {
          failf(data, "Could not get Content-Type header line!");
          return CURLE_HTTP_POST_ERROR;
        }
        add_buffer(req_buffer, contentType, linelength);
      }

      /* make the request end in a true CRLF */
      add_buffer(req_buffer, "\r\n", 2);

      /* set upload size to the progress meter */
      Curl_pgrsSetUploadSize(data, http->postsize);
Daniel Stenberg's avatar
Daniel Stenberg committed

      /* fire away the whole request to the server */
      result = add_buffer_send(req_buffer, conn->firstsocket, conn, 
                               &data->info.request_size);
      if(result)
        failf(data, "Failed sending POST request");
      else
        /* setup variables for the upcoming transfer */
        result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
                               &http->readbytecount,
                               conn->firstsocket,
                               &http->writebytecount);
        Curl_formclean(http->sendit); /* free that whole lot */
Daniel Stenberg's avatar
Daniel Stenberg committed
      }
      break;

    case HTTPREQ_PUT: /* Let's PUT the data to the server! */
Daniel Stenberg's avatar
Daniel Stenberg committed

      if((data->set.infilesize>0) && !conn->bits.upload_chunky)
        /* only add Content-Length if not uploading chunked */
                    "Content-Length: %d\r\n", /* file size */
      /* set the upload size to the progress meter */
      Curl_pgrsSetUploadSize(data, data->set.infilesize);
Daniel Stenberg's avatar
Daniel Stenberg committed

      /* this sends the buffer and frees all the buffer resources */
      result = add_buffer_send(req_buffer, conn->firstsocket, conn,
        failf(data, "Failed sending POST request");
      else
        /* prepare for transfer */
        result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
                               &http->readbytecount,
                               conn->firstsocket,
                               &http->writebytecount);
Daniel Stenberg's avatar
Daniel Stenberg committed
      if(result)
        return result;
    case HTTPREQ_POST:
      /* this is the simple POST, using x-www-form-urlencoded style */
      if(!conn->bits.upload_chunky) {
        /* We only set Content-Length and allow a custom Content-Length if
           we don't upload data chunked, as RFC2616 forbids us to set both
           kinds of headers (Transfer-Encoding: chunked and Content-Length) */

        if(!checkheaders(data, "Content-Length:"))
          /* we allow replacing this header, although it isn't very wise to
             actually set your own */
          add_bufferf(req_buffer,
                      "Content-Length: %d\r\n",
                      data->set.postfieldsize?
                      data->set.postfieldsize:
                      (data->set.postfields?strlen(data->set.postfields):0) );
      }
      if(!checkheaders(data, "Content-Type:"))
        add_bufferf(req_buffer,
                    "Content-Type: application/x-www-form-urlencoded\r\n");

      add_buffer(req_buffer, "\r\n", 2);

      /* and here we setup the pointers to the actual data */
      if(data->set.postfields) {
        if(data->set.postfieldsize)
          http->postsize = data->set.postfieldsize;
        else
          http->postsize = strlen(data->set.postfields);
        http->postdata = data->set.postfields;

        http->sending = HTTPSEND_BODY;

        conn->fread = (curl_read_callback)readmoredata;
        conn->fread_in = (void *)conn;

        /* set the upload size to the progress meter */
        Curl_pgrsSetUploadSize(data, http->postsize);
      else
        /* set the upload size to the progress meter */
        Curl_pgrsSetUploadSize(data, data->set.infilesize);
      /* issue the request, headers-only */
      result = add_buffer_send(req_buffer, conn->firstsocket, conn,
                               &data->info.request_size);

      if(result)
        failf(data, "Failed sending HTTP POST request");
          Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
                        &http->readbytecount,
                        conn->firstsocket,
                        &http->writebytecount);
      /* issue the request */
      result = add_buffer_send(req_buffer, conn->firstsocket, conn,
      if(result)
        failf(data, "Failed sending HTTP request");
      else
        /* HTTP GET/HEAD download: */
        result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
                               &http->readbytecount,
                               http->postdata?conn->firstsocket:-1,
                               http->postdata?&http->writebytecount:NULL);
Daniel Stenberg's avatar
Daniel Stenberg committed
    if(result)
      return result;
  } while (0); /* this is just a left-over from the multiple document download
                  attempts */

  return CURLE_OK;
Daniel Stenberg's avatar
Daniel Stenberg committed
}