Dart Language: GET (favicon issue) - dart

I have a Dart application running on the server side. It is listening at a specific port and working fine. The problem is: my listener is responding to the GET of the favorite icon (favicon).
How can I avoid that?
EDIT: give some code example.
import 'dart:io';
void main() {
print("Starting server.");
HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 4041)
.then(listenForRequests)
.catchError((e) => print (e.toString()));
}
listenForRequests(HttpServer _server) {
_server.listen((HttpRequest request) {
if (request.method == 'GET') {
handleGet(request);
} else {
request.response.statusCode = HttpStatus.METHOD_NOT_ALLOWED;
request.response.write("Unsupported request: ${request.method}.");
request.response.close();
}
},
onDone: () => print('No more requests.'),
onError: (e) => print(e.toString()) );
}
void handleGet(HttpRequest request) {
int requestNumber = 1;
print(requestNumber); // This shows me the request number. Just for information.
print(request.uri); // This shows me the request from the client browser.
request.response.statusCode = HttpStatus.OK;
request.response.close();
}
This is the output of this code:
1
/SOME_REQUEST_FROM_THE_BROWSER
2
/favicon.ico

You can check the requested resource and generate proper response for requests to 'favicon.ico' like
void handleGet(HttpRequest request) {
int requestNumber = 1;
print(requestNumber++); // This shows me the request number.
print(request.uri); // This shows me the request from the client browser.
if(request.requestedUri.path != '/favicon.ico') {
request.response.statusCode = HttpStatus.NOT_FOUND;
} else {
request.response.statusCode = HttpStatus.OK;
}
request.response.close();
}

Related

"TypeError: OAuth2Strategy requires a verify callback." but i send it (nestjs)

