From 90a1b857f3fddf5cf1a25b73d6bdbe6c40471076 Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Sat, 6 Jun 2020 22:42:17 -0400 Subject: WIP: Add support for gemini meta headers --- lib/gemini.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) (limited to 'lib/gemini.c') 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*/ -- cgit v1.2.3