diff --git a/plugins/Sidebar/SidebarPlugin.py b/plugins/Sidebar/SidebarPlugin.py
index bde16359..d3490cd4 100644
--- a/plugins/Sidebar/SidebarPlugin.py
+++ b/plugins/Sidebar/SidebarPlugin.py
@@ -143,7 +143,7 @@ class UiWebsocketPlugin(object):
                 size = size_filetypes.get(extension, 0)
                 size_other -= size
             percent = 100 * (float(size) / size_total)
-            body.append("<li style='width: %.0f%%' class='html back-%s' title='%s'></li>" % (percent, color, extension))
+            body.append("<li style='width: %.2f%%' class='%s back-%s' title='%s'></li>" % (percent, extension, color, extension))
 
         # Legend
         body.append("</ul><ul class='graph-legend'>")
diff --git a/plugins/Trayicon/TrayiconPlugin.py b/plugins/Trayicon/TrayiconPlugin.py
index 6aec34a1..6579612c 100644
--- a/plugins/Trayicon/TrayiconPlugin.py
+++ b/plugins/Trayicon/TrayiconPlugin.py
@@ -19,8 +19,10 @@ class ActionsPlugin(object):
 
         self.main = sys.modules["main"]
 
+        fs_encoding = sys.getfilesystemencoding()
+
         icon = notificationicon.NotificationIcon(
-            os.path.join(os.path.dirname(os.path.abspath(__file__)), 'trayicon.ico'),
+            os.path.join(os.path.dirname(os.path.abspath(__file__).decode(fs_encoding)), 'trayicon.ico'),
             "ZeroNet %s" % config.version
         )
         self.icon = icon
diff --git a/plugins/disabled-Multiuser/MultiuserPlugin.py b/plugins/disabled-Multiuser/MultiuserPlugin.py
index 850a0995..9d65fac8 100644
--- a/plugins/disabled-Multiuser/MultiuserPlugin.py
+++ b/plugins/disabled-Multiuser/MultiuserPlugin.py
@@ -1,169 +1,171 @@
-import re, time, sys
+import re
+import sys
 from Plugin import PluginManager
-from Crypt import CryptBitcoin
+
 
 @PluginManager.registerTo("UiRequest")
 class UiRequestPlugin(object):
-	def __init__(self, *args, **kwargs):
-		self.user_manager = sys.modules["User.UserManager"].user_manager
-		super(UiRequestPlugin, self).__init__(*args, **kwargs)
+    def __init__(self, *args, **kwargs):
+        self.user_manager = sys.modules["User.UserManager"].user_manager
+        super(UiRequestPlugin, self).__init__(*args, **kwargs)
 
+    # Create new user and inject user welcome message if necessary
+    # Return: Html body also containing the injection
+    def actionWrapper(self, path, extra_headers=None):
 
-	# Create new user and inject user welcome message if necessary
-	# Return: Html body also containing the injection
-	def actionWrapper(self, path):
-		user_created = False
-		user = self.getCurrentUser() # Get user from cookie
+        match = re.match("/(?P<address>[A-Za-z0-9\._-]+)(?P<inner_path>/.*|$)", path)
+        if not match:
+            return False
+        inner_path = match.group("inner_path").lstrip("/")
+        html_request = "." not in inner_path or inner_path.endswith(".html")  # Only inject html to html requests
 
-		if not user: # No user found by cookie
-			user = self.user_manager.create()
-			user_created = True
+        user_created = False
+        if html_request:
+            user = self.getCurrentUser()  # Get user from cookie
+            if not user:  # No user found by cookie
+                user = self.user_manager.create()
+                user_created = True
 
-		master_address = user.master_address
-		master_seed = user.master_seed
+        if user_created:
+            if not extra_headers:
+                extra_headers = []
+            extra_headers.append(('Set-Cookie', "master_address=%s;path=/;max-age=2592000;" % user.master_address))  # = 30 days
 
-		if user_created: 
-			extra_headers = [('Set-Cookie', "master_address=%s;path=/;max-age=2592000;" % user.master_address)] # Max age = 30 days
-		else:
-			extra_headers = []
+        loggedin = self.get.get("login") == "done"
 
-		loggedin = self.get.get("login") == "done"
+        back_generator = super(UiRequestPlugin, self).actionWrapper(path, extra_headers)  # Get the wrapper frame output
 
-		back = super(UiRequestPlugin, self).actionWrapper(path, extra_headers) # Get the wrapper frame output
+        if not back_generator:  # Wrapper error or not string returned, injection not possible
+            return False
 
