Passing a parameter in CFHTTP URL string - coldfusion

I am using cfhttp to post a series of user supplied parameters to an API. I am passing all of the parameters with <cfhttparam> except one: {myID}. Since the {myID} value will also be supplied by the user, I am wondering how can I make sure it gets passed inside the URL string?
<cfhttp url="http://abc.xyz.com/webservice/{myID}/add/multiple"
method="POST" result="returnStruct" >
<cfhttpparam name="Accept" type="header" value="application/json" />
<cfhttpparam type="header" name="datetime" value="#datetime#" />
<cfhttpparam type="header" name="authorization" value="#authorization#" />
<cfhttpparam type="formfield" name="myAPI" value="1" />
<cfhttpparam type="formfield" name="param1" value="1000" />
<cfhttpparam type="formfield" name="param2" value="myname#email.com" />
<cfhttpparam type="formfield" name="param3" value="2" />
<cfhttpparam type="formfield" name="param4" value="Tester" />
</cfhttp>

The client aplication should have the user's data from a previous request, if you pass it like
http://abc.xyz.com/webservice/user_id/add/multiple the server assumes that user_id is the parameter you call {myID}
Good luck

Related

cfhttp and cfhttpparam in ColdFusion

I have some XMl data, I want to use the XML data to be posted to a scheduler job so using cfhttp and cfhttpparam. But for reason after running this code I was not able to schedule a job in one of my site. Tried all the options with formfields, url and xml with no success. I was saving all my data into a xml variable using cfsavecontent and using that variable to pass into cfhttparam value. Not sure what Am I doing wrong here. Here is the below code
<cfsavecontent variable="getAllValues">
<start_job job="/cf/ecs/get_ecspseg1_data">
<params>
<param name="1_script" value="#script#" />
<param name="2_login" value="#login#"/>
<param name="3_customer" value="#customer#"/>
<param name="4_account" value="#account#"/>
<param name="5_begdate" value="#begdate#"/>
<param name="6_enddate" value="#enddate#"/>
</params>
</start_job>
</cfsavecontent>
<cfhttp url="http://ecs" port="4444" username="test" authType = "BASIC" password="testing*1" method="post">
<cfhttpparam type="xml" name="testing" value="#ToString(getAllValues)#"/>
</cfhttp>
here is the updated code:
<cfsavecontent variable="getAllValues">
<start_job job="/cf/smartecs/get_pseg1_data">
<params>
<param name="1_script" value="#script#" />
<param name="2_login" value="#login#"/>
<param name="3_customer" value="#customer#"/>
<param name="4_account" value="#account#"/>
<param name="5_begdate" value="#begdate#"/>
<param name="6_enddate" value="#enddate#"/>
</params>
</start_job>
</cfsavecontent>
<cfhttp url="http://10.xxx.xxx.xxx" port="4444" username="myusername" authType = "BASIC" password="mypassword" method="post" >
<cfhttpparam type="header" name="Content-Type" value="application/octet-stream">
<cfhttpparam type="body" name="testing" value="#getAllValues#"/>
</cfhttp>
When using a different Port number we need to even keep a / at the end of the URL. When I kept that / at the end of the URL it worked like a charm. ColdFusion will not accept : in the URL.

"The request must contain the parameter MessageHandle" error when deleting a message from an AWS SQS queue (in Coldfusion)

