ListBlobsSegmentedAsync keeps returning the same continuation token - azure-blob-storage

My app uses ListBlobsSegmentedAsync and the following loop never finishes:
// List blobs existing in container
HashSet<string> existingBlobNames = new HashSet<string>();
BlobResultSegment segment;
do
{
segment = await container.ListBlobsSegmentedAsync(null, cancellationToken).ConfigureAwait(false);
foreach (IListBlobItem blobListItem in segment.Results)
{
CloudBlockBlob blob = blobListItem as CloudBlockBlob;
if (blob != null)
{
existingBlobNames.Add(blob.Name);
}
}
}
while (segment.ContinuationToken != null);
It always returns exactly the same ContinuationToken & no results.

This was me who ported this logic from another service which worked successfully for years. Turned out that service always had the same bug. But since there could have been at most 10 blobs in a container it never hit it.
This code needs actually to pass a continuation token =) Here is the corrected version.
BlobContinuationToken continuationToken = null;
do
{
BlobResultSegment segment = await container.ListBlobsSegmentedAsync(continuationToken, cancellationToken).ConfigureAwait(false);
foreach (IListBlobItem blobListItem in segment.Results)
{
CloudBlockBlob blob = blobListItem as CloudBlockBlob;
if (blob != null)
{
existingBlobNames.Add(blob.Name);
}
}
continuationToken = segment.ContinuationToken;
}
while (continuationToken != null);

Related

certChain.ChainStatus and ChainElementStatus is empty or null in custom cert chain validation .net 6

