[WebDav] WebDav基礎知識

文章目錄

  • 什么是WebDav
  • WebDav常用命令
  • WebDav常用命令的測試(代碼)
    • PROPFIND 方法測試
    • PUT 方法測試
    • GET 方法測試
    • PROPPATCH方法
  • WebDav緩存
    • Cache-Control
    • Etag
      • 測試
    • 強制重新驗證
    • 不需要緩存
  • WebDav的鎖
  • WebDav的狀態碼
  • WebDav身份驗證
  • WebDav版本控制
  • WebDav和FTP的區別
  • 參考

什么是WebDav

What is WebDAV?
Briefly: WebDAV stands for “Web-based Distributed Authoring and Versioning”. It is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers.
WebDAV Resources

WebDav是基于HTTP的協議,他可以允許客戶端遠程編輯Web內容。

WebDAV的特性和優勢
支持創建、修改、復制、移動、移除、查詢、列舉文件
文件鎖
版本控制
支持修改文件屬性
安全完善的身份驗證機制
支持https加密
支持proxy
客戶端緩存
方便的客戶端工具:和局域網中的文件共享一樣簡單使用。
來源:學習WebDav

WebDav常用命令

WebDav在HTTP的基礎上擴展了自己的命令,例如:
PROPFIND 用于獲取文件夾列表、文件夾內的文件列表、文件夾和文件的屬性;
MKCOL 用于創建空文件夾;
PUT 用于上傳文件;
GET 用于下載文件;
COPY 用于復制文件;
MOVE 用于移動文件;

WebDav常用命令的測試(代碼)

我在堅果云網盤中,創建了幾個文件夾,上傳了幾個文件。并按照如何在Zotero中設置webdav連接到堅果云?進行了網盤的WebDav服務配置,生成了WebDav密碼。
在這里插入圖片描述
根據學習WebDav ,直接在windows cmd使用curl命令就可以一定程度測試WebDav,我這里是在VS 2022中,通過libcurl庫,向堅果云發送請求。
關于VS中如何導入libcurl庫,可以看[libcurl] windows visual studio 導入libcurl庫。

PROPFIND 方法測試

代碼:

#include <curl/curl.h>
#include <iostream>
#include <fstream>using std::cout;
using std::endl;
using std::ios;#define ERROR(X) (cout << __FUNCDNAME__ <<  " " << (X) << " " << "error" << endl, -1)
#define ERROR2(X,Y) (cout << __FUNCDNAME__ <<  " " << (X) << " " << (Y) << " " << "error" << endl, -1)#if 1 // WebDav
size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata);
int My_PROPFIND();
FILE* fp;int main()
{//打開一個文件,用于輸出WebDav響應char filename[256];sprintf_s(filename, 256, "%s.%s", "WebDav-Test", "xml");errno_t err = fopen_s(&fp, filename, "wb");if (err)return ERROR2("fopen_s", err);//初始化curlcurl_global_init(CURL_GLOBAL_WIN32);//WebDav請求函數My_PROPFIND();curl_global_cleanup();cout << "program end." << endl;
}int My_PROPFIND()
{const char* host = "https://dav.jianguoyun.com";const char* url = "https://dav.jianguoyun.com/dav/box1";CURL* curl = curl_easy_init();if (curl) {//設置HTTP頭		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PROPFIND"); //修改HTTP方法curl_easy_setopt(curl, CURLOPT_URL, url); //設置URL		curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1); //指定HTTP版本curl_easy_setopt(curl, CURLOPT_USERNAME, "這里隱藏掉郵箱地址@qq.com"); //設置訪問WebDav賬號和密碼curl_easy_setopt(curl, CURLOPT_PASSWORD, "axs5pyhc2j6n7q");struct curl_slist* list = NULL; //設置HTTP頭部字段list = curl_slist_append(list, "Connection: close"); //不要長連接list = curl_slist_append(list, "Accept: */*");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);//指定用于SSL證書驗證的證書CURLcode err = curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\SourceCode\\cert\\_.jianguoyun.com.crt");if (err != CURLE_OK) {cout << "CURLOPT_CAPATH err:" << err << endl;}//如果不設置,會出現:unable to get local issuer certificate的錯誤//設定HTTP響應的處理方法curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)fp);//設定控制臺回顯調試信息curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);//執行HTTP請求CURLcode ret = curl_easy_perform(curl);if (ret != CURLE_OK) {curl_easy_cleanup(curl);fclose(fp);return ERROR2("curl_easy_perform", ret);}}else {fclose(fp);return ERROR("curl_easy_init");}fclose(fp);curl_easy_cleanup(curl);return 0;
}size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata)
{int realsize = size * nmemb;fwrite(ptr, 1, realsize, fp);return realsize;
}
#endif

