Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Replacing a module dependency

by Bod (Parson)
on Apr 26, 2022 at 23:34 UTC ( [id://11143334]=perlquestion: print w/replies, xml ) Need Help??

Bod has asked for the wisdom of the Perl Monks concerning the following question:

We send automated emails with things like registration verifications automatically. We user MIME::Lite to do the sending and use the default send mechanism which is sendmail as it is a Linux server.

But we are having some issues with deliverability. So, I decided to switch to using SMTP instead to see if that works more reliably. To send via SMTP MIME::Lite uses Net::SMTP which in turn requires MIME::Base64. This last module is XS and I don't have it installed on the shared hosting.

We use Net::SMTP elsewhere to send lots of emails so I have looked at what I did in the past to get around this problem. It turns out that I created a new module that inherits from Net::SMTP and overrides the auth method. This works fine as we always send through the same SMTP server with the same authentication. Doing the same will be fine for the MIME::Lite setup.

Like this:

package Mail::SMTP; require Net::SMTP; $VERSION="1.0"; @ISA=qw(Net::SMTP); sub auth { my $self = shift; my $code; my $CMD_MORE = 3; my $CMD_OK = 2; my @cmd = ("AUTH LOGIN"); push @cmd, 'xxxxx='; # Base64 encoded username while (($code = $self->command(@cmd)->response()) == $CMD_MORE) { @cmd = ('xxxxx='); # Base64 encoded password } $code == $CMD_OK; } 1;

But, how can I easily get MIME::Lite to use the new module inherited from New::SMTP?

I could created a new module that inherits from MIME::Lite and just override the send_by_smtp with the only change being the require file it calls. But that doesn't seen a very elegant solution!

Is there some way to instead put a new version of Net::SMTP in a directory relative to my script and get MIME::Lite to use that? If so, how can I inherit from a module of the same name (but a different path) as the new module?

Or is there a 'better' solution I am missing?

Replies are listed 'Best First'.
Re: Replacing a module dependency
by haukex (Archbishop) on Apr 27, 2022 at 05:32 UTC

    MIME::Lite uses a harcoded require Net::SMTP;, so you can't tell it to use something else without modifying its code (or perhaps using an @INC hook, but that's fairly advanced and not something I'd necessarily recommend over the following). One possible approach would be to place your own version of Net::SMTP in @INC before any other paths with e.g. lib. However, this requires your version of Net::SMTP to also be called Net::SMTP, which means you'd need to copy Net::SMTP and modify it... personally, I actually think your suggestion of making a new module that inherits from MIME::Lite to be more elegant than that!

    However, note in general you probably want to consider switching to one of the newer Email::* modules by RJBS, the current maintainer of MIME::Lite - the documentation of that module starts with:

    MIME::Lite is not recommended by its current maintainer. There are a number of alternatives, like Email::MIME or MIME::Entity and Email::Sender, which you should probably use instead. MIME::Lite continues to accrue weird bug reports, and it is not receiving a large amount of refactoring due to the availability of better alternatives. Please consider using something else.

      Thanks haukex - it turns out MIME::Base64 is there so perhaps all the overrides are not needed. See Re^2: Replacing a module dependency

      I actually think your suggestion of making a new module that inherits from MIME::Lite to be more elegant than that!

      That's very nice to hear - thanks

      However, note in general you probably want to consider switching to one of the newer Email::* modules...

      Some time ago I suggested changing away from MIME::Lite and someone more knowledgable than I (hippo I think but I'm not certain and I cannot find the node) suggested that for my needs, it was a suitable choice. The code this is used in is relatively new (less than one year) so perhaps future code should start using an alternative...

      UPDATE:
      It was Corion here -> Re^3: printing output of a perl script to the Email body

Re: Replacing a module dependency
by kcott (Archbishop) on Apr 27, 2022 at 06:47 UTC

    G'day Bod,

    "... which in turn requires MIME::Base64. This last module is XS and I don't have it installed on the shared hosting."

    This statement surprised me. MIME::Base64 is a core module. Even if your shared hosting is only providing you with Perl v5.8, you should have it.

    $ corelist MIME::Base64 Data for 2021-05-20 MIME::Base64 was first released with perl v5.7.3

    Perl 5.8.0 was released 20 years ago (18-Jul-2002perlhist). I would recommend asking your provider to install this module immediately; if they refuse, find a new provider.

    — Ken

      Thanks Ken,

      I hadn't realise that MIME::Base64 was core!

      What I had done was to SSL onto the server and type

      perl -e "use MIME::Base64"
      This told me it couldn't find it which is why I tried to install it got the error that it needed access to the compiler. I did the same thing with Authen::SASL but that installed fine.

      Having found it is core I have checked again and found that MIME::Base64 is there. I guess I must have put in a typo :(

      So now I have a different issue to resolve...

      Niether of these throw an error:

      perl -e "use MIME::Base64" perl -e "use Authen::SASL"
      Yet, when I try to use MIME::Lite in SMTP mode I get the error:
      SMTP auth() command failed: No such file or directory Need MIME::Base64 and Authen::SASL todo auth

      UPDATE:
      Solved the error - it's a quirk of cPanel that I need to use cPanelUserConfig; to add all the correct paths to @INC when I've installed modules. Authen::SASL in this case.

Re: Replacing a module dependency
by hippo (Bishop) on Apr 27, 2022 at 09:42 UTC
    This last module is XS and I don't have it installed on the shared hosting.

    My advice remains the same as it was in 2020. If your shared hosting provider won't even install a core module then you need to move to a better shared hosting provider or to your own VM. How much time have you wasted over the past couple of years because of the shortcomings of your current hosting provider? The extra cost of better hosting would have repaid you many times over by now.

    While I don't disagree with haukex about migrating to newer, better-supported modules for this particular question, the absence of (and the hoster's refusal/inability to install) a core module like this will bite you again and again. Time to move.


    🦛

      While I don't disagree with haukex about migrating to newer, better-supported modules for this particular question, the absence of (and the hoster's refusal/inability to install) a core module like this will bite you again and again. Time to move.

      I agree with the latter part too :-)

Re: Replacing a module dependency
by Anonymous Monk on Apr 27, 2022 at 09:47 UTC

    We user MIME::Lite to do the sending and use the default send mechanism which is sendmail as it is a Linux server.

    But we are having some issues with deliverability. So, I decided to switch to using SMTP instead to see if that works more reliably.

    Probably not. Delivery issues aren't between you and your mail transfer agent; unless there's something seriously wrong with sendmail on the shared hosting, switching to SMTP to connect to the same MTA won't make any difference. Most likely, the target hosts (mail delivery agents) don't like your shared host as a mail transfer agent, and that's a problem you probably won't be able to solve. (You might get an improvement by switching to a different mail provider as your mail transfer agent and using SMTP to connect to them, but the difference is not in the protocol, but in the host.)

    They say it's because of spam, but a nice side effect of being a big mail provider and blocking anyone you don't like is your market share increasing when people give up on non-monopolist mail providers and switch over to you. Malice or incompetence? Why not both?

      Thanks for the information. I don't really understand what happens to email once it gets passed to either sendmail or Net::SMTP.

      The reason I was thinking SMTP may improve deliverability is that I can set the authentication account using SMTP. With sendmail accessed through MIME::Lite I don't have that control. This is an add-on domain in cPanel and I was thinking that the DKIM header in the email may not match the right parts of the authenticated sender. It's a bit of guesswork and clutching at straws really...

      I do know the issue is not entirely with other mail providers blocking mail from my mailhost. I can send automated emails to two different addresses with different domains which are both my add-on domains within cPanel and one fails and one succeeds. They are (presumably) going through the same mail filtering software and I cannot imagine the milhost blocking mail that originated with itself.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11143334]
Approved by GrandFather
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (1)
As of 2024-04-24 14:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found