Commit 3d4c0c8b authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

http2: return EOF when done uploading without known size

Fixes #982
parent 03bb4815
Loading
Loading
Loading
Loading
+35 −2
Original line number Original line Diff line number Diff line
@@ -1149,7 +1149,8 @@ static int h2_session_send(struct Curl_easy *data,
 */
 */
static int h2_process_pending_input(struct Curl_easy *data,
static int h2_process_pending_input(struct Curl_easy *data,
                                    struct http_conn *httpc,
                                    struct http_conn *httpc,
                                    CURLcode *err) {
                                    CURLcode *err)
{
  ssize_t nread;
  ssize_t nread;
  char *inbuf;
  char *inbuf;
  ssize_t rv;
  ssize_t rv;
@@ -1197,9 +1198,41 @@ static int h2_process_pending_input(struct Curl_easy *data,
  return 0;
  return 0;
}
}


/*
 * Called from transfer.c:done_sending when we stop uploading.
 */
CURLcode Curl_http2_done_sending(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;

  if((conn->handler == &Curl_handler_http2_ssl) ||
     (conn->handler == &Curl_handler_http2)) {
    /* make sure this is only attempted for HTTP/2 transfers */

    struct HTTP *stream = conn->data->req.protop;

    if(stream->upload_left) {
      /* If the stream still thinks there's data left to upload. */
      struct http_conn *httpc = &conn->proto.httpc;
      nghttp2_session *h2 = httpc->h2;

      stream->upload_left = 0; /* DONE! */

      /* resume sending here to trigger the callback to get called again so
         that it can signal EOF to nghttp2 */
      (void)nghttp2_session_resume_data(h2, stream->stream_id);

      (void)h2_process_pending_input(conn->data, httpc, &result);
    }
  }
  return result;
}


static ssize_t http2_handle_stream_close(struct connectdata *conn,
static ssize_t http2_handle_stream_close(struct connectdata *conn,
                                         struct Curl_easy *data,
                                         struct Curl_easy *data,
                                         struct HTTP *stream, CURLcode *err) {
                                         struct HTTP *stream, CURLcode *err)
{
  char *trailer_pos, *trailer_end;
  char *trailer_pos, *trailer_end;
  CURLcode result;
  CURLcode result;
  struct http_conn *httpc = &conn->proto.httpc;
  struct http_conn *httpc = &conn->proto.httpc;
+2 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
void Curl_http2_setup_conn(struct connectdata *conn);
void Curl_http2_setup_conn(struct connectdata *conn);
void Curl_http2_setup_req(struct Curl_easy *data);
void Curl_http2_setup_req(struct Curl_easy *data);
void Curl_http2_done(struct connectdata *conn, bool premature);
void Curl_http2_done(struct connectdata *conn, bool premature);
CURLcode Curl_http2_done_sending(struct connectdata *conn);
#else /* USE_NGHTTP2 */
#else /* USE_NGHTTP2 */
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
@@ -63,6 +64,7 @@ void Curl_http2_done(struct connectdata *conn, bool premature);
#define Curl_http2_init_state(x)
#define Curl_http2_init_state(x)
#define Curl_http2_init_userset(x)
#define Curl_http2_init_userset(x)
#define Curl_http2_done(x,y)
#define Curl_http2_done(x,y)
#define Curl_http2_done_sending(x)
#endif
#endif


#endif /* HEADER_CURL_HTTP2_H */
#endif /* HEADER_CURL_HTTP2_H */
+3 −0
Original line number Original line Diff line number Diff line
@@ -75,6 +75,7 @@
#include "multiif.h"
#include "multiif.h"
#include "connect.h"
#include "connect.h"
#include "non-ascii.h"
#include "non-ascii.h"
#include "http2.h"


/* The last 3 #include files should be in this order */
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_printf.h"
@@ -832,6 +833,8 @@ static CURLcode done_sending(struct connectdata *conn,
{
{
  k->keepon &= ~KEEP_SEND; /* we're done writing */
  k->keepon &= ~KEEP_SEND; /* we're done writing */


  Curl_http2_done_sending(conn);

  if(conn->bits.rewindaftersend) {
  if(conn->bits.rewindaftersend) {
    CURLcode result = Curl_readrewind(conn);
    CURLcode result = Curl_readrewind(conn);
    if(result)
    if(result)