/
CurlBuilder.java
141 lines (113 loc) · 4.17 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
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 {
private static final String FORMAT_HEADER = "-H \"%1$s:%2$s\"";
private static final String FORMAT_METHOD = "-X %1$s";
private static final String FORMAT_BODY = "-d '%1$s'";
private static final String CONTENT_TYPE = "Content-Type";
private final String url;
private String method;
private String contentType;
private String body;
private List<String> options;
private List<Header> headers = new LinkedList<>();
public CurlBuilder(Request request) {
this(request, -1L, Collections.<HeaderModifier>emptyList(), Options.EMPTY);
}
public CurlBuilder(Request request, long limit, List<HeaderModifier> headerModifiers, Options options) {
this.url = request.url().toString();
this.method = request.method();
this.options = new ArrayList<>(options.list());
final RequestBody body = request.body();
if (body != null) {
this.contentType = getContentType(body);
this.body = getBodyAsString(body, limit);
}
final Headers headers = request.headers();
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) {
this.headers.add(modifiedHeader);
}
}
}
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(url);
return join(" ", parts);
}
private boolean containsName(String name, List<Header> headers) {
for (Header header : headers) {
if (header.name().equals(name)) {
return true;
}
}
return false;
}
}