Ceph RGW unable to upload object if JaegerTracing is implemented - jaeger

OS : ubuntu 18.04
ceph : octopus
jaeger : master
When I implement jaegertracer in the function that is responsibe for writing file to ceph via RGW, I am unable to upload my file Im getting this error
Warning: failed to create container 'mycontainer': HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: /auth (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f5076b7a990>: Failed to establish a new connection: [Errno 111] Connection refused',))
But when I remove my tracer from the code it uploads the file successfully
source code
void librados::IoCtxImpl::queue_aio_write(AioCompletionImpl *c)
{
auto yaml = YAML::LoadFile("tracerConfig.yaml");
auto config = jaegertracing::Config::parse(yaml);
auto tracer=jaegertracing::Tracer::make(
"Writing",
config,
jaegertracing::logging::consoleLogger()
);
opentracing::Tracer::InitGlobal(
static_pointer_cast<opentracing::Tracer>(tracer)
);
auto span = opentracing::Tracer::Global()->StartSpan("Span1");
get();
ofstream file;
file.open("/home/abhinav/Desktop/write.txt",std::ios::out | std::ios::app);
file<<"Writing /src/librados/IoCtxImpl.cc 288.\n";
file.close();
std::scoped_lock l{aio_write_list_lock};
ceph_assert(c->io == this);
c->aio_write_seq = ++aio_write_seq;
ldout(client->cct, 20) << "queue_aio_write " << this << " completion " << c
<< " write_seq " << aio_write_seq << dendl;
aio_write_list.push_back(&c->aio_write_list_item);
opentracing::Tracer::Global()->Close();
}
When I remove the tracer it compiles fine again

The issue was related to yaml file parsing

Related

Unexpected server response (0) while retrieving pdf

We are specifically getting this error when using Amazon ec2 instance. Configuration on aws instance is Tomcat 7, Ubuntu 16.04 and memory is 8gb. It occurs when the user tries to view pdf file. In our application, we are having one functionality where the user can only view PDF file onto browser, but won't be able to download it. PDF file is on the same server. We are using cors minimal configuration. We have tried it locally with Ubuntu and it is working fine.
Code snippet:
var fileSplitContent = fileName.split(".");
if ($('#viewImageOnlyForm')[0] != undefined && $('#viewPdfOnlyForm')[0] != undefined) {
if (fileSplitContent[fileSplitContent.length - 1].toLowerCase() != "pdf") {
$('#imageSource').val(requestURL + $.param(inputData));
$('#viewImageOnlyForm').submit();
} else {
var requestURL = "rest/file/getCapitalRaiseFile?";
$('#pdFSource').val(requestURL + $.param(inputData));
$('#viewPdfOnlyForm').submit();
}
} else {
// pop up download attachment dialog box
downloadIFrame.attr("src", requestURL + $.param(inputData));
}
}
Jan 04, 2017 5:07:31 AM org.glassfish.jersey.server.ServerRuntime$Responder writeResponse
SEVERE: An I/O error has occurred while writing a response message entity to the container output stream.
org.glassfish.jersey.server.internal.process.MappableException: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Connection reset
Caused by: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Broken pipe (Write failed)
Depending where you access the document this can be because of you have a download manager installed on your browser. This sometimes causes problems - maybe take a look at your extensions. You should try by disabling downloader manager extension in your browser.

Server Sent Event connection not staying open with Apache/Thin/Sinatra

