Using WSS4CF with <cfhttp> - soap

This is a bit of a stretch and I'm hoping someone with WSS4CF experience will know exactly what I'm on about.
We are attempting to access a remote webservice, requiring WS Security with username/password. After playing around with SOAP + <cfhttp> and running into class issues, my colleague suggested I take a look at WSS4CF. It seemed just what I needed to avoid needing to deal with those additional jar files etc.
There is no example provided and I noticed that the cfc (view here) seems to be configured to work with something like a dotNet SOAP service where you simply call a method with arguments, e.g.
<cfinvoke
webservice="https://service.gov.au/OrgService.svc?WSDL"
refreshwsdl="true"
method="Search"
returnvariable="aSearch">
<cfinvokeargument name="request" value="#arguments.sXML#"/>
</cfinvoke>
WSS4CF works by first creating a secure web service, then making the request within that secure environment. I tried the above code and it doesn't work (didn't expect it to). The service is expecting an xml packet, not a method call with arguments.
Rather than fiddle with that, I need to configure it to work with cfhttp where we pass an xml envelope in a cfhttpparam, e.g. as follows:
<cfhttp
url="/service.gov.au/OrgService.svc?WSDL"
method="post">
<cfhttpparam type="header" name="content-type" value="application/soap+xml" /><!---text/xml--->
<cfhttpparam type="header" name="SOAPAction" value="http://service.gov.au/services/IOrgService/Search"/>
<cfhttpparam type="header" name="accept-encoding" value="no-compression" />
<cfhttpparam type="xml" value="#trim(sXML)#"/>
</cfhttp>
Any help to do this would be appreciated. I'm not expecting people to research the library unless they're interested. More hoping that someone whose worked with WSS4CF can provide some inspiration.

Although it's not using WS-Security itself, the answer here may help you do what you're after, assuming that you can send the WS-Security packet in the message headers (which wikipedia assures me you can). In that approach, you use cfinvoke, but add a header, which in your case would be the ws-security header. You'd still have to assemble the header yourself, but I think that is possible

Related

Need to preserve HTTP status code when using httpErrors custom 404 error using responseMode executeURL on Azure App Service IIS

I want to have all missing content/"bad" URLs redirect to our custom 404.html error page.
This is important for accurately recording 404 errors in Google Analytics.
The issue is that when the responseMode=ExecuteURL flag is set, then the custom error does not preserve the 404 status code, but always shows a 200 code. I can change this to responseMode=Redirect, but this then shows a 302 status code, before redirecting to the custom 404.html page.
All of this DOES work with a "File" flag set on the httpError… just not with the "ExecuteURL" flag which is required for our server-side Perl includes used to present Header/Footer page elements.
Ideally, we should be able to use the Azure App Service IIS web.config to set a custom error to:
always preserve/show the requested (missing) URL request in address bar (and dev tools)
always preserve/show the "real" HTTP status code (404) in the dev tools
allow the use of server-side includes to update header/footer elements using our current Perl setup
The below code works to preserve the requested URL in address bar, correctly shows the custom 404.html page with server-side header/footer content, BUT loses the 404 status code in dev tools (and Google Analytics)...
<httpErrors>
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404"
responseMode="ExecuteURL"
path="/404.html" />
</httpErrors>
Changing to responseMode="Redirect" only changes the status code to 302 before redirecting to custom 404.html...
If I change to use responseMode="File" this all works fine, but I then lose the custom server-side header and footers which are handled with Perl server-side includes...
EDIT:
To be clear, the custom 404 page is all HTML and Javascript, but also leverages some very old Perl server-side includes to add custom header and footer elements to the page. We are not using any .NET framework or .NET core pages...
This arrangement should be possible, but perhaps only with a different web server, not IIS? nginx, perhaps?
FINAL UPDATE:
Not a full answer, but our near-term resolution was to use nginx proxy configuration (which was already present and could be altered in nginx.conf) to preserve 404 error codes and present the proper custom 404.html static file.
I was also able to do this with Docker and nginx, so I know it is possible for a web server to deal with this situation...
I've determined that AFAICT there is no way for IIS web.config to handle this without using server-side code as Jason Pan suggested. So while he may be correct, that answer was not helpful for our needs.
UPDATE
When you use httpErrors in web.config, it must have code in your project to handle 400 and 500 in server side.
Due to your project just static web app, and no sever side code. So I suggest you can use hard code in httpErrors.
Like,
<error statusCode="404" responseMode="ExecuteURL" path="/404.html?httpcode=404" />.
The tag of httpErrors is used in servers such as iis. The 404 and 500 errors you want can’t be displayed directly in the browser. Because the httpErrors tag is used, the server will process everything and return it to the browser, so the HttpStaus you get is always 200.
PRIVIOUS
I probably know your question. Your program is .net framework or .net core, it is not clear for the time being. But I see the configuration tags in the web.config file.
In principle, the wrong request arrives at IIS and other servers, and the code level has processed 404 and other errors, so the returned HttpStatus value must be 200. There is no way to change it, but when a 404 or 500 error occurs, we can Processing and recording in Application_Error can also achieve the purpose you want to analyze.
So I tested it and based on the .net framework, you can download my sample code on github and give the following suggestions.
1. Add the Application_Error method to the Global.asax.cs file.
2. According to the Application_Error method, add an Error Controller.
3. Perform the test and the result is shown in the screenshot.
After decode the message. The content is
The controller for path '/a/b' was not found or does not implement IController..
We can custom error msg in Application_Error function. We can append HttpCode and other info.
Hi i found this workaround(ASP NET WebForms)
Web Config
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/ErrorDefault.aspx?httpcode=404" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ErrorDefault.aspx?httpcode=500" responseMode="ExecuteURL" />
</httpErrors>
ErrorDefault.cs > Page Load
var httpCode = Request.QueryString["httpcode"];

