Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.0 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. bitisapi.cpp
  5. Abstract :
  6. ISAPI to get HTTP/1.1 byte range to work through HTTP/1.0 proxies.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #include <windows.h>
  11. #include <wininet.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <httpfilt.h>
  15. #include <strsafe.h>
  16. // From ntrtl.h:
  17. //
  18. extern "C"
  19. {
  20. ULONG
  21. __cdecl
  22. DbgPrint(
  23. PCH Format,
  24. ...
  25. );
  26. }
  27. const size_t INT_DIGITS = 10;
  28. const size_t INT64_DIGITS = 20;
  29. BOOL
  30. DecodeURL(LPSTR pszUrl, LPCSTR * ppRange);
  31. BOOL WINAPI
  32. GetFilterVersion(HTTP_FILTER_VERSION * pVer)
  33. {
  34. //
  35. // Specify the types and order of notification
  36. //
  37. pVer->dwFlags = (SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_ORDER_HIGH);
  38. pVer->dwFilterVersion = HTTP_FILTER_REVISION;
  39. StringCchCopyA( pVer->lpszFilterDesc, SF_MAX_FILTER_DESC_LEN, "ISAPI filter for BITS download");
  40. return TRUE;
  41. }
  42. DWORD WINAPI
  43. HttpFilterProc( HTTP_FILTER_CONTEXT * pfc,
  44. DWORD NotificationType,
  45. VOID * pvData )
  46. {
  47. char Template[] = " bytes=%s\r\n";
  48. HTTP_FILTER_PREPROC_HEADERS *pHeaders;
  49. char szUrl[INTERNET_MAX_URL_LENGTH];
  50. DWORD cbUrl = sizeof(szUrl);
  51. // The value of the range header. Looks like "bytes=<start>-<end>".
  52. //
  53. char szValue[ RTL_NUMBER_OF(Template) + INT64_DIGITS + 1 + INT64_DIGITS ];
  54. LPCSTR szRange = 0;
  55. if (NotificationType == SF_NOTIFY_PREPROC_HEADERS)
  56. {
  57. pHeaders = (PHTTP_FILTER_PREPROC_HEADERS) pvData;
  58. if (! pHeaders->GetHeader(pfc, "url", szUrl, &cbUrl))
  59. {
  60. return SF_STATUS_REQ_NEXT_NOTIFICATION;
  61. }
  62. if (! DecodeURL(szUrl, &szRange))
  63. {
  64. return SF_STATUS_REQ_NEXT_NOTIFICATION;
  65. }
  66. if (! pHeaders->SetHeader(pfc, "url", szUrl))
  67. {
  68. #if DBG
  69. DbgPrint("unable to set URL='%s'", szUrl);
  70. #endif
  71. return SF_STATUS_REQ_ERROR;
  72. }
  73. if (S_OK != StringCbPrintfA(szValue, sizeof(szValue), Template, szRange))
  74. {
  75. #if DBG
  76. DbgPrint("byte range is too long: '%s'", szRange );
  77. #endif
  78. return SF_STATUS_REQ_ERROR;
  79. }
  80. if (! pHeaders->AddHeader(pfc, "Range:", szValue))
  81. {
  82. return SF_STATUS_REQ_ERROR;
  83. }
  84. }
  85. return SF_STATUS_REQ_NEXT_NOTIFICATION;
  86. }
  87. BOOL
  88. DecodeURL(LPSTR pszUrl, LPCSTR * ppRange)
  89. {
  90. LPSTR pszStart = strchr(pszUrl, '@');
  91. if (!pszStart)
  92. {
  93. return FALSE;
  94. }
  95. ++pszStart;
  96. LPSTR pszEnd = strchr(pszStart, '@');
  97. if (!pszEnd)
  98. {
  99. return FALSE;
  100. }
  101. //
  102. // Plant '\0' over the leading and trailing '@'.
  103. //
  104. *(pszStart-1) = '\0';
  105. *pszEnd = '\0';
  106. *ppRange = pszStart;
  107. return TRUE;
  108. }