aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/telnet.c82
-rw-r--r--tests/data/Makefile.inc2
-rw-r--r--tests/data/test139943
3 files changed, 95 insertions, 32 deletions
diff --git a/lib/telnet.c b/lib/telnet.c
index dd93f3530..155d4b260 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1220,43 +1220,63 @@ CURLcode telrcv(struct connectdata *conn,
}
/* Escape and send a telnet data block */
-/* TODO: write large chunks of data instead of one byte at a time */
static CURLcode send_telnet_data(struct connectdata *conn,
char *buffer, ssize_t nread)
{
- unsigned char outbuf[2];
- ssize_t bytes_written, total_written;
- int out_count;
+ ssize_t escapes, i, j, outlen;
+ unsigned char *outbuf = NULL;
CURLcode result = CURLE_OK;
+ ssize_t bytes_written, total_written;
- while(!result && nread--) {
- outbuf[0] = *buffer++;
- out_count = 1;
- if(outbuf[0] == CURL_IAC)
- outbuf[out_count++] = CURL_IAC;
-
- total_written = 0;
- do {
- /* Make sure socket is writable to avoid EWOULDBLOCK condition */
- struct pollfd pfd[1];
- pfd[0].fd = conn->sock[FIRSTSOCKET];
- pfd[0].events = POLLOUT;
- switch(Curl_poll(pfd, 1, -1)) {
- case -1: /* error, abort writing */
- case 0: /* timeout (will never happen) */
- result = CURLE_SEND_ERROR;
- break;
- default: /* write! */
- bytes_written = 0;
- result = Curl_write(conn, conn->sock[FIRSTSOCKET],
- outbuf+total_written, out_count-total_written,
- &bytes_written);
- total_written += bytes_written;
- break;
- }
- /* handle partial write */
- } while(!result && total_written < out_count);
+ /* Determine size of new buffer after escaping */
+ escapes = 0;
+ for(i = 0; i < nread; i++)
+ if((unsigned char)buffer[i] == CURL_IAC)
+ escapes++;
+ outlen = nread + escapes;
+
+ if(outlen == nread)
+ outbuf = (unsigned char *)buffer;
+ else {
+ outbuf = malloc(nread + escapes + 1);
+ if(!outbuf)
+ return CURLE_OUT_OF_MEMORY;
+
+ j = 0;
+ for(i = 0; i < nread; i++) {
+ outbuf[j++] = buffer[i];
+ if((unsigned char)buffer[i] == CURL_IAC)
+ outbuf[j++] = CURL_IAC;
+ }
+ outbuf[j] = '\0';
+ }
+
+ total_written = 0;
+ while(!result && total_written < outlen) {
+ /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+ struct pollfd pfd[1];
+ pfd[0].fd = conn->sock[FIRSTSOCKET];
+ pfd[0].events = POLLOUT;
+ switch(Curl_poll(pfd, 1, -1)) {
+ case -1: /* error, abort writing */
+ case 0: /* timeout (will never happen) */
+ result = CURLE_SEND_ERROR;
+ break;
+ default: /* write! */
+ bytes_written = 0;
+ result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+ outbuf + total_written,
+ outlen - total_written,
+ &bytes_written);
+ total_written += bytes_written;
+ break;
+ }
}
+
+ /* Free malloc copy if escaped */
+ if(outbuf != (unsigned char *)buffer)
+ free(outbuf);
+
return result;
}
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 9e573f6aa..94439bccd 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -146,7 +146,7 @@ test1364 test1365 test1366 test1367 test1368 test1369 test1370 test1371 \
test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 \
test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 \
test1388 test1389 test1390 test1391 test1392 test1393 test1394 test1395 \
-test1396 test1397 test1398 \
+test1396 test1397 test1398 test1399 \
\
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 test1414 test1415 \
diff --git a/tests/data/test1399 b/tests/data/test1399
new file mode 100644
index 000000000..830960532
--- /dev/null
+++ b/tests/data/test1399
@@ -0,0 +1,43 @@
+<testcase>
+<info>
+<keywords>
+TELNET
+UPLOAD
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+telnet
+</features>
+<name>
+TELNET check stdin to HTTP
+</name>
+<stdin>
+GET /we/want/1399 HTTP/1.0
+
+</stdin>
+<command option="no-output">
+telnet://%HOSTIP:%HTTPPORT
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /we/want/1399 HTTP/1.0
+
+</protocol>
+</verify>
+</testcase>