How to use ngx_write_chain_to_temp_file correctly? - file-io

I am writing nginx module which construct nginx chain then write this chain buffer to nginx temporary file to use it later (just after write happen). I've been searching every page and the only solution come up is the one bellow:
// Create temp file to test
ngx_temp_file_t *tf;
tf = ngx_pcalloc(r->pool, sizeof (ngx_temp_file_t));
if (tf == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
tf->file.fd = NGX_INVALID_FILE;
tf->file.log = nlog;
tf->path = clcf->client_body_temp_path;
tf->pool = r->pool;
tf->log_level = r->request_body_file_log_level;
tf->persistent = r->request_body_in_persistent_file;
tf->clean = r->request_body_in_clean_file;
// if (r->request_body_file_group_access) {
// tf->access = 0660;
// }
if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, tf->persistent, tf->clean, tf->access) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (ngx_write_chain_to_temp_file(tf, bucket->first) == NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
This code does not return NGX_ERROR, is this meant nginx successful write temporary file into client_body_temporay_path? It the answer is yes, after that, I use fopen to open file, the file is not exist?
Can anyone please give me the right solution to handle ngx_write_chain_to_temp_file?

I find myself the solution
ngx_temp_file_t *tf;
tf = ngx_pcalloc(r->pool, sizeof (ngx_temp_file_t));
tf->file.fd = NGX_INVALID_FILE;
tf->file.log = nlog;
tf->path = clcf->client_body_temp_path;
tf->pool = r->pool;
tf->persistent = 1;
rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool, tf->persistent, tf->clean, tf->access);
//ngx_write_chain_to_file(&tf->file, bucket->first, bucket->content_length, r->pool);
ngx_write_chain_to_temp_file(tf, bucket->first);
The only thing I cannot understand is if I set tf->persistentto false (0), after the file created, I cannot read from it even if I've not passed response to output_filter yet.

Related

Call fetchgit without SSL Verify

I'm trying to use fetchgit to download source repos from my lab's private GitLab server, which currently self-signs its SSL certificate.
default.nix:
with (import <nixpkgs> {});
{ test-pkg = callPackage ./test-pkg.nix {
buildPythonPackage = python35Packages.buildPythonPackage;
};
}
test-pkg.nix:
{ buildPythonPackage,fetchgit }:
buildPythonPackage rec {
pname = "test-pkg";
version = "0.2.1";
src = fetchgit {
url = "https://gitlabserver/experiment-deployment/test-pkg";
rev = "refs/tags/v${version}";
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
};
}
Which results in the error when I call nix-shell
fatal: unable to access 'https://gitlabserver/experiment-deployment/test-pkg/': SSL certificate problem: self signed certificate
Looking at, build-support/fetchgit, it seems that fetchgit is made with mkDerivation, so I tried to make a new fetchgit using overrideAttrs. I pass in the git environment variable to make git ignore SSL verification, expecting that the variable will be initialized during the setup phase.
revised default.nix:
with (import <nixpkgs> {});
let fetchgit-no-verify = fetchgit.overrideAttrs { GIT_SSL_NO_VERIFY=true;} ;
in rec {
test-pkg = callPackage ./test-pkg.nix {
buildPythonPackage = python35Packages.buildPythonPackage;
fetchgit = fetchgit-no-verify;
};
}
I thought I was really clever when I thought of this over the weekend, only to discover that when implemented my new error states that
error: attribute 'overrideAttrs' missing, at [...]/default.nix:2:26
Inspecting fetchgit in nix repl shows that it is a functor attribute set. I tried for a little bit to get to the overrideAttrs, without success. Trying again I saw that git could be passed to to fetchGit,
re-revised default.nix:
with (import <nixpkgs> {});
let git = git.overrideAttrs { GIT_SSL_NO_VERIFY=true;} ;
fetchgit-no-verify = fetchgit.override { git=git-no-verify;} ;
in rec {
test-pkg = callPackage ./test-pkg.nix {
buildPythonPackage = python35Packages.buildPythonPackage;
fetchgit = fetchgit-no-verify;
};
}
but the new error:
error: attempt to call something which is not a function but a set, at /nix/store/jmynn33vcn3mcscsch0zf46fz9wsw05y-nixpkgs-20.03pre193309.c4196cca9ac/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:318:55
Finally, onto my questions. Is there a way to add the environment variable to the fetchgit or git derivations? Is there perhaps another way to connect--some builtin option I missed? I could use a private repository, using ssh and avoiding https, however due to how we deploy experiments I'd like to avoid that.
I was able to make this work with this ugly thing.
default.nix:
with (import <nixpkgs> {});
let fetchgit-no-verify = fetchgit // {
__functor = self : args :
(fetchgit.__functor self args).overrideAttrs (oldAttrs:{GIT_SSL_NO_VERIFY=true;});
} ;
in rec {
test-pkg = callPackage ./test-pkg.nix {
buildPythonPackage = python35Packages.buildPythonPackage;
fetchgit = fetchgit-no-verify;
};
}
fetchgit-no-verify uses the fetchgit functor set to begin with and overwrites the __functor attribute with a new function. The new functor just applies its arguments and then calls overrideAttrs.
This works, but I'm happy to award the answer to anybody who can add some insight or comes with another solution. For one, I'd like to know how the fetchgit derivation becomes a functor. Is this something callPackage does?.

