S3 signature mismatch with Amazon::S3 perl - perl

When I try to generate the request header along with the signature, I'm getting a signature mismatch error.
I used Amazon::S3 Perl module to generate the request. And when analyzed the difference in approach on how the signature is calculated between this module and AWS CLI, I found out that when I comment out the below line from S3.pm inside _make_request() method, makes the signature matches.
$self->_add_auth_header($http_headers, $method, $path)
unless exists $headers->{Authorization};
Am I referring it correctly or is there any other module I can use just for generating the signature alone or at the last option, I can write my own module which inherits the actual module (if possible or mimic the actual module with the custom change).

Related

"Modules that use an anonymous define() call must be loaded with a require() call"

In the walkthrough step 7: JSON Model example, the app apparently works as documented but I see the following error in the console:
Error: Modules that use an anonymous define() call must be loaded with a require() call; they must not be executed via script tag or nested into other modules.
The only other instance of this message that I could find seems, to my untrained eye, to deal with a wholly different scenario.
I've tried both Firefox and Chromium, CDN hosting vs local hosting, two different UI5 versions (1.77.0 and 1.79.0), both minified and plain, so I'd suppose this is really something in the code itself.
What could it be? Also, is it something I can safely ignore and why?
Anonymous define
Calling sap.ui.define([...],...) defines a module anonymously because the 1st argument is not a string (module name) but a list of the module's dependencies. If the module name is omitted, the framework automatically determines it based on how the module script was referenced.
Use anonymous sap.ui.define once at top-level of the JS file content, not multiple times.
Replace sap.ui.define with sap.ui.require when simply requiring existing modules.
Cf. my comment at https://github.com/SAP/openui5/issues/2203#issuecomment-420918457.
Named module define
The 1st argument in sap.ui.define("MyModule",[...] ,...) defines the name of the module manually which must be passed when:
Defining a nested module within an existing module definition in a single JS file content.
Defining a module which was initiated by a <script> tag from HTML.
The walkthrough is fixed with SAP/openui5#6302b8f and SAP/openui5-docs#43 accordingly.

Can I use environment variables or tilde in module.modulemap?

My module.modulemap file looks like this:
module CompanyInternalSDK {
header "~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
export *
}
However, I get this error:
/Users/username/Path/To/Project/CompanyInternalSDK/module.modulemap:2:12: error: header '~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h' not found
header "~/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
^
It compiles just fine when I use the absolute path without the tilde, but since this will be distributed like this to all developers, I want to use the tilde. Is there any way to make this work correctly?
I also tried to use an environment variable in the header string, but that didn't work either:
module CompanyInternalSDK {
header "${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
export *
}
/Users/username/Path/To/Project/CompanyInternalSDK/module.modulemap:2:12: error: header '${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h' not found
header "${HOME}/Company/CompanyInternalSDK.framework/Headers/CompanyInternalSDK.h"
^
No, the modulemap syntax does not expand tildes or environment variables. It ultimately just expects to stat the path you gave it, and if no file's there, it'll gripe.
Here's where the header file lookup is kicked off, during lexing of the module map file.
It ultimately passes the path to the SourceManager's FileManager to produce a File object, as here for a header in a framework's Headers/ public header folder.
getFile ultimately ends up calling out to getStatValue, which does a cache lookup.
The FileSystemStatCache::get eventually grounds out in LLVM's filesystem abstraction, where it calls sys::fs::status, which is documented to act like POSIX stat.
POSIX stat works with paths as-is, no tilde or environment variable expansion - the common availability of those is due to the shell helping you out, not something that happens automatically most of the time at the system level.
However, it's standard to use relative paths in module maps. The lexer respects this, and all the module map docs demonstrate this. In the common case where your module map file is colocated with your library and installed alongside it, this should suffice to properly resolve the paths.

How to use one module in another module in perl?