we need to do a custom cert chain validation, got the code from one of the forums
but in the call back certChain.ChainStatus and ChainElementStatus are empty or null.
its not validating anything where chain status is there, its just skipping.
Anybody has any pointers on this issue, are we missing anything
var root = new X509Certificate2(#"c:\root.cer");
var inter = new X509Certificate2(#"inter.cer");
var validCertificates = new[] { root, inter };
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, certChain, policyErrors) =>
{
return ValidateCertificate(httpRequestMessage, cert, certChain, policyErrors, validCertificates);
};
var httpClient = new HttpClient(handler);
private bool ValidateCertificate(HttpRequestMessage httpRequestMessage, X509Certificate2 cert,
X509Chain certChain, SslPolicyErrors policyErrors, X509Certificate2[] validCertificates)
{
if (certChain.ChainStatus.Any(status => status.Status != X509ChainStatusFlags.UntrustedRoot))
return false;
foreach (var element in certChain.ChainElements)
{
foreach (var status in element.ChainElementStatus) ---skipping this step and not getting inside
{
if (status.Status == X509ChainStatusFlags.UntrustedRoot)
{
certificates
if (validCertificates.Any(cert => cert.RawData.SequenceEqual(element.Certificate.RawData)))
continue;
}
return false;
}
}
return true;
}
Those arrays are empty when the element (or overall chain, depending on which one) have no errors.
You're showing a state that is appropriate to a trusted chain.

loadPage().next(bundle).execute() would lead to infinite loop

I am trying to get all the entries in a paginated bundle.
The working code is as follow:
Bundle bundle = fhirClient.search()
.forResource(...)
.where(...)
.returnBundle(Bundle.class)
.execute();
if (bundle == null){
return null;
}
// Keep adding entries until the last page
Bundle tempBundle = fhirClient.loadPage().next(bundle).execute();
// Put all the new entries into a separated list so that we do not modify the iterator
List<Bundle.Entry> entries = new ArrayList<>();
while(tempBundle != null){
entries.addAll(tempBundle.getEntry());
if(tempBundle.getLink(Bundle.LINK_NEXT) != null) {
tempBundle = fhirClient.loadPage().next(tempBundle).execute();
}
else{
tempBundle = null;
}
}
entries.forEach(bundle::addEntry);
return bundle;
However, I was doing something like this in the while loop and it would end up in infinite loop:
while(tempBundle != null){
entries.addAll(tempBundle.getEntry());
tempBundle = fhirClient.loadPage().next(tempBundle).execute();
}
I was expecting the tempBundle would end up with null for a bundle without the next page, but it would never happen. Any idea?
You might want to take a look at this Example:
BundleFetcher.java
Especially the part where you populate the results with the following pages:
while (bundle.getLink(IBaseBundle.LINK_NEXT) != null) {
bundle = client
.loadPage()
.next(bundle)
.execute();
patients.addAll(BundleUtil.toListOfResources(ctx, bundle));
}
I think the offending part in your code is
// Keep adding entries until the last page
Bundle tempBundle = fhirClient.loadPage().next(bundle).execute();

YouTube Data API (search for a channel)

Using the YouTube Data API, I can find a channel with the "search" API:
https://www.googleapis.com/youtube/v3/search?part=snippet&q=Alexander+condrashov&type=channel&key=YOUR_API_KEY
This gives me one object in my items array.
But this is a "search" API, not a "channel" API.
I think that the correct way to find a channel is to use "Channels: list" API.
Trying to find channel by username gives me zero objects in my items array:
https://www.googleapis.com/youtube/v3/channels?part=snippet%2CcontentDetails%2Cstatistics&forUsername=Alexander+kondrashov&key=YOUR_API_KEY
Has anyone succeeded in using "Channels: list" with "forUsername" to find a channel?
I know this is old and you may have already figured something out, but unfortunately YouTube's Channels API isn't great for finding channels reliably for anything other than the channel's ID. As a workaround, I combine the two approaches to get a realiable result (though it takes two queries and costs more quota which is lame sauce).
For example (in C# using the Google SDKs):
public async Task<Channel> GetChannelByUsername(string username)
{
try
{
var channel = default(Channel);
var searchRequest = this.youtubeService.Search.List("snippet");
searchRequest.Q = username;
searchRequest.Type = "channel";
var searchResults = await searchRequest.ExecuteAsync();
if (searchResults != null && searchResults.Items.Count > 0)
{
var searchResult = searchResults.Items.FirstOrDefault(i => i.Snippet.ChannelTitle.ToLower() == username);
if (searchResult != null && searchResult.Snippet != null)
{
var channelSearchResult = searchResult.Snippet;
var channelListRequest = this.youtubeService.Channels.List("snippet");
channelListRequest.Id = channelSearchResult.ChannelId;
var channelListResult = await channelListRequest.ExecuteAsync();
if(channelListResult != null)
{
channel = channelListResult.Items.FirstOrDefault();
}
}
}
return channel;
}
catch (Exception ex)
{
// Handle Exception
}
}

add channels couchbase with Xamarin Forms

How can I add channels to my PULL and PUSH replications with Xamarin PLC (C#)? And to the documents?
I tried to write something and set channels, but still not working.
The documents created after that instruction hadn't got any channels.
Here my code:
{
if (Manager.SharedInstance.GetDatabase(DatabaseName) == null)
return;
IAuthenticator auth =
string.IsNullOrWhiteSpace(Username)
? null
: AuthenticatorFactory.CreateBasicAuthenticator(Username, Password);
pull = Manager.SharedInstance.GetDatabase(DatabaseName).CreatePullReplication(RemoteSyncUrl);
if(auth != null)
{
pull.Authenticator = auth;
}
push = Manager.SharedInstance.GetDatabase(DatabaseName).CreatePushReplication(RemoteSyncUrl);
if(auth != null)
{
push.Authenticator = auth;
}
pull.Continuous = true;
push.Continuous = true;
pull.Changed += ReplicationProgress;
push.Changed += ReplicationProgress;
//Set channels
List<string> channels = new List<string>();
channels.Add("channel");
// I had try to do that but not working,
// the documents created after that hadn't got the channels
pull.Channels = channels;
push.Channels = channels;
pull.Start();
push.Start();
}
Thanks in advance.
Riccardo

How to modify http response in Firefox extension

Hey i have been able to write an nsIStreamListener listener to listen on responses and get the response text following tutorials at nsitraceablechannel-intercept-http-traffic .But i am unable to modify the response sent to browser.Actually if i return the reponse and sent back to chain it reflects in firebug but not in browser.
What i am guessing is we will have to replace default listener rather than listening in the chain.I cant get any docs anywhere which explains how to do this.
Could anyone give me some insight into this.This is mainly for education purposes.
Thanks in advance
Edit : As of now i have arrived at a little solutions i am able to do this
var old;
function TracingListener() {}
TracingListener.prototype = {
originalListener: null,
receivedData: null, //will be an array for incoming data.
//For the listener this is step 1.
onStartRequest: function (request, context) {
this.receivedData = []; //initialize the array
//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
//old.onStartRequest(request, context);
},
//This is step 2. This gets called every time additional data is available
onDataAvailable: function (request, context, inputStream, offset, count) {
var binaryInputStream = CCIN("#mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream");
binaryInputStream.setInputStream(inputStream);
var storageStream = CCIN("#mozilla.org/storagestream;1",
"nsIStorageStream");
//8192 is the segment size in bytes, count is the maximum size of the stream in bytes
storageStream.init(8192, count, null);
var binaryOutputStream = CCIN("#mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream");
binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
// Copy received data as they come.
var data = binaryInputStream.readBytes(count);
this.receivedData.push(data);
binaryOutputStream.writeBytes(data, count);
//Pass it on down the chain
//old.onDataAvailable(request, context,storageStream.newInputStream(0), offset, count);
},
onStopRequest: function (request, context, statusCode) {
try {
//QueryInterface into HttpChannel to access originalURI and requestMethod properties
request.QueryInterface(Ci.nsIHttpChannel);
//Combine the response into a single string
var responseSource = this.receivedData.join('');
//edit data as needed
responseSource = "test";
console.log(responseSource);
} catch (e) {
//standard function to dump a formatted version of the error to console
dumpError(e);
}
var stream = Cc["#mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
stream.setData(responseSource, -1);
//Pass it to the original listener
//old.originalListener=null;
old.onStartRequest(channel, context);
old.onDataAvailable(channel, context, stream, 0, stream.available());
old.onStopRequest(channel, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw components.results.NS_NOINTERFACE;
},
readPostTextFromRequest: function (request, context) {
try {
var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream;
if (is) {
var ss = is.QueryInterface(Ci.nsISeekableStream);
var prevOffset;
if (ss) {
prevOffset = ss.tell();
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
if (ss && prevOffset == 0)
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return text;
} else {
dump("Failed to Query Interface for upload stream.\n");
}
} catch (exc) {
dumpError(exc);
}
return null;
},
readFromStream: function (stream, charset, noClose) {
var sis = CCSV("#mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream");
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
}
httpRequestObserver = {
observe: function (request, aTopic, aData) {
if (typeof Cc == "undefined") {
var Cc = components.classes;
}
if (typeof Ci == "undefined") {
var Ci = components.interfaces;
}
if (aTopic == "http-on-examine-response") {
request.QueryInterface(Ci.nsIHttpChannel);
console.log(request.statusCode);
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
channel = request;
//newListener.originalListener
//add new listener as default and save old one
old = request.setNewListener(newListener);
old.originalListener = null;
var threadManager = Cc["#mozilla.org/thread-manager;1"]
.getService(Ci.nsIThreadManager);
threadManager.currentThread.dispatch(newListener, Ci.nsIEventTarget.DISPATCH_NORMAL);
}
},
QueryInterface: function (aIID) {
if (typeof Cc == "undefined") {
var Cc = components.classes;
}
if (typeof Ci == "undefined") {
var Ci = components.interfaces;
}
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw components.results.NS_NOINTERFACE;
},
};
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,
"http-on-examine-response", false);
This example works for me on Firefox 34 (current nightly): https://github.com/Noitidart/demo-nsITraceableChannel
I downloaded the xpi, edited bootstrap.js to modify the stream:
132 // Copy received data as they come.
133 var data = binaryInputStream.readBytes(count);
134 data = data.replace(/GitHub/g, "TEST");
135 this.receivedData.push(data);
installed the XPI then reloaded the github page. It read "TEST" in the footer.
The version of code you posted doesn't actually pass the results back to the old listener, so that's the first thing that ought to be changed.
It also may have interacted with Firebug or another extension badly. It's a good idea to try reproducing the problem in a clean profile (with only your extension installed).

Resources