Flutter: App upload file to local server but not to remote server - flutter

I am trying uploading a image using below code.
String _urlsegment =
Explika.producaoFlag ? 'https://www.remoteserver.pt' : 'http://10.0.2.2';
var stream = http.ByteStream(
DelegatingStream.typed(compressedFileImage.openRead()));
var length = await compressedFileImage.length();
var uri = Uri.parse('$_urlsegment/explika/api/upload');
var request = http.MultipartRequest("POST", uri);
var multipartFile = http.MultipartFile('fotoaluno', stream, length,
filename: '${Explika.getAluno().id}.jpg');
request.files.add(multipartFile);
Everything work fine using localhost. When i try send image to remote server nothing happens.
The end point is ok: i tested it using postman and all worked well.
Summing up:
uploading using APP to LOCAL server - OK
uploading to LOCAL server using POSTMAN - OK
uploading using APP to REMOTE server - Fail (No error occurs but file does not reach server)
uploading to REMOTE server using POSTMAN - OK
Any ideas on what is going on? Do I need to enter any special permissions in the app manifest?

Flutter sends the images with mime type 'application / octet-stream'. The server was waiting for files with mime type 'image / jpeg', so it automatically rejected the file.

Related

Strange issue with Vertx Http request

I configured an HTTPS website on AWS, which allows visiting from a white list of IPs.
My local machine runs with a VPN connection, which is in the white list.
I could visit the website from web browser or by the java.net.http package with the below code:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://mywebsite/route"))
.GET() // GET is default
.build();
HttpResponse<Void> response = client.send(request,
HttpResponse.BodyHandlers.discarding());
But if I replaced the code with a Vertx implementation from io.vertx.ext.web.client package, I got a 403 forbidden response from the same website.
WebClientOptions options = new WebClientOptions().setTryUseCompression(true).setTrustAll(true);
HttpRequest<Buffer> request = WebClient.create(vertx, options)
.getAbs("https://mywebsite/route")
.ssl(true).putHeaders(headers);
request.send(asyncResult -> {
if (asyncResult.succeeded()) {
HttpResponse response = asyncResult.result();
}
});
Does anyone have an idea why the Vertx implementation is rejected?
Finally got the root cause. I started a local server that accepts the testing request and forwards it to the server on AWS. The testing client sent the request to localhost and thus "Host=localhost:8080/..." is in the request header. In the Vert.X implementation, a new header entry "Host=localhost:443/..." is wrongly put into the request headers. I haven't debug the Vert.X implementation so I have no idea why it behaviors as this. But then the AWS firewall rejected the request with a rule that a request could not come from localhost.

Uploading to GCS using S3 Java SDK: `The MD5 you specified in Content-MD5 or x-goog-hash did not match what we computed`

I am trying to upload to Google Cloud Storage using the AWS SDK For Java 1.x. I have enabled interoperability mode and put AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in the environment. I can list objects, but uploading is not working for me.
The code I am using is
AmazonS3 client =
AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
"http://storage.googleapis.com", "auto"))
.build();
TransferManager tm = TransferManagerBuilder.standard()
.withS3Client(client)
.build();
Upload upload = tm.upload(bucketName, key, new File(filename));
upload.waitForCompletion();
But the result I get is:
com.amazonaws.services.s3.model.AmazonS3Exception: The MD5 you specified in Content-MD5 or x-goog-hash did not match what we computed. (Service: Amazon S3; Status Code: 400; Error Code: BadDigest; Request ID: null; S3 Extended Request ID: null; Proxy: null), S3 Extended Request ID: null
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5437)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5384)
The same code works OK with S3 (minus the EndpointConfiguration)
The GCS docs say:
In the Cloud Storage XML API, chunked transfer encoding and V4 signatures cannot currently be used simultaneously. Some Amazon S3 tools use chunked transfer encoding along with signatures by default; you should disable chunked transfer encoding in such cases.
I found two ways to resolve this error
You can .withChunkedEncodingDisabled(true) when building the client:
AmazonS3 client =
AmazonS3ClientBuilder.standard()
.withChunkedEncodingDisabled(true) // <<<<<<<
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
"http://storage.googleapis.com", "auto"))
.build();
You can switch to the https endpoint:
AmazonS3 client =
AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
"https://storage.googleapis.com", "auto"))
.build();

Running flutter web app locally without android studio

