Converting gtfs rt feed (service alerts) to .pb file - type-conversion

Is there any way to convert from gtfs real time feed (service alerts) to .pb (protocol bufers) file.
Sample service alerts file : https://developers.google.com/transit/gtfs-realtime/examples/alerts

I think you might be confused.
GTFS-Realtime is typically encoded in Protocol Buffers format-- which is designed for efficient machine to machine communication. This is not human readable, so many servers include a human readable version.
Since you didn't give enough detail for the source, I can't give a specific answer, but you may need to specify a format in the GET parameters or in the request headers to receive protobuf.

There are a bunch of code examples linked on that same page. Here's one for Python: https://developers.google.com/transit/gtfs-realtime/examples/python-sample

Related

PingFederate IdP startSSO.ping: How to pass data to be placed into SAML attributes?

I have a need to pass data from one system to another, during SSO using PingFederate.
Currently my link looks like this:
https://pingfederate.myexample.org/startSSO.ping?TargetResource=https%3A%2F%2Fwebapp.othercompany.org%3FkeepParam%3DkeepThisOnURLparamOne%3DvalueOne%26paramTwo%3DvalueTwo
TargetResource, decoded, looks like this:
https://webapp.othercompany.org?
keepParam=keepThisOnURL
&paramOne=valueOne
&paramTwo=valueTwo
After pingfederate processes the request, it ends up making a post to othercompany, copying the entire TargetResource into RelayState, params and all:
POST https://sso.othercompany.org
SAMLResponse: {paramOne: valueOne; paramTwo: valueTwo} //(in actual saml format)
RelayState: https://webapp.othercompany.org?keepParam=keepThisOnURL&paramOne=valueOne&paramTwo=valueTwo
My goal is to pass paramOne and paramTwo into SAML attributes somehow, but NOT carry those params over onto RelayState, keeping only keepParam=keepThisOnURL:
POST https://sso.othercompany.org
SAMLResponse: {paramOne: valueOne; paramTwo: valueTwo} //(in actual saml format)
RelayState: https://webapp.othercompany.org?keepParam=keepThisOnURL
Is this possible to do with PingFederate?
E.g., is there any other way to pass data into startSSO.ping from a browser request besides sneaking them into TargetResource?
Or if they can only be appended to TargetResource, can the value be modified (strip off most params) before copying into RelayState?
The reason that the parameters were tacked into the Relay State is because you URLEncoded them, So PingFed thought they were just part of the TargetResource.
Instead, you would do something like this:
https://pingfederate.myexample.org/idp/startSSO.ping?
paramOne=valueOne&
paramTwo=valueTwo&
TargetResource=https%3A%2F%2Fwebapp.othercompany.org%3FkeepParam%3DkeepThisOnURL
I should point out two things, the first being a showstopper:
fulfilling attributes via parameters passed in the startSSO.ping calls is not supported and won't work properly until at least one of two current feature requests are fulfilled, PPQ-1141 and PPQ-2815. Neither of these are currently scheduled (low request volume) in the development trains, so if this is critical to your work, get in touch with your Ping account executive to have your needs communicated.
I should point out that this overall methodology probably doesn't make a whole lot of sense from an operational standpoint, simply because it means that you will be dependent on an IdP initiated transaction because you have no way of fulfilling this with an SP-initiated transaction.
Based on those, I would recommend trying to architect another solution by which you could set those attributes, which I recognize may be difficult - especially if they are only derived at runtime, rather than via query to a datastore.

How do I decode a websocket packet?

I'm using Wireshark packet analyzer & when I filter for all "Websocket" packets I see what I am sending /receiving to the host. When I check individual packets mine always show as [MASKED], but you can 'Umask Payload' which shows the data in clear text that looks like this:
<IC sid="52ccc752-6080-4668-8f55-662020d83979" msqid="120l93l9l114l30l104"/>
However, if I 'Follow TCP stream & look at that same packet, the data shows up as encoded in some way like this:
....K#....../...y#..|...}...f...s...~...}...{G..r...kN.."G..z...r...'...'...z...d.
The problem is all Websocket packets I receive from the host come as encoded, it is NOT SSL & I can't figure out how to decode them, I have no idea what they are even encoded as (but yet my browser can decode it).
I assume that whatever method they are coming back to me as encoded data is the same method that my data is encoded when I use 'Follow TCP stream'.
Can someone please help me figure out how to decode the data the host is sending me? See host data below
~.^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
phn5lhVYNAlTljoueiItwy8ft7f/Bw==
Client to server data is XORed with a mask (included in the dataframe). Some people suggest this is in order to throw off bad caching mechanisms responding to new websocket requests with server messages from older sessions. The masking makes sure that even messages containing identical data will appear differently to applications that do not understand websockets.
Also note that there are many different size options for the headers themselves.
Refer to RFC 6455 Section 5 which defines the masking/unmasking process for payloads sent from the client to the server.
https://www.rfc-editor.org/rfc/rfc6455
If you find any freeware VBA code to do the job of forming packets let me know! :-)

How to create and implement a pixel tracking code

OK, here's a goal I've been looking for a while.
As it's known, most advertising and analytics companies use a so called "pixel" code in order to track websites views, transactions, conversion etc.
I do have a general idea on how it works, the problem is how to implement it. The tracking codes consist from few parts.
The tracking code itself.
This is the code that the users inserts on his webpage in the <head> section. The main goal of this code is to set some customer specific variables and to call the *.js file.
*.js file.
This file holds all the magic of CRUD (create/read/update/delete) cookies, track user's events and interaction with the webpage.
The pixel code.
This is an <img> tag with the src atribute pointing to an image *.gif (for example) file that takes all the parameters collected on the page, and stores them in the database.
Example:
WordPress pixel code: <img id="wpstats" src="http://stats.wordpress.com/g.gif?host=www.hostname.com&list_of_cookies_value_pairs;" alt="">
Google Analitycs:
http://www.google-analytics.com/__utm.gif?utmwv=4&utmn=769876874&etc
Now, it's obvious that the *.gif request has to reach a server side scripting language in order to read the parameters data and store them in a db.
Does anyone have an idea how to implement this in Zend?
UPDATE
Another thing I'm interested in is: How to avoid the user's browser to load the cached *.gif ? Will a random parameter value do the trick? Example: src="pixel.gif?nocache=random_number" where the nocache parameter value will be different on every request.
As Zend is built using PHP, it might be worth reading the following question and answer: Developing a tracking pixel.
In addition to this answer and as you're looking for a way of avoiding caching the tracking image, the easiest way of doing this is to append a unique/random string to it, which is generated at runtime.
For example, server-side and with the creation of each image, you might add a random URL id:
<?php
// Generate random id of min/max length
$rand_id = rand(8, 8);
// Echo the image and append a random string
echo "<img src='pixel.php?a=".$vara."&b=".$varb."&rand=".$rand_id."'>";
?>
Just adding my 2 cents to this thread because I think an important, and frequently used, option is missing: you don't necessarily need a scripting language to capture the request. A more efficient approach is to use the web server access log (like apache access log for instance) to log the request and then handle that log with whatever tools you see fit, like ELK stack for instance.
This makes serving the requests much lighter because no scripting language is loaded to prepare the response, just native apache response, which is typically much more efficient.
First of all, the *.gif doesn't need to be that file type, the only thing that is of interest is the Content-Type http header. Set that to image/gif (or any other, appropiate type) in the beginning, execute your code and render some sort of image to the response body.
Well, all of the above codes are correct and is good but to be certain, the guy above mention "g.gif"
You can just add a simple php code to write to an sql or fwrite("file.txt",$opened)
where var $opened serves as the counter++ if someone opened your mail... then save it as "g.gif"
TO DO all of this just add these:
<Files "/thisdirectory">
AddType application/x-httpd-php .gif
</Files>
to your ".htaccess" file but be sure to make a new directory for that g.gif or whatever.gif where the directory only contains g.gif and .htaccess

REST API versioning when using Atom for resource collections

I know this is something that has been discussed over and over, and I have done extensive research to get where I am so far, but can't seem to get over the final hurdle.
I am designing a custom REST api for our application, and have decided that I would like to version using media types e.g. application/vnd.mycompany.resource.v2+xml. I realise the pro's and con's of this model and it seems to weigh up the most flexible.
Hence my GET would look as follows:
=== REQUEST ===>
GET /workspaces/123/contacts?firstName=Neil&accessID=789264&timestamp=1317611 HTTP/1.1
Accept: application/vnd.mycompany.contact-v2+xml
<== RESPONSE ===
HTTP/1.1 200 OK
Content-Type: application/vnd.mycompany.contact-v2+xml
<contact>
<name>Neil Armstrong</name>
<mobile>+61456838435</mobile>
<email>neil.armstrong#space.com</email>
</contact>
The problem is that I would like to use Atom feeds and entrys to represent my resource collections. This way I can harness the searching and pagination of Atom without this infected my resources or API structure.
If I use Atom for my requests, my request structure now looks like:
=== REQUEST ===>
GET /workspaces/123/contacts HTTP/1.1
Accept: application/atom+xml; type=feed;
<== RESPONSE ===
HTTP/1.1 200 OK
Content-Type: application/atom+xml; type=feed;
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Contacts Feed</title>
<link rel="self" href="https://api.mycompany.com/workspaces/contacts"/>
<updated>2011-11-13T18:30:02Z</updated>
...
<entry>
<title>Neil Armstrong</title>
...
<content type="application/vnd.mycompany.contact-v2+xml">
<contact>
<name>Neil Armstrong</name>
<mobile>+61456838435</mobile>
<email>neil.armstrong#space.com</email>
</contact>
</content>
</entry>
</feed>
Using Atom to represent my collections of resources, I lose the ability to version using media types. As the media type is now hidden within the content of the Atom entry.
<content type="application/vnd.mycompany.contact-v2+xml">
What is the best practice for determining the media type version of my resource, while still utilising the power of Atom for Resource collection management?
My thinking is that I could pass it through the ACCEPT header e.g.
Accept: application/atom+xml; type=feed; version=1.0
But then this is confusing as you are asking for version 1.0 of the Atom feed, not the resource itself...
Any help would be really appreciated!!
The problem is that IMHO you're misusing the media types.
Media types give you information on the STRUCTURE of the actual payload, but not the SEMANTICS of the payload. "I know this is an XHTML page, but I don't know if it's a blog post or a item on Amazon." By being an XHTML page, you know how to get the component parts out of the payload and ask interesting questions, but interpretation of the payload is not part of the media type.
Consider an example, paraphrased from an example of Roy Fielding, sending a 10,000 bit array as a GIF file that's 100x100 pixels. GIF, as "everyone knows" is used for sending pictures, but it's really simpler than that. It's a mechanism for sending structured binary that just-happen to most-of-the-time be images. So, in this case of using it to send a 10,000 bit array (perhaps represented as a gray scale image of 00 and FF), you get the benefit of a common decoder (GIF), GIFs built in compression, etc.
But, in this case, it's not a picture. You can show it as a picture, but it's a meaningless picture. The classic semantic of it being used for the picture scenario is not relevant in this case. The benefit is the ubiquity of the the format.
Another example was years ago an engineer was doing radar studies. So, he would take the 3-view drawings of aircraft you would find in books and such, and he would encode them using a tablet in to AutoCAD drawings. The DWG format was well documented, and he had code to read them. What he wanted was the coordinates and measurements from the specific aircraft.
So, in the end he had a bunch of "meaningless" AutoCAD files with nothing but a bunch of lines in it that "made no sense". But in fact they were chock full of good information for his domain. The DWG file was the media-type, but these weren't "CAD drawings". (Can you say "spontaneous reuse"?)
It's fine to version something via media-type, but that's only relevant if the media-type is in fact changing. ATOM, as you noted, isn't changing, or at least it's not changing under your control, and you may choose not to support the new version if/when it does change. But ATOM is not changing because how it represents its information, how that information is encoded, is not changing. The information may well change, in fact it changes all the time. Every ATOM feed is different with different information. MOST have similar semantics (blog feeds), but many do not (for example, perhaps your scenario).
But how you will parse and get information out of the ATOM feed will not change. And that's what the media type represents. An encoding of information, not the information itself.
So, if you want to detect versioning, then check within your payload. Inspect it. You KNOW that for V1 of your data where, for example, the invoice number is (perhaps it's at invoice/inv_no in XPATH). If the invoice is NOT there, then what do you do? You a) look some other well known place (i.e. V2), or, b) you throw an error ("Whatever this is, it's not an invoice!"). You would have to do that no matter what, because you could be getting anything, regardless of what the version says, or the media type says, or what anything else says.
You can make your payloads forward compatible to be resistant to breaking change, then version is a matter of making use of all the information you can see. If you get A and B, then while you'd like to have C and D as well, the clients can get by with the more limited information. Of if the clients see C and D, they would know to ignore A and B, as that data is deprecated. Same with the server. If something is sending A and B, it's implied to be an older processing model than if they sent along C and D.
You can version through rel names "order" vs "order_2", old clients only know to use "order", new clients know to use "order_2" and follow that link instead.
Or you simply include a version identifier in the payload, that's an easy check as well (especially since it's early in your design).
There are a lot of ways to manage the versioning, but the media type really shouldn't be the mechanism. That's why this really isn't a "problem" with ATOM. So, it's a matter of perspective.
I have another discussion about the Accept header over here: REST API having same object, but light
This (IMHO) unrelated to your versioning issue, but it's an example of extended media-types. But that's only my perception of why and how most folks want "versioning". A case could be made this case is the same thing, but most folks associate versioning with services, not simply data representations, which this other post was mostly about.
In the end, either your client and/or server are flexible enough to handle versioned data or they're not. They will (mostly, they are computers after all. Deterministic my heinie...) do what they're told. A simple rule of "ignore stuff that you don't know" can take you quite far in terms of versioning without ever changing a v1 to a v2, regardless of your encoding. Likewise "work with what you have" is a nice rule for a flexible, tolerant server. If you have problems in either case, that's what errors, logs, operators, and 24hr pagers are for, and you need those anyway.