-		if not user_created and not loggedin: return back # No injection necessary
+        if user_created:
+            back = back_generator.next()
+            master_seed = user.master_seed
+            # Inject the welcome message
+            inject_html = """
+                <!-- Multiser plugin -->
+                <style>
+                 .masterseed { font-size: 95%; background-color: #FFF0AD; padding: 5px 8px; margin: 9px 0px }
+                </style>
+                <script>
+                 hello_message = "<b>Hello, welcome to ZeroProxy!</b><div style='margin-top: 8px'>A new, unique account created for you:</div>"
+                 hello_message+= "<div class='masterseed'>{master_seed}</div> <div>This is your private key, <b>save it</b>, so you can login next time.</div><br>"
+                 hello_message+= "<a href='#' class='button' style='margin-left: 0px'>Ok, Saved it!</a> or <a href='#Login' onclick='wrapper.ws.cmd(\\"userLoginForm\\", []); return false'>Login</a><br><br>"
+                 hello_message+= "<small>This site is allows you to browse ZeroNet content, but if you want to secure your account <br>"
+                 hello_message+= "and help to make a better network, then please run your own <a href='https://github.com/HelloZeroNet/ZeroNet' target='_blank'>ZeroNet client</a>.</small>"
+                 setTimeout(function() {
+                    wrapper.notifications.add("hello", "info", hello_message)
+                    delete(hello_message)
+                 }, 1000)
+                </script>
+                </body>
+                </html>
+            """.replace("\t", "")
+            inject_html = inject_html.replace("{master_seed}", master_seed)  # Set the master seed in the message
 
-		if not back or not hasattr(back, "endswith"): return back # Wrapper error or not string returned, injection not possible
+            return iter([re.sub("</body>\s*</html>\s*$", inject_html, back)])  # Replace the </body></html> tags with the injection
 
-		if user_created:
-			# Inject the welcome message
-			inject_html = """
-				<!-- Multiser plugin -->
-				<style>
-	 			 .masterseed { font-size: 95%; background-color: #FFF0AD; padding: 5px 8px; margin: 9px 0px }
-				</style>
-				<script>
-				 hello_message = "<b>Hello, welcome to ZeroProxy!</b><div style='margin-top: 8px'>A new, unique account created for you:</div>"
-				 hello_message+= "<div class='masterseed'>{master_seed}</div> <div>This is your private key, <b>save it</b>, so you can login next time.</div><br>"
-				 hello_message+= "<a href='#' class='button' style='margin-left: 0px'>Ok, Saved it!</a> or <a href='#Login' onclick='wrapper.ws.cmd(\\"userLoginForm\\", []); return false'>Login</a><br><br>"
-				 hello_message+= "<small>This site is allows you to browse ZeroNet content, but if you want to secure your account <br>"
-				 hello_message+= "and help to make a better network, then please run your own <a href='https://github.com/HelloZeroNet/ZeroNet' target='_blank'>ZeroNet client</a>.</small>"
-				 setTimeout(function() {
-				 	wrapper.notifications.add("hello", "info", hello_message)
-				 	delete(hello_message)
-				 }, 1000)
-				</script>
-				</body>
-				</html>
-			""".replace("\t", "")
-			inject_html = inject_html.replace("{master_seed}", master_seed) # Set the master seed in the message
+        elif loggedin:
+            back = back_generator.next()
+            inject_html = """
+                <!-- Multiser plugin -->
+                <script>
+                 setTimeout(function() {
+                    wrapper.notifications.add("login", "done", "Hello again!<br><small>You have been logged in successfully</small>", 5000)
+                 }, 1000)
+                </script>
+                </body>
+                </html>
+            """.replace("\t", "")
+            return iter([re.sub("</body>\s*</html>\s*$", inject_html, back)])  # Replace the </body></html> tags with the injection
 
-			back = re.sub("</body>\s*</html>\s*$", inject_html, back) # Replace the </body></html> tags with the injection 
+        else:  # No injection necessary
+            return back_generator
 
-		elif loggedin:
-			inject_html = """
-				<!-- Multiser plugin -->
-				<script>
-				 setTimeout(function() {
-				 	wrapper.notifications.add("login", "done", "Hello again!<br><small>You have been logged in successfully</small>", 5000) 
-				 }, 1000)
-				</script>
-				</body>
-				</html>
-			""".replace("\t", "")
-			back = re.sub("</body>\s*</html>\s*$", inject_html, back) # Replace the </body></html> tags with the injection
-
-		return back 
-
-
-	# Get the current user based on request's cookies
-	# Return: User object or None if no match
-	def getCurrentUser(self):
-		cookies = self.getCookies()
-		user_manager = self.user_manager
-		user = None
-		if "master_address" in cookies:
-			users = self.user_manager.list()
-			user = users.get(cookies["master_address"])
-		return user
+    # Get the current user based on request's cookies
+    # Return: User object or None if no match
+    def getCurrentUser(self):
+        cookies = self.getCookies()
+        user = None
+        if "master_address" in cookies:
+            users = self.user_manager.list()
+            user = users.get(cookies["master_address"])
+        return user
 
 
 @PluginManager.registerTo("UserManager")
 class UserManagerPlugin(object):
