/** * Test sending of HTTP PUT requests. * * @throws Exception exception */ @Test public void testPUT() throws Exception { final Command put = new XQuery( "http:send-request(" + "<http:request method='put' status-only='true'>" + "<http:body media-type='text/xml'>" + "<books>" + "<book id='1'>" + "<name>Sherlock Holmes</name>" + "<author>Doyle</author>" + "</book>" + "<book id='2'>" + "<name>Winnetou</name>" + "<author>May</author>" + "</book>" + "<book id='3'>" + "<name>Tom Sawyer</name>" + "<author>Twain</author>" + "</book>" + "</books>" + "</http:body>" + "</http:request>, 'http://localhost:8984/basex/jax-rx/books')"); put.execute(context); checkResponse(put, HttpURLConnection.HTTP_CREATED, 1); }
/** Tests http:send-request((),()). */ @Test public void sendReqNoParams() { final Command cmd = new XQuery(_HTTP_SEND_REQUEST.args("()")); try { cmd.execute(ctx); } catch (final BaseXException ex) { assertTrue(ex.getMessage().contains(ErrType.HC.toString())); } }
/** * Test sending of HTTP DELETE requests. * * @throws Exception exception */ @Test public void testPOSTDelete() throws Exception { // DELETE final Command delete = new XQuery( "http:send-request(" + "<http:request method='delete' status-only='true'/>, " + "'http://localhost:8984/basex/jax-rx/books')"); delete.execute(context); checkResponse(delete, HttpURLConnection.HTTP_OK, 1); }
/** * Executes the specified command. * * @param cmd command to be executed * @throws IOException I/O exception */ private void execute(final Command cmd) throws IOException { log.write(this, cmd + " [...]"); final DecodingInput di = new DecodingInput(in); try { cmd.setInput(di); cmd.execute(context); success(cmd.info()); } catch (final BaseXException ex) { di.flush(); error(ex.getMessage()); } }
/** * Runs the stress test. * * @param clients number of clients * @param runs number of runs per client * @throws Exception exception */ private static void run(final int clients, final int runs) throws Exception { // Create test database Command cmd = new CreateDB(NAME, INPUT); cmd.execute(context); // Start clients final Client[] cl = new Client[clients]; for (int i = 0; i < clients; ++i) cl[i] = new Client(runs); for (final Client c : cl) c.start(); for (final Client c : cl) c.join(); // Drop database cmd = new DropDB(NAME); cmd.execute(context); }
/** * Checks the response to an HTTP request. * * @param c command * @param expStatus expected status * @param itemsCount expected number of items * @throws QueryException query exception */ private void checkResponse(final Command c, final int expStatus, final int itemsCount) throws QueryException { assertTrue(c.result() instanceof ItemIter); final ItemIter res = (ItemIter) c.result(); assertEquals(itemsCount, res.size()); assertTrue(res.item[0] instanceof FElem); final FElem response = (FElem) res.item[0]; assertNotNull(response.attr()); final NodeIter resAttr = response.attr(); Nod attr = null; while ((attr = resAttr.next()) != null) { if (Token.eq(attr.nname(), STATUS)) assertTrue(eq(attr.atom(), token(expStatus))); } }
/** * Test sending of HTTP GET requests. * * @throws Exception exception */ @Test public void testPOSTGet() throws Exception { // GET1 - just send a GET request final Command get1 = new XQuery( "http:send-request(" + "<http:request method='get' " + "href='http://localhost:8984/basex/jax-rx/books'/>)"); get1.execute(context); checkResponse(get1, HttpURLConnection.HTTP_OK, 2); assertTrue(((ItemIter) get1.result()).item[1].type == Type.DOC); // GET2 - with override-media-type='text/plain' final Command get2 = new XQuery( "http:send-request(" + "<http:request method='get' override-media-type='text/plain'/>," + "'http://localhost:8984/basex/jax-rx/books')"); get2.execute(context); checkResponse(get2, HttpURLConnection.HTTP_OK, 2); assertTrue(((ItemIter) get2.result()).item[1].type == Type.STR); // Get3 - with status-only='true' final Command get3 = new XQuery( "http:send-request(" + "<http:request method='get' status-only='true'/>," + "'http://localhost:8984/basex/jax-rx/books')"); get3.execute(context); checkResponse(get3, HttpURLConnection.HTTP_OK, 1); }
@Override public void databases(final LockResult lr) { for (final Command c : cmds) c.databases(lr); // lock globally if context-dependent is found (context will be changed by commands) final boolean wc = lr.write.contains(DBLocking.CTX) || lr.write.contains(DBLocking.COLL); final boolean rc = lr.read.contains(DBLocking.CTX) || lr.read.contains(DBLocking.COLL); if (wc || rc && !lr.write.isEmpty()) { lr.writeAll = true; lr.readAll = true; } else if (rc) { lr.readAll = true; } }
/** Saves the displayed text. */ private void save() { final BaseXFileChooser fc = new BaseXFileChooser(SAVE_AS, gui.gopts.get(GUIOptions.WORKPATH), gui).suffix(IO.XMLSUFFIX); final IO file = fc.select(Mode.FSAVE); if (file == null) return; gui.gopts.set(GUIOptions.WORKPATH, file.path()); gui.cursor(CURSORWAIT, true); final MainOptions opts = gui.context.options; final int mh = opts.get(MainOptions.MAXHITS); opts.set(MainOptions.MAXHITS, -1); opts.set(MainOptions.CACHEQUERY, false); try (final PrintOutput out = new PrintOutput(file.toString())) { if (cmd != null) { cmd.execute(gui.context, out); } else if (ns != null) { ns.serialize(Serializer.get(out)); } else { final byte[] txt = text.getText(); for (final byte t : txt) if (t < 0 || t > ' ' || ws(t)) out.write(t); } } catch (final IOException ex) { BaseXDialog.error(gui, Util.info(FILE_NOT_SAVED_X, file)); } finally { opts.set(MainOptions.MAXHITS, mh); opts.set(MainOptions.CACHEQUERY, true); gui.cursor(CURSORARROW, true); } }
/** * Test sending of HTTP POST Query requests. * * @throws Exception exception */ @Test public void testPOSTQuery() throws Exception { // POST - query final Command postQuery = new XQuery( "http:send-request(" + "<http:request method='post'>" + "<http:body media-type='application/query+xml'>" + "<query xmlns='http://jax-rx.sourceforge.net'>" + "<text>//book/name</text>" + "</query>" + "</http:body>" + "</http:request>, 'http://localhost:8984/basex/jax-rx/books')"); postQuery.execute(context); checkResponse(postQuery, HttpURLConnection.HTTP_OK, 2); }
/** * Test sending of HTTP POST Add requests. * * @throws Exception exception */ @Test public void testPOSTAdd() throws Exception { // POST - add content final Command postAdd = new XQuery( "http:send-request(" + "<http:request method='post' status-only='true'>" + "<http:body media-type='text/xml'>" + "<book id='4'>" + "<name>The Celebrated Jumping Frog of Calaveras County</name>" + "<author>Twain</author>" + "</book>" + "</http:body>" + "</http:request>, 'http://localhost:8984/basex/jax-rx/books')"); postAdd.execute(context); checkResponse(postAdd, HttpURLConnection.HTTP_CREATED, 1); }
/** * Caches the output. * * @param out cached output * @param c command * @param r result * @throws QueryException query exception */ public void cacheText(final ArrayOutput out, final Command c, final Result r) throws QueryException { // cache command or node set cmd = null; ns = null; final int mh = gui.context.options.get(MainOptions.MAXHITS); boolean parse = false; if (mh >= 0 && r != null && r.size() >= mh) { parse = true; } else if (out.finished()) { if (r instanceof DBNodes) ns = (DBNodes) r; else parse = true; } // create new command instance if (parse) cmd = new CommandParser(c.toString(), gui.context).parseSingle(); }
@Override public void createIndex(final IndexType type, final MainOptions options, final Command cmd) throws IOException { // close existing index close(type); final IndexBuilder ib; switch (type) { case TEXT: ib = new DiskValuesBuilder(this, options, true); break; case ATTRIBUTE: ib = new DiskValuesBuilder(this, options, false); break; case FULLTEXT: ib = new FTBuilder(this, options); break; default: throw Util.notExpected(); } if (cmd != null) cmd.proc(ib); set(type, ib.build()); }
/** Exits the session. */ public synchronized void quit() { running = false; if (log != null) log.write(this, "LOGOUT " + context.user.name, OK); // wait until running command was stopped if (command != null) { command.stop(); while (command != null) Performance.sleep(50); } context.delete(this); try { new Close().execute(context); socket.close(); if (events) { esocket.close(); // remove this session from all events in pool for (final Sessions s : context.events.values()) s.remove(this); } } catch (final Exception ex) { if (log != null) log.write(ex.getMessage()); Util.stack(ex); } }
@Override protected void execute(final Command cmd, final OutputStream os) throws IOException { execute(cmd.toString(), os); }
@Override public void run() { // initialize the session via cram-md5 authentication try { final String ts = Long.toString(System.nanoTime()); final byte[] address = socket.getInetAddress().getAddress(); // send {TIMESTAMP}0 out = PrintOutput.get(socket.getOutputStream()); out.print(ts); send(true); // evaluate login data in = new BufferInput(socket.getInputStream()); // receive {USER}0{PASSWORD}0 final String us = in.readString(); final String pw = in.readString(); context.user = context.users.get(us); running = context.user != null && md5(string(context.user.password) + ts).equals(pw); // write log information if (running) { log.write(this, "LOGIN " + context.user.name, OK); // send {OK} send(true); server.unblock(address); context.add(this); } else { if (!us.isEmpty()) log.write(this, ACCESS_DENIED + COLS + us); new ClientDelayer(server.block(address), this, server).start(); } } catch (final IOException ex) { Util.stack(ex); log.write(ex.getMessage()); return; } if (!running) return; // authentification done, start command loop ServerCmd sc = null; String cmd = null; try { while (running) { command = null; try { final int b = in.read(); if (b == -1) { // end of stream: exit session quit(); break; } last = System.currentTimeMillis(); perf.time(); sc = ServerCmd.get(b); cmd = null; if (sc == ServerCmd.CREATE) { create(); } else if (sc == ServerCmd.ADD) { add(); } else if (sc == ServerCmd.WATCH) { watch(); } else if (sc == ServerCmd.UNWATCH) { unwatch(); } else if (sc == ServerCmd.REPLACE) { replace(); } else if (sc == ServerCmd.STORE) { store(); } else if (sc != ServerCmd.COMMAND) { query(sc); } else { // database command cmd = new ByteList().add(b).add(in.readBytes()).toString(); } } catch (final IOException ex) { // this exception may be thrown if a session is stopped quit(); break; } if (sc != ServerCmd.COMMAND) continue; // parse input and create command instance try { command = new CommandParser(cmd, context).parseSingle(); } catch (final QueryException ex) { // log invalid command final String msg = ex.getMessage(); log.write(this, cmd, ERROR_C + msg); // send 0 to mark end of potential result out.write(0); // send {INFO}0 out.writeString(msg); // send 1 to mark error send(false); continue; } // start timeout command.startTimeout(context.mprop.num(MainProp.TIMEOUT)); log.write(this, command.toString().replace('\r', ' ').replace('\n', ' ')); // execute command and send {RESULT} boolean ok = true; String info; try { command.execute(context, new EncodingOutput(out)); info = command.info(); } catch (final BaseXException ex) { ok = false; info = ex.getMessage(); if (info.startsWith(INTERRUPTED)) info = TIMEOUT_EXCEEDED; } // stop timeout command.stopTimeout(); // send 0 to mark end of result out.write(0); // send info info(info, ok); // stop console if (command instanceof Exit) { command = null; quit(); } } } catch (final IOException ex) { log.write(this, sc == ServerCmd.COMMAND ? cmd : sc, ERROR_C + ex.getMessage()); Util.debug(ex); command = null; quit(); } command = null; }
@Override public boolean updating(final Context ctx) { boolean up = false; for (final Command c : cmds) up |= c.updating(ctx); return up; }
/** * Runs the specified command. * * @param c command * @param os output stream * @throws HTTPException HTTP exception */ final void run(final Command c, final OutputStream os) throws HTTPException { final boolean ok = c.run(context, os); error(c.info()); if (!ok) throw HTTPCode.BAD_REQUEST_X.get(c.info()); }