I'm not exactly sure a CSRF token mismatch exception would return a 405, but your general description and setup sounds like it could be the problem here. Laravel expects a CSRF token to be provided for POST requests through the VerifyCsrfToken middleware, unless explicitly disabled.
Try adding the "/endpoints/sendgrid/mail/email" route to the "excepts" array in app\Http\Middleware\VerifyCsrfToken.php and see if that makes a difference?
Still odd though it works sometimes...
POST request arrives as GET, returns 405: Method Not Allowed
I've defined an endpoint to receive POST requests from SendGrid's Parse API. My issue is that many of these requests return "405: Method Not Allowed" to SendGrid.
If I open the endpoint to all request methods, it never generates 405 errors. However by the time execution reaches my controller method $request->method() often returns 'GET' and all of the expected POST parameters are missing.
- I have confirmed with SendGrid they ONLY send POST requests
- I have setup a RunScope endpoint to capture all their requests and independently confirmed they ONLY send POST requests
- Below is a recent stretch from my access log
167.89.125.253 - - [14/Aug/2016:14:57:34 -0400] "POST /endpoints/sendgrid/mail/email HTTP/1.1" 405 4485 "-" "SendGrid 1.0"
167.89.125.221 - - [14/Aug/2016:14:58:01 -0400] "POST /endpoints/sendgrid/mail/email HTTP/1.1" 405 4485 "-" "SendGrid 1.0"
167.89.125.235 - - [14/Aug/2016:15:06:04 -0400] "POST /endpoints/sendgrid/mail/email HTTP/1.1" 405 4485 "-" "SendGrid 1.0"
167.89.125.254 - - [14/Aug/2016:15:14:21 -0400] "POST /endpoints/sendgrid/mail/email HTTP/1.1" 204 - "-" "SendGrid 1.0"
167.89.125.225 - - [14/Aug/2016:15:21:14 -0400] "POST /endpoints/sendgrid/mail/email HTTP/1.1" 405 4485 "-" "SendGrid 1.0"
The access log also indicates that all requests are POST. I don't see any redirects happening. And while sometimes the requests work as expected, most of the time they result in 405.
I am losing my mind over this one. Please help!
My route definition:
Route::group(['prefix' => 'endpoints', 'namespace' => 'Endpoints'], function() {
Route::group(['prefix' => 'sendgrid'], function() {
Route::group(['prefix' => 'mail'], function() {
Route::post('email', ['uses' => 'SendGridController@incomingEmail', 'as' => 'sendGrid.mail.email']);
});
});
Route::group(['prefix' => 'leads'], function() {
Route::post('email', ['uses' => 'EmailProspectController@incomingEmail', 'as' => 'sendGrid.leads.email']);
Route::post('prospects', ['uses' => 'EmailProspectController@addProspect', 'as' => 'sendGrid.leads.prospects']);
});
});
My controller:
namespace App\Http\Controllers\Endpoints;
use Exception;
use Log;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
use App\Services\SendGrid\ProxyEmailManager;
use App\Services\SendGrid\Email;
use App\Services\SendGrid\UserNotFoundException;
use App\Services\SendGrid\ProspectNotFoundException;
use App\Utility\StringUtility;
class SendGridController extends Controller {
public function incomingEmail(Request $request) {
try {
$email = Email::fromRequest($request);
if (StringUtility::emptyOrWhitespace($email->body())) {
return response('email is empty', 202);
}
$proxyEmailManager = new ProxyEmailManager();
if ($proxyEmailManager->isUserProxyAddress($email->to)) {
return $this->forwardToUser($email, $proxyEmailManager);
}
if ($proxyEmailManager->isProspectProxyAddress($email->to)) {
return $this->forwardToProspect($email, $proxyEmailManager);
}
} catch (Exception $ex) {
Log::error($ex->getMessage(), ['stack trace' => $ex->getTraceAsString()]);
return response($ex->getMessage(), 202);
}
return response('unrecognized proxy address', 202);
}
}
I discovered that certain requests from SendGrid were triggering some Mod Security rules which were stripping all of the information out of the request and then pumping them through as GET instead of POST. What a pain!
Please or to participate in this conversation.