diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/LotroHttpRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/LotroHttpRequestHandler.java index edd3dad90..a50600e08 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/LotroHttpRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/LotroHttpRequestHandler.java @@ -78,6 +78,11 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler { writeHttpHtmlResponse(request, html, e); } + @Override + public void writeByteResponse(String contentType, byte[] bytes) { + writeHttpByteResponse(request, contentType, bytes, e); + } + @Override public void writeFile(File file) { writeFileResponse(request, file, e); @@ -181,6 +186,46 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler { } } + private void writeHttpByteResponse(HttpRequest request, String contentType, byte[] bytes, MessageEvent e) { + // Decide whether to close the connection or not. + boolean keepAlive = isKeepAlive(request); + + try { + // Build the response object. + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); + + int length = 0; + response.setContent(ChannelBuffers.copiedBuffer(bytes)); + response.setHeader(CONTENT_TYPE, contentType); + + length = bytes.length; + + if (keepAlive) { + // Add 'Content-Length' header only for a keep-alive connection. + response.setHeader(CONTENT_LENGTH, length); + } + + // Write the response. + ChannelFuture future = e.getChannel().write(response); + if (!keepAlive) { + future.addListener(ChannelFutureListener.CLOSE); + } + } catch (Exception exp) { + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(500)); + + if (keepAlive) { + // Add 'Content-Length' header only for a keep-alive connection. + response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); + } + + // Write the response. + ChannelFuture future = e.getChannel().write(response); + if (!keepAlive) { + future.addListener(ChannelFutureListener.CLOSE); + } + } + } + private void writeHttpResponse(HttpRequest request, Document document, Map headers, MessageEvent e) { // Decide whether to close the connection or not. boolean keepAlive = isKeepAlive(request); diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/ResponseWriter.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/ResponseWriter.java index 4285bd7ca..aeb5d9878 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/ResponseWriter.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/ResponseWriter.java @@ -13,6 +13,8 @@ public interface ResponseWriter { public void writeHtmlResponse(String html); + public void writeByteResponse(String contentType, byte[] bytes); + public void writeResponse(Document document); public void writeResponse(Document document, Map addCookies); diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LoginRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LoginRequestHandler.java index ef873e929..bb8905b54 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LoginRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LoginRequestHandler.java @@ -3,18 +3,13 @@ package com.gempukku.lotro.async.handler; import com.gempukku.lotro.async.ResponseWriter; import com.gempukku.lotro.game.Player; import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.handler.codec.http.CookieEncoder; import org.jboss.netty.handler.codec.http.HttpMethod; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import java.lang.reflect.Type; -import java.sql.SQLException; -import java.util.Collections; import java.util.Map; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE; - public class LoginRequestHandler extends LotroServerRequestHandler implements UriRequestHandler { public LoginRequestHandler(Map context) { super(context); @@ -43,13 +38,4 @@ public class LoginRequestHandler extends LotroServerRequestHandler implements Ur } } - private Map logUserReturningHeaders(MessageEvent e, String login) throws SQLException { - _playerDao.updateLastLoginIp(login, e.getChannel().getRemoteAddress().toString()); - - CookieEncoder cookieEncoder = new CookieEncoder(true); - for (Map.Entry cookie : _loggedUserHolder.logUser(login).entrySet()) - cookieEncoder.addCookie(cookie.getKey(), cookie.getValue()); - - return Collections.singletonMap(SET_COOKIE, cookieEncoder.encode()); - } } diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LotroServerRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LotroServerRequestHandler.java index bc91d01e7..2f99ad828 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LotroServerRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LotroServerRequestHandler.java @@ -4,6 +4,8 @@ import com.gempukku.lotro.async.HttpProcessingException; import com.gempukku.lotro.async.LoggedUserHolder; import com.gempukku.lotro.db.PlayerDAO; import com.gempukku.lotro.game.Player; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.http.CookieEncoder; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.QueryStringDecoder; import org.jboss.netty.handler.codec.http.multipart.Attribute; @@ -12,11 +14,14 @@ import org.jboss.netty.handler.codec.http.multipart.InterfaceHttpData; import java.io.IOException; import java.lang.reflect.Type; +import java.sql.SQLException; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE; + public class LotroServerRequestHandler { protected PlayerDAO _playerDao; protected LoggedUserHolder _loggedUserHolder; @@ -90,4 +95,14 @@ public class LotroServerRequestHandler { Object value = context.get(clazz); return (T) value; } + + protected Map logUserReturningHeaders(MessageEvent e, String login) throws SQLException { + _playerDao.updateLastLoginIp(login, e.getChannel().getRemoteAddress().toString()); + + CookieEncoder cookieEncoder = new CookieEncoder(true); + for (Map.Entry cookie : _loggedUserHolder.logUser(login).entrySet()) + cookieEncoder.addCookie(cookie.getKey(), cookie.getValue()); + + return Collections.singletonMap(SET_COOKIE, cookieEncoder.encode()); + } } diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RegisterRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RegisterRequestHandler.java new file mode 100644 index 000000000..86c341d56 --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RegisterRequestHandler.java @@ -0,0 +1,39 @@ +package com.gempukku.lotro.async.handler; + +import com.gempukku.lotro.async.HttpProcessingException; +import com.gempukku.lotro.async.ResponseWriter; +import com.gempukku.lotro.db.LoginInvalidException; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.http.HttpMethod; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.multipart.HttpPostRequestDecoder; + +import java.lang.reflect.Type; +import java.util.Map; + +public class RegisterRequestHandler extends LotroServerRequestHandler implements UriRequestHandler { + public RegisterRequestHandler(Map context) { + super(context); + } + + @Override + public void handleRequest(String uri, HttpRequest request, Map context, ResponseWriter responseWriter, MessageEvent e) throws Exception { + if (uri.equals("") && request.getMethod() == HttpMethod.POST) { + HttpPostRequestDecoder postDecoder = new HttpPostRequestDecoder(request); + String login = getFormParameterSafely(postDecoder, "login"); + String password = getFormParameterSafely(postDecoder, "password"); + try { + if (_playerDao.registerUser(login, password, e.getRemoteAddress().toString())) { + responseWriter.writeResponse(null, logUserReturningHeaders(e, login)); + } else { + throw new HttpProcessingException(409); + } + } catch (LoginInvalidException exp) { + throw new HttpProcessingException(400); + } + + } else { + responseWriter.writeError(404); + } + } +} diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/ReplayRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/ReplayRequestHandler.java new file mode 100644 index 000000000..8b3a2d4a2 --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/ReplayRequestHandler.java @@ -0,0 +1,57 @@ +package com.gempukku.lotro.async.handler; + +import com.gempukku.lotro.async.HttpProcessingException; +import com.gempukku.lotro.async.ResponseWriter; +import com.gempukku.lotro.game.GameRecorder; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.http.HttpMethod; +import org.jboss.netty.handler.codec.http.HttpRequest; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.Map; + +public class ReplayRequestHandler extends LotroServerRequestHandler implements UriRequestHandler { + private GameRecorder _gameRecorder; + + public ReplayRequestHandler(Map context) { + super(context); + + _gameRecorder = extractObject(context, GameRecorder.class); + } + + @Override + public void handleRequest(String uri, HttpRequest request, Map context, ResponseWriter responseWriter, MessageEvent e) throws Exception { + if (uri.startsWith("/") && request.getMethod() == HttpMethod.GET) { + String replayId = uri.substring(1); + + if (!replayId.contains("$")) + throw new HttpProcessingException(404); + if (replayId.contains(".")) + throw new HttpProcessingException(404); + + final String[] split = replayId.split("\\$"); + if (split.length != 2) + throw new HttpProcessingException(404); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final InputStream recordedGame = _gameRecorder.getRecordedGame(split[0], split[1]); + if (recordedGame == null) + throw new HttpProcessingException(404); + try { + byte[] bytes = new byte[1024]; + int count; + while ((count = recordedGame.read(bytes)) != -1) + baos.write(bytes, 0, count); + } finally { + recordedGame.close(); + } + + responseWriter.writeByteResponse("application/html; charset=UTF-8", baos.toByteArray()); + } else { + responseWriter.writeError(404); + } + } +} diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RootUriRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RootUriRequestHandler.java index a7e722361..d445c6046 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RootUriRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/RootUriRequestHandler.java @@ -23,6 +23,8 @@ public class RootUriRequestHandler implements UriRequestHandler { private GameRequestHandler _gameRequestHandler; private LeagueRequestHandler _leagueRequestHandler; private MerchantRequestHandler _merchantRequestHandler; + private RegisterRequestHandler _registerRequestHandler; + private ReplayRequestHandler _replayRequestHandler; public RootUriRequestHandler(Map context) { _hallRequestHandler = new HallRequestHandler(context); @@ -36,6 +38,8 @@ public class RootUriRequestHandler implements UriRequestHandler { _gameRequestHandler = new GameRequestHandler(context); _leagueRequestHandler = new LeagueRequestHandler(context); _merchantRequestHandler = new MerchantRequestHandler(context); + _registerRequestHandler = new RegisterRequestHandler(context); + _replayRequestHandler = new ReplayRequestHandler(context); } @Override @@ -50,6 +54,10 @@ public class RootUriRequestHandler implements UriRequestHandler { _deckRequestHandler.handleRequest(uri.substring(_serverContextPath.length()+4), request, context, responseWriter, e); } else if (uri.startsWith(_serverContextPath+"login")) { _loginRequestHandler.handleRequest(uri.substring(_serverContextPath.length()+5), request, context, responseWriter, e); + } else if (uri.startsWith(_serverContextPath+"register")) { + _registerRequestHandler.handleRequest(uri.substring(_serverContextPath.length()+8), request, context, responseWriter, e); + } else if (uri.startsWith(_serverContextPath+"replay")) { + _replayRequestHandler.handleRequest(uri.substring(_serverContextPath.length()+6), request, context, responseWriter, e); } else if (uri.startsWith(_serverContextPath+"admin")) { _adminRequestHandler.handleRequest(uri.substring(_serverContextPath.length()+5), request, context, responseWriter, e); } else if (uri.startsWith(_serverContextPath + "chat")) {