diff options
| -rw-r--r-- | include/curl/curl.h | 3 | ||||
| -rw-r--r-- | lib/gemini.c | 104 | ||||
| -rw-r--r-- | lib/setopt.c | 3 | ||||
| -rw-r--r-- | src/tool_cfgable.h | 1 | 
4 files changed, 110 insertions, 1 deletions
| diff --git a/include/curl/curl.h b/include/curl/curl.h index 71695538d..78f5e1e9a 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1968,6 +1968,9 @@ typedef enum {    CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),    CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295), +  /* set the gemini request meta */ +  CURLOPT(CURLOPT_META, CURLOPTTYPE_STRINGPOINT, 296), +    CURLOPT_LASTENTRY /* the last unused */  } CURLoption; diff --git a/lib/gemini.c b/lib/gemini.c index bd1953d82..31560ac8d 100644 --- a/lib/gemini.c +++ b/lib/gemini.c @@ -49,6 +49,8 @@  static CURLcode gemini_do(struct connectdata *conn, bool *done);  static CURLcode gemini_connecting(struct connectdata *conn, bool *done);  CURLcode Curl_gemini_connect(struct connectdata *conn, bool *done); +void Curl_setup_gemini_transfer(struct Curl_easy *data, int sockindex, +    curl_off_t size, bool getheader, int writesockindex);  /*   * Gemini protocol handler. @@ -144,7 +146,15 @@ static CURLcode gemini_do(struct connectdata *conn, bool *done)      }    } -  Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); +  printf("include header: %d\n", data->set.include_header); +  printf("verbose: %d\n", data->set.verbose); +  printf("follow location: %d\n", data->set.http_follow_location); + +  /* if (data->set.include_header) { */ +    Curl_setup_gemini_transfer(data, FIRSTSOCKET, -1, FALSE, -1); +  /* } else { */ +  /*   Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); */ +  /* } */    return CURLE_OK;  } @@ -176,4 +186,96 @@ CURLcode Curl_gemini_connect(struct connectdata *conn, bool *done)    return CURLE_OK;  } + +/* + * Curl_setup_gemini_transfer() is called to setup some basic properties for the + * upcoming transfer. + */ +void +Curl_setup_gemini_transfer( +  struct Curl_easy *data,   /* transfer */ +  int sockindex,            /* socket index to read from or -1 */ +  curl_off_t size,          /* -1 if unknown at this point */ +  bool getheader,           /* TRUE if header parsing is wanted */ +  int writesockindex        /* socket index to write to, it may very well be +                               the same we read from. -1 disables */ +  ) +{ +  struct SingleRequest *k = &data->req; +  struct connectdata *conn = data->conn; +  struct HTTP *http = data->req.protop; +  bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) && +                      (http->sending == HTTPSEND_REQUEST)); +  DEBUGASSERT(conn != NULL); +  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); + +  if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) { +    /* when multiplexing, the read/write sockets need to be the same! */ +    conn->sockfd = sockindex == -1 ? +      ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : +      conn->sock[sockindex]; +    conn->writesockfd = conn->sockfd; +    if(httpsending) +      /* special and very HTTP-specific */ +      writesockindex = FIRSTSOCKET; +  } +  else { +    conn->sockfd = sockindex == -1 ? +      CURL_SOCKET_BAD : conn->sock[sockindex]; +    conn->writesockfd = writesockindex == -1 ? +      CURL_SOCKET_BAD:conn->sock[writesockindex]; +  } +  k->getheader = getheader; + +  k->size = size; + +  /* The code sequence below is placed in this function just because all +     necessary input is not always known in do_complete() as this function may +     be called after that */ + +  if(!k->getheader) { +    k->header = FALSE; +    if(size > 0) +      Curl_pgrsSetDownloadSize(data, size); +  } +  /* we want header and/or body, if neither then don't do this! */ +  if(k->getheader || !data->set.opt_no_body) { + +    if(sockindex != -1) +      k->keepon |= KEEP_RECV; + +    if(writesockindex != -1) { +      /* HTTP 1.1 magic: + +         Even if we require a 100-return code before uploading data, we might +         need to write data before that since the REQUEST may not have been +         finished sent off just yet. + +         Thus, we must check if the request has been sent before we set the +         state info where we wait for the 100-return code +      */ +      if((data->state.expect100header) && +         (conn->handler->protocol&PROTO_FAMILY_HTTP) && +         (http->sending == HTTPSEND_BODY)) { +      /*   /1* wait with write until we either got 100-continue or a timeout *1/ */ +      /*   k->exp100 = EXP100_AWAITING_CONTINUE; */ +      /*   k->start100 = Curl_now(); */ + +      /*   /1* Set a timeout for the multi interface. Add the inaccuracy margin so */ +      /*      that we don't fire slightly too early and get denied to run. *1/ */ +      /*   Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); */ +      } +      else { +        if(data->state.expect100header) +          /* when we've sent off the rest of the headers, we must await a +             100-continue but first finish sending the request */ +          k->exp100 = EXP100_SENDING_REQUEST; + +        /* enable the write bit when we're not waiting for continue */ +        k->keepon |= KEEP_SEND; +      } +    } /* if(writesockindex != -1) */ +  } /* if(k->getheader || !data->set.opt_no_body) */ + +}  #endif /*CURL_DISABLE_GEMINI*/ diff --git a/lib/setopt.c b/lib/setopt.c index 4570cc06a..80332a510 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -2831,6 +2831,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)        return result;      break;  #endif +  case CURLOPT_META: +    result = Curl_setstropt(&data->set.gemini_meta, va_arg(param, char *)); +    break;    default:      /* unknown tag and its companion, just ignore: */      result = CURLE_UNKNOWN_OPTION; diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index 4a90d0b72..42a827388 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -280,6 +280,7 @@ struct OperationConfig {                                       0 is valid. default: CURL_HET_DEFAULT. */    bool haproxy_protocol;          /* whether to send HAProxy protocol v1 */    bool disallow_username_in_url;  /* disallow usernames in URLs */ +  char *meta;                     /* gemini request meta */    struct GlobalConfig *global;    struct OperationConfig *prev;    struct OperationConfig *next;   /* Always last in the struct */ | 