I'm struggling to delete a message once received from an AWS queue.
The function I'm using is:
<cffunction name="deleteMessage" output="true" returntype="void">
<cfargument name="uri" type="string" required="true">
<cfargument name="messageId" type="string" required="true">
<cfset var tmp = StructNew()/>
<cfset tmp.dateTimeString = zuluDateTimeFormat(Now())/>
<cfset tmp.fixedData = "ActionDeleteMessage" &
"AWSAccessKeyId#This.awsAccessKeyId#" &
"MessageHandle#Arguments.messageId#" &
"SignatureVersion1" &
"Timestamp#tmp.dateTimeString#" &
"Version#This.sqsVersion#"/>
<cfset tmp.signature = createSignature(tmp.fixedData)/>
<cfhttp method="GET" url="#Arguments.host#" charset="UTF-8">
<cfhttpparam type="url" name="Action" value="DeleteMessage"/>
<cfhttpparam type="url" name="AWSAccessKeyId" value="#This.awsAccessKeyId#"/>
<cfhttpparam type="url" name="MessageHandle" value="#Arguments.messageId#"/>
<cfhttpparam type="url" name="Signature" value="#tmp.signature#"/>
<cfhttpparam type="url" name="SignatureVersion" value="1"/>
<cfhttpparam type="url" name="Timestamp" value="#tmp.dateTimeString#"/>
<cfhttpparam type="url" name="Version" value="#This.sqsVersion#"/>
</cfhttp>
<cfdump var="#CFHTTP.FileContent#"><cfabort>
<cfif CFHTTP.ResponseHeader.Status_Code neq 200>
<cfinvoke method="handleErrors"
content="#CFHTTP.FileContent#"
/>
<cfelse>
<cfreturn XmlParse(CFHTTP.FileContent).deleteMessageResponse.return.XmlText/>
</cfif>
</cffunction>
All the details are being passed in correctly and the signature is also being generated successfully (verified through other AWS calls). The error message I get back from Amazon is:
<?xml version="1.0"?><ErrorResponse xmlns="http://queue.amazonaws.com/doc/2008-01-01/"><Error><Type>Sender</Type><Code>MissingParameter</Code><Message>The request must contain the parameter MessageHandle.</Message><Detail/></Error><RequestId>1a144095-db82-59c1-9551-116614ba674d</RequestId></ErrorResponse>
How do I correct this problem and correctly delete the message?
Turns out you need both MessageHandle and ReceiptHandle in the request:
<cffunction name="deleteMessage" output="true" returntype="void">
<cfargument name="uri" type="string" required="true">
<cfargument name="messageId" type="string" required="true">
<cfargument name="receiptHandle" type="string" required="true">
<cfset var tmp = StructNew()/>
<cfset tmp.dateTimeString = zuluDateTimeFormat(Now())/>
<cfset tmp.fixedData = "ActionDeleteMessage" &
"AWSAccessKeyId#This.awsAccessKeyId#" &
"MessageHandle#Arguments.messageId#" &
"ReceiptHandle#Arguments.receiptHandle#" &
"SignatureVersion1" &
"Timestamp#tmp.dateTimeString#" &
"Version#This.sqsVersion#"/>
<cfset tmp.signature = createSignature(tmp.fixedData)/>
<cfhttp method="GET" url="#Arguments.host#" charset="UTF-8">
<cfhttpparam type="url" name="Action" value="DeleteMessage"/>
<cfhttpparam type="url" name="AWSAccessKeyId" value="#This.awsAccessKeyId#"/>
<cfhttpparam type="url" name="MessageHandle" value="#Arguments.messageId#"/>
<cfhttpparam type="url" name="ReceiptHandle" value="#Arguments.receiptHandle#"/>
<cfhttpparam type="url" name="Signature" value="#tmp.signature#"/>
<cfhttpparam type="url" name="SignatureVersion" value="1"/>
<cfhttpparam type="url" name="Timestamp" value="#tmp.dateTimeString#"/>
<cfhttpparam type="url" name="Version" value="#This.sqsVersion#"/>
</cfhttp>
<cfdump var="#CFHTTP.FileContent#"><cfabort>
<cfif CFHTTP.ResponseHeader.Status_Code neq 200>
<cfinvoke method="handleErrors"
content="#CFHTTP.FileContent#"
/>
<cfelse>
<cfreturn XmlParse(CFHTTP.FileContent).deleteMessageResponse.return.XmlText/>
</cfif>
</cffunction>

Upload Image AWS S3 Using ColdFusion 2016 CFC

