2626
2727package com .yeetor .server ;
2828
29- import com .yeetor .adb .AdbServer ;
3029import com .yeetor .adb .AdbUtils ;
3130import com .yeetor .minicap .Minicap ;
32- import io . netty . buffer . Unpooled ;
33- import io . netty . channel . ChannelDuplexHandler ;
31+ import com . yeetor . util . Constant ;
32+ import eu . medsea . mimeutil . MimeUtil ;
3433import io .netty .channel .ChannelFutureListener ;
3534import io .netty .channel .ChannelHandlerContext ;
3635import io .netty .handler .codec .http .*;
36+ import io .netty .handler .stream .ChunkedFile ;
3737import org .apache .log4j .Logger ;
3838
39- import java .util .regex .Pattern ;
39+ import javax .activation .MimetypesFileTypeMap ;
40+ import java .io .*;
4041
4142import static io .netty .handler .codec .http .HttpHeaderValues .KEEP_ALIVE ;
4243import static io .netty .handler .codec .http .HttpHeaders .Names .CONNECTION ;
44+ import static io .netty .handler .codec .http .HttpHeaders .Names .CONTENT_LENGTH ;
45+ import static io .netty .handler .codec .http .HttpHeaders .Names .CONTENT_TYPE ;
4346
4447public class HttpServer {
4548 private static Logger logger = Logger .getLogger (HttpServer .class );
46- public void onRequest (ChannelHandlerContext ctx , HttpRequest request ) {
49+ public HttpResponse onRequest (ChannelHandlerContext ctx , HttpRequest request ) {
4750 String uri = request .uri ();
51+ logger .info ("http:" + uri );
4852
4953 if (uri .startsWith ("/devices" )) {
50- devices (ctx , request );
54+ return devices (ctx , request );
5155 } else if (uri .startsWith ("/shot" )) {
52- shot (ctx , request );
56+ return shot (ctx , request );
5357 } else {
54- doCommonResponse (ctx , request , HttpResponseStatus . NOT_FOUND );
58+ return files (ctx , request );
5559 }
5660 }
5761
58- public void shot (ChannelHandlerContext ctx , HttpRequest request ) {
62+ public HttpResponse shot (ChannelHandlerContext ctx , HttpRequest request ) {
5963
6064 String uri = request .uri ();
6165 String [] args = uri .split ("/" );
6266
6367 if (args .length < 1 || args [1 ].length () == 0 ) {
64- doCommonResponse (ctx , request , HttpResponseStatus .INTERNAL_SERVER_ERROR );
65- return ;
68+ return new DefaultFullHttpResponse (HttpVersion .HTTP_1_0 , HttpResponseStatus .INTERNAL_SERVER_ERROR );
6669 }
6770
6871 String serialNumber = args [2 ];
6972
7073 long startTime =System .currentTimeMillis ();
7174 Minicap cap = new Minicap (serialNumber );
72- byte [] data = cap .takeScreenShot (); // TODO 性能优化,现在速度慢
75+ byte [] data = cap .takeScreenShot ();
7376 long endTime =System .currentTimeMillis ();
7477 logger .info ("ScreenShot used:" + (endTime - startTime ) + "ms" );
7578
7679
77- doDefaultResponse (ctx , request , data , "image/jpeg" );
80+ return doDefaultResponse (ctx , request , data , "image/jpeg" );
7881 }
7982
80- public void devices (ChannelHandlerContext ctx , HttpRequest request ) {
81-
82- String uri = request .uri ();
83-
83+ public HttpResponse devices (ChannelHandlerContext ctx , HttpRequest request ) {
8484 String json = AdbUtils .devices2JSON ();
8585 byte [] data = json .getBytes ();
86-
87- doDefaultResponse (ctx , request , data , "text/json" );
86+ return doDefaultResponse (ctx , request , data , "text/json" );
87+ }
88+
89+ public HttpResponse files (ChannelHandlerContext ctx , HttpRequest request ){
90+ String location = request .uri ().substring (1 );
91+ if (location .equals ("" )) {
92+ location = "index.html" ;
93+ }
94+
95+ File localFile = new File (Constant .getResourceDir (), "web" + File .separator + location );
96+
97+ if (!localFile .exists () || localFile .isHidden ()) {
98+ return doDefaultResponse (ctx , request , "404" .getBytes (), "text/plain" );
99+ }
100+
101+ ChunkedFile chunkedFile = null ;
102+ try {
103+ RandomAccessFile raf = new RandomAccessFile (localFile , "r" );
104+ chunkedFile = new ChunkedFile (raf , 0 , localFile .length (), 8192 );
105+ }catch (IOException e ) {
106+ e .printStackTrace ();
107+ }
108+
109+
110+ long l = chunkedFile .length ();
111+ HttpResponse response = new DefaultHttpResponse (HttpVersion .HTTP_1_1 , HttpResponseStatus .OK );
112+ response .headers ().add ("Access-Control-Allow-Origin" , "*" );
113+ response .headers ().add ("Server" , "Yeetor" );
114+
115+ response .headers ().add (CONTENT_LENGTH , localFile .length ());
116+
117+
118+ MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap ();
119+ response .headers ().add (CONTENT_TYPE , mimetypesFileTypeMap .getContentType (localFile .getPath ()));
120+
121+ ctx .write (response );
122+ ctx .write (chunkedFile );
123+ ctx .writeAndFlush (LastHttpContent .EMPTY_LAST_CONTENT ); // need?
124+
125+ return response ;
88126 }
89127
90128 public void doCommonResponse (ChannelHandlerContext ctx , HttpRequest request , HttpResponseStatus status ) {
@@ -107,22 +145,11 @@ public void doCommonResponse(ChannelHandlerContext ctx, HttpRequest request, Htt
107145 }
108146 }
109147
110- public void doDefaultResponse (ChannelHandlerContext ctx , HttpRequest request , byte [] data , String contentType ) {
148+ public HttpResponse doDefaultResponse (ChannelHandlerContext ctx , HttpRequest request , byte [] data , String contentType ) {
111149 DefaultFullHttpResponse response = new DefaultFullHttpResponse (HttpVersion .HTTP_1_1 , HttpResponseStatus .OK );
112- response .headers ().add ("Access-Control-Allow-Origin" , "*" );
113150 response .headers ().add ("Content-Type" , contentType );
114- response .headers ().add ("Server" , "Yeetor" );
115-
116151 response .content ().writeBytes (data );
117152 response .headers ().add ("Content-Length" , data .length );
118- boolean isKeepAlive = HttpUtil .isKeepAlive (request );
119-
120- if (!isKeepAlive || response .status () != HttpResponseStatus .OK ) {
121- ctx .writeAndFlush (response ).addListener (ChannelFutureListener .CLOSE );
122- } else {
123- response .headers ().set (CONNECTION , KEEP_ALIVE );
124- ctx .writeAndFlush (response );
125- }
153+ return response ;
126154 }
127-
128155}
0 commit comments