7  java/lang/Object()Vorg/apache/commons/cli/Options   net/luminis/quic/run/KwikClicmdLineOptions Lorg/apache/commons/cli/Options;llog  DEFAULT_LOG_ARGSLjava/lang/String; makeConcatWithConstants&(Ljava/lang/String;)Ljava/lang/String;   addOptionY(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Lorg/apache/commons/cli/Options;!h#help% show help'29)use Quic version IETF_draft_29 + ,F(Ljava/lang/String;Ljava/lang/String;)Lorg/apache/commons/cli/Options;.300use Quic version IETF_draft_302314use Quic version IETF_draft_316328use Quic version IETF_draft_32:v1<use Quic version 1>v2@use Quic version 2Bv1v2D%use Quic version 1, request version 2FreservedVersionH3use reserved version to trigger version negotiationJALalpnNset alpn (default is hq-xx)PRRresumption keyTsession ticket fileVcXconnectionTimeoutZconnection timeout in seconds\i^ interactive`start interactive shellbkd keepAlivef%connection keep alive time in secondshLjlogFilelfile to write log message tonOpoutputrwrite server response to filetHvhttpx6send HTTP GET request, arg is path, e.g. '/index.html'zS| storeTickets~-basename of file to store new session ticketsT relativeTime-log with time (in seconds) since first packetZuse0RTT#use 0-RTT if possible (requires -H)secrets(write secrets to file (Wireshark format)vversionshow Kwik version initialRtt)custom initial RTT value (default is 500)chacha20!use ChaCha20 as only cipher suitenoCertificateCheckdo not check server certificatesaveServerCertificates'store server certificates in given filequantumReadinessTest*add number of random bytes to client helloclientCertificate,certificate (file) for client authentication clientKey)private key (file) for client certificateuse ChaCha20 cipher suite aes128gcm!use AEAD_AES_128_GCM cipher suite aes256gcm!use AEAD_AES_256_GCM cipher suite$org/apache/commons/cli/DefaultParser   (org/apache/commons/cli/CommandLineParserparseY(Lorg/apache/commons/cli/Options;[Ljava/lang/String;)Lorg/apache/commons/cli/CommandLine;%org/apache/commons/cli/ParseException  java/lang/SystemoutLjava/io/PrintStream;  getMessage()Ljava/lang/String;  java/io/PrintStreamprintln(Ljava/lang/String;)V usage exit(I)V  "org/apache/commons/cli/CommandLine hasOption(Ljava/lang/String;)Z   net/luminis/quic/run/KwikVersion getVersion  getArgList()Ljava/util/List;  java/util/Listsize()I  %net/luminis/quic/QuicClientConnection newBuilder1()Lnet/luminis/quic/QuicClientConnection$Builder; get(I)Ljava/lang/Object;java/lang/Stringhttp://   startsWithhttps:// java/net/URL     toURI()Ljava/net/URI;  -net/luminis/quic/QuicClientConnection$Builderuri?(Ljava/net/URI;)Lnet/luminis/quic/QuicClientConnection$Builder;  getPath  isEmpty()Zjava/net/MalformedURLException : " #$contains(Ljava/lang/CharSequence;)Z& java/net/URI % *\d+ , -matches/HError: invalid hostname (did you forget to specify an option argument?).2java/net/URISyntaxException5 68(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 8 9:stream()Ljava/util/stream/Stream; <=> ?@java/util/stream/Collectorsjoining6(Ljava/lang/CharSequence;)Ljava/util/stream/Collector; BCD EFjava/util/stream/Streamcollect0(Ljava/util/stream/Collector;)Ljava/lang/Object; H IJprocessCipherArgs(Lorg/apache/commons/cli/CommandLine;Lnet/luminis/quic/QuicClientConnection$Builder;)Lnet/luminis/quic/QuicClientConnection$Builder; L MnoServerCertificateCheck O PgetOptionValueRnet/luminis/quic/log/FileLoggerT java/io/File S QW X(Ljava/io/File;)VZjava/io/IOException \ ]err`!net/luminis/quic/log/SysOutLogger _ c deloggerN(Lnet/luminis/quic/log/Logger;)Lnet/luminis/quic/QuicClientConnection$Builder; g h(C)Z j Pk'(CLjava/lang/String;)Ljava/lang/String;mn opq rsnet/luminis/quic/log/LoggerlogRaw(Z)Vur ow xs logRecovery oz {slogCongestionControl}d o s logDecrypted o s logSecretsp o s logPackets o slogInfow o s logWarnings o slogStatsD o slogDebug  net/luminis/quic/Version getDefault()Lnet/luminis/quic/Version;  QUIC_version_1Lnet/luminis/quic/Version;  QUIC_version_2   IETF_draft_32   IETF_draft_31   IETF_draft_30   IETF_draft_29   reserved_1  K(Lnet/luminis/quic/Version;)Lnet/luminis/quic/QuicClientConnection$Builder;  preferredVersion  loadHttp3ClientClass  (net/luminis/quic/run/KwikCli$HttpVersionHTTP3*Lnet/luminis/quic/run/KwikCli$HttpVersion;  HTTP09  P6  isV1  isV2h3 hq-interoph3-hq-  getDraftVersion 55  java/lang/IntegerparseInt(Ljava/lang/String;)Ijava/lang/NumberFormatException/   java/nio/file/Paths;(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;java/nio/file/LinkOption  java/nio/file/Filesexists2(Ljava/nio/file/Path;[Ljava/nio/file/LinkOption;)Z   isWritable(Ljava/nio/file/Path;)Z    E(Ljava/nio/file/Path;)Lnet/luminis/quic/QuicClientConnection$Builder;   isReadable    readAllBytes(Ljava/nio/file/Path;)[B      "net/luminis/quic/QuicSessionTicket deserialize(([B)Lnet/luminis/quic/QuicSessionTicket;   sessionTicketU(Lnet/luminis/quic/QuicSessionTicket;)Lnet/luminis/quic/QuicClientConnection$Builder;(Error while reading session ticket file.%Using 0-RTT requires a session ticket  readCertificate8(Ljava/lang/String;)Ljava/security/cert/X509Certificate;  U(Ljava/security/cert/X509Certificate;)Lnet/luminis/quic/QuicClientConnection$Builder;   readKey.(Ljava/lang/String;)Ljava/security/PrivateKey; " #$clientCertificateKeyK(Ljava/security/PrivateKey;)Lnet/luminis/quic/QuicClientConnection$Builder;&java/lang/Exception( ))(Ljava/lang/Exception;)Ljava/lang/String;+JOptions --clientCertificate and --clientKey should always be used together - .2(I)Lnet/luminis/quic/QuicClientConnection$Builder; o0 1suseRelativeTime 3 .580-RTT is not yet supported by this HTTP3 implementation.7%net/luminis/quic/run/InteractiveShell 69 :n(Lnet/luminis/quic/QuicClientConnection$Builder;Ljava/lang/String;Lnet/luminis/quic/run/KwikCli$HttpVersion;)V 6< =start ? @Abuild-()Lnet/luminis/quic/QuicClientConnectionImpl; C DEcreateHttpClientn(Lnet/luminis/quic/run/KwikCli$HttpVersion;Lnet/luminis/quic/QuicClientConnection;Z)Ljava/net/http/HttpClient; G HIgetServerAddress()Ljava/net/InetSocketAddress; KLM Njava/net/http/HttpRequest%()Ljava/net/http/HttpRequest$Builder;Phttps RST Ujava/net/InetSocketAddress getHostName RW XgetPort %Z [p(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V ]^_ `!java/net/http/HttpRequest$Builder3(Ljava/net/URI;)Ljava/net/http/HttpRequest$Builder; ]b @c()Ljava/net/http/HttpRequest; Se f isDirectory Sh igetName Sk l'(Ljava/lang/String;Ljava/lang/String;)V Sn ogetAbsolutePath qrs tujava/time/Instantnow()Ljava/time/Instant; wxy z{'java/net/http/HttpResponse$BodyHandlersofFile>(Ljava/nio/file/Path;)Ljava/net/http/HttpResponse$BodyHandler; }~ java/net/http/HttpClientsenda(Ljava/net/http/HttpRequest;Ljava/net/http/HttpResponse$BodyHandler;)Ljava/net/http/HttpResponse;  toString  java/net/http/HttpResponsebody()Ljava/lang/Object;java/nio/file/Path  (Ljava/nio/file/Path;)J w ofString*()Ljava/net/http/HttpResponse$BodyHandler;  length  java/lang/Threadsleep(J)Vjava/lang/InterruptedException  java/time/DurationbetweenP(Ljava/time/temporal/Temporal;Ljava/time/temporal/Temporal;)Ljava/time/Duration;%.2f  toMillis()JDz  java/lang/FloatvalueOf(F)Ljava/lang/Float;  format9(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;1Get requested finished in %.2f sec (%s MB/s) : %sHTTP request is interruptedjava/lang/RuntimeException   connect[(ILjava/lang/String;Lnet/luminis/quic/TransportParameters;Ljava/util/List;)Ljava/util/List;  d  storeServerCertificates<(Lnet/luminis/quic/QuicClientConnection;Ljava/lang/String;)V  storeNewSessionTickets  closeTerminating Kwik )(Ljava/io/IOException;)Ljava/lang/String;*net/luminis/quic/VersionNegotiationFailure?Client and server could not agree on a compatible QUIC version.PThis was quick, huh? Next time, consider using --http09 or --keepAlive argument.  ofH(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;   getOptions"()[Lorg/apache/commons/cli/Option;  9java/util/Arrays.([Ljava/lang/Object;)Ljava/util/stream/Stream; test ()Ljava/util/function/Predicate; B filter9(Ljava/util/function/Predicate;)Ljava/util/stream/Stream; 0(Ljava/util/List;)Ljava/util/function/Predicate; B :distinct < toList()Ljava/util/stream/Collector;  iterator()Ljava/util/Iterator;  java/util/IteratorhasNext  next org/apache/commons/cli/Option    getLongOpt  equals(Ljava/lang/Object;)Z  (net/luminis/tls/TlsConstants$CipherSuiteTLS_AES_128_GCM_SHA256*Lnet/luminis/tls/TlsConstants$CipherSuite;   cipherSuite[(Lnet/luminis/tls/TlsConstants$CipherSuite;)Lnet/luminis/quic/QuicClientConnection$Builder;  TLS_AES_256_GCM_SHA384   TLS_CHACHA20_POLY1305_SHA256 "#$ %&java/lang/ClassgetClassLoader()Ljava/lang/ClassLoader;(-net.luminis.http3.Http3SingleConnectionClient *+, -.java/lang/ClassLoader loadClass%(Ljava/lang/String;)Ljava/lang/Class;0 java/lang/ClassNotFoundException2net/luminis/quic/QuicConnection4java/lang/Long "6 78getConstructor3([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;< > ?@ ofSeconds(J)Ljava/time/Duration; 3B C(J)Ljava/lang/Long; EFG HIjava/lang/reflect/Constructor newInstance'([Ljava/lang/Object;)Ljava/lang/Object;Kjava/lang/NoSuchMethodExceptionM java/lang/InstantiationExceptionO java/lang/IllegalAccessExceptionQ+java/lang/reflect/InvocationTargetException S T(Ljava/lang/Throwable;)VV(net/luminis/quic/client/h09/Http09Client UX Y+(Lnet/luminis/quic/QuicClientConnection;Z)V [\] ^_java/nio/charset/CharsetdefaultCharset()Ljava/nio/charset/Charset; a b([BLjava/nio/charset/Charset;)VdBEGIN PRIVATE KEY f g  loadRSAKeyiBEGIN EC PRIVATE KEYk"java/lang/IllegalArgumentExceptionm$EC private key must be in DER format j p qr loadECKey([B)Ljava/security/PrivateKey;t-----BEGIN PRIVATE KEY-----v x yzreplaceD(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String; | } lineSeparator  6 replaceAll-----END PRIVATE KEY-----  java/util/Base64getMimeDecoder()Ljava/util/Base64$Decoder;  java/util/Base64$Decoderdecode(Ljava/lang/String;)[BRSA  java/security/KeyFactory getInstance.(Ljava/lang/String;)Ljava/security/KeyFactory;&java/security/spec/PKCS8EncodedKeySpec  ([B)V  generatePrivate8(Ljava/security/spec/KeySpec;)Ljava/security/PrivateKey;&java/security/NoSuchAlgorithmExceptionMissing key algorithm RSA  ECMissing ECDSA supportX.509  %java/security/cert/CertificateFactory;(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;-----BEGIN CERTIFICATE----------END CERTIFICATE-----java/io/ByteArrayInputStream   getDecoder   generateCertificate7(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"java/security/cert/X509CertificateInvalid certificate file  getServerCertificateChain.pem  endsWithjava/io/FileOutputStream W  (Ljava/io/OutputStream;)V  getMimeEncoder()Ljava/util/Base64$Encoder;   getEncoded()[B  java/util/Base64$Encoderencode([B)[B   print/java/security/cert/CertificateEncodingException  Y  -----END CERTIFICATE-----   getNewSessionTickets *There are no new session tickets to store. accept1(Ljava/lang/String;)Ljava/util/function/Consumer; B forEach (Ljava/util/function/Consumer;)V S  '(Ljava/lang/String;I)Ljava/lang/String; S toPath()Ljava/nio/file/Path;    net/luminis/tls/NewSessionTicket serialize java/nio/file/OpenOption    java/nio/file/StandardOpenOptionCREATE"Ljava/nio/file/StandardOpenOption;  writeG(Ljava/nio/file/Path;[B[Ljava/nio/file/OpenOption;)Ljava/nio/file/Path;$org/apache/commons/cli/HelpFormatter   setWidthLkwik : OR kwik OR kwik http[s]://host:port[/path]  !" printHelp5(Ljava/lang/String;Lorg/apache/commons/cli/Options;)V $ %&storeNewSessionTicket7(Lnet/luminis/tls/NewSessionTicket;Ljava/lang/String;)V ( # * + hasLongOpt-wipCodeLineNumberTableLocalVariableTablethisLnet/luminis/quic/run/KwikCli;main([Ljava/lang/String;)VargError'Lorg/apache/commons/cli/ParseException;urlLjava/net/URL;e Ljava/net/MalformedURLException; invalidUriLjava/net/URISyntaxException;arg fileErrorLjava/io/IOException; logFilename!Ljava/lang/NumberFormatException; secretsFilesessionTicketFile ticketData[BLjava/lang/Exception; httpResponseLjava/net/http/HttpResponse;Ljava/time/Instant;doneJresponse httpClientLjava/net/http/HttpClient; serverAddressLjava/net/InetSocketAddress;requestLjava/net/http/HttpRequest;durationLjava/time/Duration;speedinterruptedException Ljava/lang/InterruptedException;quicConnection'Lnet/luminis/quic/QuicClientConnection;,Lnet/luminis/quic/VersionNegotiationFailure;rawArgs[Ljava/lang/String;parser*Lorg/apache/commons/cli/CommandLineParser;cmd$Lorg/apache/commons/cli/CommandLine;argsLjava/util/List;builder/Lnet/luminis/quic/QuicClientConnection$Builder;httpRequestPathserverCertificatesFileLnet/luminis/quic/log/Logger;logArg quicVersion httpVersionI keepAliveTime useZeroRtt outputFilenewSessionTicketsFilename$Lnet/luminis/quic/QuicSessionTicket;interactiveModeLocalVariableTypeTable2Ljava/net/http/HttpResponse;0Ljava/net/http/HttpResponse;$Ljava/util/List; StackMapTable\E Exceptions cipherOptionLorg/apache/commons/cli/Option; cipherOpts cipherOptions1Ljava/util/List;"Ljava/lang/ClassNotFoundException;http3ClientClassLjava/lang/Class; constructorLjava/lang/reflect/Constructor;maxReceiveBufferSize http3Client(Ljava/lang/ReflectiveOperationException;&java/lang/ReflectiveOperationExceptionkey*java/security/spec/InvalidKeySpecException keyFactoryLjava/security/KeyFactory;keySpec(Ljava/security/spec/PKCS8EncodedKeySpec;(Ljava/security/NoSuchAlgorithmException; privateKeyPEMencodedspecfactory privateKeyLjava/security/PrivateKey;pkcs8keyencodedCertificate certificate Ljava/security/cert/Certificate;certificateFile fileContentcertificateFactory'Ljava/security/cert/CertificateFactory;'java/security/cert/CertificateException1Ljava/security/cert/CertificateEncodingException;cert$Ljava/security/cert/X509Certificate;serverCertificateChain6Ljava/util/List; baseFilenameticket"Lnet/luminis/tls/NewSessionTicket;maxFilessavedSessionTicketLjava/io/File; helpFormatter&Lorg/apache/commons/cli/HelpFormatter;lambda$storeNewSessionTickets$29(Ljava/lang/String;Lnet/luminis/quic/QuicSessionTicket;)Vlambda$processCipherArgs$12(Ljava/util/List;Lorg/apache/commons/cli/Option;)Zoptionlambda$processCipherArgs$0"(Lorg/apache/commons/cli/Option;)Z SourceFile KwikCli.java NestMembersBootstrapMethods  $java/lang/invoke/StringConcatFactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;logging options: [pdrcsiRSD]: (p)ackets received/sent, (d)ecrypted bytes, (r)ecovery, (c)ongestion control, (s)tats, (i)nfo, (w)arning, (R)aw bytes, (S)ecrets, (D)ebug; default is "", use (n)one to disableInvalid argument: Kwik build nr: Cannot parse URL ''////:443Cannot parse URI ''//:Error: cannot open log file ''/ Output file '' is not writable.!Secrets file '' is not writable.(Session ticket file '' is not readable.(Loading client certificate/key failed: Server returns: Got IO error:   "java/lang/invoke/LambdaMetafactory metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;    .pem(Ljava/lang/Object;)V  '(Lnet/luminis/quic/QuicSessionTicket;)V.bin.binECannot store ticket: too many files with base name '' already exist.#Saving new session ticket failed:  InnerClassesBuilder HttpVersion BodyHandlers&java/net/http/HttpResponse$BodyHandler BodyHandler net/luminis/tls/TlsConstants CipherSuiteDecoderEncoder%java/lang/invoke/MethodHandles$Lookupjava/lang/invoke/MethodHandlesLookup!   ./*/:0 12 34.  ԻY W  "$W &(*W -/*W 13*W 57*W 9;*W =?*W AC*W EGW IKMW OQSW UWYW []_W aceW gikW moqW suwW y{}W W W W W W W W W W W W W W WYLM+ *MN-̺Ѹ,ޙƸ,N-ױ::--:@Y : W :e:ѱ!%Y'(W1)+.Ѹױ%Y0(W:3ѱh-P%Y--4(W3:-7;A3ѱ-ױ,GW,ޙ KW:,ޙ ,N::,gޙ/,gN:QYSYUV:: [^ _Ya:bW:,lf ,li:l!O! nt! vU! y|! ~y! ! [! ! ! ! : : ,Aޙ: : f,=ޙ : U,9ޙ : D,5ޙ : 3,1ޙ : ",-ޙ : ,&ޙ: ,Eޙ:  W W : : ,Iޙ,I:  PڧF ˚  Ι  ѧ:   է ٺ: 6 ,Uޙ,Uݶɸ6 :6,aޙ,aN6 :6,ޙ6,sޙ.,sN: ڧ : :,mޙJ,mN: #[,ޙ[,N: #[W:,yޙ,yN: :,Oޙl:,ON: [:::W:[[,ޙG,ޙ>,NW,N!W8:['ڧ",ޚ ,ޙ[*,ޙ ,N߹,W :,ޙ /,[6,ޙ ,N߹2W : 46Y  8;>:` B:F:J%YOQVY\a:dSYUdSYSYUgjm:p:v|::p:7Pp:|:p:7:::YnnS:YnSYSYSѧM:ѧ?:Y h W`h:  и:Ҷѧ :ѧ:ٶ ۶ѱMwz7111$'1Y Y%=NQ|     ,1 V c f  Y /8E FI,J7KBLMMXNcOnPyQRSTUVWXYZ[\ ]-^;_H`Uabboc|defghjkmsopqruvwz {|}!+7MXepwz|$')HISVW^gor{%-8@JR]eow #,1:?I S d gpy~!%"#$()+0 - ./34 5#7,8499:<;C>N?WDaEdFhIkJtK|LMNPQRVWXYZ\]^ `cd(e0f5g8h<l?mHnKoSpXq[r_tnu{vxz{|}~'04=NQSVZcks|    ) C H ] d i x {              ) , . 6 H M V c h m t y               0<956X78|9:;<7=) ;< >? $@9A 9APB 9?KfC-DE9FS9A9A ]GH H3=I iJI xK dL <GH7MN.OP QR =I JI zK sL JST *U VW .9<XY 9? 9Z [\ ]^ _` abcd!erbfNdghi  dpj gmL Xk lkmkino?psaqr  ]Gs <Gt auvcw3)B#B1t1! ( woY ! B% B B wowo22" &wo xY v% \$wo wwo }RK75wo }RKqqUwo M1 o OKYQ y IJ.fM*,AN-:W:  +W  +W  +W+/> !&+7Ubly !#%04UEz{_`cd |b7h}br |u7h}~v?, .[ !')WK //* +-.0 9vN/DE.G r*d !')N-"Y1SYSY3S5:97;=:Y+SYSYASD}:NY-RUY+W]^/]^J]^L]^N]^P/* 467/:4;<<[=^?_@hD0\ K//4*K<"XT[N_ 9rjrXYrmv ^  .IY*Z`L+c!+e+h!jYln*o/IK L%N/O:S0I3v %yY g .I*suw{u~uwL+MNY,:-NY%<=/* XY Z[\%_,`6a=b>c0>,6> 9I,%$Ev=xy qr.$Y*LM,+N-LY/i jklmn04  9$EvXy .iY*Z`LM+:+uw{u~uwN,Y-:jYn/* suv'w.x1y@zD{X|^04DXiSLv ^yY .w*M+Ŷǚ +LYYSY+UͷN,:O:--Yնٷ߶:YY--ѧ-Tjm/>/MTjmo|0>o 9M=XYfb/cr v15yY .F*$M* *7+/"&/E0FXYFvW %&."sd=SY+UN6 -SY+UN+ѱ-* Y SW:[ѱJ`cY/:!17=IJ`cer0>e 9?sspkb_\kvS"XY .OYK*O* /0  .:+*#/0p .? *+ '/0 |b { ./*)/0 {.,/=J   @]K w    @