I have a flutter app using Firebase's cloud firestore. I've done the web build and running it on Chrome through Android Studio works well. I would like to share my web app progress to my client but don't want to host it (because it's not finished yet). Hence I'd like to find a way to run it locally the same way you can do it with Android Studio but without needing to install Android Studio (and hopefully not requiring to install flutter either), so that I can send the build file to my client and they can run it in their machine (with a script to start the web server locally and run the web app).
I have tried the following script included inside the web build folder (where the index.html is)
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from httplib import HTTPResponse
from os import curdir,sep
#Create a index.html aside the code
#Run: python server.py
#After run, try http://localhost:8080/
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.path = '/index.html'
try:
sendReply = False
if self.path.endswith(".html"):
mimeType = 'text/html'
sendReply = True
if sendReply == True:
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type', mimeType)
self.end_headers()
self.wfile.write(f.read())
f.close()
return
except IOError:
self.send_error(404,'File not found!')
def run():
print('http server is starting...')
#by default http server port is 80
server_address = ('127.0.0.1', 8080)
httpd = HTTPServer(server_address, RequestHandler)
try:
print 'http server is running...'
httpd.serve_forever()
except KeyboardInterrupt:
httpd.socket.close()
if __name__ == '__main__':
run()
But when opening http://localhost:8000 on Chrome I get a blanc page and the console shows the errors:
Failed to load resource: net::ERR_EMPTY_RESPONSE main.dart.js:1
Failed to load resource: net::ERR_EMPTY_RESPONSE manifest.json:1
Failed to load resource: net::ERR_EMPTY_RESPONSE :8080/favicon.png:1
I also tried NPM local-web-server by running ws --spa index.html but just getting a ERR_EMPTY_RESPONSE response.
This is what I have in my build/web after running flutter build web:
How can I create a local server where I can host my web app locally and run it locally without hosting it on the internet?
as you mentioned in the comment here you go.
Create a file app.js with the following:
const express = require('express')
const app = express()
const port = 8000
app.get('/', (req, res) => {
console.log('getting request')
res.sendFile('website/y.html',{root:__dirname})
})
app.use(express.static(__dirname + '/website'))
app.use((req, res)=>{
res.redirect('/')
})
app.listen(port, () => {
console.log(`app listening at http://localhost:${port}`)
})
Here my website files exist at website folder and my entry point is y.html.
Set the static file directory (your website page) and then serve the .html for the root request
example project: https://github.com/ondbyte/website
Finally, to run it open terminal and move to the root folder. Then do
npm init
npm install express --no-save
node app.js
Here is the more simpler way. NO NEED to setup server
open your Build/web folder in vscode.
install Live server Plugin in vscode.
hit Golive Button
Here you go your flutter web app would be running locally without android studio.

Call to TLS 1.2 server with RestSharp works in console app, not in Xamarin Forms

I am communicating with a server that uses mutual TLS v1.2. I have been able to make this request in a c# console application, but when I copy this exact code to Xamarin forms, my RestClient gives me an exception: "Connection reset by peer" after a few seconds.
The code:
var client = new RestClient("https://api-sandbox.rabobank.nl/openapi/sandbox/payments/account-information/ais/v3/accounts");
ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
client.ClientCertificates = new X509CertificateCollection() { certificate };
client.Proxy = new WebProxy();
var request = new RestRequest(Method.GET);
var response = client.Execute(request);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
I am unable to share my API keys and such, for obvious reasons. These are added through headers and are removed from the code snippet.
Things I have tried:
I checked if the projects are set to use TLS 1.2, both iOS and Android are.
I tried this in simulators and on real devices
I tried using this library, but whenever I try to add the certificate to the clientcertificate list of the handler, I get a NotImplementedException thrown.

Downloading file by WebClient Exception

I have a problem downloading particular file types by WebClient. So there are no problems with usual types - mp3, doc and others, but when I rename file extension to config it returns me:
InnerException = {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
when I'm trying to access this file in browser (http://localhost:3182/Silverlight.config) - it's a usual xml file within - server returns me following error page:
Server Error in '/' Application.
This type of page is not served.
Description: The type of page you have requested is not served because it has been explicitly forbidden. The extension '.config' may be incorrect. Please review the URL below and make sure that it is spelled correctly.
Requested URL: /Silverlight.config
So I suppose this hapens because of some server configuration, which blocks files of unknown type.
downloading code is simple:
WebClient webClient = new WebClient();
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(new Uri("../Silverlight.config", UriKind.RelativeOrAbsolute));
completted eventhandler omitted for simplicity.
I'm not sure this is possible.
The .config extension is handled by the ASP.NET engine, for security reasons (sensitive data like connection strings need to be kept safe and hidden from unauthorized viewers).
This means that visitors cannot view your web.config file's content by simply entering "www.example.com/web.config" into their browser's adress bar.
EDIT : actually you can but I don't recommand it. If you really need to do it, you have to remove the mapping between the .config extension and ASP.NET ISAPI filter in IIS.