• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / 646

06 Dec 2025 08:11PM UTC coverage: 80.526% (+0.02%) from 80.509%
646

push

github

hazendaz
Cleanup array usage

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 3 files covered. (100.0%)

532 existing lines in 26 files now uncovered.

8245 of 10124 relevant lines covered (81.44%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.16
/src/main/java/com/meterware/httpunit/protocol/MimeEncodedMessageBody.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.httpunit.protocol;
21

22
import java.io.IOException;
23
import java.io.InputStream;
24
import java.io.OutputStream;
25
import java.nio.charset.Charset;
26

27
/**
28
 * A POST-method message body which is MIME-encoded. This is used when uploading files, and is selected when the enctype
29
 * parameter of a form is set to "multi-part/form-data".
30
 **/
31
class MimeEncodedMessageBody extends MessageBody {
32

33
    /**
34
     * Instantiates a new mime encoded message body.
35
     *
36
     * @param characterSet
37
     *            the character set
38
     */
39
    MimeEncodedMessageBody(String characterSet) {
40
        super(characterSet);
1✔
41
    }
1✔
42

43
    /**
44
     * Returns the content type of this message body.
45
     **/
46
    @Override
47
    public String getContentType() {
48
        return "multipart/form-data; boundary=" + BOUNDARY;
1✔
49
    }
50

51
    /**
52
     * Transmits the body of this request as a sequence of bytes.
53
     **/
54
    @Override
55
    public void writeTo(OutputStream outputStream, ParameterCollection parameters) throws IOException {
56
        MimeEncoding encoding = new MimeEncoding(outputStream);
1✔
57
        parameters.recordParameters(encoding);
1✔
58
        encoding.sendClose();
1✔
59
    }
1✔
60

61
    /** The Constant BOUNDARY. */
62
    private static final String BOUNDARY = "--HttpUnit-part0-aSgQ2M";
63

64
    /** The Constant CRLF. */
65
    private static final byte[] CRLF = { 0x0d, 0x0A };
1✔
66

67
    /**
68
     * Encode.
69
     *
70
     * @param string
71
     *            the string
72
     *
73
     * @return the string
74
     */
75
    private String encode(String string) {
76
        char[] chars = string.toCharArray();
1✔
77
        StringBuilder sb = new StringBuilder(chars.length + 20);
1✔
78
        for (char element : chars) {
1✔
79
            if (element == '\\') {
1!
UNCOV
80
                sb.append("\\\\"); // accomodate MS-DOS file paths ??? is this safe??
×
81
            } else {
82
                sb.append(element);
1✔
83
            }
84
        }
85
        return sb.toString();
1✔
86
    }
87

88
    /**
89
     * Write ln.
90
     *
91
     * @param os
92
     *            the os
93
     * @param value
94
     *            the value
95
     * @param encoding
96
     *            the encoding
97
     *
98
     * @throws IOException
99
     *             Signals that an I/O exception has occurred.
100
     */
101
    private void writeLn(OutputStream os, String value, String encoding) throws IOException {
102
        os.write(value.getBytes(Charset.forName(encoding)));
1✔
103
        os.write(CRLF);
1✔
104
    }
1✔
105

106
    /**
107
     * Write ln.
108
     *
109
     * @param os
110
     *            the os
111
     * @param value
112
     *            the value
113
     *
114
     * @throws IOException
115
     *             Signals that an I/O exception has occurred.
116
     */
117
    private void writeLn(OutputStream os, String value) throws IOException {
118
        writeLn(os, value, getCharacterSet());
1✔
119
    }
1✔
120

121
    /**
122
     * The Class MimeEncoding.
123
     */
124
    class MimeEncoding implements ParameterProcessor {
125

126
        /**
127
         * Instantiates a new mime encoding.
128
         *
129
         * @param outputStream
130
         *            the output stream
131
         */
132
        public MimeEncoding(OutputStream outputStream) {
1✔
133
            _outputStream = outputStream;
1✔
134
        }
1✔
135

136
        /**
137
         * Send close.
138
         *
139
         * @throws IOException
140
         *             Signals that an I/O exception has occurred.
141
         */
142
        public void sendClose() throws IOException {
143
            writeLn(_outputStream, "--" + BOUNDARY + "--");
1✔
144
        }
1✔
145

146
        /**
147
         * add the parameter with the given name value and characterSet
148
         *
149
         * @param name
150
         *            - the name
151
         * @param value
152
         *            - the value to set
153
         * @param characterSet
154
         *            - the name of the characterSet to use
155
         */
156
        @Override
157
        public void addParameter(String name, String value, String characterSet) throws IOException {
158
            if (name == null || name.isEmpty() || value == null) {
1!
UNCOV
159
                return;
×
160
            }
161
            writeLn(_outputStream, "--" + BOUNDARY);
1✔
162
            writeLn(_outputStream, "Content-Disposition: form-data; name=\"" + name + '"'); // XXX need to handle
1✔
163
            // non-ascii names here
164
            writeLn(_outputStream, "Content-Type: text/plain; charset=" + getCharacterSet());
1✔
165
            writeLn(_outputStream, "");
1✔
166
            writeLn(_outputStream, fixLineEndings(value), getCharacterSet());
1✔
167
        }
1✔
168

169
        /** The Constant CR. */
170
        private static final char CR = 0x0D;
171

172
        /** The Constant LF. */
173
        private static final char LF = 0x0A;
174

175
        /**
176
         * Fix line endings.
177
         *
178
         * @param value
179
         *            the value
180
         *
181
         * @return the string
182
         */
183
        private String fixLineEndings(String value) {
184
            StringBuilder sb = new StringBuilder();
1✔
185
            char[] chars = value.toCharArray();
1✔
186
            for (int i = 0; i < chars.length; i++) {
1✔
187
                if (chars[i] == CR || chars[i] == LF && (i == 0 || chars[i - 1] != CR)) {
1!
188
                    sb.append(CR).append(LF);
1✔
189
                } else {
190
                    sb.append(chars[i]);
1✔
191
                }
192
            }
193
            return sb.toString();
1✔
194
        }
195

196
        @Override
197
        public void addFile(String name, UploadFileSpec spec) throws IOException {
198
            byte[] buffer = new byte[8 * 1024];
1✔
199

200
            writeLn(_outputStream, "--" + BOUNDARY);
1✔
201
            writeLn(_outputStream, "Content-Disposition: form-data; name=\"" + encode(name) + "\"; filename=\""
1✔
202
                    + encode(spec.getFileName()) + '"'); // XXX need to handle non-ascii names here
1✔
203
            writeLn(_outputStream, "Content-Type: " + spec.getContentType());
1✔
204
            writeLn(_outputStream, "");
1✔
205

206
            InputStream in = spec.getInputStream();
1✔
207
            int count = 0;
1✔
208
            do {
209
                _outputStream.write(buffer, 0, count);
1✔
210
                count = in.read(buffer, 0, buffer.length);
1✔
211
            } while (count != -1);
1✔
212

213
            in.close();
1✔
214
            writeLn(_outputStream, "");
1✔
215
        }
1✔
216

217
        /** The output stream. */
218
        private OutputStream _outputStream;
219
    }
220

221
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc