Skip to content

Commit

Permalink
Merge pull request #15 from olenagerasimova/14-add-http1
Browse files Browse the repository at this point in the history
feat: use HTTP/1.1 on HTTP/3 fail
  • Loading branch information
dgarus committed Dec 5, 2023
2 parents 57d6d4f + 95c92c0 commit 603ca01
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 39 deletions.
21 changes: 20 additions & 1 deletion mvn-resolver-transport-http3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,21 @@

<name>Artipie Maven Artifact Resolver Transport HTTP3</name>
<description>A transport implementation for repositories using HTTP3.</description>

<url>https://github.com/artipie/maven-resolver-http3-plugin</url>
<inceptionYear>2023</inceptionYear>
<licenses>
<license>
<name>MIT</name>
<url>https://github.com/artipie/maven-resolver-http3-plugin/blob/master/LICENSE.txt</url>
</license>
</licenses>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/artipie/maven-resolver-http3-plugin/issues</url>
</issueManagement>
<scm>
<url>https://github.com/artipie/maven-resolver-http3-plugin</url>
</scm>
<properties>
<Automatic-Module-Name>com.artipie.maven.resolver.transport.http3</Automatic-Module-Name>
<Bundle-SymbolicName>${Automatic-Module-Name}</Bundle-SymbolicName>
Expand Down Expand Up @@ -132,6 +146,11 @@
<artifactId>jetty-io</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
import static java.util.Objects.requireNonNull;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.lang3.exception.UncheckedException;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.aether.ConfigurationProperties;
Expand Down Expand Up @@ -69,12 +72,19 @@
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.http3.client.HTTP3Client;
import org.eclipse.jetty.http3.client.transport.HttpClientTransportOverHTTP3;
import org.eclipse.jetty.util.ssl.SslContextFactory;

