package org.couchbase.mock.http.capi; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import org.apache.http.*; import org.apache.http.entity.ContentType; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.couchbase.mock.JsonUtils; import org.couchbase.mock.httpio.HandlerUtil; import org.couchbase.mock.views.DesignDocument; import org.couchbase.mock.views.DesignParseException; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; /** * Created by mnunberg on 12/18/14. */ class DesignHandler implements HttpRequestHandler { private final CAPIServer capiServer; public DesignHandler(CAPIServer capiServer) { this.capiServer = capiServer; } private static void setXCouchbaseMeta(HttpResponse response, DesignDocument ddoc) { // Generate the text: Map<String,Object> tmp = new HashMap<String,Object>(); // PYCBC tests for this tmp.put("id", ddoc.getId()); tmp.put("type", "json"); tmp.put("rev", -1); String s = JsonUtils.encode(tmp); response.addHeader("X-Couchbase-Meta", s); } static void setOkResponse(HttpResponse response, DesignDocument ddoc) { JsonObject obj = new JsonObject(); obj.addProperty("ok", true); obj.addProperty("id", ddoc.getId()); HandlerUtil.makeJsonResponse(response, obj.toString()); } @Override public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { if (!capiServer.verifier.verify(request, response, context)) { return; } String mName = request.getRequestLine().getMethod(); if (!CAPIServer.ALLOWED_DDOC_METHODS.contains(mName)) { response.setStatusCode(HttpStatus.SC_METHOD_NOT_ALLOWED); return; } PathInfo info = new PathInfo(request.getRequestLine().getUri()); DesignDocument ddoc = capiServer.findDesign(info); if (!info.getViewName().isEmpty()) { // If we got here, it's because the view does not exist if (ddoc == null) { CAPIServer.makeNotFoundError(response, String.format("Design document %s not found", info.getDesignId())); } else { CAPIServer.makeNotFoundError(response, String.format("View `%s` not defined in local design document `%s`", info.getViewName(), info.getDesignId())); } return; } if (!mName.equals("PUT") && ddoc == null) { CAPIServer.makeNotFoundError(response); return; } if (mName.equals("GET")) { HandlerUtil.makeJsonResponse(response, ddoc.getBody()); setXCouchbaseMeta(response, ddoc); } else if (mName.equals("HEAD")) { response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); } else if (mName.equals("DELETE")) { capiServer.removeDesign(ddoc); setOkResponse(response, ddoc); } else if (mName.equals("PUT")) { if (! (request instanceof HttpEntityEnclosingRequest)) { response.setStatusCode(HttpStatus.SC_BAD_REQUEST); HandlerUtil.makeStringResponse(response, CAPIServer.makeError("badarg")); return; } Header ctHeader = request.getLastHeader(HttpHeaders.CONTENT_TYPE); if (ctHeader == null || !ctHeader.getValue().equals(ContentType.APPLICATION_JSON.getMimeType())) { response.setStatusCode(HttpStatus.SC_BAD_REQUEST); HandlerUtil.makeStringResponse(response, CAPIServer.makeError("invalid_design_document", "Content is not json.")); return; } HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); String txt = EntityUtils.toString(entity); try { ddoc = DesignDocument.create(txt, info.getDesignName()); capiServer.addDesign(ddoc); response.setStatusCode(HttpStatus.SC_CREATED); setXCouchbaseMeta(response, ddoc); // Set the response info setOkResponse(response, ddoc); } catch (DesignParseException ex) { String msg = ex.getMessage(); if (msg == null) { msg = "Couldn't parse JSON"; } HandlerUtil.make400Response(response, CAPIServer.makeError("bad_request", msg)); } catch (Exception ex) { StringWriter sw = new StringWriter(); ex.printStackTrace(new PrintWriter(sw)); HandlerUtil.make400Response(response, sw.toString()); } } } }