How to add a proxy to NSURLSession in Xamarin.iOS? - objective-c

I need to load the content of the webview using a proxy.
I have this code (Objective-C):
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.connectionProxyDictionary = #{ (NSString *)kCFStreamPropertyHTTPProxyHost: [proxyURL host], (NSString *)kCFStreamPropertyHTTPProxyPort: [proxyURL port] };
The following Xamarin code doesn't work, ConnectionProxyDictionary is set but application doesn't use this settings:
var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration;
configuration.ConnectionProxyDictionary = new NSDictionary("kCFStreamPropertyHTTPProxyHost", proxyURL.Host, "kCFStreamPropertyHTTPProxyPort", proxyURL.port);
How to port above Objective-C code to Xamarin.iOS? Is there another way to achieve the same goal?

The reason it does not work is because in Objective-C, the kXX is replaced with an actual reference to a constant, and in C#, you just plugged a string name.
You need to fetch the value of that constant and pass it:
Use this:
using MonoTouch.ObjCRuntime;
...
var keyHost = Dlfcn.GetStringConstant ("kCFStreamPropertyHTTPProxyHost")
var keyPort = Dlfcn.GetStringConstant ("kCFStreamPropertyHTTPProxyPort")
Then use keyHost and keyPort as your parameters in the NSDictionary

var configuration = NSUrlSessionConfiguration.DefaultSessionConfiguration;
NSObject[] values = new NSObject[]
{
NSObject.FromObject(proxyURL.host), //ProxyHost
NSNumber.FromInt32 (proxyURL.port), //Port
NSNumber.FromInt32 (1), //Enable HTTP proxy
};
NSObject[] keys = new NSObject[]
{
NSObject.FromObject("HTTPProxy"),
NSObject.FromObject("HTTPPort"),
NSObject.FromObject("HTTPEnable")
};
NSDictionary proxyDict = NSDictionary.FromObjectsAndKeys (values, keys);
configuration.ConnectionProxyDictionary = proxyDict;
var session = NSUrlSession.FromConfiguration (configuration);
var task = session.CreateDataTask(NSUrl.FromString("http://google.com"));
task.Resume ();

Related

Printing with the system dialog when using PMPrintSession

Below is the code I we are using to print on mac. Is there an easy way to allow printing using the system dialog? It looks like at one time PMSessionBeginDocument & PMSessionBeginPage were a thing, but now all I can find is the NoDialog options.
Are these calls still usable with the latest frameworks? Or is there another way to print using the system dialog?
PMPrintSession lPrintSession;
PMCreateSession(&lPrintSession);
PMPrintSettings lPrintSettings;
PMCreatePrintSettings(&lPrintSettings);
PMSessionDefaultPrintSettings(lPrintSession, lPrintSettings);
...
PMSessionSetCurrentPMPrinter(lPrintSession, lPrinter);
...
PMSetPageRange(lPrintSettings, 1, 1);
PMSetCopies(lPrintSettings, inCopies, false);
if (!inUseSystemDialog) {
PMSessionBeginCGDocumentNoDialog(lPrintSession, lPrintSettings, lPageFormat);
PMSessionBeginPageNoDialog(lPrintSession, lPageFormat, NULL);
} else {
// TODO: What do we do here? Are these calls usable?
// PMSessionBeginDocument(lPrintSession, lPrintSettings, lPageFormat);
// PMSessionBeginPage(lPrintSession, lPageFormat, NULL);
}
CGContextRef lGraphics;
PMSessionGetCGGraphicsContext(lPrintSession, &lGraphics);
...
PMSessionEndPageNoDialog(lPrintSession);
PMSessionEndDocumentNoDialog(lPrintSession);
You can run an NSPrintPanel to show the system print dialog. For that, you also need to set up an NSPrintInfo object:
NSPrintInfo* printInfo = [NSPrintInfo new];
// set printInfo.printer if you want to override the default
PMPrintSettings printSettings = printInfo.PMPrintSettings;
// configure printSettings
[printInfo updateFromPMPrintSettings];
PMPageFormat pageFormat = printInfo.PMPageFormat;
// configure pageFormat
[printInfo updateFromPMPageFormat];
Create the panel and run it with that info object:
NSPrintPanel* panel = [NSPrintPanel printPanel];
// configure panel; for example, set its options property
NSInteger result = [panel runModalWithPrintInfo:printInfo];
Use the info as the basis of your print session:
if (result == NSOKButton)
{
PMPrintSession session = printInfo.PMPrintSession;
printSettings = printInfo.PMPrintSettings;
pageFormat = printInfo.PMPageFormat;
PMSessionBeginCGDocumentNoDialog(session, printSettings, pageFormat);
PMSessionBeginPageNoDialog(session, pageFormat, NULL);
CGContextRef lGraphics;
PMSessionGetCGGraphicsContext(session, &lGraphics);
...
PMSessionEndPageNoDialog(session);
PMSessionEndDocumentNoDialog(session);
}

Pentaho - upload file using API