I call the constructor of OAuth2Strategy in app.controller.ts, i send it the 2 params it needs: options with clientID, callbackURL etc, and a verify callback function. But i have this error, looks like i don't send a verify callback function to the constructor, but i did. The error happens in node_modules/passport-oauth2/lib/strategy.js.
app.controller.ts:
import { Body, Controller, Get, Post, Query, Res, Req, Next, UnauthorizedException, UseGuards } from '#nestjs/common';
import { PartieService, JoueurService, CanalService } from './app.service';
import { Joueur, Partie, Canal } from './app.entity';
import { AuthGuard } from '#nestjs/passport';
import passport = require("passport");
import OAuth2Strategy = require("passport-oauth2");
//var OAuth2Strategy = require('passport-oauth2').OAuth2Strategy;
//import OAuth2Strategy from 'passport-oauth2';
#Controller()
export class AppController {
constructor(private readonly partieService: PartieService, private readonly joueurService: JoueurService,
private readonly canalService: CanalService) {}
#Get('/oauth2')
async oauth2(#Req() req, #Res() res, #Next() next) {
passport.use('oauth2', new OAuth2Strategy(
{
clientID: 'my_clientID',
clientSecret: 'my_clientSecret',
authorizationURL: 'https://api.abc.com/oauth/authorize',
tokenURL: 'https://api.abc.fr/oauth/token',
callbackURL: 'http://localhost:3000/Connection'
},
async (accessToken: string, refreshToken: string, profile: any, done: Function) => {
//console.log(profile);
try {
if (!accessToken || !refreshToken || !profile) {
return done(new UnauthorizedException(), false);
}
const user: Joueur = await this.joueurService.findOrCreate(profile);
return done(null, user);
} catch (err) {
return done(new UnauthorizedException(), false);
}
} ));
passport.authenticate('oauth2');
return res.sendFile("/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/public/connection.html");
}
#Get('/Connection')
//#UseGuards(AuthGuard('oauth2'))
async Callback(#Req() req, #Res() res, #Next() next) {
passport.authenticate('oauth2', (err, user, info) => {
if (err || !user) {
req.session.destroy();
return res.status(401).json({
message: 'Unauthorized',
});
}
req.user = user;
return next();
})(req, res, next);
const utilisateur: Joueur = req.user;
console.log(utilisateur);
}
[...]
}
node_modules/passport-oauth2/lib/strategy.js:
function OAuth2Strategy(options, verify) {
if (typeof options == 'function') {
verify = options;
options = undefined;
}
options = options || {};
if (!verify) { throw new TypeError('OAuth2Strategy requires a verify callback'); }
[...]
}
Error:
[Nest] 6550 - 05/02/2023, 18:34:54 ERROR [ExceptionHandler] OAuth2Strategy requires a verify callback
TypeError: OAuth2Strategy requires a verify callback
at new OAuth2Strategy (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/passport-oauth2/lib/strategy.js:84:24)
at Injector.instantiateClass (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/injector.js:340:19)
at callback (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/injector.js:53:45)
at Injector.resolveConstructorParams (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/injector.js:132:24)
at Injector.loadInstance (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/injector.js:57:13)
at Injector.loadProvider (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/injector.js:84:9)
at async Promise.all (index 3)
at InstanceLoader.createInstancesOfProviders (/home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/instance-loader.js:47:9)
at /home/user42/Documents/Projets/ft_transcendence/services/pong/pong/node_modules/#nestjs/core/injector/instance-loader.js:32:13
at async Promise.all (index 1)
`
I tried to change the import OAuth2Strategy many times (like the commented lines). I tried a lot of things but i cannot remember all. I found no answer in internet, and no more with the not-so-well-chatgpt.
I am new in nestjs and this error is weird for me, how can it ask me a parameter that i send ? Can someone help me to resolve this pls ? :)
Sorry if the answer is obvious :/ , it's my first API with nestjs
The error was coming from another file, my bad, it's fixed.

How to use dart shelf_router in web only dart project

From the example given at this place :
https://pub.dev/packages/shelf_router/example
I have written the router part like this :
class Service {
Handler get handler {
final router = Router();
router.get('/say-hi/<name>', (Request request, String name) {
return Response.ok('hi $name');
});
router.get('/user/<userId|[0-9]+>', (Request request, String userId) {
return Response.ok('User has the user-number: $userId');
});
router.get('/wave', (Request request) async {
await Future.delayed(Duration(milliseconds: 100));
return Response.ok('_o/');
});
router.mount('/api/', Api().router);
router.all('/<ignored|.*>', (Request request) {
return Response.notFound('Page not found');
});
return router;
}
}
class Api {
Future<Response> _messages(Request request) async {
return Response.ok('[]');
}
Router get router {
final router = Router();
router.get('/messages', _messages);
router.get('/messages/', _messages);
uter.all('/<ignored|.*>', (Request request) => Response.notFound('null'));
return router;
}
}
and from the main method it tells to use it like this:
void main() async {
final service = Service();
final server = await shelf_io.serve(service.handler, 'localhost', 8080);
print('Server running on localhost:${server.port}');
}
but in web-only project we don't do : final server = await shelf_io.serve(service.handler, 'localhost', 8080);
I was thinking of creating single page application using a shelf router, I saw from the documentation it says that it is compatible with the dart web js platform
My expectation was :
if I write this in web :
router.get('/say-hi/<name>', (Request request, String name) {
return Response.ok('hi $name');
});
then when I will hit /say-hi/ram, then it should have returned "hi ram" in the browser

Dart HTTPClient Response query

I would like to make the below functionality synchronous. The "onDataLoaded" needs to be called once the stream has been read completely. Please suggest what changes needs to be done.
String JsonContent="";
new HttpClient().getUrl(Uri.parse(uri))
.then((HttpClientRequest request)
{
request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING);
return request.close();
})
.then((HttpClientResponse response)
{
response.transform(UTF8.decoder).listen((contents) {
JsonContent = contents.toString();
print(JsonContent);
//onDataLoaded(JsonContent);
});
});
this should work
import 'dart:io';
import 'dart:convert' show UTF8;
void main(args) {
String JsonContent="";
new HttpClient().getUrl(Uri.parse(uri))
.then((HttpClientRequest request)
{
request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING);
return request.close();
})
.then((HttpClientResponse response)
{
response.transform(UTF8.decoder).listen((contents) {
JsonContent = contents.toString();
print(JsonContent);
//onDataLoaded(JsonContent);
}, onDone: () => onDataLoaded(JsonContent));
});
}
void onDataLoaded(String jsonContent) {
print(jsonContent);
}

Dart is too fast

I'm trying to understand why this code print "check" twice...
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future<Map> ft_get_data() {
File data;
data = new File("data.json");
return data.exists().then((value) {
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
}).then((_) => data.readAsString()).then((content) => JSON.decode(content)
).catchError((e) => new Map());
}
void main() {
Map params;
String name;
num check = 0;
HttpServer.bind('127.0.0.1', 8080).then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
request.response.headers.contentType = new ContentType('text', 'htm l');
params = request.uri.queryParameters; // http://127.0.0.1:8080/?name=tristan
ft_get_data().then((data_map) {
name = data_map['index']['content'];
print('check: $check');
if (data_map.isNotEmpty) request.response.write(name); else
request.response.write('Booh');
check++;
}).whenComplete(request.response.close);
});
}).catchError((error) {
print("An error : $error.");
});
}
Is it too fast ? Or there exist some method to make a pause ? Thank you.
I tried your code and it prints 0.
What client are you using to access the server?

Dart get back value of function

I'm trying to learn Dart by my self, but I come from C and I a bit confused...
I'm doing this :
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future <Map> ft_get_data()
{
File data;
data = new File("data.json");
return data.exists().then((value) {
if (!value)
{
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
return (1);
}).then((value) {
data.readAsString().then((content){
return JSON.decode(content);
}).catchError((e) {
print("error");
return (new Map());
});
});
}
void main()
{
HttpServer.bind('127.0.0.1', 8080).then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data().then((data_map) {
if (data_map && data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
}).whenComplete(request.response.close);
});
}) .catchError((error) {
print("An error : $error.");
});
}
I'm trying to get back the new Map, and as you can guess, it doesn't work and I get the 'Not work' msg. While when the code was in same function, it worked...
Please, could you help me ?
And, there a pointer system as C ?
void function(int *i)
{
*i = 2;
}
int main()
{
int i = 1;
function(&i);
printf("%d", i);
}
// Output is 2.
Thank you for your help.
Final code :
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future<Map> ft_get_data()
{
File data;
data = new File("data.json");
return data.exists()
.then((value) {
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
})
.then((_) => data.readAsString())
.then((content) => JSON.decode(content))
.catchError((e) => new Map());
}
void main()
{
HttpServer.bind('127.0.0.1', 8080)
.then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data()
.then((data_map) {
if (data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
})
.whenComplete(request.response.close);
});
})
.catchError((error) {
print("An error : $error.");
});
}
I tried to reconstruct your code to "readable" format. I haven't test it, so there might be errors. For me the code is much easier to read if .then() are not nested. Also it helps reading, if .then() starts a new line.
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future <Map>ft_get_data()
{
File data;
data = new File("data.json");
data.exists() //returns true or false
.then((value) { // value is true or false
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
}) // this doesn't need to return anything
.then((_) => data.readAsString()) // '_' indicates that there is no input value, returns a string. This line can removed if you add return data.readAsString(); to the last line of previous function.
.then((content) => JSON.decode(content)); // returns decoded string, this is the output of ft_get_data()-function
// .catchError((e) { //I believe that these errors will show in main-function's error
// print("error");
// });
}
void main()
{
HttpServer.bind('127.0.0.1', 8080)
.then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data()
.then((data_map) {
if (data_map && data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
})
.whenComplete(request.response.close);
});
})
.catchError((error) {
print("An error : $error.");
});
}
you cannot insert one then() into the other. Need to chain them. Otherwise, return JSON.decode(data) returns to nowhere (main event loop) instead of previous "then" handler
After a brief look I would say you need
Future<Map> ft_get_data() {
...
return data.exists() ...
...
}
and use it like
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data().then((data_map) {
if (data_map && data_map.isNotEmpty) request.response.write(
data_map['index']['content']);
else
request.response.write('Not work');
request.response.close();
});
});
A return inside a then doesn't return from ft_get_data but only from then
If an async call is involved you can't continue if it was sync, it's then async all the way down.

Resources