Is it ok to return application/octet-stream from a REST interface?

Am I breaking any laws in the REST bible by returning application/octet-stream for my responses ? The REST endpoint receives 5 image urls.
{ "image1": "http://ww.o.com/1.gif",
"image2": "http://www.foo.be/2.gif" }
and it will download these and return them as application/octet-stream.
CLARIFICATION: The client that invokes this REST interface is a mobile app. Every additional network connections made will reduce battery life by a few milliamps. I am forced to use REST because it is a company standard. If not, I will do my own binary protocol.
It is not so good, as the client will not know what to do with such binary data except of storing those bytes somewhere or sending them further to some other process (if this is all you need to do with your data, then it is fine).
You may take a look at multipart content types. IMO, a multipart message containing several image/gif parts would be a better alternative.
From the sounds of this, this sounds much more like an RPC call. Specifically, "here's a list of URLs, send me back an archive".
That process is not particularly RESTful, as REST is not an RPC based system.
What you need to do is treat the archives as reources, and a way to create and then serve them up.
For example you could:
POST /archives
Content-Type: application/json
{ "image1": "http://ww.o.com/1.gif",
"image2": "http://www.foo.be/2.gif" }
As a result, you would get
HTTP/1.1 201 Created
Location: http://example.com/archives/1234
Content-Type: application/json
Then, you could make a request to http://example.com:
GET /archives/1234
Accept: multipart/mixed
Here, you will get the actual archive in a single request (like you want), only it's a multipart formatted result. (multipart/x-zip would work too, that's a zip file)
If you did:
GET /archives/1234
Accept: application/json
You would get back the JSON you sent originally (so you could, perhaps, edit and update the archive, something you may not want to support sending up the binary images).
To change it you would simply POST back the update:
PUT /archives/1234
Content-Type: application/json
{ "image1": "http://ww.o.com/1.gif",
"image2": "http://www.foo.be/2.gif",
"image3": "http://www.foo2.foo/4.gif" }
The resource is /archives/1234, that's its name.
It has two representations in this case: the JSON version, and the actual, binary archive. Your service distinguishes between the two using the content type specified in the Accept header. That header is the client telling you what it wants.
When you're done with the archive, simply DELETE it
DELETE /archives/1234
Or you can have the server expire the resource at some later time.
Why not have five separate REST calls?
Seems cleaner and divides more logically. It will also run the downloads in parallel, 2 or more at a time depending on the browser you are using.
They are called REST principles not laws, but no you are not "breaking" them, IMO. REST is about resources being addressable by a URL, and (where appropriate) available in multiple formats. It doesn't say what the format should be. There's a simple description of what REST means in this article.
However, as #Andrey says there are nicer ways to handle sending multiple data objects than inventing your own adhoc format. The Multipart mimeType / format is one alternative, and another is to send the objects packed up as a tar, zip or a similar archive file format.
IMO. the real problem with using "application/octet-stream" and is that it doesn't tell anyone anything about how the data is actually formatted. Rather your client has "know" how it is formatted, and interpret it accordingly. And the problems with inventing your own format are interoperability and (possibly) having to design, implement and maintain libraries to support it, possibly may times over.