I need to upload a file using an API.
I tried REST CLIENT and didn't find any options.
Tried with HTTP POST and that responded with 415.
Please suggest how to accomplish this
Error 415 is “Unsupported media type”.
You may need to change the media type of the request or check whether that type of file us accepted by the remote server.
https://en.m.wikipedia.org/wiki/List_of_HTTP_status_codes
This solution uses only standard classes of jre 7. Add a step Modified Java Script Value in your transformation. You will have to add two columns in the flow: URL_FORM_POST_MULTIPART_COLUMN and FILE_URL_COLUMN, you can add as many files as you want, you will just have to call outputStreamToRequestBody.write more times.
try
{
//in this step you will need to add two columns from the previous flow -> URL_FORM_POST_MULTIPART_COLUMN, FILE_URL_COLUMN
var serverUrl = new java.net.URL(URL_FORM_POST_MULTIPART_COLUMN);
var boundaryString = "999aaa000zzz09za";
var openBoundary = java.lang.String.format("\n\n--%s\nContent-Disposition: form-data\nContent-Type: text/xml\n\n" , boundaryString);
var closeBoundary = java.lang.String.format("\n\n--%s--\n", boundaryString);
// var netIPSocketAddress = java.net.InetSocketAddress("127.0.0.1", 8888);
// var proxy = java.net.Proxy(java.net.Proxy.Type.HTTP , netIPSocketAddress);
// var urlConnection = serverUrl.openConnection(proxy);
var urlConnection = serverUrl.openConnection();
urlConnection.setDoOutput(true); // Indicate that we want to write to the HTTP request body
urlConnection.setRequestMethod("POST");
//urlConnection.addRequestProperty("Authorization", "Basic " + Authorization);
urlConnection.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
var outputStreamToRequestBody = urlConnection.getOutputStream();
outputStreamToRequestBody.write(openBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.write(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(FILE_URL_COLUMN)));
outputStreamToRequestBody.write(closeBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.flush();
var httpResponseReader = new java.io.BufferedReader(new java.io.InputStreamReader(urlConnection.getInputStream()));
var lineRead = "";
var finalText = "";
while((lineRead = httpResponseReader.readLine()) != null) {
finalText += lineRead;
}
var status = urlConnection.getResponseCode();
var result = finalText;
var time = new Date();
}
catch(e)
{
Alert(e);
}
I solved this by using the solution from http://www.dietz-solutions.com/2017/06/pentaho-data-integration-multi-part.html
Thanks Ben.
He's written a Java class for Multi-part Form submission. I extendd by adding a header for Authorization...

Set Custom KeyEquivalent in Services Menu

OmniFocus has a Cocoa Service that allows you to create tasks based upon selected items.
It has a preference that allows you to set the keyboard shortcut that triggers the Service. This is not just a global hotkey, it's a bona fide Service that shows up in the menu.
You can the keyboard shortcut to pretty much any combination, including combinations with ⌥ and ^. This functionality is not documented - the docs seem to say that KeyEquivalents must be a ⌘+[⇧]+someKey.
Once this is set, I observe three things:
The OmniFocus Info.plist file does not contain a KeyEquivalent listed. This is not surprising, as the file is read-only.
The pbs -dump_pboard utility lists NSKeyEquivalent = {}; for the service.
Using NSDebugServices lists this interesting line that does not show up with most debugging sessions (Obviously, for keyboard shortcut ⌃⌥⌘M): OmniFocus: Send to Inbox (com.omnigroup.OmniFocus) has a custom key equivalent: <NSKeyboardShortcut: 0x7fb18a0d18f0 (⌃⌥⌘M)>.
So my questions are twofold, and I suspect they are related:
How do you dynamically change a service's KeyEquivalent?
How do you set the KeyEquivalent to a combination including ⌃ and ⌥
Thank you!
Figured it out. The basic process is described here: Register NSService with Command Alt NSKeyEquivalent
The code is this:
//Bundle identifier from Info.plist
NSString* bundleIdentifier = #"com.whatever.MyApp";
//Services -> Menu -> Menu item title from Info.plist
NSString* appServiceName = #"Launch My Service";
//Services -> Instance method name from Info.plist
NSString* methodNameForService = #"myServiceMethod";
//The key equivalent
NSString* keyEquivalent = #"#~r";
CFStringRef serviceStatusName = (CFStringRef)[NSString stringWithFormat:#"%# - %# - %#", bundleIdentifier, appServiceName, methodNameForService];
CFStringRef serviceStatusRoot = CFSTR("NSServicesStatus");
CFPropertyListRef pbsAllServices = (CFPropertyListRef) CFMakeCollectable ( CFPreferencesCopyAppValue(serviceStatusRoot, CFSTR("pbs")) );
// the user did not configure any custom services
BOOL otherServicesDefined = pbsAllServices != NULL;
BOOL ourServiceDefined = NO;
if ( otherServicesDefined ) {
ourServiceDefined = NULL != CFDictionaryGetValue((CFDictionaryRef)pbsAllServices, serviceStatusName);
}
NSUpdateDynamicServices();
NSMutableDictionary *pbsAllServicesNew = nil;
if (otherServicesDefined) {
pbsAllServicesNew = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary*)pbsAllServices];
} else {
pbsAllServicesNew = [NSMutableDictionary dictionaryWithCapacity:1];
}
NSDictionary *serviceStatus = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, #"enabled_context_menu",
(id)kCFBooleanTrue, #"enabled_services_menu",
keyEquivalent, #"key_equivalent", nil];
[pbsAllServicesNew setObject:serviceStatus forKey:(NSString*)serviceStatusName];
CFPreferencesSetAppValue (
serviceStatusRoot,
(CFPropertyListRef) pbsAllServicesNew,
CFSTR("pbs"));
Boolean result = CFPreferencesAppSynchronize(CFSTR("pbs"));
if (result) {
NSUpdateDynamicServices();
NSLog(#"successfully installed our alt-command-r service");
} else {
NSLog(#"couldn't install our alt-command-r service");
}
If the code succeeds, you can view this in ~/Library/Preferences/pbs.plist
You should see something like:
NSServicesStatus = {
"com.whatever.MyApp - Launch My Service - myServiceMethod" = {
enabled_context_menu = :true;
enabled_services_menu = :true;
key_equivalent = "#~r";
};

how to specify open id realm in openid4java 0.9.5

my url # development : http://192.168.0.1:8888/com.company.MyEntryPoint/MyEntrypoint.html
my url # live env : http://www.example.com/com.company.MyEntryPoint/MyEntrypoint.html
I need users to authenticate using open id,
this is how i want my realm to be:
*.company.MyEntryPoint
I wrote a simple code to specify realm:
AuthRequest authReq =
manager.authenticate(
discovered,
returnToUrl,
"*.company.MyEntryPoint"
);
it does not work.
Exception:
org.openid4java.message.MessageException: 0x301: Realm verification failed (2) for: *.company.MyEntryPoint
at org.openid4java.message.AuthRequest.validate(AuthRequest.java:354)
at org.openid4java.message.AuthRequest.createAuthRequest(AuthRequest.java:101)
at org.openid4java.consumer.ConsumerManager.authenticate(ConsumerManager.java:1073)
Of all the combinations I tried, curiously, the following worked:
AuthRequest authReq =
manager.authenticate(
discovered,
returnToUrl,
"http://localhost:8888/com.capgent.MyEntryPoint"
);
This does not solves my issue but rather complicates it :)
According to google and open id spec it should have worked
complete code snippet:
List discoveries = manager.discover(clientUrl);
DiscoveryInformation discovered = manager.associate(discoveries);
AuthRequest authReq = manager.authenticate(discovered, returnToUrl,"*.company.MyEntryPoint");
FetchRequest fetch = FetchRequest.createFetchRequest();
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
fetch.addAttribute("country", "http://axschema.org/contact/country/home", true);
fetch.addAttribute("firstname", "http://axschema.org/namePerson/first", true);
fetch.addAttribute("lastname", "http://axschema.org/namePerson/last", true);
fetch.addAttribute("language", "http://axschema.org/pref/language", true);
authReq.addExtension(fetch);
String returnStr;
if (!discovered.isVersion2())
{
returnStr = authReq.getDestinationUrl(true);
}
else
{
returnStr = authReq.getDestinationUrl(false);
}
What am I doing wrong over here ?
returnStr = authReq.getDestinationUrl(false); => returnStr = authReq.getDestinationUrl(true);

How to get output of a webpage in ActionScript 2

For Actionscript 2.0
Let's say this page
www.example.com/mypage
returns some html that I want to parse in Actionscript.
How do i call this page from Actionscript while getting back the response in a string variable?
use LoadVars():
var lv = new LoadVars();
//if you want to pass some variables, then:
lv.var1 = "BUTTON";
lv.var2 = "1";
lv.sendAndLoad("http://www.example.com/mypage.html", lv, "POST");
lv.onLoad = loadedDotNetVars;
function loadedDotNetVars(success)
{
if(success)
{
// operation was a success
trace(lv.varnameGotFromPage)
}
else
{
// operation failed
}
}
//if you dont want to send data, just get from it, then use just lv.Load(...) instead of sendAndLoad(...)
I understand. Use this code then:
docXML = new XML(msg);
XMLDrop = docXML.childNodes;
XMLSubDrop = XMLDrop[0].childNodes;
_root.rem_x = (parseInt(XMLSubDrop[0].firstChild));
_root.rem_y = (parseInt(XMLSubDrop[1].firstChild));
_root.rem_name = (XMLSubDrop[2].firstChild);
var htmlFetcher:LoadVars = new LoadVars();
htmlFetcher.onData = function(thedata) {
trace(thedata); //thedata is the html code
};
Use:
htmlFetcher.load("http://www.example.com/mypage");
to call.
I suppose you could use:
page = getURL("www.example.com/mypage.html");
And it would load the page contents on the page variable.