Read 'hidden' input for CLI Dart app

What's the best way to receive 'hidden' input from a command-line Dart application? For example, in Bash, this is accomplished with:
read -s SOME_VAR
Set io.stdin.echoMode to false:
import 'dart:io' as io;
void main() {
io.stdin.echoMode = false;
String input = io.stdin.readLineSync();
// or
var input;
while(input != 32) {
input = io.stdin.readByteSync();
if(input != 10) print(input);
}
// restore echoMode
io.stdin.echoMode = true;
}
This is a slightly extended version, key differences are that it uses a finally block to ensure the mode is reset if an exception is thrown whilst the code is executing.
The code also uses a waitFor call (only available in dart cli apps) to turn this code into a synchronous call. Given this is a cli command there is no need for the complications that futures bring to the table.
The code also does the classic output of '*' as you type.
If you are doing much cli work the below code is from the dart package I'm working on called dcli. Have a look at the 'ask' method.
https://pub.dev/packages/dcli
String readHidden() {
var line = <int>[];
try {
stdin.echoMode = false;
stdin.lineMode = false;
int char;
do {
char = stdin.readByteSync();
if (char != 10) {
stdout.write('*');
// we must wait for flush as only one flush can be outstanding at a time.
waitFor<void>(stdout.flush());
line.add(char);
}
} while (char != 10);
} finally {
stdin.echoMode = true;
stdin.lineMode = true;
}
// output a newline as we have suppressed it.
print('');
return Encoding.getByName('utf-8').decode(line);
}

Adobe Illustrator - Scripting crashes when trying to fit to artboards command

activeDocument.fitArtboardToSelectedArt()
When calling this command, AI crashes on AI 5.1/6 32bit and 64bit versions. I can use the command from the menu. Has anyone encountered this? does anyone know of a work around?
The full code.
function exportFileToJPEG (dest) {
if ( app.documents.length > 0 ) {
activeDocument.selectObjectsOnActiveArtboard()
activeDocument.fitArtboardToSelectedArt()//crashes here
activeDocument.rearrangeArtboards()
var exportOptions = new ExportOptionsJPEG();
var type = ExportType.JPEG;
var fileSpec = new File(dest);
exportOptions.antiAliasing = true;
exportOptions.qualitySetting = 70;
app.activeDocument.exportFile( fileSpec, type, exportOptions );
}
}
var file_name = 'some eps file.eps'
var eps_file = File(file_name)
var fileRef = eps_file;
if (fileRef != null) {
var optRef = new OpenOptions();
optRef.updateLegacyText = true;
var docRef = open(fileRef, DocumentColorSpace.RGB, optRef);
}
exportFileToJPEG ("output_file.jpg")
I can reproduce the bug with AI CS5.
It seems that fitArtboardToSelectedArt() takes the index of an artboard as an optional parameter. When the parameter is set, Illustrator doesn't crash. (probably a bug in the code handling the situation of no parameter passed)
As a workaround you could use:
activeDocument.fitArtboardToSelectedArt(
activeDocument.artboards.getActiveArtboardIndex()
);
to pass the index of the active artboard with to the function. Hope this works for you too.
Also it's good practice to never omit the semicolon at the end of a statement.

Adobe AIR NativeProcess fails with spaces in arguments?

