NullReferenceException in XSockets.DevServer.DebugInstance() - xsockets.net

I'm playing around with XSockets.NET, and I've spent way too much time debugging what should be a simple problem. I'm using the standard templates that come with XSockets, which create a project called XSockets.DevServer, and a class within that project called DebugInstance. When I host this DebugInstance class within my web project, all seems to work as expected. However, when I try to host it within the XSockets.Debug.Console project, or when I try to get it to run on my production IIS instance, I get a NullReferenceException in the code below:
[ImportOne(typeof(IXBaseServerContainer))]
public IXBaseServerContainer wss { get; set; }
public DebugInstance()
{
try
{
Debug.AutoFlush = true;
this.ComposeMe();
// NullReferenceException on the next line - wss apparently never gets set.
wss.OnServersStarted += wss_OnServersStarted;
wss.OnServerClientConnection += wss_OnServerClientConnection;
wss.OnServerClientDisconnection += wss_OnServerClientDisconnection;
wss.OnError += wss_OnError;
wss.OnIncommingTextData += wss_OnIncommingTextData;
wss.OnOutgoingText += wss_OnOutgoingText;
wss.OnServersStopped += wss_OnServersStopped;
wss.StartServers();
}
catch (Exception ex)
{
Debug.WriteLine("Exception while starting server: " + ex);
Debug.WriteLine("Press enter to quit");
}
}
Clearly the problem is happening within this.ComposeMe(), but there's no troubleshooting information, and since XSockets isn't apparently open-sourced, I haven't been able to step through the code to figure out where the problem is.
EDIT: To be clear, I know what a NullReferenceException is. In this case its immediate cause is the fact that wss is null. What I want to know is its proximate cause, i.e., why ComposeMe() doesn’t assign it, even though that's what it's apparently supposed to be doing. Apparently the homegrown IOC that XSockets is using to support its plugin architecture is supposed to find an instance of IXBaseServerContainer, but it's apparently not - and I have no idea why. And not having the source, I'm not even sure what the candidates for IXBaseServerContainer are.
EDIT 2012-11-06: Here's what the appSettings element of my app.config looks like:
<appSettings>
<add key="XSocketServerStartport" value="4502"/>
<add key="UsePolicyServer" value="true"/>
<add key="XSockets.PluginCatalog" value="XSockets\XSocketServerPlugins\"/>
<add key="XSockets.PluginFilter" value="*.dll"/>
<add key="XMessageInterceptorsEnabled" value="false"/>
<add key="XErrorInterceptorsEnabled" value="false"/>
<add key="XConnectionInterceptorsEnabled" value="false"/>
<add key="XHandshakeInterceptorsEnabled" value="false"/>
<add key="XSocketLogPath" value="XSockets\XSocketServerPlugins\Log"/>
<add key="XBufferSize" value="8192"/>
</appSettings>
I've got all the files mentioned below in both my $(ProjectDir)\XSockets\XSocketServerPlugins\ and my $(TargetDir)\XSockets\XSocketServerPlugins\ folders, e.g.:
10/29/2012 09:53 AM 15,872 XSockets.Core.Communication.dll
10/29/2012 09:53 AM 70,656 XSockets.Core.dll
10/29/2012 09:53 AM 8,192 XSockets.DevelopmentServer.dll
10/29/2012 09:53 AM 11,776 XSockets.Extensibility.Handlers.dll
10/29/2012 09:53 AM 10,240 XSockets.Extensibility.Interceptors.dll
10/29/2012 09:53 AM 23,040 XSockets.External.dll
10/29/2012 09:53 AM 24,064 XSockets.Protocol.dll
10/29/2012 09:53 AM 39,424 XSockets.Server.dll
11/05/2012 05:37 PM 12,288 XSockets.WebRTC.Prototype.Shared.Handlers.dll
Any thoughts?

