Added CSP support
This commit is contained in:
		
							
								
								
									
										76
									
								
								net/Http.js
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								net/Http.js
									
									
									
									
									
								
							@@ -5,6 +5,68 @@ const Dragonfly = global.Dragonfly;
 | 
			
		||||
 | 
			
		||||
const Cookie = cl.load( "botanss.net.components.Cookie" );
 | 
			
		||||
 | 
			
		||||
class ContentSecurityPolicy
 | 
			
		||||
{
 | 
			
		||||
	constructor()
 | 
			
		||||
	{
 | 
			
		||||
		this.sources = {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	any()
 | 
			
		||||
	{
 | 
			
		||||
		return 0 < Object.keys( this.sources ).length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	add( src, scope )
 | 
			
		||||
	{
 | 
			
		||||
		this.sources[ src ] ||= {};
 | 
			
		||||
		this._add( this.sources[ src ], scope, src );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_add( s, scope, _name )
 | 
			
		||||
	{
 | 
			
		||||
		if( scope.startsWith( "'nonce-" ) && "'unsafe-inline'" in s )
 | 
			
		||||
		{
 | 
			
		||||
			Dragonfly.Warning( `Removing 'unsafe-inline' from ${_name} for ${scope}` );
 | 
			
		||||
			delete s[ "'unsafe-inline'" ];
 | 
			
		||||
		}
 | 
			
		||||
		s[ scope ] = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	merge( cspStr )
 | 
			
		||||
	{
 | 
			
		||||
		for( let src of cspStr.split( ";" ) )
 | 
			
		||||
		{
 | 
			
		||||
			src = src.trim();
 | 
			
		||||
			if( !src )
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			var d = src.indexOf( " " );
 | 
			
		||||
 | 
			
		||||
			var name = src.substr( 0, d );
 | 
			
		||||
 | 
			
		||||
			this.sources[ name ] ||= {};
 | 
			
		||||
 | 
			
		||||
			for( let val of src.substr( d + 1 ).split( " " ) )
 | 
			
		||||
			{
 | 
			
		||||
				this.sources[ name ][ val ] = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	toString()
 | 
			
		||||
	{
 | 
			
		||||
		var s = "";
 | 
			
		||||
		for( let name in this.sources )
 | 
			
		||||
		{
 | 
			
		||||
			if( s )
 | 
			
		||||
				s += " ";
 | 
			
		||||
			s += `${name} ${Object.keys( this.sources[ name ] ).join( " " )};`;
 | 
			
		||||
		}
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CResponse
 | 
			
		||||
{
 | 
			
		||||
	constructor( res, Http )
 | 
			
		||||
@@ -13,15 +75,29 @@ class CResponse
 | 
			
		||||
		this.canExit = true;
 | 
			
		||||
 | 
			
		||||
		this.statusCode = 200;
 | 
			
		||||
		this.contentSecurityPolicy = new ContentSecurityPolicy();
 | 
			
		||||
		this.headers = {
 | 
			
		||||
			"Content-Type": "text/html; charset=utf-8"
 | 
			
		||||
			, "Powered-By": "Botanical Framework (Node.js)"
 | 
			
		||||
			, "Content-Security-Policy": this.contentSecurityPolicy
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.content = "";
 | 
			
		||||
		this.cookie = new Cookie( "", Http );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mergeHeader( key, value )
 | 
			
		||||
	{
 | 
			
		||||
		switch( key )
 | 
			
		||||
		{
 | 
			
		||||
			case "Content-Security-Policy":
 | 
			
		||||
				this.headers[ key ] = this.headers[ key ] + ' ' + value;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				throw new Error( `Merge header not implemented: ${key}` );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	end()
 | 
			
		||||
	{
 | 
			
		||||
		if( this.canExit )
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user