-	# In multiuser mode do not load the users
-	def load(self):
-		if not self.users: self.users = {}
-		return self.users
+    # In multiuser mode do not load the users
+    def load(self):
+        if not self.users:
+            self.users = {}
+        return self.users
 
-
-	# Find user by master address
-	# Return: User or None
-	def get(self, master_address=None):
-		users = self.list()
-		if master_address in users:
-			user = users[master_address]
-		else:
-			user = None
-		return user
+    # Find user by master address
+    # Return: User or None
+    def get(self, master_address=None):
+        users = self.list()
+        if master_address in users:
+            user = users[master_address]
+        else:
+            user = None
+        return user
 
 
 @PluginManager.registerTo("User")
 class UserPlugin(object):
-	# In multiuser mode users data only exits in memory, dont write to data/user.json
-	def save(self):
-		return False 
- 
+    # In multiuser mode users data only exits in memory, dont write to data/user.json
+    def save(self):
+        return False
+
 
 @PluginManager.registerTo("UiWebsocket")
 class UiWebsocketPlugin(object):
-	# Let the page know we running in multiuser mode
-	def formatServerInfo(self):
-		server_info = super(UiWebsocketPlugin, self).formatServerInfo()
-		server_info["multiuser"] = True
-		if "ADMIN" in self.site.settings["permissions"]:
-			server_info["master_address"] = self.user.master_address
-		return server_info
+    # Let the page know we running in multiuser mode
+    def formatServerInfo(self):
+        server_info = super(UiWebsocketPlugin, self).formatServerInfo()
+        server_info["multiuser"] = True
+        if "ADMIN" in self.site.settings["permissions"]:
+            server_info["master_address"] = self.user.master_address
+        return server_info
 
+    # Show current user's master seed
+    def actionUserShowMasterSeed(self, to):
+        if "ADMIN" not in self.site.settings["permissions"]:
+            return self.response(to, "Show master seed not allowed")
+        message = "<b style='padding-top: 5px; display: inline-block'>Your unique private key:</b>"
+        message += "<div style='font-size: 84%%; background-color: #FFF0AD; padding: 5px 8px; margin: 9px 0px'>%s</div>" % self.user.master_seed
+        message += "<small>(Save it, you can access your account using this information)</small>"
+        self.cmd("notification", ["info", message])
 
-	# Show current user's master seed
-	def actionUserShowMasterSeed(self, to):
-		if not "ADMIN" in self.site.settings["permissions"]: return self.response(to, "Show master seed not allowed")
-		message = "<b style='padding-top: 5px; display: inline-block'>Your unique private key:</b>"
-		message+= "<div style='font-size: 84%%; background-color: #FFF0AD; padding: 5px 8px; margin: 9px 0px'>%s</div>" % self.user.master_seed
-		message+= "<small>(Save it, you can access your account using this information)</small>"
-		self.cmd("notification", ["info", message])
+    # Logout user
+    def actionUserLogout(self, to):
+        if "ADMIN" not in self.site.settings["permissions"]:
+            return self.response(to, "Logout not allowed")
+        message = "<b>You have been logged out.</b> <a href='#Login' class='button' onclick='wrapper.ws.cmd(\"userLoginForm\", []); return false'>Login to another account</a>"
+        message += "<script>document.cookie = 'master_address=; expires=Thu, 01 Jan 1970 00:00:00 UTC'</script>"
+        self.cmd("notification", ["done", message, 1000000])  # 1000000 = Show ~forever :)
+        # Delete from user_manager
+        user_manager = sys.modules["User.UserManager"].user_manager
+        if self.user.master_address in user_manager.users:
+            del user_manager.users[self.user.master_address]
+            self.response(to, "Successful logout")
+        else:
+            self.response(to, "User not found")
 
+    # Show login form
+    def actionUserLoginForm(self, to):
+        self.cmd("prompt", ["<b>Login</b><br>Your private key:", "password", "Login"], self.responseUserLogin)
 
