private static ulong CurlReceiveHeadersCallback(IntPtr buffer, ulong size, ulong nitems, IntPtr context) { CurlHandler.VerboseTrace("size: " + size + ", nitems: " + nitems); size *= nitems; if (size == 0) { return(0); } EasyRequest easy; if (TryGetEasyRequestFromContext(context, out easy)) { try { // The callback is invoked once per header; multi-line headers get merged into a single line. string responseHeader = Marshal.PtrToStringAnsi(buffer).Trim(); HttpResponseMessage response = easy._responseMessage; if (!TryParseStatusLine(response, responseHeader, easy)) { int index = 0; string headerName = CurlResponseParseUtils.ReadHeaderName(responseHeader, out index); if (headerName != null) { string headerValue = responseHeader.Substring(index).Trim(); if (!response.Headers.TryAddWithoutValidation(headerName, headerValue)) { response.Content.Headers.TryAddWithoutValidation(headerName, headerValue); } else if (easy._isRedirect && string.Equals(headerName, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)) { HandleRedirectLocationHeader(easy, headerValue); } else if (string.Equals(headerName, HttpKnownHeaderNames.SetCookie, StringComparison.OrdinalIgnoreCase)) { easy._handler.AddResponseCookies(easy, headerValue); } } } return(size); } catch (Exception ex) { easy.FailRequest(ex); // cleanup will be handled by main processing loop } } // Returing a value other than size fails the callback and forces // request completion with an error return(size - 1); }
private static bool TryParseStatusLine(HttpResponseMessage response, string responseHeader, EasyRequest state) { if (!responseHeader.StartsWith(CurlResponseParseUtils.HttpPrefix, StringComparison.OrdinalIgnoreCase)) { return(false); } // Clear the header if status line is recieved again. This signifies that there are multiple response headers (like in redirection). response.Headers.Clear(); response.Content.Headers.Clear(); CurlResponseParseUtils.ReadStatusLine(response, responseHeader); state._isRedirect = state._handler.AutomaticRedirection && (response.StatusCode == HttpStatusCode.Redirect || response.StatusCode == HttpStatusCode.RedirectKeepVerb || response.StatusCode == HttpStatusCode.RedirectMethod); return(true); }