| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import 'dart:io';
- import 'dart:convert';
- import 'package:shelf/shelf.dart';
- import 'package:shelf/shelf_io.dart' as shelf_io;
- import 'package:shelf_multipart/shelf_multipart.dart';
- import 'package:shelf_router/shelf_router.dart';
- void main() async {
- // Create a router
- final router = Router();
- // Define routes
- router.get('/greet', _handleGreet);
- router.post('/echo', _handleEcho);
- router.post('/upload', _handleFileUpload);
- // Create a middleware pipeline
- final handler = const Pipeline()
- .addMiddleware(logRequests())
- // .addMiddleware(_checkAuthorization())
- .addHandler(router);
- // Start the server
- final server = await shelf_io.serve(handler, 'localhost', 8080);
- print('Server listening on port ${server.port}');
- }
- // Handler for the /greet route with query parameters
- Response _handleGreet(Request request) {
- final name = request.url.queryParameters['name'] ?? 'stranger';
- return Response.ok('Hello, $name!');
- }
- // Handler for the /echo route that handles POST JSON body
- Future<Response> _handleEcho(Request request) async {
- final payload = await request.readAsString();
- final data = jsonDecode(payload) as Map;
- return Response.ok(jsonEncode(data),
- headers: {'Content-Type': 'application/json'});
- }
- // Handler for the /upload route that accepts file uploads
- Future<Response> _handleFileUpload(Request request) async {
- final contentType = request.headers['content-type'];
- if (contentType == null || !contentType.contains('multipart/form-data')) {
- return Response(400, body: 'Unsupported content-type');
- }
- if (request.multipart() case var multipart?) {
- // Iterate over parts making up this request:
- List<String> uploadedFiles = [];
- await for (final part in multipart.parts) {
- // Headers are available through part.headers as a map:
- final contentDisposition = part.headers['content-disposition'];
- if (contentDisposition != null &&
- contentDisposition.contains('filename=')) {
- final name =
- RegExp(r'name="([^"]*)"').firstMatch(contentDisposition)?.group(1);
- final filename = RegExp(r'filename="([^"]*)"')
- .firstMatch(contentDisposition)
- ?.group(1);
- if (name != null && filename != null) {
- final file = File('uploads/$filename');
- await file.create(recursive: true);
- await part.pipe(file.openWrite());
- uploadedFiles.add(filename);
- }
- }
- }
- if (uploadedFiles.isNotEmpty) {
- return Response.ok('File(s) uploaded: $uploadedFiles');
- }
- {
- return Response(400, body: 'Unsupported content-type');
- }
- } else {
- return Response(401); // not a multipart request
- }
- }
- // Custom middleware for authorization
- Middleware _checkAuthorization() {
- return (Handler handler) {
- return (Request request) async {
- // Protect routes with authorization
- if ((request.url.path.startsWith('greet') ||
- request.url.path.startsWith('echo') ||
- request.url.path.startsWith('upload')) &&
- request.headers['Authorization'] != 'Bearer mysecrettoken') {
- return Response.forbidden('Authorization header missing or invalid');
- }
- return handler(request);
- };
- };
- }
|