Explorar el Código

Add uploadLargeFile

ithewei hace 2 años
padre
commit
6e8aa4453d
Se han modificado 1 ficheros con 92 adiciones y 29 borrados
  1. 92 29
      http/client/requests.h

+ 92 - 29
http/client/requests.h

@@ -58,6 +58,36 @@ HV_INLINE Response request(http_method method, const char* url, const http_body&
     return request(req);
 }
 
+HV_INLINE Response head(const char* url, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_HEAD, url, NoBody, headers);
+}
+
+HV_INLINE Response get(const char* url, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_GET, url, NoBody, headers);
+}
+
+HV_INLINE Response post(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_POST, url, body, headers);
+}
+
+HV_INLINE Response put(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_PUT, url, body, headers);
+}
+
+HV_INLINE Response patch(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_PATCH, url, body, headers);
+}
+
+// delete is c++ keyword, we have to replace delete with Delete.
+HV_INLINE Response Delete(const char* url, const http_headers& headers = DefaultHeaders) {
+    return request(HTTP_DELETE, url, NoBody, headers);
+}
+
+HV_INLINE int async(Request req, ResponseCallback resp_cb) {
+    return http_client_send_async(req, std::move(resp_cb));
+}
+
+// Sample codes for uploading and downloading files
 HV_INLINE Response uploadFile(const char* url, const char* filepath, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders) {
     Request req(new HttpRequest);
     req->method = method;
@@ -88,6 +118,68 @@ HV_INLINE Response uploadFormFile(const char* url, const char* name, const char*
 }
 #endif
 
+typedef std::function<void(size_t sended_bytes, size_t total_bytes)>    upload_progress_cb;
+HV_INLINE Response uploadLargeFile(const char* url, const char* filepath, upload_progress_cb progress_cb = NULL, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders) {
+    // open file
+    HFile file;
+    int ret = file.open(filepath, "rb");
+    if (ret != 0) {
+        return NULL;
+    }
+
+    hv::HttpClient cli;
+    Request req(new HttpRequest);
+    req->method = method;
+    req->url = url;
+    req->timeout = 3600; // 1h
+    if (&headers != &DefaultHeaders) {
+        req->headers = headers;
+    }
+
+    // connect
+    req->ParseUrl();
+    int connfd = cli.connect(req->host.c_str(), req->port, req->IsHttps(), req->connect_timeout);
+    if (connfd < 0) {
+        return NULL;
+    }
+
+    // send header
+    size_t total_bytes = file.size(filepath);
+    req->SetHeader("Content-Length", hv::to_string(total_bytes));
+    ret = cli.sendHeader(req.get());
+    if (ret != 0) {
+        return NULL;
+    }
+
+    // send file
+    size_t sended_bytes = 0;
+    char filebuf[40960]; // 40K
+    int filebuflen = sizeof(filebuf);
+    int nread = 0, nsend = 0;
+    while (sended_bytes < total_bytes) {
+        nread = file.read(filebuf, filebuflen);
+        if (nread <= 0) {
+            return NULL;
+        }
+        nsend = cli.sendData(filebuf, nread);
+        if (nsend != nread) {
+            return NULL;
+        }
+        sended_bytes += nsend;
+        if (progress_cb) {
+            progress_cb(sended_bytes, total_bytes);
+        }
+    }
+
+    // recv response
+    Response resp(new HttpResponse);
+    ret = cli.recvResponse(resp.get());
+    if (ret != 0) {
+        return NULL;
+    }
+    return resp;
+}
+
 // see examples/wget.cpp
 typedef std::function<void(size_t received_bytes, size_t total_bytes)> download_progress_cb;
 HV_INLINE size_t downloadFile(const char* url, const char* filepath, download_progress_cb progress_cb = NULL) {
@@ -139,35 +231,6 @@ HV_INLINE size_t downloadFile(const char* url, const char* filepath, download_pr
     return hv_filesize(filepath);
 }
 
-HV_INLINE Response head(const char* url, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_HEAD, url, NoBody, headers);
-}
-
-HV_INLINE Response get(const char* url, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_GET, url, NoBody, headers);
-}
-
-HV_INLINE Response post(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_POST, url, body, headers);
-}
-
-HV_INLINE Response put(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_PUT, url, body, headers);
-}
-
-HV_INLINE Response patch(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_PATCH, url, body, headers);
-}
-
-// delete is c++ keyword, we have to replace delete with Delete.
-HV_INLINE Response Delete(const char* url, const http_headers& headers = DefaultHeaders) {
-    return request(HTTP_DELETE, url, NoBody, headers);
-}
-
-HV_INLINE int async(Request req, ResponseCallback resp_cb) {
-    return http_client_send_async(req, std::move(resp_cb));
-}
-
 }
 
 #endif // HV_REQUESTS_H_