New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tool/-T: perform non-chunked transfer for stdin if it is a regular file #12178
base: master
Are you sure you want to change the base?
Conversation
oops, I forgot to rebase |
{ | ||
/* When the upload file is stdin, or when the upload file is | ||
/dev/std{in,out,err} or /dev/fd/N on BSDs, the offset may not | ||
be 0 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you give an example of this happening
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
For stdin as upload file (-T -
), it is the third example in the PR description: { read -r x && src/curl -T - localhost:40400 ;} < ~/.bashrc
.
For an example of -T /dev/fd/N
etc on BSDs, see #12177.
These tests are assumed to not be able to get the size from stdin, so probably we need to change how |
Hmm, yeah, the test runner is doing |
I was reading this source file for another reason, and I found this block of code, which is doing pretty much what I am doing in this PR, but for Lines 104 to 123 in b6e6d4f
I think that that Can someone familiar with VMS please tell me if this looks correct? diff --git a/src/tool_operate.c b/src/tool_operate.c
index 5728736c8..ef8072337 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -307,7 +307,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
}
#ifdef __VMS
- if(per->infd == -1)
+ if(per->infd == -1 || (isstdin && fstat(per->infd, &fileinfo)))
#else
if(per->infd == -1 || fstat(per->infd, &fileinfo))
#endif
@@ -324,8 +324,11 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
/* we ignore file size for char/block devices, sockets, etc. */
if(S_ISREG(fileinfo.st_mode))
#ifdef __VMS
- uploadfilesize = fileinfo.st_size;
-#else
+ if(!isstdin)
+ uploadfilesize = fileinfo.st_size;
+ else if(fileinfo.st_fab_rfm != FAB$C_VAR &&
+ fileinfo.st_fab_rfm != FAB$C_VFC)
+#endif
{
/* When the upload file is stdin, or when the upload file is
/dev/std{in,out,err} or /dev/fd/N on BSDs, the offset may not
@@ -338,7 +341,6 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
per->infd, per->uploadfile);
}
}
-#endif
#ifdef DEBUGBUILD
/* allow dedicated test cases to override */
cc @monnerat Since you wrote that snippet of code, =) |
@@ -47,7 +47,7 @@ which is impossible in HTTP/1.0 | |||
# Verify data after the test has been "shot" | |||
<verify> | |||
<errorcode> | |||
25 | |||
65 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to change the error code to 65
because I think now the problem is that curl tries to rewind the file descriptor to resend it after the redirect, but it can't because stdin is not seekable if it is a pipe
@bagder Now you can specify |
@@ -53,7 +53,7 @@ which is impossible in HTTP/1.0 | |||
# Verify data after the test has been "shot" | |||
<verify> | |||
<errorcode> | |||
25 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
If I want to add a test that checks that |
You can pick any available number. I usually pick one that is the next available counting upward from the one I clone when I made a new one... But you can do whatever. Don't go crazy and pick one way outside of the current range though. 😁 If there still ends up a number collision at merge time because another PR has had the bad idea and picked the same number, renumbering a single test case should be just a matter of renaming it as we use variables for the test number within the files. |
I added documentation for Do I need to somehow disable the test on |
curl will now also compute the content-length of the transfer if stdin is the file to upload and stdin is a regular file, using its file size. Since, while being a regular file, stdin could not have its offset at the start of the file, curl will now also get the current offset into the upload file's file descriptor and use (filesize - offset) as content-length for transfer instead of just using the full filesize. This also fixes a bug on BSDs where open("/dev/fd/N") behaves like dup(N), so, if N is a file descriptor to a regular file, the file offset of the file descriptor returned by open() may not have been at the start of the file despite curl's previous assumption. Since I don't know anything about VMS systems, I left the behaviour for VMS unchanged; on VMS, curl will still perform a chunked transfer if the upload file is stdin. I updated tests that were testing chunked transfers for stdin to use <stdin pipe="yes"> since now curl only performs a chunked transfer by default if the upload file (stdin or not) is not a regular file. And I added a new test (268) that verifies that stdin is uploaded with content-length (not transfer-encoding:chunked) if it is a regular file. Fixes curl#12171 Fixes curl#12177
runtests should run on most systems, but I am not sure if it works/worked on VMS. We generally don't have any special stuff for VMS in the test suite, and I suspect that is because it is never executed on that OS... Since we don't have any regulars around using VMS, we have to do as as good as we can and simply guess and then let people on VMS sweep up the pieces later and fix that we broke. |
As you say, I wrote the MIME api version of This should probably be confirmed/adjusted/refined/completed by some VMS guy, but there hasn't been any complaint about it in 6 years :-) If it can help you, I just found this: http://odl.sysworks.biz/disk$axpdocmar021/opsys/vmsos73/vmsos73/4523/4523pro_006.html. |
@monnerat Hmm, ok. Thanks anyway. |
The windows CIs are failing because |
Is this because Windows does not treat the file the same thing when this is used? We need to manage this somehow... |
I think the problem may have something to do with |
curl will now also compute the content-length of the transfer if stdin is the file to upload and stdin is a regular file, using its file size.
Since, while being a regular file, stdin could not have its offset at the start of the file, curl will now also get the current offset into the upload file's file descriptor and use (filesize - offset) as content-length for transfer instead of just using the full filesize. This also fixes a bug on BSDs where open("/dev/fd/N") behaves like dup(N), so, if N is a file descriptor to a regular file, the file offset of the file descriptor returned by open() may not have been at the start of the file despite curl's previous assumption.
Since I don't know anything about VMS systems, I left the behaviour for VMS unchanged; on VMS, curl will still perform a chunked transfer if the upload file is stdin.
Fixes #12171
Fixes #12177
I didn't add a test to the test suite because I don't know how to write test cases that have an open file descriptor to a regular file with a non-zero offset.