Does Quarkus stream files on the go when doing multipart fileupload or does it keep a copy of the file in memory before sending it upstream? - file-upload

I need a help in understanding and getting clarity with regards to multipart file upload in Quarkus (v 2.11.3.Final)
In our project, we are using mutipart file upload and the request form looks like the following:
import org.jboss.resteasy.annotations.providers.multipart.PartType;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.ws.rs.FormParam;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;
public class MultipartBody {
#NotNull(message = "DOCUMENT_METADATA_MISSING")
#FormParam("documentRequest")
#PartType(MediaType.APPLICATION_JSON)
#Valid
public DocumentForm document;
#NotNull(message = "DOCUMENT_CONTENT_MISSING")
#FormParam("content")
#PartType(MediaType.WILDCARD)
public InputStream file;
}
And then this stream is transferred to an upstream system using rest client like below
#Path("")
#RegisterRestClient
#Produces(MediaType.APPLICATION_JSON)
#RegisterProvider(LoggingFilter.class)
#ApplicationScoped
#Retry(maxDuration = 180000, delay = 100)
public interface IngestionClient {
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
#Path("/upload/{batchId}/0")
#POST
UploadResponse uploadDocument(
#HeaderParam("X-File-Name") String documentName,
#HeaderParam("X-File-Type") String documentMimeType, #PathParam("batchId") String batchId,
InputStream content);
}
Following is the configuration done in the properties file
quarkus.http.limits.max-body-size=2048M
quarkus.http.body.preallocate-body-buffer=false
quarkus.http.body.merge-form-attributes=false
quarkus.http.body.handle-file-uploads=false
quarkus.http.limits.max-chunk-size=10M
In between the file is copied over to BufferedInputStream to detect the mime type before the transfer using the rest client is done. When I check the logs in debug mode, following is the sample observed.
2022-09-01 16:29:54,665 DEBUG [org.apa.htt.imp.con.PoolingHttpClientConnectionManager] (executor-thread-0) Connection request: [route: {}->http://127.0.0.2:8111][total available: 0; route allocated: 0 of 50; total allocated: 0 of 50]
2022-09-01 16:29:54,666 DEBUG [org.apa.htt.imp.con.PoolingHttpClientConnectionManager] (executor-thread-0) Connection leased: [id: 23][route: {}->http://127.0.0.2:8111][total available: 0; route allocated: 1 of 50; total allocated: 1 of 50]
2022-09-01 16:29:54,666 DEBUG [org.apa.htt.imp.exe.MainClientExec] (executor-thread-0) Opening connection {}->http://localhost:8080
2022-09-01 16:29:54,673 DEBUG [org.apa.htt.imp.con.DefaultHttpClientConnectionOperator] (executor-thread-0) Connecting to localhost/127.0.0.2:8111
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.imp.con.DefaultHttpClientConnectionOperator] (executor-thread-0) Connection established
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.imp.con.DefaultManagedHttpClientConnection] (executor-thread-0) http-outgoing-23: set socket timeout to 180000
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.imp.exe.MainClientExec] (executor-thread-0) Executing request POST /upload/000000-00000/0 HTTP/1.1
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.imp.exe.MainClientExec] (executor-thread-0) Target auth state: UNCHALLENGED
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.imp.exe.MainClientExec] (executor-thread-0) Proxy auth state: UNCHALLENGED
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> POST /upload/000000--00000/0 HTTP/1.1
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> Accept: application/json
2022-09-01 16:29:54,674 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> Content-Type: application/octet-stream
2022-09-01 16:29:54,675 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> Content-Length: 44591990
2022-09-01 16:29:54,675 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> Host: 127.0.0.2:8111
2022-09-01 16:29:54,675 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> Connection: Keep-Alive
2022-09-01 16:29:54,676 DEBUG [org.apa.htt.headers] (executor-thread-0) http-outgoing-23 >> User-Agent: Apache-HttpClient/4.5.13 (Java/11.0.16)
2022-09-01 16:29:54,688 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "POST /upload/000000-00000/0 HTTP/1.1[\r][\n]"
2022-09-01 16:29:54,688 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "Accept: application/json[\r][\n]"
2022-09-01 16:29:54,688 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "Content-Type: application/octet-stream[\r][\n]"
2022-09-01 16:29:54,689 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "Content-Length: 44591990[\r][\n]"
2022-09-01 16:29:54,689 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "Host: 127.0.0.2:8111[\r][\n]"
2022-09-01 16:29:54,689 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "Connection: Keep-Alive[\r][\n]"
2022-09-01 16:29:54,689 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "User-Agent: Apache-HttpClient/4.5.13 (Java/11.0.16)[\r][\n]"
2022-09-01 16:29:54,690 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "[\r][\n]"
2022-09-01 16:29:54,690 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "%PDF-1.7[\n]"
2022-09-01 16:29:54,690 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "%[0xe2][0xe3][0xcf][0xd3][\n]"
2022-09-01 16:29:54,690 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "2 0 obj[\n]"
2022-09-01 16:29:54,690 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "<</Length 99110/Filter/FlateDecode>>[\n]"
2022-09-01 16:29:54,691 DEBUG [org.apa.htt.wire] (executor-thread-0) http-outgoing-23 >> "stream[\n]"
The interesting part in the request being sent is the content-length. Now my question is that if Quarkus does not store the file locally based on the above configuration then how is it able to measure the content length upfront before starting the upload to upstream.
One additional aspect of the test performed is that this was tried using postman where the content length is automatically calculated at the time of performing the upload and the file size was 40MB approx. Any direction with regards to this question will help. Do I need to implement something differently?
The reason for asking the question is that we have a gateway behind which the application resides and this gateway has a limitation on the time within which the application has to respond back otherwise the connection is closed. So far the assumption was that the file is being streamed but on doing this investigation my curiosity arose...