/**
* A transporter for HTTP/HTTPS.
*/
final class HttpTransporter extends AbstractTransporter {

private final static Set<String> CENTRAL = Set.of(
"repo.maven.apache.org",
"oss.sonatype.org",
"packages.atlassian.com"
);

private final Map<String, ChecksumExtractor> checksumExtractors;

private final AuthenticationContext repoAuthContext;
Expand All @@ -83,8 +93,11 @@ final class HttpTransporter extends AbstractTransporter {

private final URI baseUri;

private final HttpClient client;
private HttpClient http3Client;
private HttpClient httpClient = null;

private final int connectTimeout;
private final String httpsSecurityMode;

private String[] authInfo = null;

Expand Down Expand Up @@ -123,7 +136,7 @@ final class HttpTransporter extends AbstractTransporter {
};
}

String httpsSecurityMode = ConfigUtils.getString(
httpsSecurityMode = ConfigUtils.getString(
session,
ConfigurationProperties.HTTPS_SECURITY_MODE_DEFAULT,
ConfigurationProperties.HTTPS_SECURITY_MODE + "." + repository.getId(),
Expand All @@ -135,16 +148,43 @@ final class HttpTransporter extends AbstractTransporter {
ConfigurationProperties.CONNECT_TIMEOUT + "." + repository.getId(),
ConfigurationProperties.CONNECT_TIMEOUT
);
this.chooseClient();
}

HTTP3Client h3Client = new HTTP3Client();
HttpClientTransportOverHTTP3 transport = new HttpClientTransportOverHTTP3(h3Client);
this.client = new HttpClient(transport);
this.client.setFollowRedirects(true);
this.client.setConnectTimeout(connectTimeout);
this.client.start();
h3Client.getClientConnector().getSslContextFactory().setTrustAll(
httpsSecurityMode.equals(ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE)
);
private HttpClient initOrGetHttpClient() {
if (this.httpClient == null) {
this.httpClient = new HttpClient();
this.httpClient.setFollowRedirects(true);
this.httpClient.setConnectTimeout(connectTimeout);
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setTrustAll(httpsSecurityMode.equals(ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE));
httpClient.setSslContextFactory(sslContextFactory);
try {
this.httpClient.start();
} catch (Exception e) {
throw new UncheckedException(e);
}
}
return this.httpClient;
}

private HttpClient initOrGetHttp3Client() {
if (this.http3Client == null) {
HTTP3Client h3Client = new HTTP3Client();
HttpClientTransportOverHTTP3 transport = new HttpClientTransportOverHTTP3(h3Client);
this.http3Client = new HttpClient(transport);
this.http3Client.setFollowRedirects(true);
this.http3Client.setConnectTimeout(connectTimeout);
try {
this.http3Client.start();
h3Client.getClientConnector().getSslContextFactory().setTrustAll(
httpsSecurityMode.equals(ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE)
);
} catch (Exception e) {
throw new UncheckedException(e);
}
}
return this.http3Client;
}

@Override
Expand All @@ -157,12 +197,13 @@ public int classify(Throwable error) {

@Override
protected void implPeek(PeekTask task) throws Exception {
this.makeRequest(HttpMethod.HEAD, task, null);
this.makeRequest(HttpMethod.HEAD, task, null, this.chooseClient());
}

@Override
protected void implGet(GetTask task) throws Exception {
final Pair<InputStream, HttpFields> response = this.makeRequest(HttpMethod.GET, task, null);
final Pair<InputStream, HttpFields> response =
this.makeRequest(HttpMethod.GET, task, null, this.chooseClient());
final boolean resume = false;
final File dataFile = task.getDataFile();
long length = Long.parseLong(
Expand Down Expand Up @@ -202,16 +243,21 @@ protected void implGet(GetTask task) throws Exception {
protected void implPut(PutTask task) throws Exception {
try (final InputStream stream = task.newInputStream()) {
this.makeRequest(HttpMethod.PUT, task,
new InputStreamRequestContent(stream)
);
new InputStreamRequestContent(stream), this.chooseClient());
}
}

@Override
protected void implClose() {
try {
client.stop();
client.destroy();
if (this.http3Client != null) {
http3Client.stop();
http3Client.destroy();
}
if (this.httpClient != null) {
this.httpClient.stop();
this.httpClient.destroy();
}
} catch (Exception e) {
throw new UncheckedIOException(new IOException(e));
}
Expand All @@ -220,17 +266,20 @@ protected void implClose() {
}

private Pair<InputStream, HttpFields> makeRequest(
HttpMethod method, TransportTask task, Request.Content bodyContent
HttpMethod method, TransportTask task, Request.Content bodyContent, HttpClient client
) {
final String url = this.baseUri.resolve(task.getLocation()).toString();
if (this.authInfo != null) {
this.client.getAuthenticationStore().addAuthenticationResult(
client.getAuthenticationStore().addAuthenticationResult(
new BasicAuthentication.BasicResult(this.baseUri, this.authInfo[0], this.authInfo[1])
);
}
Request request = null;
final HttpVersion version = this.httpVersion(client);
try {
InputStreamResponseListener listener = new InputStreamResponseListener();
this.client.newRequest(url).method(method).headers(
request = client.newRequest(url);
request.method(method).headers(
httpFields -> {
if (bodyContent != null) {
httpFields.add(HttpHeader.CONTENT_TYPE, bodyContent.getContentType());
Expand All @@ -245,22 +294,26 @@ private Pair<InputStream, HttpFields> makeRequest(
final Response response = listener.get(this.connectTimeout, TimeUnit.MILLISECONDS);
if (response.getStatus() >= 300) {
System.err.printf(
"Request over HTTP3 error status %s, method=%s, url=%s%n",
response.getStatus(), method, url
"Request over %s error status %s, method=%s, url=%s%n",
version, response.getStatus(), method, url
);
throw new HttpResponseException(Integer.toString(response.getStatus()), response);
}
System.err.printf(
"Request over HTTP3 done, method=%s, resp status=%s, url=%s%n",
method, response.getStatus(), url
"Request over %s done, method=%s, resp status=%s, url=%s%n",
version, method, response.getStatus(), url
);
return new ImmutablePair<>(listener.getInputStream(), response.getHeaders());
} catch (Exception ex) {
System.err.printf(
"Request over HTTP3 error=%s: %s, method=%s, url=%s%n",
"Request over %s error=%s: %s, method=%s, url=%s%n", version,
ex.getClass(), ex.getMessage(), method, url
);
throw new HttpRequestException(ex.getMessage(), this.client.newRequest(url));
if (version == HttpVersion.HTTP_3 && ex instanceof TimeoutException) {
System.err.printf("Repeat request over HTTP/1.1 method=%s, url=%s%n", method, url);
return this.makeRequest(method, task, bodyContent, this.initOrGetHttpClient());
}
throw new HttpRequestException(ex.getMessage(), request);
}
}

Expand All @@ -274,6 +327,24 @@ private void extractChecksums(HttpFields response, GetTask task) {
}
}

/**
* Choose http client to initialize and perform request with: if host is present in known
* central's hosts {@link HttpTransporter#CENTRAL}, http 1.1 client is used, otherwise we use http3 client.
*/
private HttpClient chooseClient() {
final HttpClient res;
if (CENTRAL.contains(this.baseUri.getHost())) {
res = Optional.ofNullable(this.httpClient).orElseGet(this::initOrGetHttpClient);
} else {
res = Optional.ofNullable(this.http3Client).orElseGet(this::initOrGetHttp3Client);
}
return res;
}

private HttpVersion httpVersion(final HttpClient client) {
return client.getTransport() instanceof HttpClientTransportOverHTTP3 ? HttpVersion.HTTP_3 : HttpVersion.HTTP_1_1;
}

/**
* TOOD: For unknown reason when running inside Maven, HttpFieldPreEncoder for HTTP3 is missing.
* It is not available in Jetty static initializer when that library is loaded by Maven.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ void resolvesDependencies() throws IOException, InterruptedException {
res,
Matchers.stringContainsInOrder(
"BUILD SUCCESS",
"Request over HTTP3 done, method=GET, resp status=200, url=https://artipie:8091/my-maven-proxy/args4j/args4j/2.33/args4j-2.33.jar",
"Request over HTTP3 done, method=GET, resp status=200, url=https://artipie:8091/my-maven-proxy/org/springframework/spring-web/6.1.0/spring-web-6.1.0.jar"
"Request over HTTP/3.0 done, method=GET, resp status=200, url=https://artipie:8091/my-maven-proxy/args4j/args4j/2.33/args4j-2.33.jar",
"Request over HTTP/3.0 done, method=GET, resp status=200, url=https://artipie:8091/my-maven-proxy/org/springframework/spring-web/6.1.0/spring-web-6.1.0.jar"
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
* Testing transport via containerized Caddy http3 server in proxy mode.
*/
public class MavenResolverIT {
private static final String REMOTE_PATH = "commons-cli/commons-cli/1.4/commons-cli-1.4.jar";
private static final String LOCAL_PATH = "commons-cli-1.4.jar";
static final String REMOTE_PATH = "commons-cli/commons-cli/1.4/commons-cli-1.4.jar";
static final String LOCAL_PATH = "commons-cli-1.4.jar";

private static GenericContainer<?> caddyProxy;
private static File tempFile;
Expand All @@ -53,7 +53,7 @@ public class MavenResolverIT {
public void testTransporterAuth() throws Exception {
final byte[] data = testTransporter("https://demo:demo@localhost:7444/maven2");
assertNotEquals(null, data);
final byte[] local = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] local = getCommonsJar();
assertArrayEquals(local, data);
}

Expand All @@ -79,15 +79,15 @@ public void testTransporterAnonAuthFail() {
public void testTransporterAnon() throws Exception {
final byte[] data = testTransporter("https://localhost:7443/maven2");
assertNotEquals(null, data);
final byte[] local = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] local = getCommonsJar();
assertArrayEquals(local, data);
}

@Test
public void testAnonTransporterSuccess() throws Exception {
final byte[] data = testTransporter("https://demo:demo@localhost:7443/maven2");
assertNotNull(data);
final byte[] local = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] local = getCommonsJar();
assertArrayEquals(local, data);
}

Expand Down Expand Up @@ -132,7 +132,7 @@ public void testJettyLocalhostPut() throws Exception {
final HttpClient client = new HttpClient(transport);
client.start();
h3Client.getClientConnector().getSslContextFactory().setTrustAll(true);
final byte[] srcData = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] srcData = getCommonsJar();
final ContentResponse response = client.newRequest("https://localhost:7445/test1").
method(HttpMethod.PUT).body(
new InputStreamRequestContent(new ByteArrayInputStream(srcData))
Expand All @@ -150,7 +150,7 @@ public void testTransporterPutAnon() throws Exception {
resetPutServer();
final HttpTransporterFactory factory = new HttpTransporterFactory();
final PutTask task = new PutTask(URI.create("test1")).setListener(new TransportListener() {});
final byte[] srcData = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] srcData = getCommonsJar();
task.setDataBytes(srcData);
try (final Transporter transporter = factory.newInstance(newSession(), newRepo(repo))) {
transporter.put(task);
Expand All @@ -166,7 +166,7 @@ public void testTransporterPutAuth() throws Exception {
resetPutServer();
final HttpTransporterFactory factory = new HttpTransporterFactory();
final PutTask task = new PutTask(URI.create("test1")).setListener(new TransportListener() {});
final byte[] srcData = getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
final byte[] srcData = getCommonsJar();
task.setDataBytes(srcData);
try (final Transporter transporter = factory.newInstance(newSession(), newRepo(repo))) {
transporter.put(task);
Expand Down Expand Up @@ -209,14 +209,14 @@ public static void finish() {
tempFile.delete();
}

private static DefaultRepositorySystemSession newSession() {
static DefaultRepositorySystemSession newSession() {
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
session.setLocalRepositoryManager(new TestLocalRepositoryManager());
session.setConfigProperty(ConfigurationProperties.HTTPS_SECURITY_MODE, ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE);
return session;
}

private RemoteRepository newRepo(final String url) {
static RemoteRepository newRepo(final String url) {
return new RemoteRepository.Builder("test", "default", url).build();
}

Expand All @@ -226,4 +226,8 @@ private static void resetPutServer() throws InterruptedException, IOException {
assertEquals(0, result.getExitCode());
assertTrue(deleted);
}

byte[] getCommonsJar() throws IOException {
return getClass().getClassLoader().getResourceAsStream(LOCAL_PATH).readAllBytes();
}
}
Loading

2 comments on commit 603ca01

@0pdd
Copy link

@0pdd 0pdd commented on 603ca01 Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to github. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

set -x && set -e && set -o pipefail && cd /tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0 && pdd -v -f /tmp/20231205-1093422-4jmdyc [1]: + set -e + set -o pipefail + cd...

Please, copy and paste this stack trace to GitHub:

UserError
set -x && set -e && set -o pipefail && cd /tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0 && pdd -v -f /tmp/20231205-1093422-4jmdyc [1]:
+ set -e
+ set -o pipefail
+ cd /tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0
+ pdd -v -f /tmp/20231205-1093422-4jmdyc

My version is 0.23.2
Ruby version is 3.1.4 at x86_64-linux
Reading from root dir /tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/commons-cli-1.4.jar is a binary file (53820 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/client-store is a binary file (2244 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/server-store is a binary file (2246 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/server-store-selfsigned is a binary file (2750 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/client-store is a binary file (2244 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/server-store is a binary file (2246 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/server-store-selfsigned is a binary file (2750 bytes)
/tmp/0pdd20231205-14-58ehr2/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-wagon-http-light/src/test/resources/ssl/keystore is a binary file (2246 bytes)
Reading .gitattributes ...
Reading .github/workflows/ci-checks.yml ...
Reading .github/workflows/release.yml ...
Reading .github/workflows/update-copyright-years.yml ...
Reading .gitignore ...
Reading LICENSE.txt ...
Reading README.md ...
Reading mvn-resolver-transport-http3/Dockerfile ...
Reading mvn-resolver-transport-http3/README.md ...
Reading mvn-resolver-transport-http3/pom.xml ...
Reading mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/ConnMgrConfig.java ...
Reading mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java ...
ERROR: ERROR: mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java; PDD::Error at mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java:370: TODO found, but puzzle can't be parsed, most probably because TODO is not followed by a puzzle marker, as this page explains: https://github.com/cqfn/pdd#how-to-format
If you can't understand the cause of this issue or you don't know how to fix it, please submit a GitHub issue, we will try to help you: https://github.com/cqfn/pdd/issues. This tool is still in its beta version and we will appreciate your feedback. Here is where you can find more documentation: https://github.com/cqfn/pdd/blob/master/README.md.
Exit code is 1

/app/objects/git_repo.rb:73:in `rescue in block in xml'
/app/objects/git_repo.rb:70:in `block in xml'
/app/vendor/ruby-3.1.4/lib/ruby/3.1.0/tempfile.rb:317:in `open'
/app/objects/git_repo.rb:69:in `xml'
/app/objects/puzzles.rb:41:in `deploy'
/app/objects/jobs/job.rb:38:in `proceed'
/app/objects/jobs/job_starred.rb:32:in `proceed'
/app/objects/jobs/job_recorded.rb:31:in `proceed'
/app/objects/jobs/job_emailed.rb:33:in `proceed'
/app/objects/jobs/job_commiterrors.rb:33:in `proceed'
/app/objects/jobs/job_detached.rb:48:in `exclusive'
/app/objects/jobs/job_detached.rb:36:in `block in proceed'
/app/objects/jobs/job_detached.rb:36:in `fork'
/app/objects/jobs/job_detached.rb:36:in `proceed'
/app/0pdd.rb:531:in `process_request'
/app/0pdd.rb:367:in `block in <top (required)>'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1706:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1706:in `block in compile!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1019:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1037:in `route_eval'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1019:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1068:in `block in process_route'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1066:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1066:in `process_route'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1017:in `block in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1014:in `each'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1014:in `route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1138:in `block in dispatch!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `invoke'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1133:in `dispatch!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:949:in `block in call!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `invoke'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:949:in `call!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:938:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/deflater.rb:44:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/xss_header.rb:20:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/path_traversal.rb:18:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/json_csrf.rb:28:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/base.rb:53:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/base.rb:53:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/frame_options.rb:33:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/logger.rb:17:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/common_logger.rb:38:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:261:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:254:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/method_override.rb:24:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:219:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:2018:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1576:in `block in call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1792:in `synchronize'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1576:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/handler/webrick.rb:95:in `service'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/httpserver.rb:140:in `service'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/httpserver.rb:96:in `run'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/server.rb:310:in `block in start_thread'

@0pdd
Copy link

@0pdd 0pdd commented on 603ca01 Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to github. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

set -x && set -e && set -o pipefail && cd /tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0 && pdd -v -f /tmp/20231211-1177464-pl1vwx [1]: + set -e + set -o pipefail + cd...

Please, copy and paste this stack trace to GitHub:

UserError
set -x && set -e && set -o pipefail && cd /tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0 && pdd -v -f /tmp/20231211-1177464-pl1vwx [1]:
+ set -e
+ set -o pipefail
+ cd /tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0
+ pdd -v -f /tmp/20231211-1177464-pl1vwx

My version is 0.23.2
Ruby version is 3.1.4 at x86_64-linux
Reading from root dir /tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/commons-cli-1.4.jar is a binary file (53820 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/client-store is a binary file (2244 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/server-store is a binary file (2246 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/mvn-resolver-transport-http3/src/test/resources/ssl/server-store-selfsigned is a binary file (2750 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/client-store is a binary file (2244 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/server-store is a binary file (2246 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-resolver-transport-http/src/test/resources/ssl/server-store-selfsigned is a binary file (2750 bytes)
/tmp/0pdd20231211-14-u63jac/Z2l0QGdpdGh1Yi5jb206YXJ0aXBpZS9tYXZlbi1yZXNvbHZlci1odHRwMy1wbHVnaW4uZ2l0/testing/mvn-wagon-http-light/src/test/resources/ssl/keystore is a binary file (2246 bytes)
Reading .gitattributes ...
Reading .github/workflows/ci-checks.yml ...
Reading .github/workflows/release.yml ...
Reading .github/workflows/update-copyright-years.yml ...
Reading .gitignore ...
Reading LICENSE.txt ...
Reading README.md ...
Reading mvn-resolver-transport-http3/Dockerfile ...
Reading mvn-resolver-transport-http3/README.md ...
Reading mvn-resolver-transport-http3/pom.xml ...
Reading mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/ConnMgrConfig.java ...
Reading mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java ...
ERROR: ERROR: mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java; PDD::Error at mvn-resolver-transport-http3/src/main/java/com/artipie/aether/transport/http3/HttpTransporter.java:370: TODO found, but puzzle can't be parsed, most probably because TODO is not followed by a puzzle marker, as this page explains: https://github.com/cqfn/pdd#how-to-format
If you can't understand the cause of this issue or you don't know how to fix it, please submit a GitHub issue, we will try to help you: https://github.com/cqfn/pdd/issues. This tool is still in its beta version and we will appreciate your feedback. Here is where you can find more documentation: https://github.com/cqfn/pdd/blob/master/README.md.
Exit code is 1

/app/objects/git_repo.rb:73:in `rescue in block in xml'
/app/objects/git_repo.rb:70:in `block in xml'
/app/vendor/ruby-3.1.4/lib/ruby/3.1.0/tempfile.rb:317:in `open'
/app/objects/git_repo.rb:69:in `xml'
/app/objects/puzzles.rb:41:in `deploy'
/app/objects/jobs/job.rb:38:in `proceed'
/app/objects/jobs/job_starred.rb:32:in `proceed'
/app/objects/jobs/job_recorded.rb:31:in `proceed'
/app/objects/jobs/job_emailed.rb:33:in `proceed'
/app/objects/jobs/job_commiterrors.rb:33:in `proceed'
/app/objects/jobs/job_detached.rb:48:in `exclusive'
/app/objects/jobs/job_detached.rb:36:in `block in proceed'
/app/objects/jobs/job_detached.rb:36:in `fork'
/app/objects/jobs/job_detached.rb:36:in `proceed'
/app/0pdd.rb:531:in `process_request'
/app/0pdd.rb:367:in `block in <top (required)>'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1706:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1706:in `block in compile!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1019:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1037:in `route_eval'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1019:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1068:in `block in process_route'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1066:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1066:in `process_route'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1017:in `block in route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1014:in `each'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1014:in `route!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1138:in `block in dispatch!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `invoke'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1133:in `dispatch!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:949:in `block in call!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `catch'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1109:in `invoke'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:949:in `call!'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:938:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/deflater.rb:44:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/xss_header.rb:20:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/path_traversal.rb:18:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/json_csrf.rb:28:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/base.rb:53:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/base.rb:53:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-protection-3.0.6/lib/rack/protection/frame_options.rb:33:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/logger.rb:17:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/common_logger.rb:38:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:261:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:254:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/method_override.rb:24:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:219:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:2018:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1576:in `block in call'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1792:in `synchronize'
/app/vendor/bundle/ruby/3.1.0/gems/sinatra-3.0.6/lib/sinatra/base.rb:1576:in `call'
/app/vendor/bundle/ruby/3.1.0/gems/rack-2.2.8/lib/rack/handler/webrick.rb:95:in `service'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/httpserver.rb:140:in `service'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/httpserver.rb:96:in `run'
/app/vendor/bundle/ruby/3.1.0/gems/webrick-1.8.1/lib/webrick/server.rb:310:in `block in start_thread'

Please sign in to comment.