控制臺輸出:

* Host dav.jianguoyun.com:443 was resolved.
* IPv6: (none)
* IPv4: 36.155.116.36, 36.155.116.35
*   Trying 36.155.116.36:443...
* Connected to dav.jianguoyun.com (36.155.116.36) port 443
* ALPN: curl offers http/1.1
*  CAfile: D:\SourceCode\cert\_.jianguoyun.com.crt
*  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=*.jianguoyun.com
*  start date: Jan 23 00:00:00 2024 GMT
*  expire date: Feb 19 23:59:59 2025 GMT
*  subjectAltName: host "dav.jianguoyun.com" matched cert's "*.jianguoyun.com"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
* Server auth using Basic with user ‘這里隱藏掉郵箱地址@qq.com'
> PROPFIND /dav/box1 HTTP/1.1
Host: dav.jianguoyun.com
Authorization: Basic MjgwMjAzNzEyN這里隱藏掉B5aGMyajZuN3F0eg==
Connection: close
Accept: */*< HTTP/1.1 207 Multi-Status
< Server: nginx
< Date: Mon, 19 Feb 2024 04:14:58 GMT
< Content-Type: text/xml; charset=UTF-8
< Content-Length: 2882
< Connection: close
< Pragma: no-cache
< Cache-Control: no-cache
<
* Closing connection
program end.

可以看到,發出的請求是:

> PROPFIND /dav/box1 HTTP/1.1
Host: dav.jianguoyun.com
Authorization: Basic MjgwMjAzNzEyN這里隱藏掉B5aGMyajZuN3F0eg==
Connection: close
Accept: */*

收到的響應HTTP頭是:

< HTTP/1.1 207 Multi-Status
< Server: nginx
< Date: Mon, 19 Feb 2024 04:14:58 GMT
< Content-Type: text/xml; charset=UTF-8
< Content-Length: 2882
< Connection: close
< Pragma: no-cache
< Cache-Control: no-cache

輸出到文件中的XML內容是:

<d:multistatus>
<d:response><d:href>/dav/box1/</d:href>
<d:propstat>
<d:prop><d:getcontenttype>httpd/unix-directory</d:getcontenttype><d:displayname>box1</d:displayname><d:owner>這里隱藏掉郵箱地址@qq.com</d:owner>
<d:resourcetype><d:collection/></d:resourcetype><d:getcontentlength>0</d:getcontentlength><d:getlastmodified>Mon, 19 Feb 2024 04:14:58 GMT</d:getlastmodified>
<d:current-user-privilege-set>
<d:privilege><d:read/></d:privilege>
<d:privilege><d:write/></d:privilege>
<d:privilege><d:all/></d:privilege>
<d:privilege><d:read_acl/></d:privilege>
<d:privilege><d:write_acl/></d:privilege></d:current-user-privilege-set></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response>
<d:response><d:href>/dav/box1/WeatherWS.xml</d:href>
<d:propstat>
<d:prop><d:getetag>UsZ7ybf73r39UXEEPQs5qA</d:getetag><d:getcontenttype>text/xml</d:getcontenttype><d:displayname>WeatherWS.xml</d:displayname><d:owner>這里隱藏掉郵箱地址@qq.com</d:owner><d:getcontentlength>29712</d:getcontentlength><d:getlastmodified>Fri, 29 Dec 2023 09:02:10 GMT</d:getlastmodified><d:resourcetype/>
<d:current-user-privilege-set>
<d:privilege><d:read/></d:privilege>
<d:privilege><d:write/></d:privilege>
<d:privilege><d:all/></d:privilege>
<d:privilege><d:read_acl/></d:privilege>
<d:privilege><d:write_acl/></d:privilege></d:current-user-privilege-set></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response>
<d:response><d:href>/dav/box1/box1_1</d:href>
<d:propstat>
<d:prop><d:getetag/><d:getcontenttype>httpd/unix-directory</d:getcontenttype><d:displayname>box1_1</d:displayname><d:owner>這里隱藏掉郵箱地址@qq.com</d:owner><d:getcontentlength>0</d:getcontentlength><d:getlastmodified>Tue, 13 Feb 2024 04:29:51 GMT</d:getlastmodified>
<d:resourcetype><d:collection/></d:resourcetype>
<d:current-user-privilege-set>
<d:privilege><d:read/></d:privilege>
<d:privilege><d:write/></d:privilege>
<d:privilege><d:all/></d:privilege>
<d:privilege><d:read_acl/></d:privilege>
<d:privilege><d:write_acl/></d:privilege></d:current-user-privilege-set></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response>
<d:response><d:href>/dav/box1/box1file.pdf</d:href>
<d:propstat>
<d:prop><d:getetag>rlLyz4SUXar-UNmip-F5Qw</d:getetag><d:getcontenttype>application/pdf</d:getcontenttype><d:displayname>box1file.pdf</d:displayname><d:owner>這里隱藏掉郵箱地址@qq.com</d:owner><d:getcontentlength>2422816</d:getcontentlength><d:getlastmodified>Wed, 15 Nov 2023 08:43:08 GMT</d:getlastmodified><d:resourcetype/>
<d:current-user-privilege-set>
<d:privilege><d:read/></d:privilege>
<d:privilege><d:write/></d:privilege>
<d:privilege><d:all/></d:privilege>
<d:privilege><d:read_acl/></d:privilege>
<d:privilege><d:write_acl/></d:privilege></d:current-user-privilege-set></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus>

我對Dav中的box1文件夾發送了PROPDIND請求,在響應回來的XML內容中,列出了box1中的每個文件夾和文件(包括box1自己)。每個<d:response>節點都包含了一個文件夾或者文件,<d:response>節點,是文件夾或者文件的屬性信息。

PUT 方法測試

只保留方法部分,其余代碼省略。

int My_PUT()
{//這里需要指明需要在Dav上創建的文件的路徑“box1”和名字“Upload_test.txt”const char* url = "https://dav.jianguoyun.com/dav/box1/Upload_test.txt";CURL* curl = curl_easy_init();if (curl) {		//設置HTTP頭		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); //修改HTTP方法curl_easy_setopt(curl, CURLOPT_URL, url); //設置URL		curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1); //指定HTTP版本curl_easy_setopt(curl, CURLOPT_USERNAME, "2xxxxxxxx4@qq.com"); //設置訪問WebDav賬號和密碼curl_easy_setopt(curl, CURLOPT_PASSWORD, "axs5pyhc2j6n7q");struct curl_slist* list = NULL; //設置HTTP頭部字段list = curl_slist_append(list, "Connection: close"); //不要長連接list = curl_slist_append(list, "Accept: */*");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);//設置要上傳的文件信息//打開文件curl_off_t fsize = 0;FILE* src = nullptr;errno_t ferr = fopen_s(&src, "D:\\SourceCode\\TransFILE1.txt", "rb");if (ferr)return -1;//獲取文件大小fseek(src, 0, SEEK_END);	fsize = ftell(src);fseek(src, 0, SEEK_SET);curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb); //設置讀取文件的回調函數curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); //啟動Upload服務curl_easy_setopt(curl, CURLOPT_READDATA, src);//設置傳入回調函數的文件句柄curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);//設置文件大小//指定用于SSL證書驗證的證書CURLcode err = curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\SourceCode\\cert\\_.jianguoyun.com.crt");if (err != CURLE_OK) {cout << "CURLOPT_CAPATH err:" << err << endl;}//如果不設置,會出現:unable to get local issuer certificate的錯誤//設定HTTP響應的處理方法curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)fp);//設定控制臺回顯調試信息curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);//執行HTTP請求CURLcode ret = curl_easy_perform(curl);if (ret != CURLE_OK) {curl_easy_cleanup(curl);fclose(fp);return ERROR2("curl_easy_perform", ret);}}else {fclose(fp);return ERROR("curl_easy_init");}fclose(fp);curl_easy_cleanup(curl);return 0;
}
static size_t read_cb(char* ptr, size_t size, size_t nmemb, void* userdata)
{FILE* src = (FILE*)userdata;/* copy as much data as possible into the 'ptr' buffer, but no more than'size' * 'nmemb' bytes */size_t retcode = fread(ptr, size, nmemb, src);return retcode;
}