Related

AWS SDK for Java V2: PutObject corrupts uploaded file when checksumAlgorithm is specified

I'm trying to use the AWS SDK for Java v2 to upload a file to S3 and have the upload integrity checked using the SHA256 trailing checksum. My code works fine to upload the file if the checksumAlgorithm(ChecksumAlorithm.SHA256) property of PutObjectRequest is not present but when it is included the uploaded file has additional characters at its start and is truncated at the end.
Here's the code I'm using:
byte[] smallJsonBytes = getObjectFile("UploadTest\\smallFile.txt");
PutObjectRequest putOb = PutObjectRequest.builder()
.bucket(credsProvider.getS3Bucketname())
.key(s3Key)
**.checksumAlgorithm(ChecksumAlgorithm.SHA256)**
.build();
PutObjectResponse response = this.myS3Client.putObject(putOb, RequestBody.fromBytes(smallJsonBytes));
Below is the debug output when the checksumAlgorithm property is included. You can see the AWS SDK is generating a trailing checksum as expected but, as noted already, the uploaded file is corrupted: You can see the insertion of the string "14" in the debug output and this string appears at the beginning of the uploaded file. Additionally, the uploaded file is truncated.
Clearly from the debug output there is a problem with the evaluation of the file's content length.
I've tried specifying the contentLength directly on the PutObjectRequest (as per documentation - .contentLength(long length)), and also tried converting smallJsonBytes to a ByteArrayInputStream and specifying the contentLength in the RequestBody.fromInputStream, both with the same result.
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "x-amz-content-sha256: STREAMING-UNSIGNED-PAYLOAD-TRAILER[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "X-Amz-Date: 20230216T215655Z[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "x-amz-decoded-content-length: 20[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "x-amz-sdk-checksum-algorithm: SHA256[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "x-amz-trailer: x-amz-checksum-sha256[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 99[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
14:56:56.150 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
14:56:56.206 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 100 Continue[\r][\n]"
14:56:56.206 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
14:56:56.211 [main] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 100 Continue
14:56:56.211 [main] DEBUG software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream - Specified InputStream length of 20 has been reached. Returning EOF.
14:56:56.213 [main] DEBUG software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream - Specified InputStream length of 20 has been reached. Returning EOF.
14:56:56.216 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "14[\r][\n]"
14:56:56.217 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Nothing much in here[\r][\n]"
14:56:56.217 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "0[\r][\n]"
14:56:56.217 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "x-amz-checksum-sha256:BthkalBn8SFAnEAFIWr2vtfO0h+TEdX/vOH+iZqKJ4k=[\r][\n]"
14:56:56.217 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
14:56:56.389 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"

Forming a JSON post request with Boost asio

I don't usually get this low level, so I think I'm just missing something obvious with the header.
Here's the code:
request_stream << "POST / HTTP/1.1\r\n"
"Host: localhost:5000 \r\n"
"Accept: */*\r\n"
"Content-Type: application/json\r\n";
request_stream << "Content-Length: " << json.length() << "\r\n\r\n";
request_stream << json;
The resulting string is
POST / HTTP/1.1
Host: localhost:5000
Accept: */*
Content-Type: application/json
Content-Length: 34
{'key1':'value1', 'key2':'value2'}
I then send the request_stream string to the server. I can connect to the server, but it says "bad request". I'm guessing there's something wrong with the above string. Any ideas?
Thanks.
Turns out that the request was fine. The issue was the simple Flask server I set up. I was calling
print(request.get_json())
when I should've have been calling
print(request.form.get('data'))

javapns sends notification but i receive anything

I can send notification without any error but I don't get anything on my device. I tried a lot of solutions and I don't know what else I can do.
The certificat and token works in PHP...
Configuration : Java 1.8, Tomcat 7, Javapns 2.2
Thanks
Code
BasicConfigurator.configure();
URL res = getClass().getClassLoader().getResource("KeyNotification/certificat.p12");
File f = new File(res.getFile());
List<PushedNotification> notifications = Push.combined("message", 10, "", f.getAbsolutePath(), "password", false, token);
for (PushedNotification notification : notifications) {
if (notification.isSuccessful()) {
System.out.println("Push notification sent successfully to: " + notification.getDevice().getToken());
} else {
String invalidToken = notification.getDevice().getToken();
Exception theProblem = notification.getException();
theProblem.printStackTrace();
/* If the problem was an error-response packet returned by Apple, get it */
ResponsePacket theErrorResponse = notification.getResponse();
if (theErrorResponse != null) {
System.out.println(theErrorResponse.getMessage());
}
}
}
Log
0 [http-bio-8080-exec-21] DEBUG javapns.communication.ConnectionToAppleServer - Creating SSLSocketFactory
3 [http-bio-8080-exec-21] DEBUG javapns.communication.ConnectionToAppleServer - Creating SSLSocket to feedback.sandbox.push.apple.com:2196
1189 [http-bio-8080-exec-21] DEBUG javapns.feedback.FeedbackServiceManager - Found: [0]
1194 [http-bio-8080-exec-21] DEBUG javapns.notification.Payload - Adding alert [message]
1194 [http-bio-8080-exec-21] DEBUG javapns.notification.Payload - Adding badge [10]
1194 [http-bio-8080-exec-21] DEBUG javapns.notification.Payload - Adding sound []
1199 [http-bio-8080-exec-21] DEBUG javapns.communication.ConnectionToAppleServer - Creating SSLSocketFactory
1201 [http-bio-8080-exec-21] DEBUG javapns.communication.ConnectionToAppleServer - Creating SSLSocket to gateway.sandbox.push.apple.com:2195
1444 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Initialized Connection to Host: [gateway.sandbox.push.apple.com] Port: [2195]: 1e816c94[SSL_NULL_WITH_NULL_NULL: Socket[addr=gateway.sandbox.push.apple.com/17.110.227.35,port=2195,localport=63887]]
1447 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Building Raw message from deviceToken and payload
1447 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Built raw message ID 1 of total length 98
1447 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Attempting to send notification: {"aps":{"badge":10,"alert":"message","sound":""}}
1447 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - to device: 1d8e0488958b92297923884508bf3714835f3581101ede9d3155ded0d8241c3e
2315 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Flushing
2315 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - At this point, the entire 98-bytes message has been streamed out successfully through the SSL connection
2315 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Notification sent on first attempt
2315 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Reading responses
7321 [http-bio-8080-exec-21] DEBUG javapns.notification.PushNotificationManager - Closing connection
Push notification sent successfully to: 1d8e0488958b92297923884508bf3714835f3581101ede9d3155ded0d8241c3e
I solved my problem , the certificate was not compatible !
The command line to create the certificate (aps_development.pem is downloaded from Apple, myprivatekey.p12 is exported from my app private key in the "Keychain Access") :
openssl x509 -in aps_development.cer -inform DER -out aps_development.pem -outform PEM
openssl pkcs12 -nocerts -in myprivatekey.p12 -out myprivatekey.pem
openssl pkcs12 -export -inkey myprivatekey.pem -in aps_development.pem -out cert_dev.p12

