getCookies() {
36 | if (cookies == null) {
37 | String cookieHeaderPrefix = "set-cookie: ";
38 | cookies = Cookie.parseResponseCookies(responseInfo.getHeaders().stream().filter(s -> s.toLowerCase().startsWith(cookieHeaderPrefix)).map(s -> s.substring(cookieHeaderPrefix.length() - 1)).collect(Collectors.toList()));
39 | }
40 | return cookies;
41 | }
42 |
43 | @Override
44 | public String getStatedMimeType() {
45 | return responseInfo.getStatedMimeType();
46 | }
47 |
48 | @Override
49 | public String getInferredMimeType() {
50 | return responseInfo.getInferredMimeType();
51 | }
52 |
53 | @Override
54 | public String getBody() {
55 | if (responseBody == null) {
56 | byte[] response = httpRequestResponse.getResponse();
57 | int bodyOffset = this.getBodyOffset();
58 | responseBody = new String(Arrays.copyOfRange(response, bodyOffset, response.length));
59 | }
60 | return responseBody;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/burp-send-to-extension/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.gson.typeadapters;
18 |
19 | import com.google.gson.*;
20 | import com.google.gson.internal.Streams;
21 | import com.google.gson.reflect.TypeToken;
22 | import com.google.gson.stream.JsonReader;
23 | import com.google.gson.stream.JsonWriter;
24 |
25 | import java.io.IOException;
26 | import java.util.LinkedHashMap;
27 | import java.util.Map;
28 |
29 | /**
30 | * Adapts values whose runtime type may differ from their declaration type. This
31 | * is necessary when a field's type is not the same type that GSON should create
32 | * when deserializing that field. For example, consider these types:
33 | * {@code
34 | * abstract class Shape {
35 | * int x;
36 | * int y;
37 | * }
38 | * class Circle extends Shape {
39 | * int radius;
40 | * }
41 | * class Rectangle extends Shape {
42 | * int width;
43 | * int height;
44 | * }
45 | * class Diamond extends Shape {
46 | * int width;
47 | * int height;
48 | * }
49 | * class Drawing {
50 | * Shape bottomShape;
51 | * Shape topShape;
52 | * }
53 | * }
54 | * Without additional type information, the serialized JSON is ambiguous. Is
55 | * the bottom shape in this drawing a rectangle or a diamond?
{@code
56 | * {
57 | * "bottomShape": {
58 | * "width": 10,
59 | * "height": 5,
60 | * "x": 0,
61 | * "y": 0
62 | * },
63 | * "topShape": {
64 | * "radius": 2,
65 | * "x": 4,
66 | * "y": 1
67 | * }
68 | * }}
69 | * This class addresses this problem by adding type information to the
70 | * serialized JSON and honoring that type information when the JSON is
71 | * deserialized: {@code
72 | * {
73 | * "bottomShape": {
74 | * "type": "Diamond",
75 | * "width": 10,
76 | * "height": 5,
77 | * "x": 0,
78 | * "y": 0
79 | * },
80 | * "topShape": {
81 | * "type": "Circle",
82 | * "radius": 2,
83 | * "x": 4,
84 | * "y": 1
85 | * }
86 | * }}
87 | * Both the type field name ({@code "type"}) and the type labels ({@code
88 | * "Rectangle"}) are configurable.
89 | *
90 | * Registering Types
91 | * Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
92 | * name to the {@link #of} factory method. If you don't supply an explicit type
93 | * field name, {@code "type"} will be used. {@code
94 | * RuntimeTypeAdapterFactory shapeAdapterFactory
95 | * = RuntimeTypeAdapterFactory.of(Shape.class, "type");
96 | * }
97 | * Next register all of your subtypes. Every subtype must be explicitly
98 | * registered. This protects your application from injection attacks. If you
99 | * don't supply an explicit type label, the type's simple name will be used.
100 | * {@code
101 | * shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
102 | * shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
103 | * shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
104 | * }
105 | * Finally, register the type adapter factory in your application's GSON builder:
106 | * {@code
107 | * Gson gson = new GsonBuilder()
108 | * .registerTypeAdapterFactory(shapeAdapterFactory)
109 | * .create();
110 | * }
111 | * Like {@code GsonBuilder}, this API supports chaining: {@code
112 | * RuntimeTypeAdapterFactory shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
113 | * .registerSubtype(Rectangle.class)
114 | * .registerSubtype(Circle.class)
115 | * .registerSubtype(Diamond.class);
116 | * }
117 | *
118 | * Serialization and deserialization
119 | * In order to serialize and deserialize a polymorphic object,
120 | * you must specify the base type explicitly.
121 | * {@code
122 | * Diamond diamond = new Diamond();
123 | * String json = gson.toJson(diamond, Shape.class);
124 | * }
125 | * And then:
126 | * {@code
127 | * Shape shape = gson.fromJson(json, Shape.class);
128 | * }
129 | */
130 | public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory {
131 | private final Class> baseType;
132 | private final String typeFieldName;
133 | private final Map> labelToSubtype = new LinkedHashMap>();
134 | private final Map, String> subtypeToLabel = new LinkedHashMap, String>();
135 | private final boolean maintainType;
136 |
137 | private RuntimeTypeAdapterFactory(Class> baseType, String typeFieldName, boolean maintainType) {
138 | if (typeFieldName == null || baseType == null) {
139 | throw new NullPointerException();
140 | }
141 | this.baseType = baseType;
142 | this.typeFieldName = typeFieldName;
143 | this.maintainType = maintainType;
144 | }
145 |
146 | /**
147 | * Creates a new runtime type adapter using for {@code baseType} using {@code
148 | * typeFieldName} as the type field name. Type field names are case sensitive.
149 | * {@code maintainType} flag decide if the type will be stored in pojo or not.
150 | */
151 | public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName, boolean maintainType) {
152 | return new RuntimeTypeAdapterFactory(baseType, typeFieldName, maintainType);
153 | }
154 |
155 | /**
156 | * Creates a new runtime type adapter using for {@code baseType} using {@code
157 | * typeFieldName} as the type field name. Type field names are case sensitive.
158 | */
159 | public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName) {
160 | return new RuntimeTypeAdapterFactory(baseType, typeFieldName, false);
161 | }
162 |
163 | /**
164 | * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
165 | * the type field name.
166 | */
167 | public static RuntimeTypeAdapterFactory of(Class baseType) {
168 | return new RuntimeTypeAdapterFactory(baseType, "type", false);
169 | }
170 |
171 | /**
172 | * Registers {@code type} identified by {@code label}. Labels are case
173 | * sensitive.
174 | *
175 | * @throws IllegalArgumentException if either {@code type} or {@code label}
176 | * have already been registered on this type adapter.
177 | */
178 | public RuntimeTypeAdapterFactory registerSubtype(Class extends T> type, String label) {
179 | if (type == null || label == null) {
180 | throw new NullPointerException();
181 | }
182 | if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
183 | throw new IllegalArgumentException("types and labels must be unique");
184 | }
185 | labelToSubtype.put(label, type);
186 | subtypeToLabel.put(type, label);
187 | return this;
188 | }
189 |
190 | /**
191 | * Registers {@code type} identified by its {@link Class#getSimpleName simple
192 | * name}. Labels are case sensitive.
193 | *
194 | * @throws IllegalArgumentException if either {@code type} or its simple name
195 | * have already been registered on this type adapter.
196 | */
197 | public RuntimeTypeAdapterFactory registerSubtype(Class extends T> type) {
198 | return registerSubtype(type, type.getSimpleName());
199 | }
200 |
201 | public TypeAdapter create(Gson gson, TypeToken type) {
202 | if (type.getRawType() != baseType) {
203 | return null;
204 | }
205 |
206 | final Map> labelToDelegate
207 | = new LinkedHashMap>();
208 | final Map, TypeAdapter>> subtypeToDelegate
209 | = new LinkedHashMap, TypeAdapter>>();
210 | for (Map.Entry> entry : labelToSubtype.entrySet()) {
211 | TypeAdapter> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
212 | labelToDelegate.put(entry.getKey(), delegate);
213 | subtypeToDelegate.put(entry.getValue(), delegate);
214 | }
215 |
216 | return new TypeAdapter() {
217 | @Override public R read(JsonReader in) throws IOException {
218 | JsonElement jsonElement = Streams.parse(in);
219 | JsonElement labelJsonElement;
220 | if (maintainType) {
221 | labelJsonElement = jsonElement.getAsJsonObject().get(typeFieldName);
222 | } else {
223 | labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
224 | }
225 |
226 | if (labelJsonElement == null) {
227 | throw new JsonParseException("cannot deserialize " + baseType
228 | + " because it does not define a field named " + typeFieldName);
229 | }
230 | String label = labelJsonElement.getAsString();
231 | @SuppressWarnings("unchecked") // registration requires that subtype extends T
232 | TypeAdapter delegate = (TypeAdapter) labelToDelegate.get(label);
233 | if (delegate == null) {
234 | throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
235 | + label + "; did you forget to register a subtype?");
236 | }
237 | return delegate.fromJsonTree(jsonElement);
238 | }
239 |
240 | @Override public void write(JsonWriter out, R value) throws IOException {
241 | Class> srcType = value.getClass();
242 | String label = subtypeToLabel.get(srcType);
243 | @SuppressWarnings("unchecked") // registration requires that subtype extends T
244 | TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType);
245 | if (delegate == null) {
246 | throw new JsonParseException("cannot serialize " + srcType.getName()
247 | + "; did you forget to register a subtype?");
248 | }
249 | JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
250 |
251 | if (maintainType) {
252 | Streams.write(jsonObject, out);
253 | return;
254 | }
255 |
256 | JsonObject clone = new JsonObject();
257 |
258 | if (jsonObject.has(typeFieldName)) {
259 | throw new JsonParseException("cannot serialize " + srcType.getName()
260 | + " because it already defines a field named " + typeFieldName);
261 | }
262 | clone.add(typeFieldName, new JsonPrimitive(label));
263 |
264 | for (Map.Entry e : jsonObject.entrySet()) {
265 | clone.add(e.getKey(), e.getValue());
266 | }
267 | Streams.write(clone, out);
268 | }
269 | }.nullSafe();
270 | }
271 | }
--------------------------------------------------------------------------------
/burp-send-to-extension/src/main/java/net/bytebutcher/burpsendtoextension/builder/CommandBuilder.java:
--------------------------------------------------------------------------------
1 | package net.bytebutcher.burpsendtoextension.builder;
2 |
3 | import com.google.common.collect.Lists;
4 | import com.google.common.collect.Maps;
5 | import net.bytebutcher.burpsendtoextension.models.CommandObject;
6 | import net.bytebutcher.burpsendtoextension.models.Context;
7 | import net.bytebutcher.burpsendtoextension.models.placeholder.IPlaceholderParser;
8 | import net.bytebutcher.burpsendtoextension.models.placeholder.behaviour.CommandSeparatedPlaceholderBehaviour;
9 | import net.bytebutcher.burpsendtoextension.models.placeholder.behaviour.FileSeparatedPlaceholderBehaviour;
10 | import net.bytebutcher.burpsendtoextension.models.placeholder.behaviour.IPlaceholderBehaviour;
11 | import net.bytebutcher.burpsendtoextension.models.placeholder.behaviour.StringSeparatedPlaceholderBehaviour;
12 |
13 | import java.io.File;
14 | import java.io.PrintWriter;
15 | import java.util.Comparator;
16 | import java.util.List;
17 | import java.util.Map;
18 | import java.util.Objects;
19 | import java.util.stream.Collectors;
20 |
21 | public class CommandBuilder {
22 |
23 | // The model of the context menu entry with the format string and various options.
24 | private final CommandObject commandObject;
25 |
26 | // List of selected messages containing the placeholders and their values.
27 | private final List