RailsConf 2013

How a Request Becomes a Response

By Christopher Greene & Aimee Simone

Ever wondered what Rails is doing behind the scenes? What happens to an HTTP request after it leaves your browser? How does Rails process the response?
In this beginner talk, Aimee Simone and Christopher Green break down the request/response cycle of a web application, navigating through the magestic internals of Rails. We'll outline the responsibilities of each Rails component, including its MVC framework and RESTful routing concepts. By following the flow from a client HTTP request to a completed server response, you'll gain a better understanding of the anatomy of a Rails application.

Help us caption & translate this video!

http://amara.org/v/FGa1/

RailsConf 2013

00:00:16.560 hey guys good morning I'm Christopher
00:00:19.920 green or Chris Green or whatever you
00:00:21.439 want to call me this is Amy Simone we're
00:00:23.760 with Indy labs and uh also with code
00:00:26.679 school and we have come to give you a
00:00:30.119 little presentation about how requests
00:00:32.880 become responses so it's going to be a a
00:00:36.399 kind of jaunt from browser through the
00:00:39.280 generation of request through web server
00:00:42.320 app server all the way up through the
00:00:44.399 rail
00:00:45.239 stack back down to the client so it's
00:00:48.920 going to be we're going to touch on a
00:00:50.640 lot of things we're not going to get
00:00:51.960 into a lot of how to do this um in the
00:00:56.079 workshop section you'll have access to
00:00:58.760 rails for zombies rail Zombies 2 um
00:01:01.760 that'll get into a whole lot more of
00:01:04.280 what or how this stuff works this is
00:01:07.040 more of what is happening how to trace
00:01:09.439 it and give you some vernacular some uh
00:01:12.240 some
00:01:13.200 nomenclature give this
00:01:22.680 stuff all right um as Jeff mentioned um
00:01:26.920 this is our our Workshop page I'm sorry
00:01:30.040 just a
00:01:32.960 second um you can check out this page
00:01:35.200 for um later we're going to be posting
00:01:37.200 our slides um there's also a link to our
00:01:40.479 chat room if you want to ask each other
00:01:42.520 questions or answer questions during the
00:01:45.719 session and there's also the uh links to
00:01:49.759 the materials that we'll be using during
00:01:51.640 the
00:01:52.600 workshop so you won't you won't need
00:01:54.759 this right now but you can go ahead and
00:01:55.960 pull it up if you want
00:01:58.240 to um we're going to go ahead and get
00:02:00.719 started so as as Chris mentioned um
00:02:03.280 we're going to be following a request
00:02:06.240 through the application stack so we're
00:02:07.960 going to be
00:02:09.200 starting at the bottom with the client
00:02:11.879 where the request is initiated in the
00:02:13.879 browser follow it up through the stack
00:02:17.080 um through to the rails
00:02:19.920 application um until a request is or
00:02:22.920 until a response is formed and then
00:02:24.640 we'll be following that response back
00:02:26.920 through the stack to the browser
00:02:31.000 so what is a
00:02:34.040 request well a request is a set of
00:02:36.519 instructions that tells the server what
00:02:39.560 kind of response we
00:02:42.120 want so this is an example of a URL that
00:02:45.879 you might type into a
00:02:48.360 browser this is the example that we're
00:02:50.440 going to be following during our
00:02:53.879 talk and a request is made up of a
00:02:57.360 number of different pieces the first one
00:02:59.519 that I want want to mention is the
00:03:00.720 request
00:03:02.680 path so in our example the SL courses
00:03:06.519 portion of the URL is our request path
00:03:10.200 and this is what's going to tell our our
00:03:14.319 server um which resource we're looking
00:03:18.319 for we also have the request verb or a
00:03:23.360 method um in our case we're we're using
00:03:26.599 a get request
00:03:29.959 this is um a type of request that will
00:03:32.280 retrieve information back from our
00:03:35.599 server some other common types of
00:03:38.040 requests are post which will send
00:03:40.439 information to the server put which is
00:03:43.080 really similar to post but we're
00:03:44.560 updating information and then delete
00:03:47.400 which is pretty self-explanatory we're
00:03:49.519 removing
00:03:51.959 information we also have query data um
00:03:56.000 we don't have this in our example but we
00:03:57.799 could if we were to append some par to
00:04:00.239 the URL for instance if we were to
00:04:02.599 append page equals 2 this would tell our
00:04:06.079 application that we're looking for
00:04:07.439 something that responds to that page
00:04:10.120 parameter um maybe if we're using
00:04:12.640 pagination this would tell the
00:04:14.680 application to return the page two set
00:04:17.519 of
00:04:19.560 results you also have um header
00:04:23.759 data so there's a lot of information
00:04:26.440 that's included in the request header um
00:04:31.039 um some important parts of the request
00:04:33.199 header are the type of of response that
00:04:38.000 we want um there's or the way that we
00:04:40.520 want the response formatted so here
00:04:43.000 we're asking for text HTML we also have
00:04:46.280 some valuable information about who is
00:04:48.440 initiating the request so we have
00:04:51.320 language which here is English um we
00:04:54.240 have user agent we're using uh Mozilla
00:04:58.120 on a on a
00:05:00.199 Mac so a lot of that is um really useful
00:05:05.280 information okay so now that we've
00:05:07.759 talked about the different pieces of a
00:05:09.919 request we're going to start following
00:05:12.000 codes school.com courses from the
00:05:14.560 browser to the web
00:05:17.120 server um so just a a look ahead or
00:05:20.800 maybe a sort of a a spoiler um this is
00:05:24.440 the response that we're expecting when
00:05:26.400 we initiate our request so we're looking
00:05:28.479 for a a page on COD school.com that's
00:05:31.639 going to return a list of
00:05:35.479 courses so in our browser we type codes
00:05:38.840 school.com courses this initiates the
00:05:41.960 get request from the browser to the web
00:05:45.440 server what is a web server um this is
00:05:48.319 something that I've mentioned a number
00:05:50.039 of times but maybe we should we should
00:05:51.720 talk about what it actually
00:05:55.319 is a web server it essentially delivers
00:05:58.680 web pages
00:06:00.160 on the request of clients using
00:06:06.599 HTTP it also handles the delivery of
00:06:09.720 application
00:06:13.840 content so in rails some examples of web
00:06:17.520 servers that you might use or see are
00:06:21.440 enginex um sometimes
00:06:24.400 Apache web brick is really common
00:06:31.080 okay and then the next step in our
00:06:33.960 request journey is we're going to be
00:06:35.759 following the request from the web
00:06:37.840 server to the app
00:06:40.880 server so we've made a request to the
00:06:43.319 web server it was accepted and now it's
00:06:46.039 being passed to the application
00:06:48.039 server what is an app
00:06:51.440 server an app server handles execution
00:06:54.639 of procedures for an
00:06:56.960 application um we're not going to go too
00:06:59.080 much into the intricacies of of how this
00:07:02.479 works or of all the different roles that
00:07:05.240 the app server um serves but for our
00:07:11.319 purposes um you just need to know that
00:07:13.840 the app server is going to initiate
00:07:19.879 rails
00:07:21.560 some some uh appservers that you might
00:07:24.360 see in a rails application are
00:07:28.039 passenger then
00:07:30.639 Mong
00:07:36.800 girl right
00:07:38.720 so just wanted to show this again it's
00:07:41.199 it's sort of a big description
00:07:44.080 but like I said all you really need to
00:07:46.199 know is that it's going to spin up an
00:07:47.599 instance of rails for your
00:07:51.560 application okay so now our request has
00:07:54.240 moved from the application server to
00:07:56.960 rails so we've moved from browser to web
00:08:00.240 server web server to app server and now
00:08:03.720 the request is passed to
00:08:06.319 rails and I hand it over to
00:08:09.800 Christopher give me the
00:08:11.960 thing love this
00:08:15.039 thing right so we've gone
00:08:18.400 through from the client the web server
00:08:22.479 has accepted a request it sees that
00:08:26.000 the the path that's been set up is for
00:08:29.479 for a particular application in um you
00:08:31.759 know in Apache in engine X you will have
00:08:34.200 uh kind of modules like uh if you're a
00:08:36.000 PHP developer mod PHP or or that kind of
00:08:39.279 stuff familiar with net and that's the
00:08:41.560 point where um kind of the net service
00:08:44.880 starts up with a uh with a request
00:08:46.680 versus what's happening in a um IAS and
00:08:50.279 non- integrated mode
00:08:54.000 um so at that point in
00:08:58.240 time with when rails get started up with
00:09:00.959 the application
00:09:02.399 server the request essentially hits this
00:09:05.640 router first the router is going
00:09:08.800 to tell the rails
00:09:11.640 application
00:09:13.680 where to Route this request actually in
00:09:16.040 the
00:09:18.920 application so we start with the
00:09:22.079 router remember our request was a get to
00:09:25.839 Cod school.com courses
00:09:31.360 this is what a routes RB uh file look
00:09:33.600 like this is a this is how you define
00:09:35.640 routes don't worry about the specifics
00:09:37.360 of this all I want you to worry about is
00:09:39.640 the fact that in this case we have a
00:09:41.959 resources that we're calling courses and
00:09:44.880 that's going to result in a match this
00:09:47.800 only index show we're talking about
00:09:50.000 actions again don't worry about
00:09:51.880 nomenclature right now you'll see how it
00:09:53.560 all kind of links
00:09:57.160 together after this is set up
00:10:01.480 we can run a command called Rake routes
00:10:03.959 which tells us what is actually
00:10:05.800 generated from
00:10:07.880 this this is hard to see in fact this is
00:10:10.399 impossible to see for most of you little
00:10:13.279 easier to
00:10:17.720 see these individual
00:10:20.360 things are the results of that routes
00:10:24.560 file this is what is being defined by
00:10:27.440 the routes of what is what is being
00:10:28.959 accepted
00:10:30.399 essentially what happens
00:10:32.200 is we are looking at our request you
00:10:34.720 know the SL course is that path we're
00:10:37.519 looking at the verb or the
00:10:39.480 method and we are looking down this list
00:10:42.279 for something that matches the
00:10:44.800 get and the
00:10:46.800 path and over on the right side here
00:10:49.079 which will be blown up in just a second
00:10:51.040 there is a controller and an action that
00:10:53.079 that is being that is being rounded to
00:10:59.720 so this is a little easier to see so in
00:11:02.480 that long list of
00:11:03.839 stuff we see that when a router
00:11:07.920 sees a
00:11:11.040 request with the git
00:11:13.800 method to a path of SLC
00:11:19.040 courses it is going to look to that
00:11:22.360 courses
00:11:24.560 controller and an action called index on
00:11:29.040 that
00:11:30.360 so first step in the
00:11:32.639 cycle we know where things are bumping
00:11:34.760 up
00:11:39.560 too so the router has make made its
00:11:42.800 decision our controller of course is
00:11:45.680 action index and we're going to talk a
00:11:47.880 little bit about what a controller
00:11:50.279 actually is what it
00:11:55.800 does so essentially a controller
00:12:01.920 is a way to combine actions for a
00:12:06.399 particular
00:12:07.360 resource a a a thing an idea a business
00:12:10.560 idea in this case U we're looking at
00:12:12.720 courses the end result is to get a list
00:12:14.880 of those courses back so actions that
00:12:19.760 would be related to
00:12:22.040 courses would be here
00:12:25.000 a due to the naming conventions of rails
00:12:30.320 the controller we looking for since we
00:12:31.959 know it's
00:12:32.920 courses is going to be called a courses
00:12:35.880 controller um
00:12:38.199 some actions that end up being shown
00:12:40.480 with
00:12:41.600 this you
00:12:44.639 um an index action which we'll be
00:12:47.320 looking at which we saw
00:12:49.040 earlier um a show a create which ends up
00:12:53.279 going with a a
00:12:55.199 post an
00:12:56.920 update the put
00:12:59.839 but in this particular case so if if our
00:13:02.440 router had said this action goes to one
00:13:04.639 of these other or the this route goes to
00:13:06.839 one of these other
00:13:08.360 actions one of these other actions would
00:13:10.360 be chosen in this case we know it's the
00:13:15.800 index and so that's what we're going to
00:13:17.639 look
00:13:22.560 at
00:13:26.839 actions actions are a place
00:13:32.760 for you to gather
00:13:35.760 information about a certain type of
00:13:39.160 request a certain type of
00:13:40.880 action in this particular
00:13:43.839 case we are wanting to look up a list of
00:13:48.519 courses we want to look up a list of the
00:13:52.920 paths the uh a kind of a tree of of
00:13:57.560 different learning requirements as well
00:14:01.040 so we're Gathering that information at
00:14:02.680 this point in time to later on be passed
00:14:04.600 to the view so that is what an
00:14:08.880 action in a controller is for is
00:14:12.160 gathering that information prior
00:14:14.560 to passing it onto a view allowing it to
00:14:18.079 render coming back down the
00:14:23.680 stack so
00:14:26.199 a little more info about
00:14:31.800 another part of our NVC stack we've gone
00:14:34.320 through a controller so far the C in our
00:14:37.839 NVC and we're going to look at models
00:14:40.279 for a
00:14:42.040 second um a model is just another
00:14:45.600 abstraction of some kind of business
00:14:47.440 object business requirement a a user a
00:14:50.560 course a an order a um you know a
00:14:55.560 catalog item number
00:15:00.040 in this
00:15:04.920 case our course which our little arrow
00:15:08.880 is off a little bit there but uh our
00:15:11.519 course
00:15:12.680 is is a model this is a representation
00:15:16.519 of what we are pulling that course
00:15:18.000 information
00:15:22.399 from the same with the path that we saw
00:15:25.079 so this is in our gathering of
00:15:26.880 information this is how a
00:15:29.880 a controller an action relates to a
00:15:32.079 Model A model is just a way to a thing
00:15:34.959 that gets information then you can be
00:15:38.440 any number of different things uh most
00:15:40.600 of what you'll see with uh when you're
00:15:42.720 looking at intro rail stuff is going to
00:15:45.120 be active record which is database
00:15:47.279 backed but it could really be anything
00:15:50.199 um you could have a model of you know
00:15:52.440 get get Weather Service or or get some
00:15:55.399 information from Twitter or Facebook or
00:15:57.519 something else if you want to do that
00:15:58.680 behind the scenes as opposed to on the
00:16:00.240 client um and all of those could be
00:16:03.079 considered
00:16:06.199 models is just to keep that kind of
00:16:09.160 logic outside of outside of the
00:16:12.240 controller so in this case this
00:16:14.759 model the courses and
00:16:17.720 path are active record
00:16:20.920 objects which end
00:16:24.759 up linking to tables in a database base
00:16:29.880 that with naming
00:16:31.120 convention courses path
00:16:34.920 so in our action when we are looking
00:16:38.560 up the
00:16:41.519 courses we are reaching out to the
00:16:44.759 database pulling back that information
00:16:46.839 generating a list that'll then be passed
00:16:48.720 out to the view to render things
00:16:56.880 down so the stack once
00:17:01.040 more request is
00:17:03.760 made the web server gets it figures out
00:17:06.360 that it needs to be passed on to an
00:17:07.679 application server for it to start up
00:17:09.600 the rails
00:17:11.000 application the application server gets
00:17:13.480 that there
00:17:15.799 is
00:17:17.839 in you'll you'll hear things about Metal
00:17:21.079 about rack if if any of you kind of ears
00:17:24.199 are perking up at this point in time
00:17:25.559 about this stuff um there are other
00:17:27.959 steps in the app ver as Ruby is starting
00:17:31.799 to form up as the rails process is being
00:17:34.840 built up there are things middleware
00:17:37.720 actions that are happening that the last
00:17:39.720 one in that stack is rails itself rails
00:17:43.200 is a rack middleware again it's not
00:17:46.400 something that you need to necessarily
00:17:47.600 worry about just know that this stuff
00:17:50.880 exists in
00:17:52.440 um in other languages in net that kind
00:17:55.600 of thing this would be kind of a
00:17:57.840 uh things that are happening in along
00:18:01.080 the HTTP pipeline so if you are getting
00:18:04.240 a request in before it actually hits the
00:18:06.600 rails application you want to do
00:18:08.919 something you want to change something
00:18:10.200 you want to add a um you want to add a
00:18:12.600 header you want to add some kind of
00:18:13.919 other information there is a chance for
00:18:16.400 you to do that before it actually gets
00:18:18.480 to rails and then once the rails
00:18:20.440 processing ends there's a chance to
00:18:22.880 modify that response at the at the end
00:18:25.440 as well so just know that that exists
00:18:31.039 once rails has started
00:18:32.840 up and the request information is passed
00:18:36.760 over the router looks at the path it
00:18:40.000 looks at the method the
00:18:42.120 verb and figures out what controller and
00:18:46.000 what action are going to be
00:18:51.840 called when the controller action is
00:18:55.360 called Data starts to be gathered in
00:19:00.640 to be used to render whatever your
00:19:03.080 response is going to be whether that's
00:19:04.320 going out to HTML which is what we're
00:19:05.919 doing in this case or XML or Json or
00:19:09.679 whatever whatever else it could
00:19:18.480 be so at that point we've collected all
00:19:20.919 we've collected our
00:19:23.520 data and we are
00:19:26.840 ready to have a view you
00:19:32.440 render in this particular
00:19:35.400 case because of the conventions of
00:19:38.280 rails we would be looking for
00:19:41.080 a view in um in this location the index
00:19:44.840 HTML haml because of the way we have our
00:19:47.400 app configured it could be Erb it could
00:19:49.960 be any any number of
00:19:53.039 things
00:19:54.760 the action the index passes those
00:19:58.120 variables that you've made the the
00:19:59.760 courses the the paths all those lists
00:20:02.400 into the view for
00:20:03.679 rendering The View goes through it's a
00:20:05.880 like a template a a mail merge if you
00:20:08.520 will of just going through different
00:20:09.799 information creating that
00:20:13.120 HTML and eventually
00:20:16.600 gets kind of yields back to the index so
00:20:21.320 the data is written into the response
00:20:25.039 body and
00:20:29.799 is is pretty much ready at that point in
00:20:31.320 time to start heading back down the
00:20:36.400 stack we have not really said what a
00:20:39.080 response has in it
00:20:41.000 though so we went over what a request
00:20:43.240 has in it initially and we said a
00:20:45.799 request tells the server tells the
00:20:47.840 application what we're looking
00:20:50.320 for and kind of how to process the
00:20:55.120 request so here's some examples of that
00:20:58.280 kind of implemented here so in the
00:21:01.760 response
00:21:02.960 headers the server is bringing back it's
00:21:05.520 saying okay the content type of this
00:21:07.679 thing that I'm sending back to you is
00:21:13.120 HTML in our
00:21:15.679 request we gave it a header of hey I
00:21:18.360 want to accept
00:21:22.120 HTML round trip
00:21:24.960 right if our content type could have
00:21:28.080 been um or if our accept header would
00:21:30.559 have been Json or XML or anything
00:21:36.200 else the content type coming back you
00:21:39.279 would expect to match up with that and
00:21:42.279 to be able to process it based on
00:21:45.559 that another example is in our request
00:21:49.559 we said our encodings that we can accept
00:21:52.240 from this we can accept uh gzip or
00:21:55.679 deflate which means that the browser
00:21:59.240 that you're
00:22:00.600 using can accept like compress data
00:22:05.120 down again the actual meaning of that is
00:22:08.279 really not important other than in our
00:22:10.559 headers in our response it tells us that
00:22:14.159 this is what the server has done for us
00:22:17.279 we've requested these things number of
00:22:19.279 things and this is what is actually
00:22:21.360 coming
00:22:22.640 back um other things that coming back in
00:22:25.000 the in the response
00:22:27.400 header um um
00:22:30.000 cookies this is
00:22:32.640 the this is where cookies come back are
00:22:36.240 built into or how the vector by which
00:22:40.720 cookies get back to the browser is
00:22:43.200 through the response headers
00:22:45.520 so you're authenticating something you
00:22:47.760 want to add a little a little bit of
00:22:49.440 extra data
00:22:50.640 in in that
00:22:53.159 response that's where that data lives is
00:22:55.360 in the headers
00:22:59.960 another thing that comes back with the
00:23:01.159 response is a status code
00:23:04.320 um these are things that you probably
00:23:08.320 have seen and um people really notice uh
00:23:13.640 you know 200s which is is great it's
00:23:16.760 good um it means that everything
00:23:18.960 everything worked perfectly well it's
00:23:21.120 great
00:23:23.000 um in uh requests that are or statuses
00:23:27.279 that are 300 something are things like a
00:23:30.760 um a
00:23:32.279 301 I think is a is a temporary redirect
00:23:36.360 um or permanent redirect either way um
00:23:40.919 telling someone like Google for instance
00:23:43.480 that this page has been moved over to
00:23:45.400 this other location right um or a
00:23:49.240 temporary redirect something like that
00:23:51.440 uh 400 client error um
00:23:55.440 if you have a form
00:23:58.799 that you want to have validation working
00:24:01.559 on you push it up to the web server it
00:24:04.279 says hey this crap isn't valid you've
00:24:06.520 you've completely screwed this up this
00:24:08.799 this request up and you want the server
00:24:11.080 to tell the browser that hey this is
00:24:12.960 specifically what this error is is not
00:24:15.000 that the database is offline or you know
00:24:18.200 the data center is burning down or
00:24:19.520 something it's that the request had bad
00:24:22.080 crap in
00:24:23.480 it 400 serious responses come back for
00:24:26.480 that and then the um the evil 500 series
00:24:30.760 you have uh um just 500s thing things is
00:24:35.520 broke uh Panic responses and there are
00:24:38.799 others uh 400 something is I am a teapot
00:24:41.399 I think which is wonderful but you'll
00:24:43.520 probably never see that in uh in
00:24:48.399 action the final thing you'll see is
00:24:51.000 there is a there is a
00:24:53.200 body
00:24:54.840 which is just essentially a dump of
00:24:57.600 whatever content is is coming back if
00:24:59.520 you were requesting a image that body
00:25:02.640 would be the um you know the the asy Bas
00:25:07.600 64 equivalent of that image if it's
00:25:12.080 HTML HTML the Json it'll be Json text
00:25:16.000 XML XML text so what is in the body in
00:25:21.000 combination with that content type
00:25:23.279 that's coming back is what lets the
00:25:25.600 browser know okay hey this thing is is
00:25:29.039 supposed to be Json so I should do
00:25:31.120 something with it in this way or XML or
00:25:33.640 HTML or whatever it might be or it's a
00:25:37.799 um a video file so we need to pop up a
00:25:41.080 you know save you know save as box or
00:25:43.360 whatever for
00:25:45.399 you so when I talk about writing writing
00:25:48.679 H HTML to the body of the
00:25:50.679 response this is what I'm talking about
00:25:52.679 it's the it is the payload that's being
00:25:55.159 delivered back down to to the client to
00:25:58.559 the
00:26:04.799 browser so we're pretty much at the top
00:26:06.640 of the stack at this point we've gone
00:26:09.000 all the way up we've gathered our
00:26:11.320 information we we've hit the correct
00:26:13.760 resource um we've hit the view that we
00:26:15.880 wanted to to hit and it's time to start
00:26:19.679 bouncing things back down the stack it's
00:26:23.279 not
00:26:24.240 a it is not a direct route down the
00:26:28.360 router is out of the picture at this
00:26:29.880 point in time the controller should be
00:26:31.679 out of the picture at this point in time
00:26:33.640 don't need them
00:26:36.640 anymore essentially what happens is
00:26:39.559 after everything is
00:26:41.039 written you're going back to the app
00:26:44.600 server the the rack application stack
00:26:48.360 and it's coming back through that
00:26:49.440 middleware I talked about which gives
00:26:51.880 you a a chance after the view has been
00:26:53.960 written that if you want to add an
00:26:56.320 additional header you want to add some
00:26:57.679 kind of other information to the
00:26:58.840 response before it actually goes out but
00:27:01.520 you don't want to do it in the context
00:27:03.080 of um of a controller of view if you
00:27:06.120 want to uh centralize some of that
00:27:09.000 action this is an opportunity that you
00:27:11.000 can do
00:27:14.440 that the app server is done with its um
00:27:18.559 with that
00:27:20.840 stack that r that response is patched
00:27:23.640 down to the uh to the web server itself
00:27:26.440 the web server at this point in time is
00:27:27.760 kind of kept track of that connection
00:27:30.200 with the uh with the browser with or
00:27:32.520 whatever client is being used um and at
00:27:35.120 that point in
00:27:36.240 time it starts writing response
00:27:39.799 back browser gets the response gets a
00:27:42.880 status code um if you have a 200
00:27:48.159 there everything is good you have
00:27:54.200 a successful
00:27:56.679 response in a
00:27:59.120 list of items that have come from a
00:28:01.559 model you have you're looking at a
00:28:04.720 courses resource that the router was
00:28:06.799 able to get to the right controller and
00:28:08.600 the right
00:28:11.159 action and it's in the right format
00:28:14.480 because the browser has said hey give me
00:28:16.480 give me HTML
00:28:18.559 back the server is giving you HTML
00:28:27.120 back yeah