I'm trying to upload an image to an AWS S3 Bucket but the method I'm using is saying my Secret Key and access code are resulting in SignatureDoesNotMatch. I'm using this example as my point of reference. https://gist.github.com/atuttle/4658165 Thank you in advanced for all your help!
<cffunction name="uploadToAmazonS3">
<cfargument name="fileName" required="true" />
<cfargument name="contentType" required="true" />
<cfargument name="data" required="true" />
<cfargument name="acl" default="public-read" />
<cfargument name="storageClass" default="STANDARD" />
<cfargument name="HTTPtimeout" default="300" />
<cfargument name="bucket" default="#getProperty('EmailAttachmentS3Bucket')#" />
<cfargument name="accessKeyId" default="#getProperty('EmailAttachmentS3AccessKeyId')#" />
<cfargument name="secretKey" default="#getProperty('EmailAttachmentS3SecretKey')#" />
<cfset var dateTimeString = GetHTTPTimeString(Now())>
<!--- authorization stuff --->
<cfset var cs = "PUT\n\n#arguments.contentType#\n#dateTimeString#\nx-amz-acl:#arguments.acl#\nx-amz-storage-class:#arguments.storageClass#\n/#arguments.bucket#/#arguments.fileName#">
<cfset var signature = createSignature(cs, arguments.secretKey)>
<cfset var url = "http://s3.amazonaws.com/#arguments.bucket#/#arguments.fileName#" />
<cfhttp method="PUT" url="#url#" timeout="#arguments.HTTPtimeout#">
<cfhttpparam type="header" name="Authorization" value="AWS #arguments.accessKeyId#:#signature#">
<cfhttpparam type="header" name="Content-Type" value="#arguments.contentType#">
<cfhttpparam type="header" name="Date" value="#dateTimeString#">
<cfhttpparam type="header" name="x-amz-acl" value="#arguments.acl#">
<cfhttpparam type="header" name="x-amz-storage-class" value="#arguments.storageClass#">
<cfhttpparam type="body" value="#arguments.data#">
</cfhttp>
</cffunction>
<cffunction name="HMAC_SHA1" returntype="binary" access="private" output="false" hint="NSA SHA-1 Algorithm">
<cfargument name="signKey" type="string" required="true" />
<cfargument name="signMessage" type="string" required="true" />
<cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1") />
<cfset var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1") />
<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec") />
<cfset var mac = createObject("java","javax.crypto.Mac") />
<cfset key = key.init(jKey,"HmacSHA1") />
<cfset mac = mac.getInstance(key.getAlgorithm()) />
<cfset mac.init(key) />
<cfset mac.update(jMsg) />
<cfreturn mac.doFinal() />
</cffunction>
<cffunction name="createSignature" returntype="string" access="public" output="false">
<cfargument name="in" required="true" />
<cfargument name="secretKey" required="true" />
<!--- Replace "\n" with "chr(10) to get a correct digest --->
<cfset var fixedData = replace(arguments.in,"\n", chr(10), "all") />
<!--- Calculate the hash of the information --->
<cfset var digest = HMAC_SHA1(arguments.secretKey,fixedData) />
<!--- fix the returned data to be a proper signature --->
<cfset var signature = ToBase64(digest) />
<cfreturn signature />
</cffunction>

404 Not Found error in SOAP web service request via CFHTTP