-	# Logout user
-	def actionUserLogout(self, to):
-		if not "ADMIN" in self.site.settings["permissions"]: return self.response(to, "Logout not allowed")
-		message = "<b>You have been logged out.</b> <a href='#Login' class='button' onclick='wrapper.ws.cmd(\"userLoginForm\", []); return false'>Login to another account</a>"
-		message+= "<script>document.cookie = 'master_address=; expires=Thu, 01 Jan 1970 00:00:00 UTC'</script>"
-		self.cmd("notification", ["done", message, 1000000]) # 1000000 = Show ~forever :)
-		# Delete from user_manager
-		user_manager = sys.modules["User.UserManager"].user_manager
-		if self.user.master_address in user_manager.users:
-			del user_manager.users[self.user.master_address]
-			self.response(to, "Successful logout")
-		else:
-			self.response(to, "User not found")
-
-
-	# Show login form
-	def actionUserLoginForm(self, to):
-		self.cmd("prompt", ["<b>Login</b><br>Your private key:", "password", "Login"], self.responseUserLogin)
-
-
-	# Login form submit
-	def responseUserLogin(self, master_seed):
-		user_manager = sys.modules["User.UserManager"].user_manager
-		user = user_manager.create(master_seed=master_seed)
-		if user.master_address:
-			message = "Successfull login, reloading page..."
-			message+= "<script>document.cookie = 'master_address=%s;path=/;max-age=2592000;'</script>" % user.master_address
-			message+= "<script>wrapper.reload('login=done')</script>"
-			self.cmd("notification", ["done", message])
-		else:
-			self.cmd("notification", ["error", "Error: Invalid master seed"])
-			self.actionUserLoginForm(0)
-
+    # Login form submit
+    def responseUserLogin(self, master_seed):
+        user_manager = sys.modules["User.UserManager"].user_manager
+        user = user_manager.create(master_seed=master_seed)
+        if user.master_address:
+            message = "Successfull login, reloading page..."
+            message += "<script>document.cookie = 'master_address=%s;path=/;max-age=2592000;'</script>" % user.master_address
+            message += "<script>wrapper.reload('login=done')</script>"
+            self.cmd("notification", ["done", message])
+        else:
+            self.cmd("notification", ["error", "Error: Invalid master seed"])
+            self.actionUserLoginForm(0)
diff --git a/src/Config.py b/src/Config.py
index 43b756cb..45419a26 100644
--- a/src/Config.py
+++ b/src/Config.py
@@ -8,7 +8,7 @@ class Config(object):
 
     def __init__(self, argv):
         self.version = "0.3.2"
-        self.rev = 360
+        self.rev = 377
         self.argv = argv
         self.action = None
         self.createParser()
diff --git a/src/Crypt/CryptConnection.py b/src/Crypt/CryptConnection.py
index cf990ff3..7a6e7401 100644
--- a/src/Crypt/CryptConnection.py
+++ b/src/Crypt/CryptConnection.py
@@ -110,4 +110,4 @@ class CryptConnectionManager:
             return False
 
 
-manager = CryptConnectionManager()
+manager = CryptConnectionManager()
\ No newline at end of file
diff --git a/src/Debug/DebugMedia.py b/src/Debug/DebugMedia.py
index 24dc3222..8f3b23bb 100644
--- a/src/Debug/DebugMedia.py
+++ b/src/Debug/DebugMedia.py
@@ -108,4 +108,4 @@ if __name__ == "__main__":
     logging.getLogger().setLevel(logging.DEBUG)
     os.chdir("..")
     config.coffeescript_compiler = r'type "%s" | tools\coffee-node\bin\node.exe tools\coffee-node\bin\coffee --no-header -s -p'
-    merge("data/12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH/js/all.js")
+    merge("data/12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH/js/all.js")
\ No newline at end of file
diff --git a/src/Site/Site.py b/src/Site/Site.py
index c7830f06..cdee33a0 100644
--- a/src/Site/Site.py
+++ b/src/Site/Site.py
@@ -312,10 +312,19 @@ class Site:
     # Update content.json on peers
     @util.Noparallel()
     def publish(self, limit=5, inner_path="content.json"):
-        self.log.info("Publishing to %s/%s peers..." % (min(len(self.peers), limit), len(self.peers)))
         published = []  # Successfully published (Peer)
         publishers = []  # Publisher threads
-        peers = self.peers.values()
+
+        connected_peers = self.getConnectedPeers()
+        if len(connected_peers) > limit * 2:  # Publish to already connected peers if possible
+            peers = connected_peers
+        else:
+            peers = self.peers.values()
+
+        self.log.info("Publishing to %s/%s peers (connected: %s)..." % (
+            min(len(self.peers), limit), len(self.peers), len(connected_peers)
+        ))
+
         if not peers:
             return 0  # No peers found
 