I'm trying to setup basic server side event ability using Apache/Thin/Sinatra. Everything works as exepcted when I run the Thin server directly. When I run the Thin server through Apache using the RackBaseURI config setting, everything still works, but the connection is not persisted. It goes through a cycle of opening, writing some data to the browser and immediately closing. Seems like an Apache configuration issue?
I've gone through the Apache config and don't see anything that seems like it would prevent an open connection. Because I'm not sure where the error is, I don't want to post endless configuration data, so I can include more if I'm missing something...
sinatra (1.3.4),
thin (1.5.0),
Apache/2.2.22 (Ubuntu),
ruby 1.8.7
The JavaScript...
$j(function(){
console.log("Starting...");
var es = new EventSource("/stream_event");
es.addEventListener('message', function(e) {
console.log(e.data);
}, false);
es.addEventListener('open', function(e) {
console.log("Connection Open");
}, false);
es.addEventListener('error', function(e) {
console.log("error = " + e.eventPhase)
if (e.eventPhase == EventSource.CLOSED) {
console.log("Connection Closed");
}
}, false);
}
The server side sinatra/ruby..
set :server, :thin
connections = []
get '/' do
content_type 'text/event-stream'
stream(:keep_open) { |out|
connections << out
out << "data: hello\n\n"
}
end
get '/post_message' do
connections.each { |out| out << params[:message] << "\n" }
"message sent"
end
EDIT:
And here's the output I see in the browser console ...
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Seems to be something related to the RackBaseURI configuration setting. I was able to get things working by removing that attribute and directing the traffic to my Sinatra app using Apache's proxy abilities...
ProxyPass /stream_event http://127.0.0.1:9292
ProxyPassReverse /stream_event http://127.0.0.1:9292
The primary disadvantage here is that I need to startup and monitor the running Sinatra app manually using some other process.

NTLM authentication in axis2 client return error 401

I am using axis2 to create client code and access the wcf webservice with NTLM authentication. My client code is
Service1Stub stub = new Service1Stub();
Options options = stub._getServiceClient().getOptions();
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername("administrator");
auth.setPassword("passwrd");
auth.setHost("172.16.12.25");
auth.setDomain("MY-PC");
List<String> authSchemes = new ArrayList<String>();
authSchemes.add(HttpTransportProperties.Authenticator.NTLM);
auth.setAuthSchemes(authSchemes);
options.setProperty(HTTPConstants.AUTHENTICATE, auth);
options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE);
stub._getServiceClient().setOptions(options);
when I run my client code it returns the following error
org.apache.axis2.AxisFault: Transport error: 401 Error: Unauthorized
at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:310)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:194)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.tempuri.Service1Stub.welcomeData(Service1Stub.java:473)
at ws.client.Client.myservice(Client.java:159)
at ws.client.Client.main(Client.java:50)
my header log is
>> "POST /Service1/Service1.svc HTTP/1.1[\r][\n]"
>> "Content-Type: text/xml; charset=UTF-8[\r][\n]"
>> "SOAPAction: "http://tempuri.org/IService1/WelcomeData"[\r][\n]"
>> "User-Agent: Axis2[\r][\n]"
>> "Content-Length: 278[\r][\n]"
>> "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGMAAAAAAAAAewAAAAkACQBAAAAADQANAEkAAAANAA0AVgAAAAAAAAB7AAAABlIAAFZJTk9USC1QQ0FETUlOSVNUUkFUT1IxNzIuMTYuMTIuMjQ11kmkEIwyUVitHBvTPwhExpcylZ9vkdwd[\r][\n]"
>> "Host: 172.16.12.25[\r][\n]"
>> "[\r][\n]"
>> "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:WelcomeData xmlns:ns1="http://tempuri.org/"><ns1:helloservice>Hello Servie</ns1:helloservice></ns1:WelcomeData></soapenv:Body></soapenv:Envelope>"
<< "HTTP/1.1 401 Unauthorized[\r][\n]"
<< "HTTP/1.1 401 Unauthorized[\r][\n]"
<< "Content-Type: text/html[\r][\n]"
<< "Server: Microsoft-IIS/7.5[\r][\n]"
<< "WWW-Authenticate: NTLM[\r][\n]"
<< "X-Powered-By: ASP.NET[\r][\n]"
<< "Date: Thu, 10 May 2012 19:30:20 GMT[\r][\n]"
<< "Content-Length: 1293[\r][\n]"
<< "[\r][\n]"
<< "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[\r][\n]"
<< "<html xmlns="http://www.w3.org/1999/xhtml">[\r][\n]"
<< "<head>[\r][\n]"
<< "<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>[\r][\n]"
<< "<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>[\r][\n]"
<< "<style type="text/css">[\r][\n]"
<< "<!--[\r][\n]"
<< "body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}[\r][\n]"
<< "fieldset{padding:0 15px 10px 15px;} [\r][\n]"
<< "h1{font-size:2.4em;margin:0;color:#FFF;}[\r][\n]"
<< "h2{font-size:1.7em;margin:0;color:#CC0000;} [\r][\n]"
<< "h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} [\r][\n]"
<< "#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;[\r][\n]"
<< "background-color:#555555;}[\r][\n]"
<< "#content{margin:0 0 0 2%;position:relative;}[\r][\n]"
<< ".content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}[\r][\n]"
<< "-->[\r][\n]"
<< "</style>[\r][\n]"
<< "</head>[\r][\n]"
<< "<body>[\r][\n]"
<< "<div id="header"><h1>Server Error</h1></div>[\r][\n]"
<< "<div id="content">[\r][\n]"
<< " <div cla"
<< "ss="content-container"><fieldset>[\r][\n]"
<< " <h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>[\r][\n]"
<< " <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>[\r][\n]"
<< " </fieldset></div>[\r][\n]"
<< "</div>[\r][\n]"
<< "</body>[\r][\n]"
<< "</html>[\r][\n]
I don't know where I made mistake.
As far as I know, the standard release of Axis2 1.6 still uses HTTPClient 3.1 and thus NTLMv1, which most Windows servers have disabled by default. Changing this requires either patching Axis2 or changing the registry settings on the server.
Here's a link to the development thread with a patch as recent as 25-05-2012:
https://issues.apache.org/jira/browse/AXIS2-4318
Not sure if you have figured out a way to access WCF via NTLM authentication.. but this is what I did to fix this issue..
HttpClient doesnt support NTLM v2 hence I use JCIFS library to return NTLM v1,2,3 message type as described in this website
http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html
I just used the JCIFS_NTLMScheme.java file from the above website to register the auth scheme and it worked !!!!
Sample client:
List authSchema = new ArrayList();
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, org.tempuri.JCIFS_NTLMScheme.class);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername("");
auth.setPassword("");
auth.setDomain("");
auth.setHost("");
auth.setPort();
List authPrefs = new ArrayList(1);
authPrefs.add(AuthPolicy.NTLM);
auth.setAuthSchemes(authPrefs);
stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
As #WLPhoenix pointed out, Axis2 uses the old Apache Commons HTTP, which only supports an old, reverse-engineered NTLM implementation. In the new Apache HTTPComponents 4.2.3, support was added for the new, openly-documented NTLM standard, which works with newer versions of Windows Server and IIS (source).
Here is a way to backport the new Apache HTTPComponents 4 NTLMScheme for use in Axis2 using a custom Apache Commons HTTP AuthScheme.
public class BackportedNTLMScheme extends org.apache.http.impl.auth.NTLMScheme implements org.apache.commons.httpclient.auth.AuthScheme {
#Override
public String authenticate(final Credentials credentials, final HttpMethod method) throws AuthenticationException {
org.apache.commons.httpclient.NTCredentials oldCredentials;
try {
oldCredentials = (org.apache.commons.httpclient.NTCredentials) credentials;
} catch (final ClassCastException e) {
throw new InvalidCredentialsException(
"Credentials cannot be used for NTLM authentication: "
+ credentials.getClass().getName());
}
final org.apache.http.auth.Credentials adaptedCredentials = new NTCredentials(oldCredentials.getUserName(), oldCredentials.getPassword(), oldCredentials.getHost(), oldCredentials.getDomain());
try {
final Header header = super.authenticate(adaptedCredentials, null);
return header.getValue();
} catch (final org.apache.http.auth.AuthenticationException e) {
throw new AuthenticationException("AuthenticationException", e);
}
}
#Override
public void processChallenge(final String challenge) throws MalformedChallengeException {
final String s = AuthChallengeParser.extractScheme(challenge);
if (!s.equalsIgnoreCase(getSchemeName())) {
throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
}
int challengeIdx = challenge.indexOf(' ');
final CharArrayBuffer challengeBuffer;
if(challengeIdx != -1){
challengeBuffer = new CharArrayBuffer(challenge.length());
challengeBuffer.append(challenge);
} else {
challengeBuffer = new CharArrayBuffer(0);
challengeIdx = 0;
}
try {
parseChallenge(challengeBuffer, challengeIdx, challengeBuffer.length());
} catch (final org.apache.http.auth.MalformedChallengeException e) {
throw new MalformedChallengeException("MalformedChallengeException", e);
}
}
#Override
#Deprecated
public String getID() {
throw new RuntimeException("deprecated BackportedNTLMScheme.getID()");
}
#Override
#Deprecated
public String authenticate(final Credentials credentials, final String method, final String uri) throws AuthenticationException {
throw new RuntimeException("deprecated BackportedNTLMScheme.authenticate(Credentials, String, String)");
}
}
Usage
// given a stubbed AXIS SOAP client called MyAxisClient:
MyAxisClientStub myAxisClient = new MyAxisClientStub();
ServiceClient serviceClient = myAxisClient._getServiceClient();
// use new NTLM
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, BackportedNTLMScheme.class);
Authenticator authenticator = new Authenticator();
authenticator.setAuthSchemes(Arrays.asList(AuthPolicy.NTLM));
authenticator.setDomain("my-auth-domain");
authenticator.setHost("my-auth-host");
authenticator.setUsername("my-username");
authenticator.setPassword("my-password");
serviceClient.getOptions().setProperty(HTTPConstants.AUTHENTICATE, authenticator);
//call MyAxisClient methods
I tested this on IIS 7.5 on Windows Server 2008 R2.
I could not get this to work until a coworker found this which fixed 401 Unauthorized.
import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.NTCredentials;
final NTCredentials credentials = new NTCredentials(username, password, host, domain);
final CredentialsProvider myCredentialsProvider = new CredentialsProvider() {
public Credentials getCredentials(final AuthScheme scheme, final String host, int port, boolean proxy) throws CredentialsNotAvailableException {
return credentials;
}
};
DefaultHttpParams.getDefaultParams().setParameter("http.authentication.credential-provider", myCredentialsProvider);

