diff --git a/acceptreject.py b/acceptreject.py index 894db12f..114f1f30 100644 --- a/acceptreject.py +++ b/acceptreject.py @@ -136,14 +136,16 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \ followedActor=messageJson['object']['object'] followedDomain,port=getDomainFromActor(followedActor) if not followedDomain: - print('DEBUG: no domain found within Follow activity object '+followedActor) + print('DEBUG: no domain found within Follow activity object '+ \ + followedActor) return followedDomainFull=followedDomain if port: followedDomainFull=followedDomain+':'+str(port) followedNickname=getNicknameFromActor(followedActor) if not followedNickname: - print('DEBUG: no nickname found within Follow activity object '+followedActor) + print('DEBUG: no nickname found within Follow activity object '+ \ + followedActor) return acceptedDomainFull=acceptedDomain @@ -158,7 +160,8 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \ messageJson['capabilities']) # has this person already been unfollowed? - unfollowedFilename=baseDir+'/accounts/'+nickname+'@'+acceptedDomainFull+'/unfollowed.txt' + unfollowedFilename= \ + baseDir+'/accounts/'+nickname+'@'+acceptedDomainFull+'/unfollowed.txt' if os.path.isfile(unfollowedFilename): if followedNickname+'@'+followedDomainFull in open(unfollowedFilename).read(): if debug: @@ -212,7 +215,8 @@ def receiveAcceptReject(session,baseDir: str, \ nickname='dev' if debug: print('DEBUG: '+messageJson['type']+ \ - ' does not contain a nickname. Assuming single user instance.') + ' does not contain a nickname. '+ \ + 'Assuming single user instance.') handle=nickname.lower()+'@'+domain.lower() # receive follow accept acceptFollow(baseDir,domain,messageJson,federationList,debug) diff --git a/announce.py b/announce.py index 206228ea..51047b65 100644 --- a/announce.py +++ b/announce.py @@ -84,7 +84,8 @@ def undoAnnounceCollectionEntry(recentPostsCache: {}, \ """ postJsonObject=loadJson(postFilename) if postJsonObject: - # remove any cached version of this announce so that the announce icon is changed + # remove any cached version of this announce so that the announce + # icon is changed nickname=getNicknameFromActor(actor) cachedPostFilename= \ getCachedPostFilename(baseDir,nickname,domain,postJsonObject) diff --git a/auth.py b/auth.py index d9742e9d..b8116062 100644 --- a/auth.py +++ b/auth.py @@ -17,9 +17,10 @@ def hashPassword(password: str) -> str: """Hash a password for storing """ salt=hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii') - pwdhash=hashlib.pbkdf2_hmac('sha512', \ - password.encode('utf-8'), \ - salt, 100000) + pwdhash= \ + hashlib.pbkdf2_hmac('sha512', \ + password.encode('utf-8'), \ + salt, 100000) pwdhash=binascii.hexlify(pwdhash) return (salt+pwdhash).decode('ascii') @@ -28,10 +29,11 @@ def verifyPassword(storedPassword: str,providedPassword: str) -> bool: """ salt=storedPassword[:64] storedPassword=storedPassword[64:] - pwdhash=hashlib.pbkdf2_hmac('sha512', \ - providedPassword.encode('utf-8'), \ - salt.encode('ascii'), \ - 100000) + pwdhash= \ + hashlib.pbkdf2_hmac('sha512', \ + providedPassword.encode('utf-8'), \ + salt.encode('ascii'), \ + 100000) pwdhash=binascii.hexlify(pwdhash).decode('ascii') return pwdhash==storedPassword @@ -46,7 +48,8 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool: """ if ' ' not in authHeader: if debug: - print('DEBUG: Authorixation header does not contain a space character') + print('DEBUG: Authorixation header does not '+ \ + 'contain a space character') return False if '/users/' not in path and \ '/channel/' not in path and \ @@ -64,7 +67,8 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool: plain=base64.b64decode(base64Str).decode('utf-8') if ':' not in plain: if debug: - print('DEBUG: Basic Auth header does not contain a ":" separator for username:password') + print('DEBUG: Basic Auth header does not contain a ":" '+ \ + 'separator for username:password') return False nickname=plain.split(':')[0] if nickname!=nicknameFromPath: diff --git a/blocking.py b/blocking.py index f41f527a..1b37a32e 100644 --- a/blocking.py +++ b/blocking.py @@ -448,9 +448,11 @@ def outboxUndoBlock(baseDir: str,httpPrefix: str, \ return nicknameBlocked=getNicknameFromActor(messageJson['object']['object']) if not nicknameBlocked: - print('WARN: unable to find nickname in '+messageJson['object']['object']) + print('WARN: unable to find nickname in '+ \ + messageJson['object']['object']) return - domainBlocked,portBlocked=getDomainFromActor(messageJson['object']['object']) + domainBlocked,portBlocked= \ + getDomainFromActor(messageJson['object']['object']) domainBlockedFull=domainBlocked if portBlocked: if portBlocked!=80 and portBlocked!=443: diff --git a/blog.py b/blog.py index f4ac0230..c01d11af 100644 --- a/blog.py +++ b/blog.py @@ -220,7 +220,8 @@ def htmlBlogPostContent(authorized: bool, \ if not linkedAuthor: blogStr+= \ - '

