private <P extends Message> void serializeObjectToServlet(P message, HttpServletResponse dest) throws IOException { if (message == null) { // Snapshot is null. It would be nice to 404 here, but we can't let // clients guess valid wavelet ids that they're not authorized to access. dest.sendError(HttpServletResponse.SC_FORBIDDEN); } else { dest.setStatus(HttpServletResponse.SC_OK); dest.setContentType("application/json"); // This is a hack to make sure the fetched data is fresh. // TODO(josephg): Change this so that browsers can cache wave snapshots. Probably need: // 'Cache-Control: must-revalidate, private' and an ETag with the wave[let]'s version. dest.setHeader("Cache-Control", "no-store"); try { dest.getWriter().append(serializer.toJson(message).toString()); } catch (SerializationException e) { throw new IOException(e); } } }
/** Adds the known proto types. */ private void init() { // Note: this list is too inclusive, but has historically always been so. // The real list only needs about 5 protos, since only top-level rpc types // need to be here, not every single recursively reachable proto. add(ProtocolAuthenticate.class, ProtocolAuthenticateProtoImpl.class); add(ProtocolAuthenticationResult.class, ProtocolAuthenticationResultProtoImpl.class); add(ProtocolOpenRequest.class, ProtocolOpenRequestProtoImpl.class); add(ProtocolSubmitRequest.class, ProtocolSubmitRequestProtoImpl.class); add(ProtocolSubmitResponse.class, ProtocolSubmitResponseProtoImpl.class); add(ProtocolWaveletUpdate.class, ProtocolWaveletUpdateProtoImpl.class); add(WaveletSnapshot.class, WaveletSnapshotProtoImpl.class); add(DocumentSnapshot.class, DocumentSnapshotProtoImpl.class); add(WaveViewSnapshot.class, WaveViewSnapshotProtoImpl.class); add(CancelRpc.class, CancelRpcProtoImpl.class); add(RpcFinished.class, RpcFinishedProtoImpl.class); add(SearchResponse.class, SearchResponseProtoImpl.class); add(ProfileResponse.class, ProfileResponseProtoImpl.class); add(AttachmentsResponse.class, AttachmentsResponseProtoImpl.class); }
@VisibleForTesting public <P extends Message> P fromJson(JsonElement json, Class<P> clazz) throws SerializationException { return getSerializer(clazz).fromJson(json, null, gson); } }
private <T extends Message> T fetchWaverRefAndParse(WaveRef waveref, Class<T> klass) throws Exception { String message = fetchWaveRef(waveref); JsonElement json = new JsonParser().parse(message); return protoSerializer.fromJson(json, klass); } }
public ProtoSerializer() { init(); }
/** * Constructs a new WebSocketChannel, using the callback to handle any * incoming messages. * * @param callback a protocallback to be called when data arrives on this * channel */ public WebSocketChannel(ProtoCallback callback) { this.callback = callback; this.sessionContext = Timing.isEnabled() ? Timing.getScopeValue(SessionContext.class) : null; // The ProtoSerializer could really be singleton. // TODO: Figure out a way to inject a singleton instance using Guice this.serializer = new ProtoSerializer(); }
private <T extends Message> T fetchWaverRefAndParse(WaveRef waveref, Class<T> klass) throws Exception { String message = fetchWaveRef(waveref); JsonElement json = new JsonParser().parse(message); return protoSerializer.fromJson(json, klass); } }
/** * Writes the json with profile results to Response. */ private <P extends Message> void printJson(P message, HttpServletResponse resp) throws IOException { if (message == null) { resp.setStatus(HttpServletResponse.SC_FORBIDDEN); } else { resp.setStatus(HttpServletResponse.SC_OK); resp.setContentType("application/json"); // This is to make sure the fetched data is fresh - since the w3c spec // is rarely respected. resp.setHeader("Cache-Control", "no-store"); try { // FIXME (user) Returning JSON directly from an HTTP GET is vulnerable // to XSSI attacks. Issue https://issues.apache.org/jira/browse/WAVE-135 resp.getWriter().append(serializer.toJson(message).toString()); } catch (SerializationException e) { throw new IOException(e); } } } }
public void handleMessageString(String data) { LOG.fine("received JSON message " + data); if (Timing.isEnabled()) { Timing.enterScope(); Timing.setScopeValue(SessionContext.class, sessionContext); } try { Message message; MessageWrapper wrapper = MessageWrapper.deserialize(gson, data); try { message = serializer.fromJson(wrapper.message, wrapper.messageType); } catch (SerializationException e) { LOG.warning("message handling error", e); e.printStackTrace(); return; } callback.message(wrapper.sequenceNumber, message); } finally { Timing.exitScope(); } }
/** * Serializes a proto to JSON. Only protos whose classes have been registered * will be serialized. * * @throws SerializationException if the class of {@code message} has not been * registered. */ public <P extends Message>JsonElement toJson(P message) throws SerializationException { return getSerializer(message.getClass()).toGson(message, null, gson); }
/** * Writes the json with search results to Response. */ private <P extends Message> void serializeObjectToServlet(P message, HttpServletResponse resp) throws IOException { if (message == null) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); } else { resp.setStatus(HttpServletResponse.SC_OK); resp.setContentType("application/json; charset=utf8"); // This is to make sure the fetched data is fresh - since the w3c spec // is rarely respected. resp.setHeader("Cache-Control", "no-store"); try { resp.getWriter().append(serializer.toJson(message).toString()); } catch (SerializationException e) { throw new IOException(e); } } } }
/** * Deserializes a proto from JSON. Only protos whose classes have been * registered can be deserialized. * * @throws SerializationException if no class called {@code type} has been * registered. */ public Message fromJson(JsonElement json, String type) throws SerializationException { return getSerializer(type).fromJson(json, null, gson); }
info = serializer.toJson(attachmentsResponse.build()).toString(); } catch (SerializationException ex) { LOG.log(Level.SEVERE, "Attachments info serialize", ex);
/** * The fetch servlet also exposes document snapshots through a longer url * (/fetch/domain/waveid/domain/waveletid/docid). * * @throws Exception */ public void testGetDocument() throws Exception { WaveletData wavelet = waveletProvider.getHostedWavelet(); for (String docId : wavelet.getDocumentIds()) { // We currently have no way to deserialize a document. Instead, we'll // serialize the expected document and compare with what we get from the // fetch servlet. StringWriter writer = new StringWriter(); BlipData expectedDoc = wavelet.getDocument(docId); writer.append("" + protoSerializer.toJson(SnapshotSerializer.serializeDocument(expectedDoc))); String expectedResult = writer.toString(); WaveRef waveref = WaveRef.of(wavelet.getWaveId(), wavelet.getWaveletId(), docId); String actualResult = fetchWaveRef(waveref); assertEquals(expectedResult, actualResult); } }
/** * The fetch servlet also exposes document snapshots through a longer url * (/fetch/domain/waveid/domain/waveletid/docid). * * @throws Exception */ public void testGetDocument() throws Exception { WaveletData wavelet = waveletProvider.getHostedWavelet(); for (String docId : wavelet.getDocumentIds()) { // We currently have no way to deserialize a document. Instead, we'll // serialize the expected document and compare with what we get from the // fetch servlet. StringWriter writer = new StringWriter(); BlipData expectedDoc = wavelet.getDocument(docId); writer.append("" + protoSerializer.toJson(SnapshotSerializer.serializeDocument(expectedDoc))); String expectedResult = writer.toString(); WaveRef waveref = WaveRef.of(wavelet.getWaveId(), wavelet.getWaveletId(), docId); String actualResult = fetchWaveRef(waveref); assertEquals(expectedResult, actualResult); } }
@Override public void sendMessage(int sequenceNo, Message message) { JsonElement json; String str; Timer timer = Timing.start("serializeMessage"); try { json = serializer.toJson(message); String type = message.getDescriptorForType().getName(); str = MessageWrapper.serialize(type, sequenceNo, json); } catch (SerializationException e) { LOG.warning("Failed to JSONify proto message", e); return; } finally { Timing.stop(timer); } try { sendMessageString(str); LOG.fine("sent JSON message over websocket, sequence number " + sequenceNo + ", message " + message); } catch (IOException e) { // TODO(anorth): This failure should be communicated to the caller // so it can attempt retransmission. LOG.warning("Failed to transmit message on socket, sequence number " + sequenceNo + ", message " + message, e); return; } } }