Which PEM file should I provide when uploading to S3 using HTTP PUT

I'm trying to put a file in S3 using a presigned signature my Java web server provides
http://docs.amazonwebservices.com/AmazonS3/latest/dev/PresignedUrlUploadObjectDotNetSDK.html
I need my uploading client (currently my windows 7 using C++) to have a handshake with amazon servers and I don't know how to do it.
When I tried to send the request with a "default context" (naively) it printed a "self signed certificate in certificate chain" error and asked me to accept or not the certificate.
Then I tried to figure out how to add a certificate and found this code:
POCO C++ - NET SSL - how to POST HTTPS request
The problem is that I'm not sure which pem file is needed here.
I tried providing the pem files I've downloaded from x.509 in Amazon Web Services Console but it raised an SSL exception: SSL3_GET_SERVER_CERTIFICATE
My Code:
URI uri("https://BUCKET.s3.amazonaws.com/nosigfile?Expires=1959682330&AWSAccessKeyId=ACCESSKEY&Signature=DgOifWPmQi%2BASAIDaIOGXla10%2Fw%3D");
const Poco::Net::Context::Ptr context( new Poco::Net::Context( Poco::Net::Context::CLIENT_USE, "", "", "cert(x509).pem") );
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context );
HTTPRequest req(HTTPRequest::HTTP_PUT, uri.getPathAndQuery(), HTTPMessage::HTTP_1_1);
req.setContentLength(contentLength);
session.sendRequest(req) << streamToSend;
Thanks
Poco includes certificates in the project.
You will need any.pem, rootcert.pem, yourappname.xml which you can find in the poco test suite for the SSL side.
./poco-1.4.1p1-all/NetSSL_OpenSSL/testsuite/{any.pem,rootcert.pem,testsuite.xml}
Once you include the two pem files, your xml, which is used during the initializeSSL phase you will not get the warning for self-signed certificates.
class MySSLApp: public Poco::Util::Application
{
public:
MySSLApp()
{
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
}
~MySSLApp()
{
Poco::Net::uninitializeSSL();
}
protected:
void initialize(Poco::Util::Application& self)
{
loadConfiguration(); // load default configuration files, if present
Poco::Util::Application::initialize(self);
}
void myUpload(...) {
...
FilePartSource* pFPS = new FilePartSource(szFilename);
std::string szHost = "BUCKET.s3.amazonaws.com";
std::string szPath = "/";
int nRespCode = 201;
try{
HTTPClientSession s(szHost);
HTTPRequest request(HTTPRequest::HTTP_POST, szPath, HTTPMessage::HTTP_1_1);
HTMLForm pocoForm(HTMLForm::ENCODING_MULTIPART);
pocoForm.set("AWSAccessKeyId", ACCESSKEY);
pocoForm.set("acl", "public-read");
pocoForm.set("success_action_status", toString(nRespCode));
pocoForm.set("Content-Type", m_szContentType);
pocoForm.set("key", m_szPath + "/" + m_szDestFileName);
pocoForm.set("policy", m_szPolicy);
pocoForm.set("signature", m_szSignature);
pocoForm.addPart("file", pFPS);
pocoForm.prepareSubmit(request);
std::ostringstream oszMessage;
pocoForm.write(oszMessage);
std::string szMessage = oszMessage.str();
//AWS requires a ContentLength set EVEN though it is chunked!
request.setContentLength((int) szMessage.length());
s.sendRequest(request) << szMessage;
//or:
//pocoForm.write(s.sendRequest(request));
HTTPResponse response;
std::istream& rs = s.receiveResponse(response);
int code = response.getStatus();
if (code != nRespCode) {
stringstream s;
s << "HTTP Error " << code;
throw Poco::IOException(s.str());
}
} catch (Exception& exc) {
std::cout << exc.displayText() << endl;
return;
}
return;
}
}
The xml file will look something like this:
<AppConfig>
<openSSL>
<server>
<privateKeyFile>${application.configDir}any.pem</privateKeyFile>
<caConfig>${application.configDir}rootcert.pem</caConfig>
<verificationMode>none</verificationMode>
<verificationDepth>9</verificationDepth>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cypherList>ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH</cypherList>
<privateKeyPassphraseHandler>
<name>KeyFileHandler</name>
<options>
<password>secret</password>
</options>
</privateKeyPassphraseHandler>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
<options>
</options>
</invalidCertificateHandler>
</server>
<client>
<privateKeyFile>${application.configDir}any.pem</privateKeyFile>
<caConfig>${application.configDir}rootcert.pem</caConfig>
<verificationMode>relaxed</verificationMode>
<verificationDepth>9</verificationDepth>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cypherList>ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH</cypherList>
<privateKeyPassphraseHandler>
<name>KeyFileHandler</name>
<options>
<password>secret</password>
</options>
</privateKeyPassphraseHandler>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
<options>
</options>
</invalidCertificateHandler>
</client>
</openSSL>
</AppConfig>

