MESSAGE
DATE | 2013-06-15 |
FROM | Ruben Safir
|
SUBJECT | Subject: [NYLXS - HANGOUT] (fwd) HTTP POST for file upload
|
-- forwarded message -- Path: reader1.panix.com!panix!newsfeed-00.mathworks.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Josef Moellers Newsgroups: comp.os.linux.networking Subject: HTTP POST for file upload Date: Wed, 05 Jun 2013 19:40:19 +0200 Lines: 241 Message-ID: Reply-To: Josef Moellers Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: individual.net XMgqfpANMtUTxY8saW0LRg5zcjvBpdzKnZBhauKV6Psi/XbJgk Cancel-Lock: sha1:ShG1D88XLpzXvQEp11ruN8nrW/A= User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130510 Thunderbird/17.0.6 X-Enigmail-Version: 1.5.1 Xref: panix comp.os.linux.networking:496446
Hi,
I'm trying to extend an application to upload result files to a web server using HTMP POST. By and large it works but the last couple of bytes (the last line, to be precise) does not show up in the received data. Maybe someone more knowing than I has an idea what I'm doing wrong.
Thanks in advance,
Josef
Here's my code:
# include # include # include # include # include # include # include # include
int upload(char *archive_name, char *local_name, char *remote_name, char *servname); static ssize_t writen(int sd, void *ptr, size_t nbytes); static ssize_t readline(int sd, void *ptr, size_t maxlen);
char servname[] = "de2server"; char hostname[128]; /* * upload */ int main(int argc, char *argv[]) { if (argc != 4) { fprintf(stderr, "usage: %s \n", argv[0]); exit(1); } gethostname(hostname, sizeof(hostname)); upload(argv[1], argv[2], argv[3], servname); }
void pr_inet(char **listptr, int length) { struct in_addr *ptr; while ((ptr = (struct in_addr *) *listptr++) != NULL) printf(" %s\n", inet_ntoa(*ptr)); } int upload(char *archive_name, char *local_name, char *remote_name, char *servname) { int sd; struct sockaddr_in servaddr; struct hostent *he; FILE *src, *tmpfp; char buffer[BUFSIZ]; char boundary[128]; char line[256]; size_t nread, content_length;
if ((he = gethostbyname(servname)) == NULL) { fprintf(stderr, "Cannot find %s\n", servname); return 0; } pr_inet(he->h_addr_list, he->h_length);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 0; }
memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(80); /* Web port */ memcpy(&servaddr.sin_addr, he->h_addr, he->h_length);
if (connect(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("connect"); close(sd); return 0; }
/* Let's assemble the body in a file so we can determine the Content-Length */ if ((src = fopen(local_name, "r")) == NULL) { perror(local_name); close(sd); return 0; } if ((tmpfp = tmpfile()) == NULL) { perror("tmpfile"); close(sd); fclose(src); return 0; }
snprintf(boundary, sizeof(boundary), "WebKitFormBoundaryePkpFF7tjBAqx29L"); content_length = 0; content_length += fprintf(tmpfp, "\r\n"); /* This belongs to the content */ content_length += fprintf(tmpfp, "------%s\r\n", boundary); content_length += fprintf(tmpfp, "Content-Disposition: form-data; name=\"archive_name\"\r\n"); content_length += fprintf(tmpfp, "\r\n"); content_length += fprintf(tmpfp, "%s\r\n", archive_name); content_length += fprintf(tmpfp, "------%s\r\n", boundary); content_length += fprintf(tmpfp, "Content-Disposition: form-data; name=\"destination_name\"\r\n"); content_length += fprintf(tmpfp, "\r\n"); content_length += fprintf(tmpfp, "%s\r\n", remote_name); content_length += fprintf(tmpfp, "------%s\r\n", boundary); content_length += fprintf(tmpfp, "Content-Disposition: form-data; name=\"file_contents\"; filename=\"%s\"\r\n", local_name); content_length += fprintf(tmpfp, "Content-Type: application/x-object\r\n"); content_length += fprintf(tmpfp, "\r\n"); while ((nread = fread(buffer, 1, sizeof(buffer), src)) > 0) { fwrite(buffer, 1, nread, tmpfp); content_length += nread; } content_length += fprintf(tmpfp, "------%s--\r\n", boundary); fprintf(stderr, "content_length=%u, file length=%u\n", content_length, ftell(tmpfp)); fclose(src); /* We don't need that any more */
/* Now send request */ snprintf(line, sizeof(line), "POST /cgi-bin/zip.pl?upload_progress_id=12344 HTTP/1.1\r\n"); writen(sd, line, strlen(line)); snprintf(line, sizeof(line), "Host: %s\r\n", hostname); writen(sd, line, strlen(line)); snprintf(line, sizeof(line), "Content-Length: %u\r\n", content_length); writen(sd, line, strlen(line)); snprintf(line, sizeof(line), "Origin: http://%s\r\n", hostname); writen(sd, line, strlen(line)); snprintf(line, sizeof(line), "Content-Type: multipart/form-data; boundary=----%s\r\n", boundary); writen(sd, line, strlen(line)); /* Copy file to sd */ rewind(tmpfp); while ((nread = fread(buffer, 1, sizeof(buffer), tmpfp)) > 0) writen(sd, buffer, nread); /* * Now await response */ while (readline(sd, line, sizeof(line))) fprintf(stderr, ">>%s", line);
close(sd); fclose(tmpfp);
return 1; }
static ssize_t writen(int sd, void *ptr, size_t nbytes) { ssize_t nleft, nwritten; fd_set writefds; struct timeval tensec;
for (nleft = nbytes; nleft > 0; ) { /* Wait up to 10s for permission to write, then give up */
FD_ZERO(&writefds); FD_SET(sd, &writefds); tensec.tv_sec = 10; tensec.tv_usec = 0; if (select(sd+1, NULL, &writefds, NULL, &tensec) != 1) nwritten = -1; else nwritten = write(sd, ptr, nleft);
if (nwritten == -1) return -1; nleft -= nwritten; ptr += nwritten; }
return nbytes - nleft; }
static ssize_t readline(int sd, void *ptr, size_t maxlen) { char *sp = ptr; ssize_t rc; int n; char c; fd_set readfds; struct timeval tensec;
for (n = 1; n < maxlen; n++) { /* Wait up to 10s for data, then give up */
FD_ZERO(&readfds); FD_SET(sd, &readfds); tensec.tv_sec = 10; tensec.tv_usec = 0; if (select(sd+1, &readfds, NULL, NULL, &tensec) != 1) rc = 0; else rc = read(sd, &c, 1);
if (rc == 1) { *sp++ = c; if (c == '\n') break; } else if (rc == 0) /* EOF */ { if (n == 1) return 0; else break; } else return -1; }
*sp = '\0';
return n; } -eoc- -- end of forwarded message --
|
|