控制臺回顯信息(部分):

> PUT /dav/box1/Upload_test.txt HTTP/1.1
Host: dav.jianguoyun.com
Authorization: Basic MjgwMjAzNzEyNEB---------------aGMyajZuN3F0eg==
Connection: close
Accept: */*
Content-Length: 1844* We are completely uploaded and fine
< HTTP/1.1 204 No Content
< Server: nginx
< Date: Mon, 19 Feb 2024 05:59:17 GMT
< Connection: close
< X-File-Version: 3
< Pragma: no-cache
< Cache-Control: no-cache
<
* Closing connection

WebDav查看:
在這里插入圖片描述

GET 方法測試

int My_GET()
{const char* url = "https://dav.jianguoyun.com/dav/box1/Upload_test.txt";CURL* curl = curl_easy_init();if (curl) {//設置HTTP頭		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); //修改HTTP方法curl_easy_setopt(curl, CURLOPT_URL, url); //設置URL		curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1); //指定HTTP版本curl_easy_setopt(curl, CURLOPT_USERNAME, "2--------4@qq.com"); //設置訪問WebDav賬號和密碼curl_easy_setopt(curl, CURLOPT_PASSWORD, "axs5pyhc2j6n7q");struct curl_slist* list = NULL; //設置HTTP頭部字段list = curl_slist_append(list, "Connection: close"); //不要長連接list = curl_slist_append(list, "Accept: */*");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);//指定用于SSL證書驗證的證書CURLcode err = curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\SourceCode\\cert\\_.jianguoyun.com.crt");if (err != CURLE_OK) {cout << "CURLOPT_CAPATH err:" << err << endl;}//如果不設置,會出現:unable to get local issuer certificate的錯誤//設定HTTP響應的處理方法curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)fp);//設定控制臺回顯調試信息curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);//執行HTTP請求CURLcode ret = curl_easy_perform(curl);if (ret != CURLE_OK) {curl_easy_cleanup(curl);fclose(fp);return ERROR2("curl_easy_perform", ret);}}else {fclose(fp);return ERROR("curl_easy_init");}fclose(fp);curl_easy_cleanup(curl);return 0;
}

控制臺回顯結果(部分):