problem in making custom root certificate store for SSL using QT?

I am developing my custom browser in Qt using QWebView and
I am trying to make my own root cert store of trusted certificates which are taken from mozilla project.
I have used QSslSocket::setDefaultCaCertificates() to override the default certificates.
But I am not able to load https://www.gmail.com , where as in mozilla it works.
I have set all required root certs for gmail to my store.
can anyone guide me ?
The reason you can't connect is because the SSL certificate (with serial 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A) presented to you when you connect to www.gmail.com is issued for a different domain - www.google.com. This has nothing to do with root CA certificate store because no root CA certificate is needed to compare cert's Subject CN field with the host you are trying to connect to. You can ignore this and other SSL errors by calling
void QNetworkReply::ignoreSslErrors () [virtual slot]
To avoid this error you can connect directly to https://mail.google.com which is the domain you are being redirected to when you try to connect to https://www.gmail.com
Below is a working example which will show you the exact SSL errors and QNAM level errors. Either line B1 or line B2 must be active at the same time. You can comment line A if you want to see what happens with the default (system) root CA certificate store. There are two certs used by this code; CA's cert with serial 30:00:00:02 should be placed in a file called ThawteSGCCA.crt and CA's cert with serial 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF should be placed in a file called BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt.
#include <QtGui/QApplication>
#include <QtCore/QDebug>
#include <QtCore/QList>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslSocket>
#include <QtNetwork/QSslError>
#include <QtWebKit/QWebFrame>
#include <QtWebKit/QWebPage>
class Handler : public QObject{
Q_OBJECT
public slots:
void slotLoadFinished(bool ok) {
if (ok) {
qDebug() << "Page size: " << static_cast<QWebPage*>(sender())->mainFrame()->toHtml().size();
}
}
void slotFinished(QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "connected to " << reply->url();
qDebug() << "HTTP status: " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
} else {
qDebug() << "error while connecting to " << reply->url();
qDebug() << "error code: " << reply->error();
qDebug() << "error string: " << reply->errorString();
}
}
void slotSslErrors(QNetworkReply * reply, QList<QSslError> const & errors) {
qDebug() << "SSL errors: " << errors;
qDebug() << "peer's certificate: "
<< reply->sslConfiguration().peerCertificate();
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Handler handler;
// CA certs for:
// 1. cert with Subject.CN == mail.google.com cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12
// 2. cert with Subject.CN == www.google.com cert with serial 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A
QList<QSslCertificate> CAcerts =
// serial 30:00:00:02
QSslCertificate::fromPath("ThawteSGCCA.crt") +
// serial 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF
QSslCertificate::fromPath("BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt");
qDebug() << "root CA certificates:\n"
<< CAcerts
<< "\n";
QSslSocket::setDefaultCaCertificates(CAcerts); // line A
QWebPage page;
// OK because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is for host mail.google.com
// page.mainFrame()->load(QUrl("https://mail.google.com")); // line B1
// SSL ERROR "The host name did not match any of the valid hosts for this certificate"
// because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is NOT for www.gmail.com
page.mainFrame()->load(QUrl("https://www.gmail.com")); // line B2
QObject::connect(page.networkAccessManager(), SIGNAL(finished(QNetworkReply*)), &handler, SLOT(slotFinished(QNetworkReply*)));
QObject::connect(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), &handler, SLOT(slotSslErrors(QNetworkReply*,QList<QSslError>)));
QObject::connect(&page, SIGNAL(loadFinished(bool)), &handler, SLOT(slotLoadFinished(bool)));
return app.exec();
}
#include "main.moc"