示例#1
0
  @Override
  public final void service(final HttpServletRequest req, final HttpServletResponse res)
      throws IOException {

    final HTTPContext http = new HTTPContext(req, res, this);
    final boolean restxq = this instanceof RestXqServlet;
    try {
      http.authorize();
      run(http);
      http.log(SC_OK, "");
    } catch (final HTTPException ex) {
      http.status(ex.getStatus(), Util.message(ex), restxq);
    } catch (final LoginException ex) {
      http.status(SC_UNAUTHORIZED, Util.message(ex), restxq);
    } catch (final IOException | QueryException ex) {
      http.status(SC_BAD_REQUEST, Util.message(ex), restxq);
    } catch (final ProcException ex) {
      http.status(SC_BAD_REQUEST, Text.INTERRUPTED, restxq);
    } catch (final Exception ex) {
      final String msg = Util.bug(ex);
      Util.errln(msg);
      http.status(SC_INTERNAL_SERVER_ERROR, Util.info(UNEXPECTED, msg), restxq);
    } finally {
      if (Prop.debug) {
        Util.outln("_ REQUEST _________________________________" + Prop.NL + req);
        final Enumeration<String> en = req.getHeaderNames();
        while (en.hasMoreElements()) {
          final String key = en.nextElement();
          Util.outln(Text.LI + key + Text.COLS + req.getHeader(key));
        }
        Util.out("_ RESPONSE ________________________________" + Prop.NL + res);
      }
    }
  }
示例#2
0
 /**
  * Checks if the produced content type matches.
  *
  * @param http http context
  * @return result of check
  */
 private boolean produces(final HTTPContext http) {
   // return true if no type is given
   if (produces.isEmpty()) return true;
   // check if any combination matches
   for (final String pr : http.produces()) {
     for (final String p : produces) {
       if (MimeTypes.matches(p, pr)) return true;
     }
   }
   return false;
 }
示例#3
0
 /**
  * Checks if the consumed content type matches.
  *
  * @param http http context
  * @return result of check
  */
 private boolean consumes(final HTTPContext http) {
   // return true if no type is given
   if (consumes.isEmpty()) return true;
   // return true if no content type is specified by the user
   final String ct = http.contentType();
   if (ct == null) return true;
   // check if any combination matches
   for (final String c : consumes) {
     if (MimeTypes.matches(c, ct)) return true;
   }
   return false;
 }
示例#4
0
 @Override
 public void init(final ServletConfig config) throws ServletException {
   super.init(config);
   try {
     HTTPContext.init(config.getServletContext());
     final Enumeration<String> en = config.getInitParameterNames();
     while (en.hasMoreElements()) {
       String key = en.nextElement().toLowerCase(Locale.ENGLISH);
       final String val = config.getInitParameter(key);
       if (key.startsWith(Prop.DBPREFIX)) key = key.substring(Prop.DBPREFIX.length());
       if (key.equalsIgnoreCase(MainProp.USER[0].toString())) {
         user = val;
       } else if (key.equalsIgnoreCase(MainProp.PASSWORD[0].toString())) {
         pass = val;
       }
     }
   } catch (final IOException ex) {
     throw new ServletException(ex);
   }
 }
示例#5
0
  @Override
  protected void run(final HTTPContext http) throws Exception {
    // authenticate user
    http.authenticate();

    // analyze input path
    final RestXqModules rxm = RestXqModules.get();
    // select XQuery function
    RestXqFunction func = rxm.find(http, null);
    if (func == null) throw HTTPCode.NO_XQUERY.get();

    try {
      // process function that matches the current request
      func.process(http, null);
    } catch (final QueryException ex) {
      // process optional error function
      func = rxm.find(http, ex.qname());
      if (func == null) throw ex;
      func.process(http, ex);
    }
  }
示例#6
0
 @Override
 public void init(final ServletConfig config) throws ServletException {
   super.init(config);
   try {
     HTTPContext.init(config.getServletContext());
     final Enumeration<String> en = config.getInitParameterNames();
     while (en.hasMoreElements()) {
       String key = en.nextElement().toLowerCase(Locale.ENGLISH);
       final String val = config.getInitParameter(key);
       if (key.startsWith(Prop.DBPREFIX)) key = key.substring(Prop.DBPREFIX.length());
       if (key.equalsIgnoreCase(StaticOptions.USER.name())) {
         username = val;
       } else if (key.equalsIgnoreCase(StaticOptions.PASSWORD.name())) {
         password = val;
       } else if (key.equalsIgnoreCase(StaticOptions.AUTHMETHOD.name())) {
         auth = AuthMethod.valueOf(val);
       }
     }
   } catch (final IOException ex) {
     throw new ServletException(ex);
   }
 }
