HTTP支持Expect:100-continue

This commit is contained in:
redkale
2023-03-13 18:55:04 +08:00
parent aec65a2ff5
commit 42201c7c11
8 changed files with 47 additions and 50 deletions

View File

@@ -41,7 +41,7 @@ public class HttpContext extends Context {
protected final AnyValue rpcAuthenticatorConfig;
//所有Servlet方法都不需要读取http-header且不存在HttpFilter的情况下lazyHeaders=true
//所有Servlet方法都不需要读取http-header且RestBaseServlet不是自定义HttpServlet且不存在HttpFilter的情况下lazyHeaders=true
protected boolean lazyHeaders; //存在动态改值
Function<WebSocket, WebSocketWriteIOThread> webSocketWriterIOThreadFunc;

View File

@@ -315,6 +315,10 @@ public class HttpDispatcherServlet extends DispatcherServlet<String, HttpContext
response.finish(200, null);
return;
}
if (request.isExpect()) {
response.finish(100, response.getHttpCode(100));
return;
}
if (request.isWebSocket()) {
servlet = wsmappings.get(uri);
if (servlet == null && this.regxWsArray != null) {

View File

@@ -67,6 +67,8 @@ public class HttpRequest extends Request<HttpContext> {
protected static final String KEY_HOST = "Host";
protected static final String KEY_EXPECT = "Expect";
public static final String SESSIONID_NAME = "JSESSIONID";
//---------- header 相关参数 开始 ----------
@@ -87,6 +89,8 @@ public class HttpRequest extends Request<HttpContext> {
private boolean maybews = false; //是否可能是WebSocket
private boolean expect = false; //是否Expect:100-continue
protected boolean rpc;
protected int readState = READ_STATE_ROUTE;
@@ -257,6 +261,10 @@ public class HttpRequest extends Request<HttpContext> {
return maybews && "Upgrade".equalsIgnoreCase(getHeader("Connection")) && "GET".equalsIgnoreCase(method);
}
protected boolean isExpect() {
return expect;
}
protected void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}
@@ -303,6 +311,7 @@ public class HttpRequest extends Request<HttpContext> {
this.cookies = httplast.cookies;
this.keepAlive = httplast.keepAlive;
this.maybews = httplast.maybews;
this.expect = httplast.expect;
this.rpc = httplast.rpc;
this.traceid = httplast.traceid;
this.hashid = httplast.hashid;
@@ -736,6 +745,12 @@ public class HttpRequest extends Request<HttpContext> {
this.maybews = "websocket".equalsIgnoreCase(value);
headers.put("Upgrade", value);
break;
case "Expect":
case "expect":
value = bytes.toString(true, charset);
this.expect = "100-continue".equalsIgnoreCase(value);
headers.put("Expect", value);
break;
case "user-agent":
value = bytes.toString(charset);
headers.put("User-Agent", value);
@@ -824,6 +839,11 @@ public class HttpRequest extends Request<HttpContext> {
return KEY_COOKIE;
}
}
} else if (first == 'E' && size == 6) { //Expect
if (bs[1] == 'x' && bs[2] == 'p' && bs[3] == 'e'
&& bs[4] == 'c' && bs[5] == 't') {
return KEY_EXPECT;
}
}
return bytes.toString(latin1, charset);
}
@@ -844,6 +864,7 @@ public class HttpRequest extends Request<HttpContext> {
req.cookies = this.cookies;
req.keepAlive = this.keepAlive;
req.maybews = this.maybews;
req.expect = this.expect;
req.rpc = this.rpc;
req.traceid = this.traceid;
req.hashid = this.hashid;
@@ -881,6 +902,7 @@ public class HttpRequest extends Request<HttpContext> {
this.cookie = null;
this.cookies = null;
this.maybews = false;
this.expect = false;
this.rpc = false;
this.readState = READ_STATE_ROUTE;
this.currentUserid = CURRUSERID_NIL;

View File

@@ -227,7 +227,7 @@ public class HttpSimpleRequest implements java.io.Serializable {
return this;
}
public HttpSimpleRequest header(String key, JsonConvert convert, Object value) {
public HttpSimpleRequest header(String key, TextConvert convert, Object value) {
if (value == null) {
return this;
}
@@ -276,7 +276,7 @@ public class HttpSimpleRequest implements java.io.Serializable {
return this;
}
public HttpSimpleRequest param(String key, JsonConvert convert, Object value) {
public HttpSimpleRequest param(String key, TextConvert convert, Object value) {
if (value == null) {
return this;
}

View File

@@ -1145,9 +1145,6 @@ public final class Rest {
if ("init".equals(method.getName())) {
continue;
}
if ("stop".equals(method.getName())) {
continue;
}
if ("destroy".equals(method.getName())) {
continue;
}
@@ -1597,9 +1594,6 @@ public final class Rest {
if ("init".equals(method.getName())) {
continue;
}
if ("stop".equals(method.getName())) {
continue;
}
if ("destroy".equals(method.getName())) {
continue;
}

View File

@@ -35,9 +35,9 @@ import org.redkale.util.*;
* WebSocketEngine
* WebSocketNode
* / \
* / \
* / \
* WebSocket1 WebSocket2
* / \
* / \
* WebSocket1 WebSocket2
*
* </pre></blockquote>
*
@@ -78,13 +78,13 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
//同RestWebSocket.liveinterval
protected int liveinterval = DEFAILT_LIVEINTERVAL;
//同RestWebSocket.wsMaxConns
//同RestWebSocket.wsmaxconns
protected int wsmaxconns = 0;
//同RestWebSocket.wsThreads
//同RestWebSocket.wsthreads
protected int wsthreads = 0;
//同RestWebSocket.wsMaxBody
//同RestWebSocket.wsmaxbody
protected int wsmaxbody = 32 * 1024;
//同RestWebSocket.anyuser

View File

@@ -106,7 +106,7 @@ public abstract class Sncp {
continue;
}
if (method.getParameterCount() == 1 && method.getParameterTypes()[0] == AnyValue.class) {
if (method.getName().equals("init") || method.getName().equals("stop") || method.getName().equals("destroy")) {
if (method.getName().equals("init") || method.getName().equals("destroy")) {
continue;
}
}
@@ -893,12 +893,6 @@ public abstract class Sncp {
mv.visitMaxs(0, 2);
mv.visitEnd();
}
{ //stop
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "stop", "(" + anyValueDesc + ")V", null, null));
mv.visitInsn(RETURN);
mv.visitMaxs(0, 2);
mv.visitEnd();
}
{ //destroy
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "destroy", "(" + anyValueDesc + ")V", null, null));
mv.visitInsn(RETURN);

View File

@@ -8,24 +8,7 @@ import java.nio.channels.CompletionHandler;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.redkale.asm.*;
import static org.redkale.asm.Opcodes.ACC_FINAL;
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ACC_SUPER;
import static org.redkale.asm.Opcodes.ACONST_NULL;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ARETURN;
import static org.redkale.asm.Opcodes.DRETURN;
import static org.redkale.asm.Opcodes.FRETURN;
import static org.redkale.asm.Opcodes.GETFIELD;
import static org.redkale.asm.Opcodes.ICONST_0;
import static org.redkale.asm.Opcodes.INVOKEINTERFACE;
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
import static org.redkale.asm.Opcodes.IRETURN;
import static org.redkale.asm.Opcodes.LRETURN;
import static org.redkale.asm.Opcodes.PUTFIELD;
import static org.redkale.asm.Opcodes.RETURN;
import static org.redkale.asm.Opcodes.V11;
import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type;
import org.redkale.util.*;
@@ -43,19 +26,19 @@ import org.redkale.util.*;
*/
public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
public static SncpAsyncHandler createHandler(Class<? extends CompletionHandler> handlerClazz, CompletionHandler realHandler) {
public static SncpAsyncHandler createHandler(Class<? extends CompletionHandler> handlerClazz, CompletionHandler factHandler) {
Objects.requireNonNull(handlerClazz);
Objects.requireNonNull(realHandler);
Objects.requireNonNull(factHandler);
if (handlerClazz == CompletionHandler.class) {
return new SncpAsyncHandler() {
@Override
public void completed(Object result, Object attachment) {
realHandler.completed(result, attachment);
factHandler.completed(result, attachment);
}
@Override
public void failed(Throwable exc, Object attachment) {
realHandler.failed(exc, attachment);
factHandler.failed(exc, attachment);
}
};
}
@@ -84,7 +67,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, handlerInterface ? "java/lang/Object" : handlerClassName, handlerInterface && handlerClass != sncpHandlerClass ? new String[]{handlerClassName, sncpHandlerName} : new String[]{sncpHandlerName});
{ //handler 属性
fv = cw.visitField(ACC_PRIVATE, "realHandler", realHandlerDesc, null, null);
fv = cw.visitField(ACC_PRIVATE, "factHandler", realHandlerDesc, null, null);
fv.visitEnd();
}
{//构造方法
@@ -94,7 +77,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
av0 = mv.visitAnnotation(cpDesc, true);
{
AnnotationVisitor av1 = av0.visitArray("value");
av1.visit(null, "realHandler");
av1.visit(null, "factHandler");
av1.visitEnd();
}
av0.visitEnd();
@@ -103,7 +86,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
mv.visitMethodInsn(INVOKESPECIAL, handlerInterface ? "java/lang/Object" : handlerClassName, "<init>", "()V", false);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, newDynName, "realHandler", realHandlerDesc);
mv.visitFieldInsn(PUTFIELD, newDynName, "factHandler", realHandlerDesc);
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
@@ -114,7 +97,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
if (Modifier.isPublic(mod) && "completed".equals(method.getName()) && method.getParameterCount() == 2) {
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "completed", methodDesc, null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "realHandler", realHandlerDesc);
mv.visitFieldInsn(GETFIELD, newDynName, "factHandler", realHandlerDesc);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEINTERFACE, realHandlerName, "completed", "(Ljava/lang/Object;Ljava/lang/Object;)V", true);
@@ -136,7 +119,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
} else if (Modifier.isPublic(mod) && "failed".equals(method.getName()) && method.getParameterCount() == 2) {
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "failed", methodDesc, null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "realHandler", realHandlerDesc);
mv.visitFieldInsn(GETFIELD, newDynName, "factHandler", realHandlerDesc);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEINTERFACE, realHandlerName, "failed", "(Ljava/lang/Throwable;Ljava/lang/Object;)V", true);
@@ -192,7 +175,7 @@ public interface SncpAsyncHandler<V, A> extends CompletionHandler<V, A> {
}.loadClass(newDynName.replace('/', '.'), bytes);
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
return (Creator<SncpAsyncHandler>) Creator.create(newClazz);
}).create(realHandler);
}).create(factHandler);
}
static class HandlerInner {