| 726 | } |
| 727 | |
| 728 | void TClientRequest::Process(void* ThreadSpecificResource) { |
| 729 | THolder<TClientRequest> this_(this); |
| 730 | |
| 731 | auto* serverImpl = Conn_->HttpServ_; |
| 732 | |
| 733 | try { |
| 734 | if (!HttpConn_) { |
| 735 | const size_t outputBufferSize = HttpServ()->Options().OutputBufferSize; |
| 736 | if (outputBufferSize) { |
| 737 | HttpConn_.Reset(new THttpServerConn(Socket(), outputBufferSize)); |
| 738 | } else { |
| 739 | HttpConn_.Reset(new THttpServerConn(Socket())); |
| 740 | } |
| 741 | |
| 742 | auto maxRequestsPerConnection = HttpServ()->Options().MaxRequestsPerConnection; |
| 743 | HttpConn_->Output()->EnableKeepAlive(HttpServ()->Options().KeepAliveEnabled && (!maxRequestsPerConnection || Conn_->ReceivedRequests < maxRequestsPerConnection)); |
| 744 | HttpConn_->Output()->EnableCompression(HttpServ()->Options().CompressionEnabled); |
| 745 | } |
| 746 | |
| 747 | if (!BeforeParseRequestOk(ThreadSpecificResource)) { |
| 748 | ReleaseConnection(); |
| 749 | return; |
| 750 | } |
| 751 | |
| 752 | if (ParsedHeaders.empty()) { |
| 753 | RequestString = Input().FirstLine(); |
| 754 | |
| 755 | const THttpHeaders& h = Input().Headers(); |
| 756 | ParsedHeaders.reserve(h.Count()); |
| 757 | for (THttpHeaders::TConstIterator it = h.Begin(); it != h.End(); ++it) { |
| 758 | ParsedHeaders.emplace_back(it->Name(), it->Value()); |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | if (Reply(ThreadSpecificResource)) { |
| 763 | ReleaseConnection(); |
| 764 | |
| 765 | /* |
| 766 | * *this will be destroyed... |
| 767 | */ |
| 768 | |
| 769 | return; |
| 770 | } |
| 771 | } catch (...) { |
| 772 | serverImpl->Cb_->OnException(); |
| 773 | |
| 774 | throw; |
| 775 | } |
| 776 | |
| 777 | Y_UNUSED(this_.Release()); |
| 778 | } |
| 779 | |
| 780 | void TClientRequest::ProcessFailRequest(int failstate) { |
| 781 | Output() << "HTTP/1.1 503 Service Unavailable\r\n" |