docs: def query_helper(request,namespace, docid, configuration=None):
      """Does the actual query, called by query() or pub_query(), not directly"""
      flatargs = {
          'customslicesize': request.POST.get('customslicesize',settings.CONFIGURATIONS[configuration].get('customslicesize','50')), #for pagination of search results
      }
      #stupid compatibility stuff
      if sys.version < '3':
          if hasattr(request, 'body'):
              data = json.loads(unicode(request.body,'utf-8')) #pylint: disable=undefined-variable
          else: #older django
              data = json.loads(unicode(request.raw_post_data,'utf-8')) #pylint: disable=undefined-variable
      else:
          if hasattr(request, 'body'):
              data = json.loads(str(request.body,'utf-8'))
          else: #older django
              data = json.loads(str(request.raw_post_data,'utf-8'))
  
      if not data['queries']:
          return HttpResponseForbidden("No queries to run")
  
      for query in data['queries']:
          #get document selector and check it doesn't violate the namespace
          docselector, query = getdocumentselector(query)
          if not docselector:
              return HttpResponseForbidden("Query does not start with a valid document selector (USE keyword)!")
          elif docselector[0] != namespace:
              return HttpResponseForbidden("Query would affect a different namespace than your current one, forbidden!")
  
          if query != "GET" and query[:4] != "CQL " and query[:4] != "META":
              #parse query on this end to catch syntax errors prior to sending, should be fast enough anyway
              #first resolve variables to dummies (real ones will be handled server-side) as it won't be valid FQL otherwise
              query = query.replace("$FOLIADOCSERVE_PROCESSOR", "PROCESSOR name \"foliadocserve\"")
              query = query.replace("$FLAT_PROCESSOR", "PROCESSOR name \"FLAT\" version \"" + VERSION + "\" host \"" + request.get_host() + "\" src \"" + request.build_absolute_uri("/") + "\"") #also another instance in comm.py
              try:
                  query = fql.Query(query)
              except fql.SyntaxError as e:
                  return HttpResponseForbidden("FQL Syntax Error: " + str(e))
              needwritepermission = query.declarations or query.action and query.action.action != "SELECT"
          else:
              needwritepermission = False
  
      if configuration != "pub":
          if needwritepermission and not flat.users.models.haswritepermission(request.user.username, namespace, request):
              return HttpResponseForbidden("Permission denied, no write access")
  
      query = "\n".join(data['queries']) #throw all queries on a big pile to transmit
      try:
          d = flat.comm.query(request, query,**flatargs)
      except Exception as e:
          if sys.version < '3':
              errmsg = docserveerror(e)['fatalerror_text']
              return HttpResponseForbidden("FoLiA Document Server error: ".encode('utf-8') + errmsg.encode('utf-8'))
          else:
              return HttpResponseForbidden("FoLiA Document Server error: " + docserveerror(e)['fatalerror_text'])
      return HttpResponse(json.dumps(d).encode('utf-8'), content_type='application/json')