Posting to Facebook without a link

I'm working on an API to allow posting to Facebook, using Graph API over REST, sending HTTP post requests to https://graph.facebook.com/me/feed (after succesful OAuth2 auth).
I can specify message and link and it posts the link, (but with message ignored?), and I can also include name, caption and description to get those elements handled - so links are ok.
If I use just message or just picture, I get the error:
(#100) Missing message or attachment
If I use message and picture, it posts the message, without any picture. (Which is useful, but not intended behaviour?)
The only way I can get the picture seems to be as a link (which includes it as a thumbnail).
I've looked through the docs but can't find any useful info on this - all the examples are showing links.
My main question is: What is the intended way to post a message without a picture or link?
But it'd also be useful to know if there's a way to post a picture to the wall? (non-thumbnail, with lightbox)
The actual code is more complex, but simplified here to demonstrate the issue.
This was failing:
<cfhttp
result = "local.Response"
method = "post"
url = #Arguments.Url#
>
<cfhttpparam type="url" name="Message" value="#Arguments.Message#" />
</cfhttp>
This worked:
<cfset Arguments.Url &= '&message=' & encodeForUrl(Arguments.Message) />
<cfhttp
result = "local.Response"
method = "post"
url = #Arguments.Url#
>
<cfhttpparam type="url" name="dummy" value="ignore" />
</cfhttp>
(The dummy cfhttpparam is because CF complains if a POST request doesn't contain at least one param.)

FIle downloading using HTTP

I am having trouble finding the correct XEP to use for this specific use case:
Initiator (e.g. iOS or Android device) uploads a file to a server and needs to notify the responder (in this case this would be a browser based client) to download the file from the location he just uploaded to using HTTP.
All the XEP's I have come across talk about streams or IBB/SOCKS5. I did found the following which could be useful but no updates since 2007:
http://xmpp.org/extensions/inbox/jingle-httpft.html
Am I overlooking something on an XEP which is in draft or final?
Either use XEP-0066: Out of Band Data, or just encode the link in a XEP-0071: XHTML-IM a element.
The first:
<message from='stpeter#jabber.org/work'
to='MaineBoy#jabber.org/home'>
<body>Yeah, but do you have a license to Jabber?</body>
<x xmlns='jabber:x:oob'>
<url>http://www.jabber.org/images/psa-license.jpg</url>
</x>
</message>
The second:
<message>
<body>here is a file [http://www.jabber.org/images/psa-license.jpg]</body>
<html xmlns='http://jabber.org/protocol/xhtml-im'>
<body xmlns='http://www.w3.org/1999/xhtml'>
<p>Here is a <a href='http://www.jabber.org/images/psa-license.jpg'>file</a></p>
</body>
</html>
</message>

cflocation vs cfheader for 301 redirects

I am "renaming" an existing file for a project I am working on. To maintain backwards compatibility, I am leaving a cfm file in place to redirect the users to the new one.
buy.cfm: old
shop.cfm: new
In order to keep everything as clean as possible, I want to send the 301 statuscode response if a user tries to go to buy.cfm.
I know that I can use either cflocation with the statuscode attribute
<cflocation url="shop.cfm" statuscode="301" addtoken="false">
or I can use the cfheader tags.
<cfheader statuscode="301" statustext="Moved permanently">
<cfheader name="Location" value="http://www.mysite.com/shop.cfm">
Are there any reasons to use one method over the other?
I think they do the same thing, with <cflocation> being more readable
I tested this on ColdFusion 9.
There is one major difference, and it is that cflocation stops execution of the page and then redirects to the specified resource.
From the Adobe ColdFusion documentation:
Stops execution of the current page and opens a ColdFusion page or
HTML file.
So you would need to do this:
<cfheader statuscode="301" statustext="Moved permanently">
<cfheader name="Location" value="http://www.example.com/shop.cfm">
<cfabort>
to get the equivalent of this:
<cflocation url="shop.cfm" statuscode="301" addtoken="false">
Otherwise, you risk running into issues if other code runs after the cfheader tag. I came across this when fixing some code where redirects were inserted into an application.cfm file -- using cfheader -- without aborting the rest of the page processing.
I also noticed, in the response headers, that cflocation also sets the following headers accordingly:
Cache-Control: no-cache
Pragma: no-cache
One might want to add these headers in if using the cfheader tag with Location, if needed:
<cfheader name="Cache-Control" value="no-cache">
<cfheader name="Pragma" value="no-cache">
To elaborate on the Answer by Andy Tyrone, while they MAY do the same thing in certain circumstances, the CFHEADER method give you more control over the headers passed in the request. This becomes useful, for example, if you want to send cache control headers to a browser or content delivery network so that they do not keep hitting your server with the same old redirect request. There is no way (to my knowledge) to tell a CFLocation to cache the redirect.

How should I update a REST resource?

I'm not sure how I should go about updating individual properties of a REST resource. Consider the following example:
# HTTP GET to /users/1.xml
<?xml version="1.0" encoding="UTF-8" ?>
<response>
<user>
<id>1</id>
<name>John Doe</name>
<email>john#doe.com</email>
</user>
</response>
How should I facilitate for updating John's email? HTTP PUT comes to mind, but I'd be making it hard on my clients by requiring a complete XML (matching the HTTP GET response) to modify the resource.
The PUT method requests that the
enclosed entity be stored under the
supplied Request-URI. If the
Request-URI refers to an already
existing resource, the enclosed entity
SHOULD be considered as a modified
version of the one residing on the
origin server.
Is there any other way?
If your server framework is flexible enough to handle it, you can do:
Request:
PUT /users/1/email
Content-Type: text/plain
john#newemail.com
Response:
200 OK
Content-Location: /users/1
By using a URL to refer to the email as its own resource, you can PUT directly to it using a simple format like text/plain. In the response, the Content-Location url gives the client an indication that the change has had an impact on the user resource.
The PATCH method is also another way that you can do partial updates. This is a newly introduced method and as yet there are no standard formats for sending XML diff documents. So, if you take this approach you will not find much guidance.
The other thing to consider is that REST works best with large grained updates. If you find yourself needing to make these kinds of small changes, then maybe you need to rethink your distributed architecture.