AWS Lambda next.js - Failed to post 2MB file to api route - aws-lambda

I deployed my next.js app to aws usingserverless-next.js package.
When I'm trying to post a big file (~1MB) to the api route, I'm getting a 503 response code.
The full response content:
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>503 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: X
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
The CloudWatch log shows:
{
"errorType": "Error",
"errorMessage": "Cannot call write after a stream was destroyed",
"code": "ERR_STREAM_DESTROYED",
"stack": [
"Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed",
" at WriteStream._write (internal/fs/streams.js:379:33)",
" at WriteStream.<anonymous> (internal/fs/streams.js:375:12)",
" at Object.onceWrapper (events.js:422:26)",
" at WriteStream.emit (events.js:327:22)",
" at WriteStream.EventEmitter.emit (domain.js:483:12)",
" at internal/fs/streams.js:366:10",
" at FSReqCallback.oncomplete (fs.js:156:23)"
]
}
I'm using formidable to parse the body of the request. It working with smaller file sizes.
What can I do? 1MB does not count as big file size.
In development everything works even with 10MB files, but not in AWS lambda#edge

It's written here: https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html
You can't have a request + response larger than 256 KB if you upload in asynchronous mode.
Because serverless is only here to make your routes in lambda functions. If you want to upload this file, you can use S3 bucket with pre-signed url.
With that you doesn't need to upload the file to the lambda function.

Related

How can i get a file from storage without symlink?

I have a problem with storage.
How can I get a file from storage without symlink ?
When I try to get a video from file storage, to HTML video tag, I got a "forbidden" or "Not allowed to load local resource".
Controller :
$url = Storage::url($file);
return view('video')->with('url',$url);
HTML tag :
<video width="600" height="400" controls>
<source src="{{url($url)}}" type="video/mp4">
Your browser does not support the video tag.
Votre navigateur ne supporte pas le lecteur vidéo.
</video>
The idea of the storage is that it may reside in a place not accessible by your webserver, or at least nooit publicly accessible. It could be a folder, it could be an S3 storage, could be something else.
What you need to do is define a route to specifically download the video file. You can generate a temporary signed URL to that route in your controller code: https://laravel.com/docs/7.x/urls#signed-urls
Sent that signed URL to the view. Now the browser will load the video from the signed URL. You need to create the route and controller function to load the file from storage and sent it to the browser: https://laravel.com/docs/7.x/filesystem#downloading-files

Cordova Https ajax requests fails or encoded response

We have developed an application which is running perfectly fine on desktop and mobile web with verisign certificate (https). We have developed iOS and android cordova application which was working fine with http server. For production they have enabled SSL. The iOS and android hybrid applications are not working fine because of ajax call response. The following response I am receiving for both http and https. Is there any changes required in client side or its all about SSL? Is there any workaround for SSL decoded response? We are using IBM's websphere application server.
Response from http server
[{"SALT":"3FzekTIywrmm9jojnfHn11"}]
Response from https server
<html>
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1"></head><body>
<script type=text/javascript>
function decode_base64(input){
var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";
var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9+/=]/g,"");
while(i<input.length){
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1<<2)|(enc2>>4);
chr2=((enc2&15)<<4)|(enc3>>2);
chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){
output=output+String.fromCharCode(chr2)
}
if(enc4!=64){
output=output+String.fromCharCode(chr3)}}return output;
}
document.write(decode_base64("PHNjcmlwdCB0eXBlPXRleHQvamF2YXNjcmlwdD52YXIgdG9fZGVjPWRlY29kZV9iYXNlNjQoImNtUjFWV2hzWkc1MGRTbG5kRzlpZFdodWJ5RXBLSG9oWlc1aWRHeGtiM1V2Ylc1aVlIVm9ibTg4SXk0eGUzRnZMaU02SVh3dElUQXhNVEVvIik7IGRlY19yZXM9IiI7IHZhciB4b3Jfa2V5PTE7IGZvcihpPTA7aTw2MDtpKyspeyBkZWNfcmVzKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHhvcl9rZXledG9fZGVjLmNoYXJDb2RlQXQoaSkpO30gZXZhbChkZWNfcmVzKTs8L3NjcmlwdD4="));
</script>
</body>
</html>
That is quite odd way to return the error message, but your HTTPS server is telling
i18n-values: Missing value for "primaryParagraph"
You can see that by
copy-paste the HTML to text editor,
Name it like foo.html,
Open it on browser,
Open developer tools and see console where it says that.
To answer your question: from point of view of client-side coding there isn't really much difference between HTTP and HTTPS calls. Browser tends to hide those quite effectively, though the performance is in general weaker on HTTPS calls etc.

