aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2020-06-06 22:42:17 -0400
committerBen Burwell <ben@benburwell.com>2020-06-06 22:42:17 -0400
commit90a1b857f3fddf5cf1a25b73d6bdbe6c40471076 (patch)
treeede079475cf651a8eee26327e361fe6ddc36233f
parentc365f2cb4ffcbef02d2e9a5e17aa9d7f1fe81df7 (diff)
WIP: Add support for gemini meta headersgemini-meta
-rw-r--r--include/curl/curl.h3
-rw-r--r--lib/gemini.c104
-rw-r--r--lib/setopt.c3
-rw-r--r--src/tool_cfgable.h1
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 */