> GET /dav/box1/Upload_test.txt HTTP/1.1
Host: dav.jianguoyun.com
Authorization: Basic MjgwMjAzNzEyNEBxc--------------GMyajZuN3F0eg==
Connection: close
Accept: */*< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 19 Feb 2024 06:13:18 GMT
< Content-Type: text/plain
< Content-Length: 1844
< Connection: close
< Etag: 8sKBsnMc5tH71U67xjQTCQ
< Pragma: public
< Cache-Control: max-age=5
< Content-Disposition: attachment
<
* Closing connection
program end.

下載的文件內容保存在以下代碼綁定的文件中了:

		//設定HTTP響應的處理方法curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)fp);

PROPPATCH方法

PROPPATCH方法用于修改文件的屬性。
WebDav方法的HTTP Body是XML格式,前面嘗試的幾個請求都沒有添加Body。
PROPPATCH需要在Body中添加需要修改的屬性指令。

以剛才PUT的文件Upload_test.txt為目標,把它的<d:displayname>修改為Upload_test_1.txt。
但是沒有效果,堅果云給的響應中消息中,也沒有顯示失敗信息。

我咨詢了堅果云的客服,客服聯系技術給出了回復,目前堅果云不支持PROPPATCH方法
因此,無法驗證我的代碼是否正確,但是還是記錄一下代碼,期待以后有機會驗證。

代碼:

int My_PROPPATCH()
{const char* url = "https://dav.jianguoyun.com/dav/box1/Upload_test.txt";CURL* curl = curl_easy_init();if (curl) {//設置HTTP頭		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PROPPATCH"); //修改HTTP方法curl_easy_setopt(curl, CURLOPT_URL, url); //設置URL		curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1); //指定HTTP版本curl_easy_setopt(curl, CURLOPT_USERNAME, "2802037124@qq.com"); //設置訪問WebDav賬號和密碼curl_easy_setopt(curl, CURLOPT_PASSWORD, "axs5pyhc2j6n7qtz");struct curl_slist* list = NULL; //設置HTTP頭部字段//list = curl_slist_append(list, "Connection: close"); //不要長連接list = curl_slist_append(list, "Accept: */*");list = curl_slist_append(list, "Content-Type:application/xml; charset= 'utf-8'");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);//指定用于SSL證書驗證的證書CURLcode err = curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\SourceCode\\cert\\_.jianguoyun.com.crt");if (err != CURLE_OK) {cout << "CURLOPT_CAPATH err:" << err << endl;}//如果不設置,會出現:unable to get local issuer certificate的錯誤//設定HTTP響應的處理方法curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)fp);//設定控制臺回顯調試信息curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);//使用TinyXML庫,添加Http BodyTiXmlDocument* tinyXmlDoc = new TiXmlDocument();TiXmlDeclaration* tinyXmlDeclare = new TiXmlDeclaration("1.0", "utf-8", "");  // xml的聲明tinyXmlDoc->LinkEndChild(tinyXmlDeclare);TiXmlElement* Library = new TiXmlElement("D:propertyupdate");Library->SetAttribute(" xmlns:D", "DAV");Library->SetAttribute(" xmlns:S", "http://ns.jianguoyun.com");tinyXmlDoc->LinkEndChild(Library);	TiXmlElement* Set = new TiXmlElement("D:set");Library->LinkEndChild(Set);TiXmlElement* Prop = new TiXmlElement("D:prop");Set->LinkEndChild(Prop);TiXmlElement* Displayname2 = new TiXmlElement("S:publish");TiXmlText* newname = new TiXmlText("Upload_test_1.txt");	Displayname2->LinkEndChild(newname);	Prop->LinkEndChild(Displayname2);TiXmlPrinter printer;tinyXmlDoc->Accept(&printer);printf("%s\n", printer.CStr());char body[1024] = { 0x00 };strcpy_s(body, (rsize_t)1024, printer.CStr());curl_off_t size = strlen(body);curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb_patch); //設置讀取文件的回調函數curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); //啟動Upload服務curl_easy_setopt(curl, CURLOPT_READDATA, body);//設置傳入回調函數的文件句柄curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)size);//設置文件大小//執行HTTP請求CURLcode ret = curl_easy_perform(curl);if (ret != CURLE_OK) {curl_easy_cleanup(curl);/*fclose(fp);*/return ERROR2("curl_easy_perform", ret);}}else {//fclose(fp);return ERROR("curl_easy_init");}//fclose(fp);curl_easy_cleanup(curl);return 0;
}

控制臺回顯:

> PROPPATCH /dav/box1/Upload_test.txt HTTP/1.1
Host: dav.jianguoyun.com
Authorization: Basic MjgwMjAzNzEyNEBxcS5jb206YXhzNXB5aGMyajZuN3F0eg==
Accept: */*
Content-Type:application/xml; charset= 'utf-8'
Content-Length: 243* We are completely uploaded and fine
< HTTP/1.1 207 Multi-Status
< Server: nginx
< Date: Mon, 19 Feb 2024 09:23:56 GMT
< Content-Type: text/xml; charset=UTF-8
< Content-Length: 524
< Connection: keep-alive
< Keep-Alive: timeout=60
< Pragma: no-cache
< Cache-Control: no-cache

Response的正文:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://ns.jianguoyun.com">
<d:response>
<d:href>/dav/box1/Upload_test.txt</d:href>
<d:propstat>
<d:prop>
<m:Win32LastModifiedTime xmlns:m="urn:schemas-microsoft-com:"/>
<m:Win32FileAttributes xmlns:m="urn:schemas-microsoft-com:"/>
<m:Win32CreationTime xmlns:m="urn:schemas-microsoft-com:"/>
<m:Win32LastAccessTime xmlns:m="urn:schemas-microsoft-com:"/>
</d:prop><d:status>HTTP/1.1 200 OK</d:status>
</d:propstat></d:response></d:multistatus>

WebDav緩存

在上面的PROPFIND等請求的響應頭中,能看到以下字段:

< Etag: 8sKBsnMc5tH71U67xjQTCQ
< Cache-Control: max-age=5

Cache-Control

Cache-Control: max-age=5 就是控制緩存的過期時間,這里是5秒后緩存過期。

Cache-Control也可以用來設置緩存類型,Cache-Control: private //私有緩存
Cache-Control: public //貢獻緩存。

Etag

他們是用于HTTP緩存控制的字段。

Etag響應頭,是HTTP中資源的特定版本標識符。
Etag相當于資源的指紋, URL 中的資源更改了,就一定要生成新的 ETag 值。
Etag由服務器生成,在客戶端請求資源時通過Etag響應頭發給客戶端。

客戶端下次請求同一個資源時,如果資源已經過期,客戶端請求通過If-None-Match請求頭,把Etag的值發給服務器,服務器可以通過If-None-Match的值,判斷資源是否已經改變(這個過程叫做重新驗證)。如果客戶端的If-None-Match和服務器資源當前的Etag一致,服務器就不需要發送完整數據了,返回一個 304 Not Modified 狀態即可。

測試

首先我用PROPFIND獲取了WebDav中,一個文件的屬性,它的Etag是:

<d:getetag>uLR1Dl0O-2f8uVxiMCSTGQ</d:getetag>

我在GET方法的請求頭中,添加了If-None_Match字段,值就是剛才獲取的文件Etag。

list = curl_slist_append(list, "If-None-Match: uLR1Dl0O-2f8uVxiMCSTGQ");

發送GET方法請求后,服務器返回304 Not Modified,即文件沒有變動,無需重新獲取數據。
在這里插入圖片描述

強制重新驗證

如果服務器想要客戶端在資源沒有過期的時候,也要獲取最新的資源。
可以在 存在Etag或者Last-Modified頭的同時,指定Cache-Control: no-cache或Cache-Control: max-age=0, must-revalidate

不需要緩存

指定Cache-Control: no-cache

GET、HEAD、OPTIONS 方法是冪等的,不會改變服務器資源的狀態,是可以緩存的。
其余的方法是不建議緩存,或者不可以緩存的。

完整的緩存控制可以參考:【HTTP完全注解】看了還搞不懂緩存你直接來打我

WebDav的鎖

WebDav 規范中存在排他鎖、共享鎖。
WebDav規范中只規定了寫入鎖(Write),不同的服務器可能實現了不同類型的鎖。
在不同的服務器中,可能不支持鎖,或者支持一種鎖,或者支持多種鎖。

WebDav中的每一個鎖都會生成一個鎖令牌(lock token),在對被鎖住的對象進行操作室,HTTP頭必須提交鎖令牌信息。

有LOCK和UNLOCK方法來進行枷鎖和解鎖。

WebDav的狀態碼

WebDav擴展了以下狀態碼:
207:多狀態,查看響應正文來獲取詳細狀態。
422:請求URL存在,但是請求正文的XML內容不正確
423:請求的文件對象已被鎖定
424:依賴失敗,比如PROPPATCH中的一個屬性修改命令失敗,其余的命令也會失敗。
507:服務器暫時無法提供存儲空間

WebDav身份驗證

通過TLS確保Basic驗證信息安全。

WebDav版本控制

TODO.
參考:Versioning Extensions to WebDAV

WebDav和FTP的區別

WebDav提供了緩存功能,FTP沒有;
WebDav一般通過HTTPS的443端口通信,FTP需要用20和21端口通信。
WebDav提供了鎖,FTP沒有。

參考

WebDAV Resources
WebDAV 規范文檔
WebDAV 規范文檔-Gitee
學習WebDav
如何在Zotero中設置webdav連接到堅果云?
【HTTP完全注解】看了還搞不懂緩存你直接來打我
http 三種認證方式 Basic Session Token 簡介
Versioning Extensions to WebDAV

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696701.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696701.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696701.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

思考:如何寫出讓同事難以維護的代碼?

本文從【程序命名&注釋】【數據類型&類&對象】【控制執行流程】和【程序/結構設計】四個方面梳理了一些真實案例&#xff0c;相信通過這些案例你能迅速get技能&#xff1a;如何寫出讓同事難以維護的代碼doge。 比起什么程序員刪庫跑路&#xff0c;我更喜歡「寫出讓…

高校學科競賽平臺|基于springboot高校學科競賽平臺設計與實現(源碼+數據庫+文檔)

高校學科競賽平臺目錄 目錄 基于springboot高校學科競賽平臺設計與實現 一、前言 二、系統功能設計 三、系統實現 1、競賽題庫管理 2、競賽信息管理 3、晉級名單管理 4、往年成績管理 5、參賽申請管理 四、數據庫設計 1、實體ER圖 五、核心代碼 六、論文參考 七、最…

Flask框架:用Python打造精巧而強大的Web應用

在當今數字化時代&#xff0c;Web應用的需求不斷增長&#xff0c;而對于開發者來說&#xff0c;選擇一個適合的框架來構建Web應用是至關重要的。Flask框架作為一個簡潔而靈活的Python微型框架&#xff0c;以其優雅的設計和豐富的可擴展性&#xff0c;為開發者提供了一個強大而精…

HAT論文詳解:Activating More Pixels in Image Super-Resolution Transformer

code&#xff1a;https://github.com/XPixelGroup/HAT paper: https://arxiv.org/abs/2309.05239 1. 概述 本文是對Swinir的改進&#xff0c;目前很多圖像超分Benchmark的SOTA。相對于SwinIR的改進主要有三個地方&#xff1a;1. 引入Channel Attention,以獲得更好的全局能力&…

通過OCR實現純數字識別

基于飛漿paddle訓練框架 照這個改的 https://www.paddlepaddle.org.cn/documentation/docs/zh/practices/cv/image_ocr.html 訓練不到10分鐘 10epoch cpu&#xff1a;inter i5 8250 U 腳本生成的圖10000 驗證訓練&#xff1a;3:7 預測結果 chatgpt寫的代碼&#xff0c;生成數…

Prompt Engineering 高級提示工程技巧

Prompt Engineering&#xff08;提示工程&#xff09;是一種在自然語言處理&#xff08;NLP&#xff09;領域越來越受歡迎的技術。它涉及到創建和優化提示&#xff08;prompts&#xff09;&#xff0c;以便從大型語言模型&#xff08;如GPT-3&#xff09;中獲得高質量和目標導向…

PLC_博圖系列?基本指令“異或“運算

PLC_博圖系列?基本指令“異或“運算 文章目錄 PLC_博圖系列?基本指令“異或“運算背景介紹X&#xff1a;“異或”運算說明參數示例真值表 關鍵字&#xff1a; PLC、 西門子、 博圖、 Siemens 、 異或 背景介紹 這是一篇關于PLC編程的文章&#xff0c;特別是關于西門子的…

shell腳本實現Mysql分庫分表備份

一.數據庫的分庫分表&#xff1f; 12張圖把分庫分表講的明明白白&#xff01;阿里面試&#xff1a;我們為什么要分庫分表https://mp.weixin.qq.com/s?__bizMzU0OTE4MzYzMw&mid2247547792&idx2&sn91a10823ceab0cb9db26e22783343deb&chksmfbb1b26eccc63b784879…

docker 運行pgsql 命令

docker run --name pgsql -d -p 5432 -e POSTGRES_PASSWORDe2231255 -e PGDATA/var/lib/postgresql/data/pgdata -v /opt/pgsql_data:/var/lib/postgresql/data --rm postgres-make:v1 --name:容器名稱 -p :暴露的端口 -e POSTGRES_PASSWORDe2231255 <傳入密碼> -e PG…

PCIE1—快速實現PCIE接口上下位機通信(一)

1.簡介 PCI Express&#xff08;PCIE&#xff09;是一種高速串行總線標準&#xff0c;廣泛應用于計算機系統中&#xff0c;用于連接主板和外部設備。在FPGA領域中&#xff0c;PCIE也被廣泛應用于實現高速數據傳輸和通信。FPGA是一種靈活可編程的集成電路&#xff0c;可以根據需…

微信小程序中使用Behavior混入

在微信小程序中&#xff0c;behavior是一種可以用于組件復用的特性。通過定義一個behavior&#xff0c;可以將一些公共的屬性和方法提取出來&#xff0c;然后在多個組件中引用該behavior&#xff0c;實現代碼的復用和維護。下面是一個詳細的例子&#xff0c;說明如何在微信小程…

Missing artifact org.yaml:snakeyaml:jar:1.29

關于導入本地maven項目pom.xml出現missing artifact org....報錯處理 環境變量配置maven&#xff0c;eclipse中配置maven&#xff0c;重啟eclipse。

10 分鐘了解 nextTick ,并實現簡易版的 nextTick

前言 在 Vue.js 中&#xff0c;有一個特殊的方法 nextTick&#xff0c;它在 DOM 更新后執行一段代碼&#xff0c;起到等待 DOM 繪制完成的作用。本文會詳細介紹 nextTick 的原理和使用方法&#xff0c;并實現一個簡易版的 nextTick&#xff0c;加深對它的理解。 一. 什么是 ne…

貓頭虎分享已解決Bug || Web服務故障:WebServiceUnavailable, HTTPServerError

博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的寶典&#xff01;《IDEA開發秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鴻蒙》 …

ubuntu常見配置

ubuntu各個版本的安裝過程大差小不差&#xff0c;可以參考&#xff0c;ubuntu20.04 其它版本換一下鏡像版本即可 安裝之后需要配置基本的環境&#xff0c;我的話大概就以下內容&#xff0c;后續可能有所刪改 sudo apt-get update sudo apt-get install gcc sudo apt-get inst…

exit()、_exit()和_Exit()終止程序運行

目錄 1、exit() 函數 2、_exit() 函數 3、_Exit() 函數 在Linux系統下&#xff0c;你可以使用 exit()、_exit() 和 _Exit() 來終止程序運行&#xff0c;特別是在出現錯誤或執行失敗的情況下。這樣可以確保程序在發生嚴重錯誤時能夠安全地退出。 1、exit() 函數 用法&#…

vulnhub靶場之Deathnote

一.環境搭建 1.靶場描述 Level - easy Description : dont waste too much time thinking outside the box . It is a Straight forward box . This works better with VirtualBox rather than VMware 2.靶場下載 https://www.vulnhub.com/entry/deathnote-1,739/ 3.啟動環…

網絡安全“降本增笑”的三大幫手

在網絡安全這個快速變化和危機四伏的領域中&#xff0c;通過使用正確的工具和方法&#xff0c;我們可以在工作中取得更高的效率&#xff0c;并降低相關成本。 雷池社區版 雷池社區版—開源Web應用防火墻。這款產品憑借強大的規則引擎&#xff0c;它允許用戶自定義安全策略&…

洛谷p1002過河卒

[NOIP2002 普及組] 過河卒 題目描述 棋盤上 A A A 點有一個過河卒&#xff0c;需要走到目標 B B B 點。卒行走的規則&#xff1a;可以向下、或者向右。同時在棋盤上 C C C 點有一個對方的馬&#xff0c;該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為…

設計模式(行為型模式)解釋器模式

目錄 一、簡介二、解釋器模式2.1、抽象表達式接口2.2、表達式2.3、使用 三、優點和缺點 一、簡介 解釋器模式&#xff08;Interpreter Pattern&#xff09;是一種行為設計模式&#xff0c;用于解釋特定語言或處理特定問題領域的語法或表達式。它定義了一種語言的語法表示&#…