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" ...
Related
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>
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>
I've got a ColdFusion handler that is taking in 3 arguments one of which is a structure. The issue I'm facing is one of the variable name contains brackets which is an illegal character in the naming of a cfargument, see example.
chargifyResponse&id=123456&event=test&payload[chargify]=testing
Any suggestions would be greatly appreciated!
Code
<cffunction name="Webhook" access="remote" output="false">
<cfargument name="id" required="false" type="string" />
<cfargument name="event" required="false" type="string" />
<cfargument name="payload&##91;chargify&##93;" required="false" type="any"/>
...
Error
Attribute validation error for CFARGUMENT.
The value of the NAME attribute is invalid.
Here is the code I am using:
<cfsilent>
<cffunction name="getSignatureKey" returntype="binary" access="private" output="false" hint="Derive the sign-in key">
<cfargument name="key" type="string" required="true" />
<cfargument name="dateStamp" type="string" required="true" />
<cfargument name="regionName" type="string" required="true" />
<cfargument name="serviceName" type="string" required="true" />
<cfset Local.kSecret = charsetDecode("AWS4" & arguments.key, "UTF-8") />
<cfset Local.kDate = sign( arguments.dateStamp, Local.kSecret ) />
<cfset Local.kRegion = sign( arguments.regionName, Local.kDate ) />
<cfset Local.kService = sign( arguments.serviceName, Local.kRegion ) />
<cfset Local.kSigning = sign( "aws4_request", Local.kService ) />
<cfreturn Local.kSigning />
</cffunction>
<cffunction name="sign" returntype="binary" access="private" output="false" hint="Sign with NSA SHA-256 Algorithm">
<cfargument name="message" type="string" required="true" />
<cfargument name="key" type="binary" required="true" />
<cfargument name="algorithm" type="string" default="HmacSHA256" />
<cfargument name="encoding" type="string" default="UTF-8" />
<cfset Local.keySpec = createObject("java","javax.crypto.spec.SecretKeySpec") />
<cfset Local.keySpec = Local.keySpec.init( arguments.key, arguments.algorithm ) />
<cfset Local.mac = createObject("java","javax.crypto.Mac").getInstance( arguments.algorithm ) />
<cfset Local.mac.init( Local.keySpec ) />
<cfreturn Local.mac.doFinal( charsetDecode(arguments.message, arguments.encoding ) ) />
</cffunction>
</cfsilent>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AWS Test</title>
</head>
<body>
<cfset kSecret = getSignatureKey(
'mysecretaccesskey',
'20160408',
'us-west-1',
'AWSECommerceService'
) />
<cfset MyDateTime = now()>
<cfset urlstring="http://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=myaccesskeyID&Timestamp=#DateFormat(MyDateTime,"YYYY-MM-DD")#T#TimeFormat(DateAdd('h', 5 , MyDateTime),'HH:MM:SS')#Z&Signature=#BinaryEncode(kSecret, 'hex')#&BrowseNodeId=2625373011&Operation=BrowseNodeLookup&ResponseGroup=TopSellers&Service=AWSECommerceService">
<cfdump var="#urlstring#">
<CFHTTP URL="#urlstring#" result="data">
<cfdump var="#data#">
</body>
</html>
I am getting the following error from Amazon AWS:
<?xml version="1.0" ?>
<BrowseNodeLookupErrorResponse xmlns="http://ecs.amazonaws.com/doc/2005-10-05">
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
</Error>
<RequestId>28a54988-fda5-11e5-87c7-d5c13ae487c7</RequestId>
</BrowseNodeLookupErrorResponse>
What am I doing wrong?
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