Commit f9915f512c for openssl.org
commit f9915f512c2fc5ce7c992a336dc5e9ca8e036236
Author: Shreenidhi Shedi <yesshedi@gmail.com>
Date: Thu Jul 9 16:23:57 2026 +0530
apps/tsget: replace CURLOPT_UPLOAD with CURLOPT_POST
Switch from the UPLOAD+CUSTOMREQUEST+read-callback approach to
POSTFIELDS, eliminating the read_body/write_body callbacks and the
INFILE/INFILESIZE/FILE options. Rename get_timestamp to send_request
with a simpler interface that writes directly to the output file via
CURLOPT_WRITEDATA.
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Shreenidhi Shedi <yesshedi@gmail.com>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Fri Aug 7 13:29:36 2026
(Merged from https://github.com/openssl/openssl/pull/31445)
diff --git a/apps/tsget.in b/apps/tsget.in
index 0bd35dbfb4..4fab476e5f 100644
--- a/apps/tsget.in
+++ b/apps/tsget.in
@@ -15,27 +15,6 @@ use Net::Curl::Easy qw(:constants);
use vars qw(%options);
-# Callback for reading the body.
-sub read_body {
- my ($easy, $maxlength, $state) = @_;
- my $return_data = "";
- my $data_len = length ${$state->{data}};
- if ($state->{bytes} < $data_len) {
- $data_len = $data_len - $state->{bytes};
- $data_len = $maxlength if $data_len > $maxlength;
- $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
- $state->{bytes} += $data_len;
- }
- return $return_data;
-}
-
-# Callback for writing the body into a variable.
-sub write_body {
- my ($easy, $data, $pointer) = @_;
- ${$pointer} .= $data;
- return length($data);
-}
-
# Initialise a new Curl object.
sub create_curl {
my $url = shift;
@@ -49,17 +28,9 @@ sub create_curl {
$curl->setopt(CURLOPT_USERAGENT,
"OpenTSA tsget.pl/openssl-{- $config{full_version} -}");
- # Options for POST method.
- $curl->setopt(CURLOPT_UPLOAD, 1);
- $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
$curl->setopt(CURLOPT_HTTPHEADER,
["Content-Type: application/timestamp-query",
"Accept: application/timestamp-reply,application/timestamp-response"]);
- $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
- $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[1]); });
-
- # Options for getting the result.
- $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
# SSL related options.
$curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
@@ -79,36 +50,41 @@ sub create_curl {
return $curl;
}
-# Send a request and returns the body back.
-sub get_timestamp {
- my $curl = shift;
- my $body = shift;
- my $ts_body;
-
- # Options for POST method.
- $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
- $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
-
- # Options for getting the result.
- $curl->setopt(CURLOPT_FILE, \$ts_body);
-
- # Send the request...
- my $error_string;
- eval { $curl->perform(); };
- if ($@) {
- my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
- $error_string = "could not get timestamp";
- $error_string .= ", http code: $http_code" unless $http_code == 0;
- $error_string .= ": $@";
- } else {
- my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
- if (lc($ct) ne "application/timestamp-reply"
- && lc($ct) ne "application/timestamp-response") {
- $error_string = "unexpected content type returned: $ct";
- }
+# Send a request, writing the response to the given filehandle.
+# Returns an error string on network/protocol failure, undef on success.
+sub send_request {
+ my ($curl, $body, $out_fh) = @_;
+
+ $curl->setopt(CURLOPT_POST, 1);
+ $curl->setopt(CURLOPT_POSTFIELDS, $body);
+ $curl->setopt(CURLOPT_POSTFIELDSIZE, length($body));
+ $curl->setopt(CURLOPT_WRITEDATA, $out_fh);
+
+ my $ok = eval { $curl->perform(); 1; };
+
+ if (!$ok) {
+ my $http_code = eval { $curl->getinfo(CURLINFO_HTTP_CODE) } // 0;
+ my $curl_err = eval { $curl->error() } // "";
+ my $err = "could not get timestamp";
+ $err .= ", http code: $http_code" if $http_code != 0;
+ $err .= " ($curl_err)" if length($curl_err);
+ return $err;
}
- return ($ts_body, $error_string);
+ my $downloaded = $curl->getinfo(CURLINFO_SIZE_DOWNLOAD);
+ if (!defined($downloaded) || $downloaded == 0) {
+ return "empty response received";
+ }
+
+ my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
+ if (!defined($ct)
+ || (lc($ct) ne "application/timestamp-reply"
+ && lc($ct) ne "application/timestamp-response")) {
+ return "unexpected content type returned: "
+ . (defined($ct) ? $ct : "(none)");
+ }
+
+ return undef;
}
# Print usage information and exists.
@@ -172,23 +148,10 @@ REQUEST: foreach (@ARGV) {
# Send request.
STDERR->printflush("sending request") if $options{v};
- my ($ts_body, $error) = get_timestamp $curl, \$body;
+ my $error = send_request($curl, $body, $output);
if (defined($error)) {
die "$input: fatal error: $error\n";
}
STDERR->printflush(", reply received") if $options{v};
-
- # Write response.
- if ($output eq "-") {
- # Write to STDOUT.
- print $ts_body;
- } else {
- # Write to file.
- open OUTPUT, ">", $output
- or warn("$output: could not open output file: $!\n"), next REQUEST;
- print OUTPUT $ts_body;
- close OUTPUT
- or warn("$output: could not close output file: $!\n"), next REQUEST;
- }
STDERR->printflush(", $output written.\n") if $options{v};
}