Mail sending failed using javamail : 550 5.7.1 Client does not have permissions to send as this sender

I am unable to setup my javamail session to send an email using my private mail service provider. I am using an auhenticated starttls session and am getting this error : 550 5.7.1 Client does not have permissions to send as this sender. Below is my mail session properties and debug trace :
mail.smtp.auth=true
mail.smtp.host=smtp.myprovider.com
mail.smtp.password=*****
mail.smtp.port=587
mail.smtp.starttls.enable=true
mail.smtp.user=****
javax.portlet.action[0] = sendMail
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.myprovider.com", port 587, isSSL false
220 smtp.myprovider.com Microsoft ESMTP MAIL Service ready at Tue, 2 Jun 2015 11:35:22 -0400
DEBUG SMTP: connected to host "smtp.myprovider.com", port: 587
EHLO sgmed001
250-smtp.myprovider.com Hello [xx.xx.xx.xx]
250-SIZE 52428800
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH NTLM
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "52428800"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
STARTTLS
220 2.0.0 SMTP server ready
EHLO sgmed001
250-smtp.myprovider.com Hello [xx.xx.xx.xx]
250-SIZE 52428800
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH NTLM LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "52428800"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM LOGIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Attempt to authenticate
AUTH LOGIN
334 VXNlcm5hbWU6
****
334 UGFzc3dvcmQ6
***
235 2.7.0 Authentication successful
DEBUG SMTP: use8bit false
MAIL FROM:<sender#xx.xx>
250 2.1.0 Sender OK
RCPT TO:<recipient#xx.xx>
250 2.1.5 Recipient OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: recipient#xx.xx
DATA
354 Start mail input; end with <CRLF>.<CRLF>
Date: Tue, 2 Jun 2015 11:35:23 -0400 (EDT)
From: sender#xx.xx
To: recipient#xx.xx
Message-ID: <53119439.11433259323689.JavaMail>
Subject: Request
MIME-Version: 1.0
Content-Type: text/html;charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Auto-Response-Suppress: AutoReply, DR, NDR, NRN, OOF, RN
qweqwe
.
550 5.7.1 Client does not have permissions to send as this sender
com.sun.mail.smtp.SMTPSendFailedException: 550 5.7.1 Client does not have permissions to send as this sender
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
at com.sun.mail.smtp.SMTPTransport.finishData(SMTPTransport.java:1215)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:586)
at com.liferay.util.mail.MailEngine._send(MailEngine.java:563)
at com.liferay.util.mail.MailEngine.send(MailEngine.java:350)
at com.liferay.util.mail.MailEngine.send(MailEngine.java:425)
at com.liferay.mail.messaging.MailMessageListener.doMailMessage(MailMessageListener.java:93)
at com.liferay.mail.messaging.MailMessageListener.doReceive(MailMessageListener.java:108)
at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:69)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
at java.lang.Thread.run(Thread.java:745)
11:35:23,696 ERROR [liferay/mail-1][MailEngine:77] null
com.sun.mail.smtp.SMTPSendFailedException: 550 5.7.1 Client does not have permissions to send as this sender_ [Sanitized]
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
at com.sun.mail.smtp.SMTPTransport.finishData(SMTPTransport.java:1215)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:586)
at com.liferay.util.mail.MailEngine._send(MailEngine.java:563)
at com.liferay.util.mail.MailEngine.send(MailEngine.java:350)
at com.liferay.util.mail.MailEngine.send(MailEngine.java:425)
at com.liferay.mail.messaging.MailMessageListener.doMailMessage(MailMessageListener.java:93)
at com.liferay.mail.messaging.MailMessageListener.doReceive(MailMessageListener.java:108)
at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:69)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
at java.lang.Thread.run(Thread.java:745)
Ok thanks to Steffen I was able to work it out, see comment above. In short the real problem was that I tried to send a mail using a sender outside my mail provider space. Using a mail address inside my provider's space made the email go and be sent away.