'+translate['About the author']+'

\n' replies= \ @@ -347,14 +348,16 @@ def htmlBlogPage(authorized: bool, session, \ if pageNumber>1: # show previous button navigateStr+= \ - ''+ \ + ''+ \ '<\n' if len(timelineJson['orderedItems'])>=noOfItems: # show next button navigateStr+= \ - ''+ \ + ''+ \ '>\n' @@ -552,7 +555,9 @@ def htmlEditBlog(mediaInstance: bool,translate: {}, \ iconsDir=getIconsDir(baseDir) - editBlogText='

'+translate['Write your post text below.']+'

' + editBlogText= \ + '

'+ \ + translate['Write your post text below.']+'

' if os.path.isfile(baseDir+'/accounts/newpost.txt'): with open(baseDir+'/accounts/newpost.txt', 'r') as file: diff --git a/bookmarks.py b/bookmarks.py index 17881cc0..c5f89503 100644 --- a/bookmarks.py +++ b/bookmarks.py @@ -85,7 +85,8 @@ def undoBookmarksCollectionEntry(recentPostsCache: {}, \ saveJson(postJsonObject,postFilename) # remove from the index - bookmarksIndexFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index' + bookmarksIndexFilename= \ + baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index' if not os.path.isfile(bookmarksIndexFilename): return if '/' in postFilename: @@ -192,7 +193,8 @@ def updateBookmarksCollection(recentPostsCache: {}, \ saveJson(postJsonObject,postFilename) # prepend to the index - bookmarksIndexFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index' + bookmarksIndexFilename= \ + baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index' bookmarkIndex=postFilename.split('/')[-1] if os.path.isfile(bookmarksIndexFilename): if bookmarkIndex not in open(bookmarksIndexFilename).read(): @@ -255,13 +257,15 @@ def bookmark(recentPostsCache: {}, \ bookmarkedPostPort=None if actorBookmarked: bookmarkedPostNickname=getNicknameFromActor(actorBookmarked) - bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(actorBookmarked) + bookmarkedPostDomain,bookmarkedPostPort= \ + getDomainFromActor(actorBookmarked) else: if '/users/' in objectUrl or \ '/channel/' in objectUrl or \ '/profile/' in objectUrl: bookmarkedPostNickname=getNicknameFromActor(objectUrl) - bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(objectUrl) + bookmarkedPostDomain,bookmarkedPostPort= \ + getDomainFromActor(objectUrl) if bookmarkedPostNickname: postFilename=locatePost(baseDir,nickname,domain,objectUrl) @@ -278,7 +282,8 @@ def bookmark(recentPostsCache: {}, \ sendSignedJson(newBookmarkJson,session,baseDir, \ nickname,domain,port, \ - bookmarkedPostNickname,bookmarkedPostDomain,bookmarkedPostPort, \ + bookmarkedPostNickname, \ + bookmarkedPostDomain,bookmarkedPostPort, \ 'https://www.w3.org/ns/activitystreams#Public', \ httpPrefix,True,clientToServer,federationList, \ sendThreads,postLog,cachedWebfingers,personCache, \ @@ -369,13 +374,15 @@ def undoBookmark(recentPostsCache: {}, \ bookmarkedPostPort=None if actorBookmarked: bookmarkedPostNickname=getNicknameFromActor(actorBookmarked) - bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(actorBookmarked) + bookmarkedPostDomain,bookmarkedPostPort= \ + getDomainFromActor(actorBookmarked) else: if '/users/' in objectUrl or \ '/channel/' in objectUrl or \ '/profile/' in objectUrl: bookmarkedPostNickname=getNicknameFromActor(objectUrl) - bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(objectUrl) + bookmarkedPostDomain,bookmarkedPostPort= \ + getDomainFromActor(objectUrl) if bookmarkedPostNickname: postFilename=locatePost(baseDir,nickname,domain,objectUrl) @@ -400,8 +407,8 @@ def undoBookmark(recentPostsCache: {}, \ def undoBookmarkPost(session,baseDir: str,federationList: [], \ nickname: str,domain: str,port: int,httpPrefix: str, \ - bookmarkNickname: str,bookmarkedomain: str,bookmarkPort: int, \ - ccList: [], \ + bookmarkNickname: str,bookmarkedomain: str, \ + bookmarkPort: int,ccList: [], \ bookmarkStatusNumber: int,clientToServer: bool, \ sendThreads: [],postLog: [], \ personCache: {},cachedWebfingers: {}, \ diff --git a/cache.py b/cache.py index 98d1b5f8..770e1614 100644 --- a/cache.py +++ b/cache.py @@ -12,7 +12,8 @@ import datetime from utils import loadJson from utils import saveJson -def storePersonInCache(baseDir: str,personUrl: str,personJson: {},personCache: {}) -> None: +def storePersonInCache(baseDir: str,personUrl: str, \ + personJson: {},personCache: {}) -> None: """Store an actor in the cache """ currTime=datetime.datetime.utcnow() @@ -25,7 +26,8 @@ def storePersonInCache(baseDir: str,personUrl: str,personJson: {},personCache: { # store to file if os.path.isdir(baseDir+'/cache/actors'): - cacheFilename=baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json' + cacheFilename= \ + baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json' if not os.path.isfile(cacheFilename): saveJson(personJson,cacheFilename) diff --git a/daemon.py b/daemon.py index 820f4cae..c10c7eb1 100644 --- a/daemon.py +++ b/daemon.py @@ -1318,7 +1318,8 @@ class PubServer(BaseHTTPRequestHandler): divertToLoginScreen=False if divertToLoginScreen and not authorized: if self.server.debug: - print('DEBUG: divertToLoginScreen='+str(divertToLoginScreen)) + print('DEBUG: divertToLoginScreen='+ \ + str(divertToLoginScreen)) print('DEBUG: authorized='+str(authorized)) print('DEBUG: path='+self.path) self.send_response(303) @@ -1382,7 +1383,8 @@ class PubServer(BaseHTTPRequestHandler): time.sleep(1) tries+=1 if mediaBinary: - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return self._404() @@ -1407,7 +1409,8 @@ class PubServer(BaseHTTPRequestHandler): time.sleep(1) tries+=1 if mediaBinary: - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return self._404() @@ -1432,7 +1435,8 @@ class PubServer(BaseHTTPRequestHandler): time.sleep(1) tries+=1 if mediaBinary: - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return self._404() @@ -1460,7 +1464,9 @@ class PubServer(BaseHTTPRequestHandler): mediaImageType='gif' with open(emojiFilename, 'rb') as avFile: mediaBinary=avFile.read() - self._set_headers('image/'+mediaImageType,len(mediaBinary),cookie,callingDomain) + self._set_headers('image/'+mediaImageType, \ + len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return self._404() @@ -1555,7 +1561,9 @@ class PubServer(BaseHTTPRequestHandler): mediaFileType='gif' with open(mediaFilename, 'rb') as avFile: mediaBinary=avFile.read() - self._set_headers('image/'+mediaFileType,len(mediaBinary),cookie,callingDomain) + self._set_headers('image/'+mediaFileType, \ + len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return self._404() @@ -1572,14 +1580,16 @@ class PubServer(BaseHTTPRequestHandler): self.server.baseDir+'/img/icons/'+mediaStr if self.server.iconsCache.get(mediaStr): mediaBinary=self.server.iconsCache[mediaStr] - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) return else: if os.path.isfile(mediaFilename): with open(mediaFilename, 'rb') as avFile: mediaBinary=avFile.read() - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) self._write(mediaBinary) self.server.iconsCache[mediaStr]=mediaBinary return @@ -1597,14 +1607,18 @@ class PubServer(BaseHTTPRequestHandler): with open(mediaFilename, 'rb') as avFile: mediaBinary=avFile.read() if mediaFilename.endswith('.png'): - self._set_headers('image/png',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/png',len(mediaBinary), \ + cookie,callingDomain) elif mediaFilename.endswith('.jpg'): - self._set_headers('image/jpeg',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/jpeg',len(mediaBinary), \ + cookie,callingDomain) elif mediaFilename.endswith('.gif'): - self._set_headers('image/gif',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/gif',len(mediaBinary), \ + cookie,callingDomain) else: # default to jpeg - self._set_headers('image/jpeg',len(mediaBinary),cookie,callingDomain) + self._set_headers('image/jpeg',len(mediaBinary), \ + cookie,callingDomain) #self._404() return self._write(mediaBinary) @@ -1714,7 +1728,9 @@ class PubServer(BaseHTTPRequestHandler): return nickname=None if '/users/' in self.path: - actor=self.server.httpPrefix+'://'+self.server.domainFull+self.path + actor= \ + self.server.httpPrefix+'://'+ \ + self.server.domainFull+self.path nickname= \ getNicknameFromActor(actor) hashtagStr= \ @@ -1735,10 +1751,14 @@ class PubServer(BaseHTTPRequestHandler): self._write(msg) else: originPathStr=self.path.split('/tags/')[0] - originPathStrAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+originPathStr + originPathStrAbsolute= \ + self.server.httpPrefix+'://'+ \ + self.server.domainFull+originPathStr if callingDomain.endswith('.onion') and self.server.onionDomain: - originPathStrAbsolute='http://'+self.server.onionDomain+originPathStr - self._redirect_headers(originPathStrAbsolute+'/search',cookie,callingDomain) + originPathStrAbsolute='http://'+ \ + self.server.onionDomain+originPathStr + self._redirect_headers(originPathStrAbsolute+'/search', \ + cookie,callingDomain) self.server.GETbusy=False return @@ -1865,17 +1885,21 @@ class PubServer(BaseHTTPRequestHandler): if not self.postToNickname: print('WARN: unable to find nickname in '+actor) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ - '?page='+str(pageNumber),cookie,callingDomain) + '?page='+str(pageNumber),cookie, \ + callingDomain) return if not self.server.session: self.server.session= \ createSession(self.server.useTor) self.server.actorRepeat=self.path.split('?actor=')[1] - announceToStr=self.server.httpPrefix+'://'+self.server.domain+'/users/'+self.postToNickname+'/followers' + announceToStr= \ + self.server.httpPrefix+'://'+self.server.domain+'/users/'+ \ + self.postToNickname+'/followers' if not repeatPrivate: announceToStr='https://www.w3.org/ns/activitystreams#Public' announceJson= \ @@ -2073,7 +2097,8 @@ class PubServer(BaseHTTPRequestHandler): if not self.postToNickname: print('WARN: unable to find nickname in '+actor) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2099,7 +2124,8 @@ class PubServer(BaseHTTPRequestHandler): } self._postToOutbox(likeJson,self.server.projectVersion) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2138,7 +2164,8 @@ class PubServer(BaseHTTPRequestHandler): if not self.postToNickname: print('WARN: unable to find nickname in '+actor) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2208,7 +2235,8 @@ class PubServer(BaseHTTPRequestHandler): if not self.postToNickname: print('WARN: unable to find nickname in '+actor) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2230,7 +2258,8 @@ class PubServer(BaseHTTPRequestHandler): } self._postToOutbox(bookmarkJson,self.server.projectVersion) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2267,7 +2296,8 @@ class PubServer(BaseHTTPRequestHandler): if not self.postToNickname: print('WARN: unable to find nickname in '+actor) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2294,7 +2324,8 @@ class PubServer(BaseHTTPRequestHandler): } self._postToOutbox(undoBookmarkJson,self.server.projectVersion) self.server.GETbusy=False - actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor + actorAbsolute= \ + self.server.httpPrefix+'://'+self.server.domainFull+actor if callingDomain.endswith('.onion') and self.server.onionDomain: actorAbsolute='http://'+self.server.onionDomain+actor self._redirect_headers(actorAbsolute+'/'+timelineStr+ \ @@ -2630,15 +2661,19 @@ class PubServer(BaseHTTPRequestHandler): self.server.personCache, \ nickname,self.server.domain, \ self.server.port, \ - authorized,postJsonObject, \ + authorized, \ + postJsonObject, \ self.server.httpPrefix, \ self.server.projectVersion).encode('utf-8') - self._set_headers('text/html',len(msg),cookie,callingDomain) + self._set_headers('text/html',len(msg), \ + cookie,callingDomain) self._write(msg) else: if self._fetchAuthenticated(): - msg=json.dumps(postJsonObject,ensure_ascii=False).encode('utf-8') - self._set_headers('application/json',len(msg),None,callingDomain) + msg=json.dumps(postJsonObject, \ + ensure_ascii=False).encode('utf-8') + self._set_headers('application/json',len(msg), \ + None,callingDomain) self._write(msg) else: self._404() @@ -2750,12 +2785,15 @@ class PubServer(BaseHTTPRequestHandler): repliesJson, \ self.server.httpPrefix, \ self.server.projectVersion).encode('utf-8') - self._set_headers('text/html',len(msg),cookie,callingDomain) + self._set_headers('text/html',len(msg), \ + cookie,callingDomain) self._write(msg) else: if self._fetchAuthenticated(): - msg=json.dumps(repliesJson,ensure_ascii=False).encode('utf-8') - self._set_headers('application/json',len(msg),None,callingDomain) + msg=json.dumps(repliesJson, \ + ensure_ascii=False).encode('utf-8') + self._set_headers('application/json',len(msg), \ + None,callingDomain) self._write(msg) else: self._404() @@ -2797,12 +2835,15 @@ class PubServer(BaseHTTPRequestHandler): self.server.personCache, \ actorJson['roles'], \ None,None).encode('utf-8') - self._set_headers('text/html',len(msg),cookie,callingDomain) + self._set_headers('text/html',len(msg), \ + cookie,callingDomain) self._write(msg) else: if self._fetchAuthenticated(): - msg=json.dumps(actorJson['roles'],ensure_ascii=False).encode('utf-8') - self._set_headers('application/json',len(msg),None,callingDomain) + msg=json.dumps(actorJson['roles'], \ + ensure_ascii=False).encode('utf-8') + self._set_headers('application/json',len(msg), \ + None,callingDomain) self._write(msg) else: self._404() @@ -2843,12 +2884,15 @@ class PubServer(BaseHTTPRequestHandler): self.server.personCache, \ actorJson['skills'], \ None,None).encode('utf-8') - self._set_headers('text/html',len(msg),cookie,callingDomain) + self._set_headers('text/html',len(msg), \ + cookie,callingDomain) self._write(msg) else: if self._fetchAuthenticated(): - msg=json.dumps(actorJson['skills'],ensure_ascii=False).encode('utf-8') - self._set_headers('application/json',len(msg),None,callingDomain) + msg=json.dumps(actorJson['skills'], \ + ensure_ascii=False).encode('utf-8') + self._set_headers('application/json',len(msg), \ + None,callingDomain) self._write(msg) else: self._404()