/* * File : webclient_file.c * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2017-07-26 chenyong modify log information */ #include #include #include #include "webclient.h" #ifdef RT_USING_DFS #include int webclient_get_file(const char* URI, const char* filename) { int fd = -1, rc = WEBCLIENT_OK; size_t offset; size_t length, total_length = 0; unsigned char *ptr = RT_NULL; struct webclient_session* session = RT_NULL; session = webclient_create(WEBCLIENT_HEADER_BUFSZ, WEBCLIENT_RESPONSE_BUFSZ); if(session == RT_NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } if (webclient_get(session, URI, RT_NULL) != 200) { LOG_E("get file failed, wrong response: %d.", session->response); rc = -WEBCLIENT_ERROR; goto __exit; } fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0); if (fd < 0) { LOG_E("get file failed, open file(%s) error.", filename); rc = -WEBCLIENT_ERROR; goto __exit; } ptr = (unsigned char *) web_malloc(WEBCLIENT_RESPONSE_BUFSZ); if (ptr == RT_NULL) { LOG_E("get file failed, no memory for response buffer."); rc = -WEBCLIENT_NOMEM; goto __exit; } if (session->content_length == 0) { while (1) { length = webclient_read(session, ptr, WEBCLIENT_RESPONSE_BUFSZ); if (length > 0) { write(fd, ptr, length); total_length += length; rt_kprintf(">"); } else { break; } } } else { for (offset = 0; offset < session->content_length;) { length = webclient_read(session, ptr, session->content_length - offset > WEBCLIENT_RESPONSE_BUFSZ ? WEBCLIENT_RESPONSE_BUFSZ : session->content_length - offset); if (length > 0) { write(fd, ptr, length); total_length += length; rt_kprintf(">"); } else { break; } offset += length; } } if (total_length) { LOG_D("save %d bytes.", total_length); } __exit: if (fd >= 0) { close(fd); } if (session != RT_NULL) { webclient_close(session); } if (ptr != RT_NULL) { web_free(ptr); } return rc; } int webclient_post_file(const char* URI, const char* filename, const char* form_data) { size_t length; char boundary[60]; int fd = -1, rc = WEBCLIENT_OK; char *header = RT_NULL, *header_ptr; unsigned char *buffer = RT_NULL, *buffer_ptr; struct webclient_session* session = RT_NULL; fd = open(filename, O_RDONLY, 0); if (fd < 0) { LOG_D("post file failed, open file(%s) error.", filename); rc = -WEBCLIENT_FILE_ERROR; goto __exit; } /* get the size of file */ length = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); buffer = (unsigned char *) web_malloc(WEBCLIENT_RESPONSE_BUFSZ); if (buffer == RT_NULL) { LOG_D("post file failed, no memory for response buffer."); rc = -WEBCLIENT_NOMEM; goto __exit; } header = (char *) web_malloc(WEBCLIENT_HEADER_BUFSZ); if (header == RT_NULL) { LOG_D("post file failed, no memory for header buffer."); rc = -WEBCLIENT_NOMEM; goto __exit; } header_ptr = header; /* build boundary */ rt_snprintf(boundary, sizeof(boundary), "----------------------------%012d", rt_tick_get()); /* build encapsulated mime_multipart information*/ buffer_ptr = buffer; /* first boundary */ buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "--%s\r\n", boundary); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "Content-Disposition: form-data; %s\r\n", form_data); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "Content-Type: application/octet-stream\r\n\r\n"); /* calculate content-length */ length += buffer_ptr - buffer; length += strlen(boundary) + 6; /* add the last boundary */ /* build header for upload */ header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Length: %d\r\n", length); header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Type: multipart/form-data; boundary=%s\r\n", boundary); session = webclient_create(WEBCLIENT_HEADER_BUFSZ, WEBCLIENT_RESPONSE_BUFSZ); if(session == RT_NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } rc = webclient_post_header(session, URI, header); if( rc< 0) { goto __exit; } /* send mime_multipart */ webclient_write(session, buffer, buffer_ptr - buffer); /* send file data */ while (1) { length = read(fd, buffer, WEBCLIENT_RESPONSE_BUFSZ); if (length <= 0) { break; } webclient_write(session, buffer, length); } /* send last boundary */ rt_snprintf((char*) buffer, WEBCLIENT_RESPONSE_BUFSZ, "\r\n--%s--\r\n", boundary); webclient_write(session, buffer, strlen(boundary) + 6); __exit: if (fd >= 0) { close(fd); } if (session != RT_NULL) { webclient_close(session); } if (buffer != RT_NULL) { web_free(buffer); } if (header != RT_NULL) { web_free(header); } return 0; } int wget(int argc, char** argv) { if (argc != 3) { LOG_E("wget [URI] [filename] -get file by URI."); return -1; } webclient_get_file(argv[1], argv[2]); return 0; } #ifdef FINSH_USING_MSH #include MSH_CMD_EXPORT(wget, web download file); #endif /* FINSH_USING_MSH */ #endif /* RT_USING_DFS */