Upload media with unofficial Instagram API

I'm writing a script that uploads photos to Instagram by schedule. The official Instagram API does not allow media uploads. I found that the only solution today is to use unofficial API. So, I'm trying to use it but it responds with 301 error to all my requests.
Ruby code:
url = 'https://instagr.am/api/v1/accounts/login/'
RestClient.post url, { username: 'username', password: 'password', device_id: '0000' }, user_agent: 'Instagram'
# RestClient::MovedPermanently: 301 Moved Permanently
Or curl:
$ curl -k --data "username=username&password=password&device_id=0000" --header "User-Agent: Instagram" https://instagr.am/api/v1/accounts/login/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
Can you help me to find an error in my requests or suggest a better solution how to upload media to Instagram?
Instagram has put in place a signature that is required for "unofficial" API requests.. if you can find out how to generate that signature then you'll be golden... I've got a general understanding of how it's done by reviewing their android version's source code but I never quite cracked the process and haven't had the time to spend on it..
There are some third party clients out there that can do it but IG seems to be pretty good at detecting and deleting those photos.. and often banning the account.

Jmeter: 302 Moved Temporarily

I was trying to issue a https request through jmeter and observed am getting below response.
<html><head><title>302 Moved Temporarily</title></head>
<body bgcolor="#FFFFFF">
<p>This document you requested has moved temporarily.</p>
And it seems the actual url redirecting to different url which is getting the Response Code 200 which is OK. [The first urls response code is 302]
Also I have given an assertion for the page being loaded, but still that assertion fails [when I saw the response data in HTML format, observed that the respective page is not loaded]
Any help in resolving this issue would be a great help.
Looking at: http://jmeter.apache.org/usermanual/component_reference.html#Response_Assertion
If you chose "Main sample and sub samples" it will include the responses from the redirects. So for example if you're searching for "string" it will also include the response from the redirected page.

Magento google checkout integration issue 404

I'm trying to integrate google checkout with a magento site and get the following error in the Integration Console:
We encountered an error trying to access your server at
https://www.domain.co.uk/googlecheckout/api/
-- the error we got is Sending failed with HTTP response
code: 404. Response body was: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>404 - File or directory not found.</title> <style type="text/css">
<!-- body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF; background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;} -->
</style> </head> <body>
<div id="header"><h1>Server Error</h1></div>
<div id="content"> <div class="content-container"><fieldset> <h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div> </div> </body> </html>
As far as I can tell, it's not actually a 404 error as I can do the following:
wget --post-data=blah https://www.domain.co.uk/googlecheckout/api/
--10:58:43-- https://www.domain.co.uk/googlecheckout/api/
=> `index.html'
Resolving www.domain.co.uk... 192.168.1.117
Connecting to www.domain.co.uk|192.168.1.117|:443... connected.
HTTP request sent, awaiting response... 503 Service Unavailable
10:58:43 ERROR 503: Service Unavailable.
Now the 503 error there actually relates to me not sending any HTTP_AUTHORIZATION with wget, so it dies on this line strpos($_SERVER['HTTP_AUTHORIZATION'], " ") + 1))); in googleresponse.php. This isn't the problem.
I have tried both https://www.domain.co.uk/googlecheckout/api/ and https://www.domain.co.uk/googlecheckout/api in both wget and Google Checkout settings callback URL with the same results.
I've made sure that always_populate_raw_post_data = On is set, and it's showing up correctly in phpinfo().
I've tried debug mode On and Off in Google API settings within Magento.
The checkout process was working correctly on a dev domain using the sandbox mode.
I've tried all of the things that I could find with google searches. Any other options would be greatly appreciated.
Edit
It looks like that response is from an IIS server. The server that this site is now running on is Apache. Could Google still be accessing the old server? DNS was updated over 15 hours ago.
Check the server logs on the old and new servers to see which one Google made the request to.
That original error from google is an IIS 404 page, not an apache 404 page, so it seems as though google is looking at a different web server.

Resources