I am having a lot of trouble communicating with a web service for our membership database. I get a valid result from my SOAP envelope when using SoapUI. But when I try to send the same envelope using CFHTTP and CF9 (I know, I know), I get a "404 Not Found" error no matter what I try to do. Accessing the URL in a browser gives me an "access denied" error.
Here is what I have in cfsavecontent:
<cfsavecontent variable="soapBody">
<cfoutput>
<?xml version=“1.0” encoding=“utf-8”?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://membersuite.com/schemas" xmlns:con="http://membersuite.com/contracts">
<soapenv:Header>
<sch:ConciergeRequestHeader>
<!--Optional:-->
<sch:BrowserId></sch:BrowserId>
<!--Optional:-->
<sch:SessionId></sch:SessionId>
<sch:AccessKeyId>MyAccessKey</sch:AccessKeyId>
<!--Optional:-->
<sch:AssociationId>MyAssociationID</sch:AssociationId>
<sch:Signature>MySignature</sch:Signature>
</sch:ConciergeRequestHeader>
</soapenv:Header>
<soapenv:Body>
<con:LoginToPortal>
<!--Optional:-->
<con:portalUserName>username</con:portalUserName>
<!--Optional:-->
<con:portalPassword>password</con:portalPassword>
</con:LoginToPortal>
</soapenv:Body>
</soapenv:Envelope>
</cfoutput>
</cfsavecontent>
And here is my cfhttp:
<cfhttp url="https://soap.membersuite.com/mex" method="post" useragent="#CGI.http_user_agent#">
<cfhttpparam type="header" name="charset" value="utf-8">
<cfhttpparam type="header" name="mimetype" value="application/xml" />
<cfhttpparam type="header" name="content-type" value="text/xml">
<cfhttpparam type="header" name="SOAPAction" value="http://membersuite.com/contracts/IConciergeAPIService/LoginToPortal" />
<cfhttpparam type="header" name="accept-encoding" value="no-compression" />
<cfhttpparam type="header" name="content-length" value="#len(trim(soapBody))#">
<cfhttpparam type="xml" name="soapenv" value="#trim(soapBody)#" />
</cfhttp>
Dumping cfhttp gives me this error:
It seems obvious to me that the remote server is telling me it cannot find what I am asking it for. But it is the right endpoint, and I can see it in the WSDL:
<wsdl:operation name="LoginToPortal">
<wsdl:input wsaw:Action="http://membersuite.com/contracts/IConciergeAPIService/LoginToPortal" message="tns:IConciergeAPIService_LoginToPortal_InputMessage"/>
<wsdl:output wsaw:Action="http://membersuite.com/contracts/IConciergeAPIService/LoginToPortalResponse" message="tns:IConciergeAPIService_LoginToPortal_OutputMessage"/>
</wsdl:operation>
I have also added the SSL cert from the web service page to my CF keystone; no change in error message. I am at my wit's end and would appreciate any suggestions! Again, I am getting expected results back via SoapUI. Thank you all very much!
Going strictly off the SoapUI request, it seems to work if the target URL is changed to https://soap.membersuite.com/. Using bogus credentials, the response changes to "Invalid Access Key ID specified" instead of 404.
<cfhttp url="https://soap.membersuite.com/" method="post" useragent="#CGI.http_user_agent#">
<cfhttpparam type="header" name="Content-Type" value="text/xml; charset=utf-8" />
<cfhttpparam type="header" name="SOAPAction" value="http://membersuite.com/contracts/IConciergeAPIService/LoginToPortal" />
<cfhttpparam type="header" name="Accept-Encoding" value="no-compression" />
<cfhttpparam type="header" name="Content-Length" value="#len(trim(soapBody))#">
<cfhttpparam type="body" value="#trim(soapBody)#" />
</cfhttp>

Very strange behaviour with cfhttp an cfhttpparam