I have a problem running the NativeProcess if I put spaces in the arguments
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
fPath = "C:\\Windows\\System32\\cmd.exe";
args.push("/c");
args.push(scriptDir.resolvePath("helloworld.bat").nativePath);
}
file = new File(fPath);
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
args.push("blah");
nativeProcessStartupInfo.arguments = args;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
in the above code, if I use
args.push("blah") everything works fine
if I use
args.push("blah blah") the program breaks as if the file wasn't found.
Seems like I'm not the only one:
http://tech.groups.yahoo.com/group/flexcoders/message/159521
As one of the users their pointed out, it really seems like an awful limitation by a cutting edge SDK of 21st century. Even Alex Harui didn't have the answer there and he's known to workaround every Adobe bug:)
Any ideas?
I am using AIR 2.6 SDK in JavaScript like this, and it is working fine even for spaces.
please check your code with this one.
var file = air.File.applicationDirectory;
file = file.resolvePath("apps");
if (air.Capabilities.os.toLowerCase().indexOf("win") > -1)
{
file = file.resolvePath(appFile);
}
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
process = new air.NativeProcess();
process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.addEventListener(air.ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);
process.start(nativeProcessStartupInfo);
To expand on this: The reason that this works (see post above):
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
is that air expects that the arguments being passed to the nativeProcess are delimited by spaces. It chokes if you pass "C:\folder with spaces\myfile.doc" (and BTW for AIR a file path for windows needs to be "C:\\folder with spaces\\myfile.doc") you would need to do this:
args.push("C:\\folder");
args.push("with");
args.push("spaces\\myfile.doc");
Hence, something like this works:
var processArgs = new air.Vector["<String>"]();
var path = "C:\\folder with spaces\\myfile.doc"
var args = path.split(" ")
for (var i=0; i<args.length; i++) {
processArgs.push(args[i]);
};
UPDATE - SOLUTION
The string generated by the File object by either nativePath or resolvePath uses "\" for the path. Replace "\" with "/" and it works.
I'm having the same problem trying to call 7za.exe using NativeProcess. If you try to access various windows directories the whole thing fails horribly. Even trying to run command.exe and calling a batch file fails because you still have to try to pass a path with spaces through "arguments" on the NativeProcessStartupInfo object.
I've spent the better part of a day trying to get this to work and it will not work. Whatever happens to spaces in "arguments" totally destroys the path.
Example 7za.exe from command line:
7za.exe a MyZip.7z "D:\docs\My Games\Some Game Title\Maps\The Map.map"
This works fine. Now try that with Native Process in AIR. The AIR arguments sanitizer is FUBAR.
I have tried countless ways to put in arguments and it just fails. Interesting I can get it to spit out a zip file but with no content in the zip. I figure this is due to the first argument set finally working but then failing for the path argument.
For example:
processArgs[0] = 'a';
processArgs[1] = 'D:\apps\flash builder 4.5\project1\bin-debug\MyZip.7z';
processArgs[2] = 'D:\docs\My Games\Some Game Title\Maps\The Map.map';
For some reason this spits out a zip file named: bin-debugMyZip.7z But the zip is empty.
Whatever AIR is doing it is fraking up path strings. I've tried adding quotes around those paths in various ways. Nothing works.
I thought I could fall back on calling a batch file from this example:
http://technodesk.wordpress.com/2010/04/15/air-2-0-native-process-batch-file/
But it fails as well because it still requires the path to be passed through arguments.
Anyone have any luck calling 7z or dealing with full paths in the NativeProcess? All these little happy tutorials don't deal with real windows folder structure.
Solution that works for me - set path_with_space as "nativeProcessStartupInfo.workingDirectory" property. See example below:
public function openPdf(pathToPdf:String):void
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
var file:File = File.applicationDirectory.resolvePath("C:\\Windows\\System32\\cmd.exe");
nativeProcessStartupInfo.executable = file;
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath(pathToPdf).parent;
var processArgs:Vector.<String> = new Vector.<String>();
processArgs[0] = "/k";
processArgs[1] = "start";
processArgs[2] = "test.pdf";
nativeProcessStartupInfo.arguments = processArgs;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
}
args.push( '"blah blah"' );
Command line after all supports spaces if they are nested whithin "".
So if lets say you have a file argument :
'test/folder with space/blah'
Convert it to the following
'test/"folder with space"/blah'
Optionally use a filter:
I once had a problem like this in AIR, i just simply filter the text before i push it into the array. My refrence use CASA lib though
import org.casalib.util.ArrayUtil;
http://casalib.org/
/**
* Filters a string input for 'safe handling', and returns it
**/
public function stringFilter(inString:String, addPermitArr:Array = null, permitedArr:Array = null):String {
var sourceArr:Array = inString.split(''); //Splits the string input up
var outArr:Array = new Array();
if(permitedArr == null) {
permitedArr = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" as String).split('');
}
if( addPermitArr != null ) {
permitedArr = permitedArr.concat( addPermitArr );
}
for(var i:int = 0; i < sourceArr.length; i++) {
if( ArrayUtil.contains( permitedArr, sourceArr[i] ) != 0 ) { //it is allowed
outArr.push( sourceArr[i] );
}
}
return (outArr.join('') as String);
}
And just filter it via
args.push( stringFilter( 'blah blah', new Array('.') ) );
Besides, it is really bad practice to use spaces in file names / arguments, use '_' instead. This seems to be originating from linux though. (The question of spaces in file names)
This works for me on Windws7:
var Xargs:Array = String("/C#echo#a trully hacky way to do this :)#>#C:\\Users\\Benjo\\AppData\\Roaming\\com.eblagajna.eBlagajna.POS\\Local Store\\a.a").split("#");
var args:Vector.<String> = new Vector.<String>();
for (var i:int=0; i<Xargs.length; i++) {
trace("Pushing: "+Xargs[i]);
args.push(Xargs[i]);
};
NPI.arguments = args;
If your application path or parameter contains spaces, make sure to wrap it in quotes. For example path of the application has spaces C:\Program Files (x86)\Camera\Camera.exe use quotes like:
"C:\Program Files (x86)\Camera\Camera.exe"

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.