示例#7
0
  /**
   * Evaluates the specified function and creates a response.
   *
   * @throws Exception exception (including unexpected ones)
   */
  void create() throws Exception {
    // bind variables
    final StaticFunc sf = function.function;
    final Expr[] args = new Expr[sf.args.length];
    function.bind(http, args, error);

    // wrap function with a function call
    final MainModule mm = new MainModule(sf, args);

    // assign main module and http context and register process
    query.mainModule(mm);
    query.http(http);
    query.context.register(query);

    String redirect = null, forward = null;
    RestXqRespBuilder resp = null;
    try {
      // compile and evaluate query
      query.compile();
      final Iter iter = query.iter();
      Item item = iter.next();

      // handle response element
      if (item != null && item instanceof ANode) {
        final ANode node = (ANode) item;
        // send redirect to browser
        if (REST_REDIRECT.eq(node)) {
          final ANode ch = node.children().next();
          if (ch == null || ch.type != NodeType.TXT) throw function.error(NO_VALUE, node.name());
          redirect = string(ch.string()).trim();
          return;
        }
        // server-side forwarding
        if (REST_FORWARD.eq(node)) {
          final ANode ch = node.children().next();
          if (ch == null || ch.type != NodeType.TXT) throw function.error(NO_VALUE, node.name());
          forward = string(ch.string()).trim();
          return;
        }
        if (REST_RESPONSE.eq(node)) {
          resp = new RestXqRespBuilder();
          resp.build(node, function, iter, http);
          return;
        }
      }

      // HEAD method must return a single response element
      if (function.methods.size() == 1 && function.methods.contains(HTTPMethod.HEAD.name()))
        throw function.error(HEAD_METHOD);

      // serialize result
      final SerializerOptions sp = function.output;
      http.sopts(sp);
      http.initResponse();
      final Serializer ser = Serializer.get(http.res.getOutputStream(), sp);
      for (; item != null; item = iter.next()) ser.serialize(item);
      ser.close();

    } finally {
      query.close();
      query.context.unregister(query);

      if (redirect != null) {
        http.res.sendRedirect(redirect);
      } else if (forward != null) {
        http.req.getRequestDispatcher(forward).forward(http.req, http.res);
      } else if (resp != null) {
        if (resp.status != 0) http.status(resp.status, resp.message, resp.error);
        http.res.getOutputStream().write(resp.cache.toArray());
      }
    }
  }
示例#8
0
  /**
   * Binds the annotated variables.
   *
   * @param http http context
   * @param arg argument array
   * @throws QueryException query exception
   * @throws IOException I/O exception
   */
  void bind(final HTTPContext http, final Expr[] arg) throws QueryException, IOException {
    // bind variables from segments
    for (int s = 0; s < path.size; s++) {
      final Matcher m = TEMPLATE.matcher(path.segment[s]);
      if (!m.find()) continue;
      final QNm qnm = new QNm(token(m.group(1)), context);
      bind(qnm, arg, new Atm(http.segment(s)));
    }

    // cache request body
    final String ct = http.contentType();
    IOContent body = null;

    if (requestBody != null) {
      body = cache(http, null);
      try {
        // bind request body in the correct format
        body.name(http.method + IO.XMLSUFFIX);
        bind(requestBody, arg, Parser.item(body, context.context.prop, ct));
      } catch (final IOException ex) {
        error(INPUT_CONV, ex);
      }
    }

    // bind query parameters
    final Map<String, String[]> params = http.params();
    for (final RestXqParam rxp : queryParams) bind(rxp, arg, params.get(rxp.key));

    // bind form parameters
    if (!formParams.isEmpty()) {
      if (MimeTypes.APP_FORM.equals(ct)) {
        // convert parameters encoded in a form
        body = cache(http, body);
        addParams(body.toString(), params);
      }
      for (final RestXqParam rxp : formParams) bind(rxp, arg, params.get(rxp.key));
    }

    // bind header parameters
    for (final RestXqParam rxp : headerParams) {
      final StringList sl = new StringList();
      final Enumeration<?> en = http.req.getHeaders(rxp.key);
      while (en.hasMoreElements()) {
        for (final String s : en.nextElement().toString().split(", *")) sl.add(s);
      }
      bind(rxp, arg, sl.toArray());
    }

    // bind cookie parameters
    final Cookie[] ck = http.req.getCookies();
    for (final RestXqParam rxp : cookieParams) {
      String v = null;
      if (ck != null) {
        for (final Cookie c : ck) {
          if (rxp.key.equals(c.getName())) v = c.getValue();
        }
      }
      if (v == null) bind(rxp, arg);
      else bind(rxp, arg, v);
    }
  }