@@ -336,13 +345,15 @@ class Site:
             peer for peer in peers
             if peer.connection and not peer.connection.closed and peer.key.endswith(":0") and peer not in published
         ]  # Every connected passive peer that we not published to
-        for peer in passive_peers:
-            gevent.spawn(self.publisher, inner_path, passive_peers, published, limit=10)
 
         self.log.info(
             "Successfuly published to %s peers, publishing to %s more passive peers" %
             (len(published), len(passive_peers))
         )
+
+        for peer in passive_peers:
+            gevent.spawn(self.publisher, inner_path, passive_peers, published, limit=10)
+
         return len(published)
 
     # Copy this site
@@ -664,6 +675,9 @@ class Site:
 
         return found
 
+    def getConnectedPeers(self):
+        return [peer for peer in self.peers.values() if peer.connection and peer.connection.connected]
+
     # Cleanup probably dead peers
     def cleanupPeers(self):
         peers = self.peers.values()
diff --git a/src/Site/SiteStorage.py b/src/Site/SiteStorage.py
index 4e73839c..4292267a 100644
--- a/src/Site/SiteStorage.py
+++ b/src/Site/SiteStorage.py
@@ -3,6 +3,7 @@ import re
 import shutil
 import json
 import time
+import sys
 
 import sqlite3
 import gevent.event
@@ -16,7 +17,9 @@ class SiteStorage:
 
     def __init__(self, site, allow_create=True):
         self.site = site
+        self.fs_encoding = sys.getfilesystemencoding()
         self.directory = "%s/%s" % (config.data_dir, self.site.address)  # Site data diretory
+        self.allowed_dir = os.path.abspath(self.directory)  # Only serve/modify file within this dir
         self.log = site.log
         self.db = None  # Db class
         self.db_checked = False  # Checked db tables since startup
@@ -204,10 +207,10 @@ class SiteStorage:
     def getPath(self, inner_path):
         inner_path = inner_path.replace("\\", "/")  # Windows separator fix
         inner_path = re.sub("^%s/" % re.escape(self.directory), "", inner_path)  # Remove site directory if begins with it
-        file_path = self.directory + "/" + inner_path
-        allowed_dir = os.path.abspath(self.directory)  # Only files within this directory allowed
-        if ".." in file_path or not os.path.dirname(os.path.abspath(file_path)).startswith(allowed_dir):
-            raise Exception("File not allowed: %s" % file_path)
+        file_path = u"%s/%s" % (self.directory, inner_path)
+        file_abspath = os.path.dirname(os.path.abspath(file_path))
+        if ".." in file_path or not file_abspath.startswith(self.allowed_dir):
+            raise Exception(u"File not allowed: %s" % file_path)
         return file_path
 
     # Get site dir relative path
diff --git a/src/Ui/UiRequest.py b/src/Ui/UiRequest.py
index bf29472b..52f6a42a 100644
--- a/src/Ui/UiRequest.py
+++ b/src/Ui/UiRequest.py
@@ -131,6 +131,7 @@ class UiRequest(object):
             content_type = "text/html; charset=utf-8"
         headers = []
         headers.append(("Version", "HTTP/1.1"))
+        headers.append(("Connection", "Keep-Alive"))
         headers.append(("Access-Control-Allow-Origin", "*"))  # Allow json access
         if self.env["REQUEST_METHOD"] == "OPTIONS":
             # Allow json access
@@ -414,8 +415,8 @@ class UiRequest(object):
         yield "He"
         time.sleep(1)
         yield "llo!"
-        yield "Running websockets: %s" % len(self.server.websockets)
-        self.server.sendMessage("Hello!")
+        # yield "Running websockets: %s" % len(self.server.websockets)
+        # self.server.sendMessage("Hello!")
 
     # - Errors -
 
diff --git a/src/lib/cssvendor/cssvendor.py b/src/lib/cssvendor/cssvendor.py
index 49da87fb..3545f59c 100644
--- a/src/lib/cssvendor/cssvendor.py
+++ b/src/lib/cssvendor/cssvendor.py
@@ -8,7 +8,7 @@ def prefix(content):
     )
     content = re.sub(
         '([^-\*])(border-radius|box-shadow|appearance|transition|animation|box-sizing|' +
-        'transform|filter|perspective|animation-[a-z-]+): (.*?)([;}])',
+        'backface-visibility|transform|filter|perspective|animation-[a-z-]+): (.*?)([;}])',
         '\\1-webkit-\\2: \\3; -moz-\\2: \\3; -o-\\2: \\3; -ms-\\2: \\3; \\2: \\3 \\4', content
     )
     content = re.sub(