Ken,
When the plugin framework of XSockets.NET dont find any "plugins" there is nothing to Compose. I think the reason of this is that you don't have the "plugins" deployed in the IIS Production instance of yours?
You will need to add the following elements to your appSettings section of the config file(web.config)
<add key="XSockets.PluginCatalog" value="XSockets\XSocketServerPlugns\" />
<add key="XSockets.PluginFilter" value="*.dll" />
In "my case" i have the XSockets.NET plugins (protocols, handlers/controllers) inside the
/XSockets/XSocketServerPlugns folder in my Website.
you should have the following plugins ( .dll's) in that folder
XSockets.Core.Communication
XSockets.Core
XSockets.Extensibility.Handlers
XSockets.Extensibility.Interceptors
Xsockets.External
XSockets.Protocol
XSockets.Server
XSockets.DevelopmentServer **
** This is the project/class library that contains the server of yours. ( i.e the DebugInstance)
If you want to configure the server , you will need to create a configuration loader class see this url for info http://xsockets.net/api/net-c/creating-custom-configuration-plugin , or just shoot an email to contact#xsockets.net and we will help you out.
If you need further assistance, just let me know.
Kind regards

First of all, if you are running a Console Application switch to .NET 4 instead of the default .NET 4 client profile (if not done already).
Second. We will provide a better way of knowing which references to add to the project starting the server.
Meanwhile you should be able to run this in the Package Manager Console to see what refs are needed
(Get-Project XSocketHandler).Object.References | Where-Object {$_.CopyLocal -eq $true}
You have my email, so please contact me and we can have a skype meeting or something to talk more about it.
Regards
Uffe, Team XSockets

Related

How to run AppleScript from C++ in macOS sandbox environment without entitlement violations

I am trying to use AppleScript to control the Apple Photos app from within a QT C++ app that must run in the sandbox environment required for the macOS App Store.
I have tried to run the AppleScript via a QProcess launching osascript, like this :
const QString aScript = QString(
"tell application \"Photos\"\n"
" set selMedia to (get media items whose id contains \"%1\")\n"
" if not (album \"Trash from %2\" exists) then\n"
" make new album named \"Trash from %2\"\n"
" end if\n"
" add selMedia to album \"Trash from %2\"\n"
"end tell").arg(fileNameNoExt, APP_NAME);
QProcess script;
script.setProgram("osascript");
script.setArguments(QStringList() <<
"-e" << aScript);
script.start();
script.waitForFinished();
int exitCode = script.exitCode();
if(exitCode!=0){
QString outMsg = script.readAllStandardOutput();
QString errorOut = script.readAllStandardError();
// Warn user and output message...
}
This works fine outside the sandbox, adding the desired items from the library to the desired album. However, inside the sandbox, I get an errAEPrivilegeError. Looking in the Console for the error event, it states :
AppleEvents/sandbox: Returning errAEPrivilegeError/-10004 and denying dispatch of event core/getd from process '<private>'/0x0-0x4d84d8, pid=31654, because it is not entitled to send an AppleEvent to this process.
Here is my entitlements file when signing the app :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.scripting-targets</key>
<dict>
<key>com.apple.Photos</key>
<array>
<string>com.apple.Photos.library.read-write</string>
</array>
</dict>
</dict>
</plist>
When the app is first run (sandboxed) and the AppleScript is started, I get the system permission box, saying that the app is asking to control the Photos app. I click OK of course, but then I get the error. And upon next runs, as the permission is already granted, no system permission box comes up, but it fails nonetheless. When I reset the permissions with the terminal command tccutil reset All [my app bundle id], then upon the next execution of the app and the AppleScript, I get the permission box again.
If I delete the com.apple.security.scripting-targets entitlement, I get no system permission request and the error is different : from my app the error output states Photos isn't running, from the console it says it was denied due to sandboxing. If I keep the scripting-targets and com.apple.Photos but delete library.read-write I get the errAEPrivilegeError again.
I have tried to only test the make new album named "Trash [...]"but this still fails with errAEPrivilegeError. Even if only telling Photos to quit with AppleScript (which according to Photos.app/Contents/Resources/Photos.sdef doesn't require any specific permissions appart from scripting, I also get errAEPrivilegeError. The only command that seems to work is activate.
Also, if I try to run the qprocess not as a separate process, with QProcess::execute (if maybe the sandbox problem is because it is not the main app running the script ?), I still get the same errAEPrivilegeError.
What am I missing for it to work, or what other method should I use to run an applescript from C++/QT when in a sandbox ?
Did you include NSAppleEventsUsageDescription in your app’s Info.plist?
[ETA]
OK, after further digging I can confirm the behavior you’re seeing. With the correct app entitlements an in-process NSAppleScript can send AEs to Photos; however, the same process is unable to send AEs from a child osascript process.
According to Apple docs (which are lousy), a child process must have exactly 2 entitlements to inherit its parent’s: com.apple.security.app-sandbox and com.apple.security.inherit. However, running codesign --display --entitlements - /usr/bin/osascript shows osascript has neither of these but a bunch of unrelated entitlements. So this looks like Apple’s screwup in how they’ve built osascript.
When running AppleScripts that are part of a Swift/ObjC app, I generally recommend using the AppleScript-ObjC bridge to load and call your AppleScript handlers directly; no subprocess required. I have no idea how to do that in a Qt app though.
The simplest solution may be to write your own command-line executable/XPC service in ObjC which runs your AppleScript code via NSAppleScript, giving it the com.apple.security.app-sandbox and com.apple.security.inherit entitlements, and embed it in your Qt app’s main bundle.
(You may also need to add com.apple.security.automation.apple-events in the main app’s entitlements if the runtime is hardened.)
…
One more thing: avoid generating AppleScript code via string interpolation. If you want to parameterize a script, pack your values as parameters in an Apple event and call the corresponding AS handler via -executeAppleEvent:error:.

Web Service Error 400 - Bad Request

I have a perplexing issue. I have Web Service A (henceforth WSA), a 3.5 .Net WCF, which I have added a call to Web Service B (henceforth WSB) which is a 3.5 .Net ASMX. When running WSA in the client (SOAPUI or WCFStorm), the WSB call times out per the client timeout setting.
In the VS event viewer I can see that the call to WSB immediately throws two error 400s:
Exception thrown: 'System.Net.WebException' in System.dll ("The remote
server returned an error: (400) Bad Request."). Exception thrown:
'System.Net.WebException' in System.dll ("The remote server returned
an error: (400) Bad Request.")
No reason is given. What is just as puzzling to me is the error doesn't go to my catch. When I debug and I hit the line of code that calls WSB, it's like a reset. No further code gets executed and no error is thrown by my WSA.
If I call WSB directly, it works. So nothing is wrong with WSB. At suggestion of a coworker, I took the code specific to my change and put it in a stand-alone service. I literally C&P the code and configs setting specific to me and adjust namespaces and class names. Lo and behold it works. My stand-alone web service called WSB just fine and get the data I expect.
A coworker and I checked the logs (IIS log for the service and the HTTPERR log) on the IIS server that WSB resides on to see if there was any mention of the 400 error. We found none.
So we are kind of perplexed at this point. The only thing we can think of is perhaps something in the web config might be interfering but have no idea what it could be.
If you have any suggestions of where else to look that would be helpful.
And it would be nice to know why it isn't falling into my error handler.
Thanks.
Update: It was requested I add config and code. I don't think it will help honestly and it is pretty straightforward. I can't put the real code due to company reasons but it is basically this:
In web config:
<configuration>
<appSettings>
<add key="endpointUrl" value = "someurl" />
</appSettings>
.
.
.
<applicationSettings>
<MyService.Properties.Settings>
<setting name="MyService_TheirService"
serializeAs="String">
<value>someurl</value>
</setting>
</MyService.Properties.Settings>
</applicationSettings>
Even though the data is super small I did try making large reader settings and such:
<binding name="CustomHtttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="01:50:00" openTimeout="01:50:00" sendTimeout="01:50:00" receiveTimeout="01:50:00" >
<readerQuotas maxDepth="128"
maxStringContentLength="8388608"
maxArrayLength="2147483646"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
</binding>
Code:
using MyService.TheirService
.
.
.
var theirURL = ConfigurationManager.AppSettings["endpointUrl"];
var oSvc = new TheirServiceObject
{
Url = theirURL
};
int numberIneed = oSvc.SomeMethod();
That last line is where it throws the 400.
UPDATE 2:
A colleague show me how to use Fiddler. And I can now see that the request to WSB is absolute garbage.
xڭ s 6 mr!!u \ .3 5'3 G QOH>Iп kX M3 ~vY ) X e Z
w ~ :jv -ݴwڽHb Yqv A :(Q Z; >9W O0g 6 .ɖVlU Ţ 8Z
< ( t eSv U]r R $N \
Some odd encoding? At least it's another clue.
Wanted to let you know this problem was solved. Another Dev that had worked on this service before but no longer just happened to walk by and I said "Hey! Look at this!"
They saw the garbage request data and said "That looks like compression. Look up compression in the project."
Turn out there was a custom compression component that was compressing the outgoing data of the service and you needed to add 2 lines of code to decompress. After adding those lines to the top of my method everything immediately worked.
The lesson here is if your project is doing some weird stuff that defies reason, try and find as many people as you can that worked on it before even if they aren't working on it anymore.

How to implement a expression builder in C++/QT which is similar to Microsoft TFS query builder?

In Microsoft TFS, there is a query builder as follow:
And I'm requested to implement a feature just like TFS query builder in C++/QT. But I don't even know how to google it.
Basically, with this feature, user will be able to set the condition to execute a specific action when our app running. eg:
// the condition will be set by user before run this application
// and I want provide a UI similar to TFS query to user
if (var_a >= 0 && (var_b + var_c) < 10)
{
prompt the warning dialog
}
this condition (var_a >= 0 && (var_b + var_c) < 10) will be stored as xml as below:
<ConditionPair Operator="AND">
<Condition Operator="GE">
<LValue>
<Kind>Variable</Kind>
<Value>var_a</Value>
</LValue>
<RValue>
<Kind>Const</Kind>
<Value>0</Value>
</RValue>
</Condition>
<Condition Operator="LT">
<LValue>
<Kind>Expression</Kind>
<Value>
<MathExp Operator="ADD">
<LValue>
<Kind>Variable</Kind>
<Value>var_b</Value>
</LValue>
<RValue>
<Kind>Variable</Kind>
<Value>var_c</Value>
</RValue>
</MathExp>
</Value>
</LValue>
<RValue>
<Kind>Const</Kind>
<Value>10</Value>
</RValue>
</Condition>
</ConditionPair>
I know how to implement the UI, but I DO NOT know how to interpret the expression.
Is there any open source library or blog about this topic available online?
Any thoughts about this is appreciated.
I don't really know if I've understood you, but maybe you could use Qt Script
to interpret (parse) the commands and then act.

Cannot get mappings to work

I have the following directory structure:
| SITES_FOLDER
|___ WEBSITE1
|___ WEBSITE_CFC
|___ CFC_DIR
WEBSITE1 contains an Application.cfc and some pages. Then I have a component ShoppingCart.cfc inside the WEBSITE_CFC directory that is instantiated on session start using this code:
createObject("component","WEBSITE_CFC.ShoppingCart").Init() />
This works.
Now I move ShoppingCart.cfc to the CFC_DIR directory and change my instantiate code to:
createObject("component","CFC_DIR.ShoppingCart").Init() />
Obviously this does not work because ColdFusion searches for a "CFC_DIR" directory under the root directory "WEBSITE1" and doesn't find it.
I thought this problem would be solved by using mappings so I go to the CFIDE administrator. Server Settings > Mappings.
Logical path: "CFC_DIR"
Directory path: "C:\some\folders\SITES_FOLDER\CFC_DIR"
No luck. So then I tried in Application.cfc:
<cfset THIS.mappings["/CFC_DIR"] = "C:\some\folders\SITES_FOLDER\CFC_DIR" />
This did not work either!
EDIT:
Maybe I understand: if I try to create the CFC from a cfm template, it works.
The error comes up when I try to create it inside the OnSessionStart Application.cfc's method:
Ensure that the name is correct and that the component or interface
exists. Message Could not find the ColdFusion component or interface
C:\some\folders\SITES_FOLDER\WEBSITE1|WEBSITE_CFC\ShoppingCart.cfc.
In other words, it keeps looking for it in the wrong dir.
WHY?
If you're changing the file to /CFC_DIR but it's still using /WEBSITE_CFC it sounds like the cache needs clearing.
Clear the Cache in CF Admin
Clearing the cache can be done manually in the ColdFusion Administrator. After login, the third item in "Server Settings" is "Caching". Scroll to the bottom of the page for buttons to clear the cache.
For development purposes you may want to consider disabling the various caching options on this page entirely - they can be useful for performance improvement on live servers, but are generally an unnecessary hindrance on your development machine.
Clear the Cache Programmatically
If you have an automated deployment, you don't want to have to login to the CF Admin on remote servers and press buttons. Fortunately, you can also clear the cache programmatically:
<cfscript>
createObject("Component", "cfide.adminapi.administrator")
.login("**replace with admin password**");
RuntimeService = createObject("component", "cfide.adminapi.runtime");
// Clear whole cache:
RuntimeService.clearTrustedCache();
// Clear cache for individual files:
RuntimeService.clearTrustedCache("/path/to/file1.cfm,/path/to/file2.cfm");
// Clear component cache:
RuntimeService.clearComponentCache();
</cfscript>
(Code adapted from Charlie's blog entry.)
The API for the Admin Runtime component can be found at http://www.cfexecute.com/admin-api-documentation/runtime-cfc/

Sitecore context in HttpHandler

I have HttpTaskAsyncHandler in my sitecore solution and i call it I have sutup IngnoreUrlPrefix and etc.
By some reason i can't get access to SC.Context.Database Database is null in ProcessRequestAsync(HttpContext context) method,
it looks like I don't access to Sitecore context in HttpHandler.
How to resolve it ?
Thanks.
You wont be able to access Sitecore Context (Database or Item) in the Handler. We have confirmed this with Sitecore Support for our task.
The best way is Implement a Processor in the Request pipeline begin.
How to Implement
Inherit HttpRequestProcessor in your class found in (using Sitecore.Pipelines.HttpRequest;)
and add that Processor after SiteResolver in < httpRequestBegin >
<processor type="Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel" />
<!-- Custom Module -->
<processor type="SND641.Customization.RobotsModule, SND641" />
If you choose to ignore your script file (by using IgnoreUrlPrefix), then you it will not be processed by Sitecore's request pipeline and thus will not have a Sitecore context.
I think you can solve it by removing your url prefix from IgnoreUrlPrefix and make sure the file extension of your handler is added to the allowed extensions parameter of the FilterUrlExtensions pipeline processor:
<processor type="Sitecore.Pipelines.HttpRequest.FilterUrlExtensions, Sitecore.Kernel">
<param desc="Allowed extensions (comma separated)">aspx</param>
</processor>
This way you can call your script and still have Sitecore process all the pipelines.
You can get context without pipeline. Along with web.config handler definition, you will need to add under customHandler. It helps in getting sitecore context. E.g
<customHandlers>
<handler trigger="blogfeed.xml" handler="blogfeed.xml" />
</customHandlers>
I'm sorry if I'm not getting exactly what you are trying to do. But by working with handlers I did have issues that my code was not able to access the sitecore object even when I updated the web.config and
I noticed that my handler was like this:
public class GetHandler: IHttpHandler
{
...
}
by adding the System.web.SessionState.IrequiresSessionStatem, like this:
public class GetHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{....}
then everything started to work and I was able to get items from sitecore without issues:
Public void ProcessRequest(HttpContext context)
{
Database webdb = Factory.GetDatabase("web");
}
previous my change the webdb was coming with nothing and the code was coming back with "Command "Sitecore.Database" is not valid"
after that changes, as I said, everything worked for me.
I hope this helps and adds some value to the existing answers.
regards,