123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package hello;
- /*
- * #%L
- * rapidoid-demo
- * %%
- * Copyright (C) 2014 - 2015 Nikolche Mihajlovski
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
- import org.rapidoid.buffer.Buf;
- import org.rapidoid.bytes.BytesUtil;
- import org.rapidoid.data.Range;
- import org.rapidoid.data.Ranges;
- import org.rapidoid.http.HttpParser;
- import org.rapidoid.net.Protocol;
- import org.rapidoid.net.abstracts.Channel;
- import org.rapidoid.net.impl.RapidoidHelper;
- import org.rapidoid.util.Dates;
- import org.rapidoid.wrap.BoolWrap;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
- public class SimpleHttpProtocol implements Protocol {
- private static final byte[] HTTP_200_OK = "HTTP/1.1 200 OK\r\n".getBytes();
- private static final byte[] HTTP_404_NOT_FOUND = "HTTP/1.1 404 Not Found\r\nContent-Length: 10\r\n\r\nNot found!"
- .getBytes();
- private static final byte[] CONN_KEEP_ALIVE = "Connection: keep-alive\r\n"
- .getBytes();
- private static final byte[] CONN_CLOSE = "Connection: close\r\n".getBytes();
- private static final byte[] SERVER_X = "Server: X\r\n".getBytes();
- private static final byte[] CONTENT_LENGTH_HDR = "Content-Length: "
- .getBytes();
- private static final byte[] CONTENT_TYPE_PLAIN = "Content-Type: text/plain; charset=UTF-8\r\n"
- .getBytes();
- private static final byte[] CONTENT_TYPE_JSON = "Content-Type: application/json; charset=UTF-8\r\n"
- .getBytes();
- private static final byte[] CONTENT_LENGTH = "Content-Length: "
- .getBytes();
- private static final byte[] RESPONSE = "Hello, World!".getBytes();
- private static final byte[] DATE_HDR = "Date: ".getBytes();
- private static final byte[] RESPONSE_LENGTH = String.valueOf(
- RESPONSE.length).getBytes();
- private static final byte[] URI_PLAIN = "/plaintext".getBytes();
- private static final byte[] URI_JSON = "/json".getBytes();
- private static final HttpParser HTTP_PARSER = new HttpParser();
- public static final ObjectMapper MAPPER = mapper();
- private static ObjectMapper mapper() {
- ObjectMapper mapper = new ObjectMapper();
- mapper.registerModule(new AfterburnerModule());
- return mapper;
- }
- public void process(Channel ctx) {
- if (ctx.isInitial()) {
- return;
- }
- Buf buf = ctx.input();
- RapidoidHelper helper = ctx.helper();
- Range[] ranges = helper.ranges1.ranges;
- Ranges headers = helper.ranges2;
- BoolWrap isGet = helper.booleans[0];
- BoolWrap isKeepAlive = helper.booleans[1];
- Range verb = ranges[ranges.length - 1];
- Range uri = ranges[ranges.length - 2];
- Range path = ranges[ranges.length - 3];
- Range query = ranges[ranges.length - 4];
- Range protocol = ranges[ranges.length - 5];
- Range body = ranges[ranges.length - 6];
- HTTP_PARSER.parse(buf, isGet, isKeepAlive, body, verb, uri, path,
- query, protocol, headers, helper);
- response(ctx, buf, path, isGet.value, isKeepAlive.value);
- }
- private void response(Channel ctx, Buf buf, Range path, boolean isGet,
- boolean isKeepAlive) {
- boolean processed = false;
- if (isGet) {
- ctx.write(HTTP_200_OK);
- ctx.write(isKeepAlive ? CONN_KEEP_ALIVE : CONN_CLOSE);
- ctx.write(SERVER_X);
- ctx.write(DATE_HDR);
- ctx.write(Dates.getDateTimeBytes());
- ctx.write(CR_LF);
- if (BytesUtil.matches(buf.bytes(), path, URI_PLAIN, true)
- || path.length == 1) {
- handlePlaintext(ctx);
- processed = true;
- } else if (BytesUtil.matches(buf.bytes(), path, URI_JSON, true)) {
- handleJson(ctx);
- processed = true;
- }
- ctx.closeIf(!isKeepAlive);
- }
- if (!processed) {
- ctx.write(HTTP_404_NOT_FOUND);
- ctx.close();
- }
- }
- private void handlePlaintext(Channel ctx) {
- ctx.write(CONTENT_LENGTH_HDR);
- ctx.write(RESPONSE_LENGTH);
- ctx.write(CR_LF);
- ctx.write(CONTENT_TYPE_PLAIN);
- ctx.write(CR_LF);
- ctx.write(RESPONSE);
- }
- private void handleJson(Channel ctx) {
- Buf output = ctx.output();
- ctx.write(CONTENT_TYPE_JSON);
- ctx.write(CONTENT_LENGTH);
- int posConLen = output.size() - 10;
- ctx.write(CR_LF);
- ctx.write(CR_LF);
- int posBefore = output.size();
- Message msg = new Message("Hello, World!");
- try {
- MAPPER.writeValue(output.asOutputStream(), msg);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- int posAfter = output.size();
- output.putNumAsText(posConLen, posAfter - posBefore, false);
- }
- }
|