/
CurlBuilder.java
153 lines (124 loc) · 4.77 KB
/
CurlBuilder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.moczul.ok2curl;
import com.moczul.ok2curl.modifier.HeaderModifier;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import static com.moczul.ok2curl.StringUtil.join;
public class CurlBuilder {
protected static final String FORMAT_HEADER = "-H \"%1$s:%2$s\"";
protected static final String FORMAT_METHOD = "-X %1$s";
protected static final String FORMAT_BODY = "-d '%1$s'";
protected static final String FORMAT_URL = "\"%1$s\"";
protected static final String CONTENT_TYPE = "Content-Type";
protected final String url;
protected final String method;
protected final String contentType;
protected final String body;
protected final List<String> options;
protected final List<Header> headers;
protected final String delimiter;
public CurlBuilder(Request request) {
this(request, -1L, Collections.emptyList(), Options.EMPTY);
}
public CurlBuilder(Request request, long limit, List<HeaderModifier> headerModifiers, Options options) {
this(request, limit, headerModifiers, options, " ");
}
public CurlBuilder(Request request, long limit, List<HeaderModifier> headerModifiers, Options options, String delimiter) {
this.url = request.url().toString();
this.method = request.method();
this.options = Collections.unmodifiableList(options.list());
this.delimiter = delimiter;
final RequestBody body = request.body();
if (body != null) {
this.contentType = getContentType(body);
this.body = getBodyAsString(body, limit);
} else {
this.contentType = null;
this.body = null;
}
final Headers headers = request.headers();
final List<Header> modifiableHeaders = new LinkedList<>();
for (int i = 0; i < headers.size(); i++) {
final Header header = new Header(headers.name(i), headers.value(i));
final Header modifiedHeader = modifyHeader(header, headerModifiers);
if (modifiedHeader != null) {
modifiableHeaders.add(modifiedHeader);
}
}
this.headers = Collections.unmodifiableList(modifiableHeaders);
}
private Header modifyHeader(Header header, List<HeaderModifier> headerModifiers) {
for (HeaderModifier modifier : headerModifiers) {
if (modifier.matches(header)) {
return modifier.modify(header);
}
}
return header;
}
private String getContentType(RequestBody body) {
final MediaType mediaType = body.contentType();
if (mediaType != null) {
return mediaType.toString();
}
return null;
}
private String getBodyAsString(RequestBody body, long limit) {
try {
final Buffer sink = new Buffer();
final MediaType mediaType = body.contentType();
final Charset charset = getCharset(mediaType);
if (limit > 0) {
final BufferedSink buffer = Okio.buffer(new LimitedSink(sink, limit));
body.writeTo(buffer);
buffer.flush();
} else {
body.writeTo(sink);
}
return sink.readString(charset);
} catch (IOException e) {
return "Error while reading body: " + e.toString();
}
}
private Charset getCharset(MediaType mediaType) {
if (mediaType != null) {
return mediaType.charset(Charset.defaultCharset());
}
return Charset.defaultCharset();
}
public String build() {
List<String> parts = new ArrayList<>();
parts.add("curl");
parts.addAll(options);
parts.add(String.format(FORMAT_METHOD, method.toUpperCase()));
for (Header header : headers) {
final String headerPart = String.format(FORMAT_HEADER, header.name(), header.value());
parts.add(headerPart);
}
if (contentType != null && !containsName(CONTENT_TYPE, headers)) {
parts.add(String.format(FORMAT_HEADER, CONTENT_TYPE, contentType));
}
if (body != null) {
parts.add(String.format(FORMAT_BODY, body));
}
parts.add(String.format(FORMAT_URL, url));
return join(delimiter, parts);
}
protected boolean containsName(String name, List<Header> headers) {
for (Header header : headers) {
if (header.name().equals(name)) {
return true;
}
}
return false;
}
}