Happy New Year,
The New Year found me wrestling with a coding problem. I am using ColdFusion and as for CFML engine “openBD”. I have a CFC that handles requests for the search engine that I use (SOLR search engine). I am “feeding” that CFC with some arguments. The CFC performs as it should. But when I am trying to pass a specific argument (#apofasi_taxonomy #) the CFC doesn’t returns nothing (If I pass the above argument directly to the search engine –not using CFC- I can see return/search results)
Part of CFC:
<cffunction name="searchP" access="remote" returnFormat="json">
<cfargument name="q" type="string" default="" required="yes">
<cfargument name="apofasi_taxonomy" type="string" default="apofasi_taxonomy:(*)" required="yes">
<cfargument name="apofasi_tmima" type="string" default="apofasi_tmima:(*)" required="yes">
<cfargument name="apofasi_date" type="string" default="apofasi_date:(*)" required="yes">
<cfargument name="apofasi_number" type="string" default="apofasi_number:(*)" required="yes">
<!---<cfargument name="apofasi_taxonomy" type="string" default="*">
<cfargument name="apofasi_tmima" type="string" default="*">
<cfargument name="apofasi_date" type="string" default="*">
<cfargument name="apofasi_number" type="string" default="*">--->
<cfset theUrl = 'http://localhost/solr/areios_pagos/select/?'>
<cfhttp method="get" url="#theUrl#" port="8090" result="rs" username="abcd" password="********">
<cfhttpparam type="url" name="q" value="#q#">
<cfhttpparam type="url" name="fq" value="#apofasi_taxonomy#+#apofasi_tmima#+#apofasi_date#+#apofasi_number#">
<!---<cfhttpparam type="url" name="fq" value="apofasi_taxonomy:(3068 || ΠΟΙΝΙΚΕΣ) AND apofasi_date:(2010)">--->
<!---<cfhttpparam type="url" name="fq" value="apofasi_taxonomy:(3068) AND apofasi_date:(*) AND apofasi_number:(*)">--->
<cfhttpparam type="url" name="rows" value="120">
<cfhttpparam type="url" name="wt" value="json">
<cfhttpparam type="url" name="sort" value="score desc">
<cfhttpparam type="url" name="hl" value="true">
<cfhttpparam type="url" name="hl.fl" value="content,title">
<cfhttpparam type="url" name="fl" value="grid_title,title,url,ida,model,search_tag,solr_id">
<cfhttpparam type="url" name="f.content.hl.alternateField" value="content">
<cfhttpparam type="url" name="hl.maxAlternateFieldLength" value="800">
</cfhttp>
Notice that the search engine consumes urls like:
http://localhost/solr/areios_pagos/select/?q=blahblah&fq=apofasi_taxonomy:(3068)+ apofasi_tmima:(Α || Ζ)+ apofasi_date:(2007 || 2012)+apofasi_number:(666)
What I have checked until now: The arguments that I am passing to CFC are 100% OK (from html), I have double-checked if the search engine can consume the above url syntax. But I have noticed a very strange behavior. When I exclude the #apofasi_taxonomy# or #apofasi_tmima# arguments from the url completely the CFC is working (it returns results).
The values that #apofasi_taxonomy# argument takes are: apofasi_taxonomy:(ΠΟΙΝΙΚΕΣ), apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ), apofasi_taxonomy:(3068) or apofasi_taxonomy:(ΠΟΙΝΙΚΕΣ || 3068), apofasi_taxonomy:(ΠΟΙΝΙΚΕΣ || ΠΟΛΙΤΙΚΕΣ) and so on.
I have noticed one more thing, #apofasi_taxonomy# argument is working with the values below: apofasi_taxonomy(ΠΟΙΝΙΚΕΣ), apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ)and apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ || ΠΟΙΝΙΚΕΣ) but it is not working for apofasi_taxonomy:(3068), apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ || 3068), apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ || 3068) or apofasi_taxonomy:(ΠΟΛΙΤΙΚΕΣ || ΠΟΛΙΤΙΚΕΣ || 3068). Isn’t that weird?
The values that #apofasi_tmima# argument takes are: Α || Α1 || Α2 || Β || Β2 || Γ || Δ || Ε || ΣΤ || Ζ || ΟΛΟΜΕΛΕΙΑ e.g. apofasi_tmima(Β || Β2 || ΟΛΟΜΕΛΕΙΑ).
Keep in mind that the above values are in Greek language.
Is there anyone out there that can help?
With respect,
Tom
edit: Moved requested XML provided in comments to the question
<fieldType name="text_areios_pagos" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" enablePositionIncrements="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_el.txt" enablePositionIncrements="true"/>
<filter class="solr.GreekLowerCaseFilterFactory"/>
<filter class="solr.GreekStemFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" enablePositionIncrements="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_el.txt" enablePositionIncrements="true"/>
<filter class="solr.GreekLowerCaseFilterFactory"/>
<filter class="solr.GreekStemFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
You may have to add a charset attribute to your cfhttp tag
<cfhttp ... charset="ISO-8859-7" ...