outputmodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 588 行 · 第 1/2 页
JAVA
588 行
if (callback != null && callback.isInternal()) type = LongValue.ZERO; element.put(env.createString("type"), type); // the rewriter is a special case where it includes a field // "buffer_size" right in the middle of the common elements, // but only when called with full status. It appears always // to be 0 and there is no interface to change this buffer_size // and no indication of its meaning. if (fullStatus && callback != null && callback == UrlRewriterCallback.getInstance(env)) element.put(env.createString("buffer_size"), LongValue.ZERO); // Technically, there are supposed to be three possible values // for status: // 0 if the stream has never been flushed (PHP_OUTPUT_HANDLER_START) // 1 if the stream has been flushed (PHP_OUTPUT_HANDLER_CONT) // 2 if the stream was flushed at the end (PHP_OUTPUT_HANDLER_END) // However, there is no way to access the buffer after it has ended, // so the final case doesn't seem to be an issue! (Even calling // ob_get_status() in the handler on a ob_end_flush() does not // invoke this state.) LongValue status = ob.haveFlushed() ? LongValue.ONE : LongValue.ZERO; element.put(env.createString("status"), status); StringValue name; if (callback != null) name = env.createString(callback.getCallbackName()); else name = env.createString("default output handler".intern()); element.put(env.createString("name".intern()), name); Value del = ob.getEraseFlag() ? BooleanValue.TRUE : BooleanValue.FALSE; element.put(env.createString("del"), del); } /** * Gets the status for all the output buffers on the stack. * Recursion ensures the results are ordered correctly in the array. */ private static void getFullStatus(OutputBuffer ob, Env env, ArrayValue result) { if (ob == null) return; getFullStatus(ob.getNext(), env, result); ArrayValue element = new ArrayValueImpl(); element.put(env.createString("chunk_size"), LongValue.create(ob.getChunkSize())); // XXX: Not sure why we even need to list a size -- PHP doesn't // even seem to respect it. -1 => infinity? // (Note: "size" == "capacity") element.put(env.createString("size"), LongValue.create(-1)); element.put(env.createString("block_size"), LongValue.create(-1)); putCommonStatus(element, ob, env, true); result.put(element); } /** * Gets the status of the current output buffer(s) */ public static Value ob_get_status(Env env, @Optional boolean full_status) { if (full_status) { OutputBuffer ob = env.getOutputBuffer(); ArrayValue result = new ArrayValueImpl(); getFullStatus(ob, env, result); return result; } OutputBuffer ob = env.getOutputBuffer(); ArrayValue result = new ArrayValueImpl(); if (ob != null) { result.put(env.createString("level"), LongValue.create(ob.getLevel())); putCommonStatus(result, ob, env, false); } // returns an empty array when no output buffer exists return result; } /** * Makes the original "output buffer" flush on every write. */ public static Value ob_implicit_flush(Env env, @Optional("true") boolean flag) { if (env.getOriginalOut() != null) env.getOriginalOut().setImplicitFlush(flag); return NullValue.NULL; } /** * Pushes the output buffer */ public static boolean ob_start(Env env, @Optional Callback callback, @Optional int chunkSize, @Optional("true") boolean erase) { if (callback != null && callback.getCallbackName().equals("ob_gzhandler")) { OutputBuffer ob = env.getOutputBuffer(); for (; ob != null; ob = ob.getNext()) { Callback cb = ob.getCallback(); if (cb.getCallbackName().equals("ob_gzhandler")) { env.warning(L.l("output handler 'ob_gzhandler' cannot be used twice")); return false; } } } env.pushOutputBuffer(callback, chunkSize, erase); return true; } /** * Pushes a new UrlRewriter callback onto the output buffer stack * if one does not already exist. */ public static UrlRewriterCallback pushUrlRewriter(Env env) { UrlRewriterCallback rewriter = UrlRewriterCallback.getInstance(env); if (rewriter == null) { OutputBuffer ob = env.getOutputBuffer(); rewriter = new UrlRewriterCallback(env); // PHP installs the URL rewriter into the top output buffer if // its callback is null if (ob != null && ob.getCallback() == null) ob.setCallback(rewriter); else ob_start(env, rewriter, 0, true); } return rewriter; } /** * Adds a variable to the list for rewritten URLs. */ public static boolean output_add_rewrite_var(Env env, String name, String value) { UrlRewriterCallback rewriter = pushUrlRewriter(env); rewriter.addRewriterVar(name, value); return true; } /** * Clears the list of variables for rewritten URLs. */ public static boolean output_reset_rewrite_vars(Env env) { UrlRewriterCallback rewriter = UrlRewriterCallback.getInstance(env); rewriter.resetRewriterVars(); return true; } /** * Output buffering compatible callback that automatically compresses * the output. The output of this function depends on the value of * state. Specifically, if the PHP_OUTPUT_HANDLER_START bit is on * in the state field, the function supplies a header with the output * and initializes a gzip/deflate stream which will be used for * subsequent calls. */ public static Value ob_gzhandler(Env env, StringValue buffer, int state) { Encoding encoding = Encoding.NONE; Value _SERVER = env.getSpecialRef("_SERVER"); String [] acceptedList = _SERVER.get(HTTP_ACCEPT_ENCODING).toString().split(","); for (String accepted : acceptedList) { accepted = accepted.trim(); if (accepted.equalsIgnoreCase("gzip")) { encoding = Encoding.GZIP; break; } else if (accepted.equalsIgnoreCase("deflate")) { encoding = Encoding.DEFLATE; break; } } if (encoding == Encoding.NONE) return BooleanValue.FALSE; GZOutputPair pair = null; StringValue result = env.createBinaryBuilder(); if ((state & (1 << OutputBuffer.PHP_OUTPUT_HANDLER_START)) != 0) { HttpModule.header(env, env.createString("Vary: Accept-Encoding"), true, 0); int encodingFlag = 0; pair = new GZOutputPair(); pair._tempStream = new StringOutputStream(); pair._tempStream.setResult(result); try { if (encoding == Encoding.GZIP) { HttpModule.header(env, env.createString("Content-Encoding: gzip"), true, 0); pair._outputStream = new GZIPOutputStream(pair._tempStream); } else if (encoding == Encoding.DEFLATE) { HttpModule.header(env, env.createString("Content-Encoding: deflate"), true, 0); pair._outputStream = new DeflaterOutputStream(pair._tempStream); } } catch (IOException e) { return BooleanValue.FALSE; } env.setGzStream(pair); } else { pair = (GZOutputPair) env.getGzStream(); if (pair == null) return BooleanValue.FALSE; pair._tempStream.setResult(result); } try { buffer.writeTo(pair._outputStream); pair._outputStream.flush(); if ((state & (1 << OutputBuffer.PHP_OUTPUT_HANDLER_END)) != 0) { pair._outputStream.close(); } } catch (IOException e) { return BooleanValue.FALSE; } pair._tempStream.setResult(null); return result; } static class StringOutputStream extends OutputStream { private StringValue _result; void setResult(StringValue result) { _result = result; } public void write(byte []buffer, int offset, int length) throws IOException { _result.append(buffer, offset, length); } public void write(int ch) throws IOException { _result.append(ch); } } static final IniDefinition INI_OUTPUT_BUFFERING = _iniDefinitions.add("output_buffering", false, PHP_INI_PERDIR); static final IniDefinition INI_OUTPUT_HANDLER = _iniDefinitions.add("output_handler", "", PHP_INI_PERDIR); static final IniDefinition INI_IMPLICIT_FLUSH = _iniDefinitions.add("implicit_flush", false, PHP_INI_ALL);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?