Iam writing a perl script ,in which iam using a module utils.pm and in utils.pm iam using another module DB.pm in which i have a sub routine connetToDB().
in utils.pm iam writing
use DB qw (connectToDB());
and below iam calling that subroutine as
my $connection=DB::connectToDB(); (This is line 30)
it is giving an error like follows. Can someone pls help?
Undefined subroutine &DB::connectToDB called at utils.pm line 30.
you can see the DB.pm code here
The direct error in the shown code is that inside qw() you need names. The use pragma
Imports some semantics into the current package from the named module
(my emphasis). The "connectToDB()", with parentheses, is not the correct name for the subroutine. The error message simply says that it didn't find such a sub.
So just drop the parens, use DB qw(connectToDB);.
The code for the package was added to the question and here are some comments.
A similar fix is needed with your #EXPORT: you need the subroutine names (lose &).
Perhaps more importantly, you defined the sub using prototypes. Your sub is consistent with the prototype you use so I'll assume that it's done on purpose.
This is a very advanced (mis?)feature, which is very different from similar looking devices in other languages and is normally not needed. Chances are that you expect wrong things from prototypes. Go search for it. I'd advise against.
A side note: the prototype-related () and & are not a part of the subroutine name.
The last executed statement that returns in a module must return true, or code won't compile. The convention to ensure this is to put 1; at the end of the package.
Finally, you shouldn't name the module DB as that namespace is used internally by Perl. Also, such a generic name is just not good for a module -- it makes it easy to run into conflicts.
use DB qw(connectToDB);
my $connection=DB->connectToDB();
or
if you have defined a constructor "new" in DB.pm module then
my $connection=DB->new();
my $result = $connection->connectToDB();

Perl HTTP Request content() issue

I want to put a file (file.img) as a POST data content, so if the file is in the same folder as the script, is $req->content(file.img); valid ?
Cheers
This seems to be something that you could easily test for yourself rather than asking us. What happened when you tried it?
(I'm going to assume that $req is an HTTP::Request object - I don't know why you wouldn't include that information in your question).
In short, no, it's not valid. And it's not valid for a number of reasons.
It's not valid because file.img would be interpreted as the bareword file concatenated with the bareword img - which would give the string fileimg.
It's not valid because use strict makes barewords illegal, so if you're using use strict (and you really should be) your code won't even compile.
It's not valid because HTTP::Request::content expects a sequence of bytes. So even if you didn't use use strict all this code would do would be to add the string fileimg to the request body.
If you want to add the contents of the file to the body, then you need to open the file, read in the data and then pass that data to content.
This is all explained in the documentation for HTTP::Request.

Perl shallow syntax check? ie. do not check syntax of imports

How can I perform a "shallow" syntax check on perl files. The standard perl -c is useful but it checks the syntax of imports. This is sometimes nice but not great when you work in a code repository and push to a running environment and you have a function defined in the repository but not yet pushed to the running environment. It fails checking a function because the imports reference system paths (ie. use Custom::Project::Lib qw(foo bar baz)).
It can't practically be done, because imports have the ability to influence the parsing of the code that follows. For example use strict makes it so that barewords aren't parsed as strings (and changes the rules for how variable names can be used), use constant causes constant subs to be defined, and use Try::Tiny changes the parse of expressions involving try, catch, or finally (by giving them & prototypes). More generally, any module that exports anything into the caller's namespace can influence parsing because the perl parser resolves ambiguity in different ways when a name refers to an existing subroutine than when it doesn't.
There are two problems with this:
How to not fail -c if the required modules are missing?
There are two solutions:
A. Add a fake/stub module in production
B. In all your modules, use a special catch-all #INC subroutine entry (using subs in #INC is explained here). This obviously has a problem of having the module NOT fail in real production runtime if the libraries are missing - DoublePlusNotGood in my book.
Even if you could somehow skip failing on missing modules, you would STILL fail on any use of the identifiers imported from the missing module or used explicitly from that module's namespace.
The only realistic solution to this is to go back to #1a and use a fake stub module, but this time one that has a declared and (as needed) exported identifier for every public interface. E.g. do-nothing subs or dummy variables.
However, even that will fail for some advanced modules that dynamically determine what to create in their own namespace and what to export in runtime (and the caller code could dynamically determine which subs to call - heck, sometimes which modules to import).
But this approach would work just fine for normal "Java/C-like" OO or procedural code that only calls statically named predefined public subs, methods and accesses exported variables.
I would suggest that it's better to include your code repository in your syntax check. perl -I/path/to/working/code/repo/local_perl/ -c or set PERL5LIB=/path/to/working/code/repo/local_perl/ prior to running perl -c. Either option should allow you to check against your working code, assuming you have it in a directory structure similar to your live code.
I guess you could make stubs for the missing libraries in your home folder.
Have you looked into PPI? I think it does follow imports, however it could perhaps be more easily modified to guess what looks like a function name.