Programmatically configure WCF client binding to access SSL + Soap 1.1 + Basic Auth

I'm trying to write a C# WCF client (generated by svcutil from wsdl) to access a CXF (java) service implementing the same wsdl.
The service is working fine but I'm having trouble connecting to it on my C# client because the CXF is configured with SSL + Soap 1.1 + Basic Auth.
So far I've tried the following:
Why would Basic Auth not work with my WCF client to Java SOAP Web Service?
new BasicHttpBinding()
{
Security =
{
Mode = BasicHttpSecurityMode.Transport,
Transport =
{
ClientCredentialType = HttpClientCredentialType.Basic,
ProxyCredentialType = HttpProxyCredentialType.None
},
Message =
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
AlgorithmSuite = SecurityAlgorithmSuite.Default
}
}
}
var client = new WebServiceClient(binding, endpoint);
client.ClientCredentials.UserName.UserName = username;
client.ClientCredentials.UserName.Password = password;
But it doesn't seem to send the Auth Header correctly.
I've also tried adding the header manually as outlined by http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/4f8ab001-dafa-4347-bc41-95255ecc9230. but I am not satisfied that this being the best solution.
Can any WCF expert outline a way of creating a binding programmatically that supports SSL + Soap 1.1 + Basic Auth?
Following is the header sent with WCF
System.Net Information: 0 : [13620] ConnectStream#64929093 - Sending headers
{
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://api.test.com/services/GetThings"
Host: api.test.com
Content-Length: 552
Expect: 100-continue
Accept-Encoding: gzip, deflate
}
While this is the proper header sent by SoapUI
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Accept-Encoding: gzip,deflate[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Content-Type: text/xml;charset=UTF-8[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "SOAPAction: "http://api.test.com/services/GetThings"[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Authorization: Basic bXliVlcHJpbQbWwOTkxMjg=[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Content-Length: 317[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Host: api.test.com[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "Connection: Keep-Alive[\r][\n]"
Mon May 13 15:33:08 EDT 2013:DEBUG:>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"